| @@ -28,6 +28,7 @@ | |||||
| #include "../jucer_Headers.h" | #include "../jucer_Headers.h" | ||||
| #include "jucer_MainWindow.h" | #include "jucer_MainWindow.h" | ||||
| #include "jucer_CommandLine.h" | #include "jucer_CommandLine.h" | ||||
| #include "../project/jucer_Module.h" | |||||
| #include "jucer_AutoUpdater.h" | #include "jucer_AutoUpdater.h" | ||||
| #include "../Code Editor/jucer_SourceCodeEditor.h" | #include "../Code Editor/jucer_SourceCodeEditor.h" | ||||
| @@ -109,8 +109,6 @@ public: | |||||
| bool isDifferentVersionToCurrent() const | bool isDifferentVersionToCurrent() const | ||||
| { | { | ||||
| JUCE_COMPILER_WARNING("testing") | |||||
| return true; | |||||
| return version != JUCE_STRINGIFY(JUCE_MAJOR_VERSION) | return version != JUCE_STRINGIFY(JUCE_MAJOR_VERSION) | ||||
| "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) | "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) | ||||
| "." JUCE_STRINGIFY(JUCE_BUILDNUMBER) | "." JUCE_STRINGIFY(JUCE_BUILDNUMBER) | ||||
| @@ -141,23 +139,69 @@ return true; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| JUCE_COMPILER_WARNING("todo") | |||||
| if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | |||||
| TRANS("Download JUCE version 123?").replace ("123", info.version), | |||||
| TRANS("A new version of JUCE is available - would you like to download it?"))) | |||||
| { | |||||
| return; | |||||
| } | |||||
| File targetFolder; | |||||
| File targetFolder (findDefaultModulesFolder()); | |||||
| // FileChooser f; | |||||
| if (isJuceModulesFolder (targetFolder)) | |||||
| targetFolder = targetFolder.getParentDirectory(); | |||||
| DownloadNewVersionThread::performDownload (info.url, targetFolder); | |||||
| FileChooser chooser (TRANS("Please select the location into which you'd like to install the new version"), | |||||
| targetFolder); | |||||
| if (chooser.browseForDirectory()) | |||||
| { | |||||
| targetFolder = chooser.getResult(); | |||||
| if (isJuceModulesFolder (targetFolder)) | |||||
| targetFolder = targetFolder.getParentDirectory(); | |||||
| if (targetFolder.getChildFile ("JUCE").isDirectory()) | |||||
| targetFolder = targetFolder.getChildFile ("JUCE"); | |||||
| if (targetFolder.getChildFile (".git").isDirectory()) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||||
| TRANS ("Downloading new JUCE version"), | |||||
| TRANS ("This folder is a GIT repository!\n\n" | |||||
| "You should use a \"git pull\" to update it to the latest version. " | |||||
| "Or to use the Introjucer to get an update, you should select an empty " | |||||
| "folder into which you'd like to download the new code.")); | |||||
| return; | |||||
| } | |||||
| if (isJuceFolder (targetFolder)) | |||||
| { | |||||
| if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | |||||
| TRANS("Overwrite existing JUCE folder?"), | |||||
| TRANS("Do you want to overwrite the folder:\n\n" | |||||
| "xfldrx\n\n" | |||||
| " ..with the latest version from juce.com?\n\n" | |||||
| "(Please note that this will overwrite everything in that folder!)") | |||||
| .replace ("xfldrx", targetFolder.getFullPathName()))) | |||||
| { | |||||
| return; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| targetFolder = targetFolder.getChildFile ("JUCE").getNonexistentSibling(); | |||||
| } | |||||
| DownloadNewVersionThread::performDownload (info.url, targetFolder); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static bool isZipFolder (const File& f) | static bool isZipFolder (const File& f) | ||||
| { | { | ||||
| JUCE_COMPILER_WARNING("testing") | |||||
| return true; | |||||
| return f.getChildFile ("modules").isDirectory() | return f.getChildFile ("modules").isDirectory() | ||||
| && f.getChildFile ("extras").isDirectory() | && f.getChildFile ("extras").isDirectory() | ||||
| && f.getChildFile ("examples").isDirectory() | && f.getChildFile ("examples").isDirectory() | ||||
| @@ -220,7 +264,7 @@ private: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| JUCE_COMPILER_WARNING("todo") | |||||
| new RelaunchTimer (targetFolder); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -252,7 +296,7 @@ JUCE_COMPILER_WARNING("todo") | |||||
| if (threadShouldExit()) | if (threadShouldExit()) | ||||
| return Result::fail ("cancel"); | return Result::fail ("cancel"); | ||||
| size_t written = mo.writeFromInputStream (*in, 8192); | |||||
| int64 written = mo.writeFromInputStream (*in, 8192); | |||||
| if (written == 0) | if (written == 0) | ||||
| break; | break; | ||||
| @@ -273,7 +317,8 @@ JUCE_COMPILER_WARNING("todo") | |||||
| { | { | ||||
| setStatusMessage ("Installing..."); | setStatusMessage ("Installing..."); | ||||
| File tempUnzipped; | |||||
| File unzipTarget; | |||||
| bool isUsingTempFolder = false; | |||||
| { | { | ||||
| MemoryInputStream input (data, false); | MemoryInputStream input (data, false); | ||||
| @@ -282,32 +327,43 @@ JUCE_COMPILER_WARNING("todo") | |||||
| if (zip.getNumEntries() == 0) | if (zip.getNumEntries() == 0) | ||||
| return Result::fail ("The downloaded file wasn't a valid JUCE file!"); | return Result::fail ("The downloaded file wasn't a valid JUCE file!"); | ||||
| tempUnzipped = targetFolder.getNonexistentSibling(); | |||||
| unzipTarget = targetFolder; | |||||
| if (! tempUnzipped.createDirectory()) | |||||
| return Result::fail ("Couldn't create a folder to unzip the new version!"); | |||||
| if (unzipTarget.exists()) | |||||
| { | |||||
| isUsingTempFolder = true; | |||||
| unzipTarget = targetFolder.getNonexistentSibling(); | |||||
| Result r (zip.uncompressTo (tempUnzipped)); | |||||
| if (! unzipTarget.createDirectory()) | |||||
| return Result::fail ("Couldn't create a folder to unzip the new version!"); | |||||
| } | |||||
| Result r (zip.uncompressTo (unzipTarget)); | |||||
| if (r.failed()) | if (r.failed()) | ||||
| { | { | ||||
| tempUnzipped.deleteRecursively(); | |||||
| if (isUsingTempFolder) | |||||
| unzipTarget.deleteRecursively(); | |||||
| return r; | return r; | ||||
| } | } | ||||
| } | } | ||||
| File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling()); | |||||
| if (! targetFolder.moveFileTo (targetFolder.getNonexistentSibling())) | |||||
| if (isUsingTempFolder) | |||||
| { | { | ||||
| tempUnzipped.deleteRecursively(); | |||||
| return Result::fail ("Could not remove the existing folder!"); | |||||
| } | |||||
| File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling()); | |||||
| if (! tempUnzipped.moveFileTo (targetFolder)) | |||||
| { | |||||
| tempUnzipped.deleteRecursively(); | |||||
| return Result::fail ("Could not overwrite the existing folder!"); | |||||
| if (! targetFolder.moveFileTo (oldFolder)) | |||||
| { | |||||
| unzipTarget.deleteRecursively(); | |||||
| return Result::fail ("Could not remove the existing folder!"); | |||||
| } | |||||
| if (! unzipTarget.moveFileTo (targetFolder)) | |||||
| { | |||||
| unzipTarget.deleteRecursively(); | |||||
| return Result::fail ("Could not overwrite the existing folder!"); | |||||
| } | |||||
| } | } | ||||
| return Result::ok(); | return Result::ok(); | ||||
| @@ -320,6 +376,37 @@ JUCE_COMPILER_WARNING("todo") | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadNewVersionThread) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadNewVersionThread) | ||||
| }; | }; | ||||
| struct RelaunchTimer : private Timer | |||||
| { | |||||
| RelaunchTimer (const File& f) : parentFolder (f) | |||||
| { | |||||
| startTimer (1500); | |||||
| } | |||||
| void timerCallback() override | |||||
| { | |||||
| stopTimer(); | |||||
| File app = parentFolder.getChildFile ( | |||||
| #if JUCE_MAC | |||||
| "Introjucer.app"); | |||||
| #elif JUCE_WINDOWS | |||||
| "Introjucer.exe"); | |||||
| #elif JUCE_LINUX | |||||
| "Introjucer"); | |||||
| #endif | |||||
| JUCEApplication::quit(); | |||||
| if (app.exists()) | |||||
| app.startAsProcess(); | |||||
| delete this; | |||||
| } | |||||
| File parentFolder; | |||||
| }; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LatestVersionChecker) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LatestVersionChecker) | ||||
| }; | }; | ||||
| @@ -543,3 +543,24 @@ Project* MainWindowList::getFrontmostProject() | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| File findDefaultModulesFolder (bool mustContainJuceCoreModule) | |||||
| { | |||||
| const MainWindowList& windows = IntrojucerApp::getApp().mainWindowList; | |||||
| for (int i = windows.windows.size(); --i >= 0;) | |||||
| { | |||||
| if (Project* p = windows.windows.getUnchecked (i)->getProject()) | |||||
| { | |||||
| const File f (EnabledModuleList::findDefaultModulesFolder (*p)); | |||||
| if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule)) | |||||
| return f; | |||||
| } | |||||
| } | |||||
| if (mustContainJuceCoreModule) | |||||
| return findDefaultModulesFolder (false); | |||||
| return File::nonexistent; | |||||
| } | |||||
| @@ -895,3 +895,13 @@ void EnabledModuleList::addModuleOfferingToCopy (const File& f) | |||||
| addModule (m.manifestFile, areMostModulesCopiedLocally()); | addModule (m.manifestFile, areMostModulesCopiedLocally()); | ||||
| } | } | ||||
| bool isJuceFolder (const File& f) | |||||
| { | |||||
| return isJuceModulesFolder (f.getChildFile ("modules")); | |||||
| } | |||||
| bool isJuceModulesFolder (const File& f) | |||||
| { | |||||
| return f.isDirectory() && f.getChildFile ("juce_core").isDirectory(); | |||||
| } | |||||
| @@ -30,6 +30,11 @@ | |||||
| class ProjectExporter; | class ProjectExporter; | ||||
| class ProjectSaver; | class ProjectSaver; | ||||
| //============================================================================== | |||||
| File findDefaultModulesFolder (bool mustContainJuceCoreModule = true); | |||||
| bool isJuceModulesFolder (const File&); | |||||
| bool isJuceFolder (const File&); | |||||
| //============================================================================== | //============================================================================== | ||||
| struct ModuleDescription | struct ModuleDescription | ||||
| { | { | ||||
| @@ -30,7 +30,7 @@ | |||||
| #include "../Project Saving/jucer_ProjectExporter.h" | #include "../Project Saving/jucer_ProjectExporter.h" | ||||
| #include "../Utility/jucer_TranslationTool.h" | #include "../Utility/jucer_TranslationTool.h" | ||||
| #include "../Utility/jucer_JucerTreeViewBase.h" | #include "../Utility/jucer_JucerTreeViewBase.h" | ||||
| #include "jucer_NewFileWizard.h" | |||||
| #include "../Wizards/jucer_NewFileWizard.h" | |||||
| #include "jucer_GroupInformationComponent.h" | #include "jucer_GroupInformationComponent.h" | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -241,7 +241,8 @@ void ProjectContentComponent::resized() | |||||
| if (contentView != nullptr) | if (contentView != nullptr) | ||||
| contentView->setBounds (r); | contentView->setBounds (r); | ||||
| logo->setBounds (r.reduced (r.getWidth() / 4, r.getHeight() / 4)); | |||||
| if (logo != nullptr) | |||||
| logo->setBounds (r.reduced (r.getWidth() / 4, r.getHeight() / 4)); | |||||
| } | } | ||||
| void ProjectContentComponent::lookAndFeelChanged() | void ProjectContentComponent::lookAndFeelChanged() | ||||
| @@ -26,7 +26,7 @@ | |||||
| #define __JUCER_NEWFILEWIZARD_JUCEHEADER__ | #define __JUCER_NEWFILEWIZARD_JUCEHEADER__ | ||||
| #include "../jucer_Headers.h" | #include "../jucer_Headers.h" | ||||
| #include "jucer_Project.h" | |||||
| #include "../Project/jucer_Project.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -77,33 +77,6 @@ static File& getLastWizardFolder() | |||||
| return lastFolder; | return lastFolder; | ||||
| } | } | ||||
| static bool isJuceModulesFolder (const File& f) | |||||
| { | |||||
| return f.isDirectory() | |||||
| && f.getChildFile ("juce_core").isDirectory(); | |||||
| } | |||||
| static File findDefaultModulesFolder (bool mustContainJuceCoreModule = true) | |||||
| { | |||||
| const MainWindowList& windows = IntrojucerApp::getApp().mainWindowList; | |||||
| for (int i = windows.windows.size(); --i >= 0;) | |||||
| { | |||||
| if (Project* p = windows.windows.getUnchecked (i)->getProject()) | |||||
| { | |||||
| const File f (EnabledModuleList::findDefaultModulesFolder (*p)); | |||||
| if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule)) | |||||
| return f; | |||||
| } | |||||
| } | |||||
| if (mustContainJuceCoreModule) | |||||
| return findDefaultModulesFolder (false); | |||||
| return File::nonexistent; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| struct NewProjectWizard | struct NewProjectWizard | ||||
| { | { | ||||
| @@ -24,8 +24,8 @@ | |||||
| #include "../jucer_Headers.h" | #include "../jucer_Headers.h" | ||||
| #include "jucer_NewProjectWizardClasses.h" | #include "jucer_NewProjectWizardClasses.h" | ||||
| #include "jucer_ProjectType.h" | |||||
| #include "jucer_Module.h" | |||||
| #include "../Project/jucer_ProjectType.h" | |||||
| #include "../Project/jucer_Module.h" | |||||
| #include "../Project Saving/jucer_ProjectExporter.h" | #include "../Project Saving/jucer_ProjectExporter.h" | ||||
| #include "../Application/jucer_Application.h" | #include "../Application/jucer_Application.h" | ||||
| #include "../Application/jucer_MainWindow.h" | #include "../Application/jucer_MainWindow.h" | ||||
| @@ -154,7 +154,7 @@ public: | |||||
| listBox.setOpaque (false); | listBox.setOpaque (false); | ||||
| listBox.setMultipleSelectionEnabled (true); | listBox.setMultipleSelectionEnabled (true); | ||||
| listBox.setClickingTogglesRowSelection (true); | listBox.setClickingTogglesRowSelection (true); | ||||
| listBox.setColour (ListBox::ColourIds::backgroundColourId, Colours::white.withAlpha (0.0f)); | |||||
| listBox.setColour (ListBox::backgroundColourId, Colours::white.withAlpha (0.0f)); | |||||
| addAndMakeVisible (listBox); | addAndMakeVisible (listBox); | ||||
| selectDefaultExporterIfNoneSelected(); | selectDefaultExporterIfNoneSelected(); | ||||
| @@ -203,7 +203,7 @@ public: | |||||
| if (rowIsSelected) | if (rowIsSelected) | ||||
| g.fillAll (Colour (0x99f29000)); | g.fillAll (Colour (0x99f29000)); | ||||
| Rectangle<float> dotSelect (height, height); | |||||
| Rectangle<float> dotSelect ((float) height, (float) height); | |||||
| dotSelect.reduce (12, 12); | dotSelect.reduce (12, 12); | ||||
| g.setColour (Colour (0x33ffffff)); | g.setColour (Colour (0x33ffffff)); | ||||
| @@ -38,13 +38,13 @@ public: | |||||
| { | { | ||||
| // svg for thumbnail icon | // svg for thumbnail icon | ||||
| ScopedPointer<XmlElement> svg (XmlDocument::parse (thumbSvg)); | ScopedPointer<XmlElement> svg (XmlDocument::parse (thumbSvg)); | ||||
| assert (svg != nullptr); | |||||
| jassert (svg != nullptr); | |||||
| thumb = Drawable::createFromSVG (*svg); | thumb = Drawable::createFromSVG (*svg); | ||||
| // svg for thumbnail background highlight | // svg for thumbnail background highlight | ||||
| ScopedPointer<XmlElement> backSvg (XmlDocument::parse (BinaryData::wizard_Highlight_svg)); | ScopedPointer<XmlElement> backSvg (XmlDocument::parse (BinaryData::wizard_Highlight_svg)); | ||||
| assert (backSvg != nullptr); | |||||
| jassert (backSvg != nullptr); | |||||
| hoverBackground = Drawable::createFromSVG (*backSvg); | hoverBackground = Drawable::createFromSVG (*backSvg); | ||||
| @@ -60,7 +60,7 @@ public: | |||||
| if (isMouseOverButton) | if (isMouseOverButton) | ||||
| { | { | ||||
| if (getStyle() == ButtonStyle::ImageFitted) | |||||
| if (getStyle() == ImageFitted) | |||||
| { | { | ||||
| hoverBackground->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | hoverBackground->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | ||||
| thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | ||||
| @@ -75,7 +75,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (getStyle() == ButtonStyle::ImageFitted) | |||||
| if (getStyle() == ImageFitted) | |||||
| { | { | ||||
| thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); | ||||
| } | } | ||||
| @@ -89,7 +89,7 @@ public: | |||||
| Rectangle<float> textTarget; | Rectangle<float> textTarget; | ||||
| // center the text for the text buttons or position the text in the image buttons | // center the text for the text buttons or position the text in the image buttons | ||||
| if (getStyle() != ButtonStyle::ImageFitted) | |||||
| if (getStyle() != ImageFitted) | |||||
| { | { | ||||
| textTarget = getLocalBounds().toFloat(); | textTarget = getLocalBounds().toFloat(); | ||||
| } | } | ||||
| @@ -145,7 +145,7 @@ public: | |||||
| ScopedPointer<NewProjectWizard> wizard (createWizardType (i)); | ScopedPointer<NewProjectWizard> wizard (createWizardType (i)); | ||||
| TemplateOptionButton* b = new TemplateOptionButton (wizard->getName(), | TemplateOptionButton* b = new TemplateOptionButton (wizard->getName(), | ||||
| TemplateOptionButton::ButtonStyle::ImageFitted, | |||||
| TemplateOptionButton::ImageFitted, | |||||
| wizard->getIcon()); | wizard->getIcon()); | ||||
| optionButtons.add (b); | optionButtons.add (b); | ||||
| addAndMakeVisible (b); | addAndMakeVisible (b); | ||||
| @@ -156,9 +156,9 @@ public: | |||||
| // Handle Open Project button functionality | // Handle Open Project button functionality | ||||
| ApplicationCommandManager& commandManager = IntrojucerApp::getCommandManager(); | ApplicationCommandManager& commandManager = IntrojucerApp::getCommandManager(); | ||||
| addAndMakeVisible (blankProjectButton = new TemplateOptionButton ("Create Blank Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| addAndMakeVisible (exampleProjectButton = new TemplateOptionButton ("Open Example Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| addAndMakeVisible (openProjectButton = new TemplateOptionButton ("Open Existing Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| addAndMakeVisible (blankProjectButton = new TemplateOptionButton ("Create Blank Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| addAndMakeVisible (exampleProjectButton = new TemplateOptionButton ("Open Example Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| addAndMakeVisible (openProjectButton = new TemplateOptionButton ("Open Existing Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); | |||||
| blankProjectButton->addListener (this); | blankProjectButton->addListener (this); | ||||
| exampleProjectButton->addListener (this); | exampleProjectButton->addListener (this); | ||||
| @@ -191,7 +191,7 @@ public: | |||||
| void resized() override | void resized() override | ||||
| { | { | ||||
| Rectangle<int> allOpts = getLocalBounds().reduced (40, 60); | Rectangle<int> allOpts = getLocalBounds().reduced (40, 60); | ||||
| allOpts.removeFromBottom (allOpts.getHeight() * 0.25); | |||||
| allOpts.removeFromBottom (allOpts.getHeight() / 4); | |||||
| const int numHorizIcons = 4; | const int numHorizIcons = 4; | ||||
| const int optStep = allOpts.getWidth() / numHorizIcons; | const int optStep = allOpts.getWidth() / numHorizIcons; | ||||
| @@ -41,7 +41,7 @@ | |||||
| @code | @code | ||||
| XmlDocument myDocument (File ("myfile.xml")); | XmlDocument myDocument (File ("myfile.xml")); | ||||
| XmlElement* mainElement = myDocument.getDocumentElement(); | |||||
| ScopedPointer<XmlElement> mainElement (myDocument.getDocumentElement()); | |||||
| if (mainElement == nullptr) | if (mainElement == nullptr) | ||||
| { | { | ||||
| @@ -57,7 +57,7 @@ | |||||
| Or you can use the static helper methods for quick parsing.. | Or you can use the static helper methods for quick parsing.. | ||||
| @code | @code | ||||
| XmlElement* xml = XmlDocument::parse (myXmlFile); | |||||
| ScopedPointer<XmlElement> xml (XmlDocument::parse (myXmlFile)); | |||||
| if (xml != nullptr && xml->hasTagName ("foobar")) | if (xml != nullptr && xml->hasTagName ("foobar")) | ||||
| { | { | ||||
| @@ -501,13 +501,20 @@ void Path::addRoundedRectangle (float x, float y, float w, float h, float cs) | |||||
| addRoundedRectangle (x, y, w, h, cs, cs); | addRoundedRectangle (x, y, w, h, cs, cs); | ||||
| } | } | ||||
| void Path::addTriangle (const float x1, const float y1, | |||||
| const float x2, const float y2, | |||||
| const float x3, const float y3) | |||||
| void Path::addTriangle (float x1, float y1, | |||||
| float x2, float y2, | |||||
| float x3, float y3) | |||||
| { | { | ||||
| startNewSubPath (x1, y1); | |||||
| lineTo (x2, y2); | |||||
| lineTo (x3, y3); | |||||
| addTriangle (Point<float> (x1, y1), | |||||
| Point<float> (x2, y2), | |||||
| Point<float> (x3, y3)); | |||||
| } | |||||
| void Path::addTriangle (Point<float> p1, Point<float> p2, Point<float> p3) | |||||
| { | |||||
| startNewSubPath (p1); | |||||
| lineTo (p2); | |||||
| lineTo (p3); | |||||
| closeSubPath(); | closeSubPath(); | ||||
| } | } | ||||
| @@ -377,6 +377,18 @@ public: | |||||
| float x2, float y2, | float x2, float y2, | ||||
| float x3, float y3); | float x3, float y3); | ||||
| /** Adds a triangle to the path. | |||||
| The triangle is added as a new closed sub-path. (Any currently open paths will be left open). | |||||
| Note that whether the vertices are specified in clockwise or anticlockwise | |||||
| order will affect how the triangle is filled when it overlaps other | |||||
| shapes (the winding order setting will affect this of course). | |||||
| */ | |||||
| void addTriangle (Point<float> point1, | |||||
| Point<float> point2, | |||||
| Point<float> point3); | |||||
| /** Adds a quadrilateral to the path. | /** Adds a quadrilateral to the path. | ||||
| The quad is added as a new closed sub-path. (Any currently open paths will be left open). | The quad is added as a new closed sub-path. (Any currently open paths will be left open). | ||||
| @@ -102,7 +102,7 @@ public: | |||||
| private: | private: | ||||
| #if JUCE_CATCH_DEPRECATED_CODE_MISUSE | #if JUCE_CATCH_DEPRECATED_CODE_MISUSE | ||||
| // Note that this method has been removed - instead, see LookAndFeel::getTextButtonWidthToFitText() | |||||
| // Note that this method has been removed - instead, see LookAndFeel::getTextButtonFont() | |||||
| virtual int getFont() { return 0; } | virtual int getFont() { return 0; } | ||||
| #endif | #endif | ||||