The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

939 lines
32KB

  1. /*
  2. ==============================================================================
  3. This is an automatically generated file!
  4. Be careful when adding custom code to these files, as only the code within
  5. the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
  6. and re-saved.
  7. Created for JUCE version: JUCE v2.0.9
  8. ------------------------------------------------------------------------------
  9. JUCE is copyright 2004-11 by Raw Material Software ltd.
  10. ==============================================================================
  11. */
  12. //[CppHeaders] You can add your own extra header files here...
  13. #include "../Project Saving/jucer_ProjectExporter.h"
  14. #include "jucer_Module.h"
  15. #include "../Application/jucer_JuceUpdater.h"
  16. //[/CppHeaders]
  17. #include "jucer_ProjectInformationComponent.h"
  18. //[MiscUserDefs] You can add your own user definitions and misc code here...
  19. //==============================================================================
  20. class ModulesPanel : public PropertyComponent,
  21. public FilenameComponentListener,
  22. public ButtonListener
  23. {
  24. public:
  25. ModulesPanel (Project& project_)
  26. : PropertyComponent ("Modules", 500),
  27. project (project_),
  28. modulesLocation ("modules", ModuleList::getLocalModulesFolder (&project),
  29. true, true, false, "*", String::empty,
  30. "Select a folder containing your JUCE modules..."),
  31. modulesLabel (String::empty, "Module source folder:"),
  32. updateModulesButton ("Check for module updates..."),
  33. moduleListBox (moduleList)
  34. {
  35. moduleList.rescan (ModuleList::getLocalModulesFolder (&project));
  36. addAndMakeVisible (&modulesLocation);
  37. modulesLocation.setBounds ("150, 3, parent.width - 180, 28");
  38. modulesLocation.addListener (this);
  39. modulesLabel.attachToComponent (&modulesLocation, true);
  40. addAndMakeVisible (&updateModulesButton);
  41. updateModulesButton.setBounds ("parent.width - 175, 3, parent.width - 4, 28");
  42. updateModulesButton.addListener (this);
  43. moduleListBox.setOwner (this);
  44. addAndMakeVisible (&moduleListBox);
  45. moduleListBox.setBounds ("4, 31, parent.width / 2 - 4, parent.height - 3");
  46. }
  47. void filenameComponentChanged (FilenameComponent*)
  48. {
  49. moduleList.rescan (modulesLocation.getCurrentFile());
  50. modulesLocation.setCurrentFile (moduleList.getModulesFolder(), false, false);
  51. ModuleList::setLocalModulesFolder (moduleList.getModulesFolder());
  52. moduleListBox.refresh();
  53. }
  54. void buttonClicked (Button*)
  55. {
  56. JuceUpdater::show (moduleList, getTopLevelComponent(), "");
  57. filenameComponentChanged (nullptr);
  58. }
  59. bool isEnabled (const ModuleList::Module* m) const
  60. {
  61. return project.isModuleEnabled (m->uid);
  62. }
  63. void setEnabled (const ModuleList::Module* m, bool enable)
  64. {
  65. if (enable)
  66. project.addModule (m->uid, true);
  67. else
  68. project.removeModule (m->uid);
  69. refresh();
  70. }
  71. bool areDependenciesMissing (const ModuleList::Module* m)
  72. {
  73. return moduleList.getExtraDependenciesNeeded (project, *m).size() > 0;
  74. }
  75. void selectionChanged (const ModuleList::Module* selectedModule)
  76. {
  77. settings = nullptr;
  78. if (selectedModule != nullptr)
  79. addAndMakeVisible (settings = new ModuleSettingsPanel (project, moduleList, selectedModule->uid));
  80. }
  81. void refresh()
  82. {
  83. moduleListBox.refresh();
  84. if (settings != nullptr)
  85. settings->refreshAll();
  86. }
  87. void paint (Graphics& g) // (overridden to avoid drawing the name)
  88. {
  89. getLookAndFeel().drawPropertyComponentBackground (g, getWidth(), getHeight(), *this);
  90. }
  91. //==============================================================================
  92. class ModuleSelectionListBox : public ListBox,
  93. public ListBoxModel
  94. {
  95. public:
  96. ModuleSelectionListBox (ModuleList& list_)
  97. : list (list_), owner (nullptr)
  98. {
  99. setColour (ListBox::backgroundColourId, Colours::white.withAlpha (0.4f));
  100. setTooltip ("Use this list to select which modules should be included in your app.\n"
  101. "Any modules which have missing dependencies will be shown in red.");
  102. }
  103. void setOwner (ModulesPanel* owner_)
  104. {
  105. owner = owner_;
  106. setModel (this);
  107. }
  108. void refresh()
  109. {
  110. updateContent();
  111. repaint();
  112. }
  113. int getNumRows()
  114. {
  115. return list.modules.size();
  116. }
  117. void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
  118. {
  119. if (rowIsSelected)
  120. g.fillAll (findColour (TextEditor::highlightColourId));
  121. const ModuleList::Module* const m = list.modules [rowNumber];
  122. if (m != nullptr)
  123. {
  124. const float tickSize = height * 0.7f;
  125. getLookAndFeel().drawTickBox (g, *this, (height - tickSize) / 2, (height - tickSize) / 2, tickSize, tickSize,
  126. owner->isEnabled (m), true, false, false);
  127. if (owner->isEnabled (m) && owner->areDependenciesMissing (m))
  128. g.setColour (Colours::red);
  129. else
  130. g.setColour (Colours::black);
  131. g.setFont (height * 0.7f, Font::bold);
  132. g.drawFittedText (m->uid, height, 0, 200, height, Justification::centredLeft, 1);
  133. g.setFont (height * 0.55f, Font::italic);
  134. g.drawText (m->name, height + 200, 0, width - height - 200, height, Justification::centredLeft, true);
  135. }
  136. }
  137. void listBoxItemClicked (int row, const MouseEvent& e)
  138. {
  139. if (e.x < getRowHeight())
  140. flipRow (row);
  141. }
  142. void listBoxItemDoubleClicked (int row, const MouseEvent& e)
  143. {
  144. flipRow (row);
  145. }
  146. void returnKeyPressed (int row)
  147. {
  148. flipRow (row);
  149. }
  150. void selectedRowsChanged (int lastRowSelected)
  151. {
  152. owner->selectionChanged (list.modules [lastRowSelected]);
  153. }
  154. void flipRow (int row)
  155. {
  156. const ModuleList::Module* const m = list.modules [row];
  157. if (m != nullptr)
  158. owner->setEnabled (m, ! owner->isEnabled (m));
  159. }
  160. private:
  161. ModuleList& list;
  162. ModulesPanel* owner;
  163. };
  164. //==============================================================================
  165. class ModuleSettingsPanel : public PropertyPanel
  166. {
  167. public:
  168. ModuleSettingsPanel (Project& project_, ModuleList& moduleList_, const String& moduleID_)
  169. : project (project_), moduleList (moduleList_), moduleID (moduleID_)
  170. {
  171. setBounds ("parent.width / 2 + 1, 31, parent.width - 3, parent.height - 3");
  172. refreshAll();
  173. }
  174. void refreshAll()
  175. {
  176. setEnabled (project.isModuleEnabled (moduleID));
  177. clear();
  178. Array <PropertyComponent*> props;
  179. ScopedPointer<LibraryModule> module (moduleList.loadModule (moduleID));
  180. if (module != nullptr)
  181. {
  182. props.add (new ModuleInfoComponent (project, moduleList, moduleID));
  183. if (project.isModuleEnabled (moduleID))
  184. {
  185. const ModuleList::Module* m = moduleList.findModuleInfo (moduleID);
  186. if (m != nullptr && moduleList.getExtraDependenciesNeeded (project, *m).size() > 0)
  187. props.add (new MissingDependenciesComponent (project, moduleList, moduleID));
  188. }
  189. props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID),
  190. "Add source to project", "Make module files browsable in projects"));
  191. props.getLast()->setTooltip ("If this is enabled, then the entire source tree from this module will be shown inside your project, "
  192. "making it easy to browse/edit the module's classes. If disabled, then only the minimum number of files "
  193. "required to compile it will appear inside your project.");
  194. props.add (new BooleanPropertyComponent (project.shouldCopyModuleFilesLocally (moduleID),
  195. "Create local copy", "Copy the module into the project folder"));
  196. props.getLast()->setTooltip ("If this is enabled, then a local copy of the entire module will be made inside your project (in the auto-generated JuceLibraryFiles folder), "
  197. "so that your project will be self-contained, and won't need to contain any references to files in other folders. "
  198. "This also means that you can check the module into your source-control system to make sure it is always in sync with your own code.");
  199. StringArray possibleValues;
  200. possibleValues.add ("(Use Default)");
  201. possibleValues.add ("Enabled");
  202. possibleValues.add ("Disabled");
  203. Array<var> mappings;
  204. mappings.add (Project::configFlagDefault);
  205. mappings.add (Project::configFlagEnabled);
  206. mappings.add (Project::configFlagDisabled);
  207. OwnedArray <Project::ConfigFlag> flags;
  208. module->getConfigFlags (project, flags);
  209. for (int i = 0; i < flags.size(); ++i)
  210. {
  211. ChoicePropertyComponent* c = new ChoicePropertyComponent (flags[i]->value, flags[i]->symbol, possibleValues, mappings);
  212. c->setTooltip (flags[i]->description);
  213. c->setPreferredHeight (22);
  214. props.add (c);
  215. }
  216. }
  217. addProperties (props);
  218. }
  219. private:
  220. Project& project;
  221. ModuleList& moduleList;
  222. String moduleID;
  223. //==============================================================================
  224. class ModuleInfoComponent : public PropertyComponent
  225. {
  226. public:
  227. ModuleInfoComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_)
  228. : PropertyComponent ("Module", 100), project (project_), moduleList (moduleList_), moduleID (moduleID_)
  229. {
  230. }
  231. void refresh() {}
  232. void paint (Graphics& g)
  233. {
  234. g.setColour (Colours::white.withAlpha (0.4f));
  235. g.fillRect (0, 0, getWidth(), getHeight() - 1);
  236. const ModuleList::Module* module = moduleList.findModuleInfo (moduleID);
  237. if (module != nullptr)
  238. {
  239. String text;
  240. text << module->name << newLine << "Version: " << module->version << newLine << newLine
  241. << module->description;
  242. GlyphArrangement ga;
  243. ga.addJustifiedText (Font (13.0f), text, 4.0f, 16.0f, getWidth() - 8.0f, Justification::topLeft);
  244. g.setColour (Colours::black);
  245. ga.draw (g);
  246. }
  247. }
  248. private:
  249. Project& project;
  250. ModuleList& moduleList;
  251. String moduleID;
  252. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleInfoComponent);
  253. };
  254. //==============================================================================
  255. class MissingDependenciesComponent : public PropertyComponent,
  256. public ButtonListener
  257. {
  258. public:
  259. MissingDependenciesComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_)
  260. : PropertyComponent ("Dependencies", 100),
  261. project (project_), moduleList (moduleList_), moduleID (moduleID_),
  262. fixButton ("Enable Required Modules")
  263. {
  264. const ModuleList::Module* module = moduleList.findModuleInfo (moduleID);
  265. if (module != nullptr)
  266. missingDependencies = moduleList.getExtraDependenciesNeeded (project, *module);
  267. addAndMakeVisible (&fixButton);
  268. fixButton.setColour (TextButton::buttonColourId, Colours::red);
  269. fixButton.setColour (TextButton::textColourOffId, Colours::white);
  270. fixButton.setBounds ("right - 160, parent.height - 26, parent.width - 8, top + 22");
  271. fixButton.addListener (this);
  272. }
  273. void refresh() {}
  274. void paint (Graphics& g)
  275. {
  276. g.setColour (Colours::white.withAlpha (0.4f));
  277. g.fillRect (0, 0, getWidth(), getHeight() - 1);
  278. String text ("This module requires the following dependencies:\n");
  279. text << missingDependencies.joinIntoString (", ");
  280. GlyphArrangement ga;
  281. ga.addJustifiedText (Font (13.0f), text, 4.0f, 16.0f, getWidth() - 8.0f, Justification::topLeft);
  282. g.setColour (Colours::red);
  283. ga.draw (g);
  284. }
  285. void buttonClicked (Button*)
  286. {
  287. bool isModuleCopiedLocally = project.shouldCopyModuleFilesLocally (moduleID).getValue();
  288. for (int i = missingDependencies.size(); --i >= 0;)
  289. project.addModule (missingDependencies[i], isModuleCopiedLocally);
  290. ModulesPanel* mp = findParentComponentOfClass ((ModulesPanel*) nullptr);
  291. if (mp != nullptr)
  292. mp->refresh();
  293. }
  294. private:
  295. Project& project;
  296. ModuleList& moduleList;
  297. String moduleID;
  298. StringArray missingDependencies;
  299. TextButton fixButton;
  300. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MissingDependenciesComponent);
  301. };
  302. };
  303. private:
  304. Project& project;
  305. ModuleList moduleList;
  306. FilenameComponent modulesLocation;
  307. Label modulesLabel;
  308. TextButton updateModulesButton;
  309. ModuleSelectionListBox moduleListBox;
  310. ScopedPointer<ModuleSettingsPanel> settings;
  311. };
  312. //==============================================================================
  313. class ProjectSettingsComponent : public Component
  314. {
  315. public:
  316. ProjectSettingsComponent (Project& project_)
  317. : project (project_),
  318. configs ("Configurations", "Add a New Configuration", false),
  319. exporters ("Export Targets", "Add a New Exporter...", true)
  320. {
  321. addAndMakeVisible (&mainProjectInfoPanel);
  322. addAndMakeVisible (&modulesPanelGroup);
  323. addAndMakeVisible (&configs);
  324. addAndMakeVisible (&exporters);
  325. Array<PropertyComponent*> props;
  326. props.add (new ModulesPanel (project));
  327. modulesPanelGroup.setProperties (props);
  328. modulesPanelGroup.setName ("Modules");
  329. createItems();
  330. }
  331. void updateSize (int width)
  332. {
  333. width = jmax (550, width);
  334. int y = 0;
  335. y += mainProjectInfoPanel.updateSize (y, width);
  336. y += modulesPanelGroup.updateSize (y, width);
  337. y += configs.updateSize (y, width);
  338. y += exporters.updateSize (y, width);
  339. setSize (width, y);
  340. }
  341. void parentSizeChanged()
  342. {
  343. updateSize (getParentWidth());
  344. }
  345. void visibilityChanged()
  346. {
  347. if (isVisible())
  348. refreshAll();
  349. }
  350. void refreshAll()
  351. {
  352. {
  353. Array <PropertyComponent*> props;
  354. project.createPropertyEditors (props);
  355. mainProjectInfoPanel.setProperties (props);
  356. mainProjectInfoPanel.setName ("Project Settings");
  357. }
  358. int i;
  359. for (i = configs.groups.size(); --i >= 0;)
  360. {
  361. PropertyGroup& pp = *configs.groups.getUnchecked(i);
  362. Array <PropertyComponent*> props;
  363. project.getConfiguration (i).createPropertyEditors (props);
  364. pp.setProperties (props);
  365. }
  366. for (i = exporters.groups.size(); --i >= 0;)
  367. {
  368. PropertyGroup& pp = *exporters.groups.getUnchecked(i);
  369. Array <PropertyComponent*> props;
  370. ScopedPointer <ProjectExporter> exp (project.createExporter (i));
  371. jassert (exp != nullptr);
  372. if (exp != nullptr)
  373. {
  374. exp->createPropertyEditors (props);
  375. for (int j = props.size(); --j >= 0;)
  376. props.getUnchecked(j)->setPreferredHeight (22);
  377. pp.setProperties (props);
  378. }
  379. }
  380. refreshSectionNames();
  381. updateSize (getWidth());
  382. }
  383. void refreshSectionNames()
  384. {
  385. int i;
  386. for (i = configs.groups.size(); --i >= 0;)
  387. {
  388. PropertyGroup& pp = *configs.groups.getUnchecked(i);
  389. pp.setName (project.getConfiguration (i).getName().toString().quoted());
  390. pp.repaint();
  391. }
  392. for (i = exporters.groups.size(); --i >= 0;)
  393. {
  394. PropertyGroup& pp = *exporters.groups.getUnchecked(i);
  395. ScopedPointer <ProjectExporter> exp (project.createExporter (i));
  396. jassert (exp != nullptr);
  397. if (exp != nullptr)
  398. pp.setName (exp->getName());
  399. pp.repaint();
  400. }
  401. }
  402. void createItems()
  403. {
  404. configs.clear();
  405. exporters.clear();
  406. int i;
  407. for (i = 0; i < project.getNumConfigurations(); ++i)
  408. {
  409. PropertyGroup* p = configs.createGroup();
  410. if (project.getNumConfigurations() > 1)
  411. p->addDeleteButton ("config " + String (i), "Deletes this configuration.");
  412. }
  413. for (i = 0; i < project.getNumExporters(); ++i)
  414. {
  415. PropertyGroup* p = exporters.createGroup();
  416. p->addDeleteButton ("exporter " + String (i), "Deletes this export target.");
  417. }
  418. lastProjectType = project.getProjectTypeValue().getValue();
  419. refreshAll();
  420. }
  421. void update()
  422. {
  423. if (configs.groups.size() != project.getNumConfigurations()
  424. || exporters.groups.size() != project.getNumExporters()
  425. || lastProjectType != project.getProjectTypeValue().getValue())
  426. {
  427. createItems();
  428. }
  429. refreshSectionNames();
  430. }
  431. void deleteButtonClicked (const String& name)
  432. {
  433. if (name.startsWith ("config"))
  434. project.deleteConfiguration (name.getTrailingIntValue());
  435. else
  436. project.deleteExporter (name.getTrailingIntValue());
  437. }
  438. void createNewExporter (TextButton& button)
  439. {
  440. StringArray exporters (ProjectExporter::getExporterNames());
  441. PopupMenu menu;
  442. for (int i = 0; i < exporters.size(); ++i)
  443. menu.addItem (i + 1, "Create a new " + exporters[i] + " target");
  444. const int r = menu.showAt (&button);
  445. if (r > 0)
  446. project.addNewExporter (exporters [r - 1]);
  447. }
  448. void createNewConfig()
  449. {
  450. project.addNewConfiguration (nullptr);
  451. }
  452. void newItemButtonClicked (TextButton& button)
  453. {
  454. if (button.getName().containsIgnoreCase ("export"))
  455. createNewExporter (button);
  456. else
  457. createNewConfig();
  458. }
  459. private:
  460. //==============================================================================
  461. class PropertyGroup : public Component,
  462. public ButtonListener
  463. {
  464. public:
  465. PropertyGroup()
  466. : deleteButton ("Delete"), preferredHeight (0)
  467. {
  468. deleteButton.addListener (this);
  469. }
  470. void addDeleteButton (const String& name, const String& tooltip)
  471. {
  472. addAndMakeVisible (&deleteButton);
  473. deleteButton.setBounds ("right - 55, 11, parent.width - 10, 26");
  474. deleteButton.setColour (TextButton::buttonColourId, Colour (0xa0fcbdbd));
  475. deleteButton.setColour (TextButton::textColourOffId, Colours::darkred);
  476. deleteButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight);
  477. deleteButton.setName (name);
  478. deleteButton.setTooltip (tooltip);
  479. }
  480. void setProperties (const Array<PropertyComponent*>& newProps)
  481. {
  482. properties.clear();
  483. properties.addArray (newProps);
  484. preferredHeight = 32;
  485. for (int i = properties.size(); --i >= 0;)
  486. {
  487. addAndMakeVisible (properties.getUnchecked(i));
  488. preferredHeight += properties.getUnchecked(i)->getPreferredHeight();
  489. }
  490. }
  491. int getPreferredHeight() const
  492. {
  493. return preferredHeight;
  494. }
  495. int updateSize (int y, int width)
  496. {
  497. setBounds (0, y, width, preferredHeight);
  498. y = 30;
  499. for (int i = 0; i < properties.size(); ++i)
  500. {
  501. PropertyComponent* pp = properties.getUnchecked(i);
  502. pp->setBounds (10, y, width - 20, pp->getPreferredHeight());
  503. y += pp->getHeight();
  504. }
  505. return preferredHeight;
  506. }
  507. void paint (Graphics& g)
  508. {
  509. g.setFont (14.0f, Font::bold);
  510. g.setColour (Colours::black);
  511. g.drawFittedText (getName(), 12, 0, getWidth() - 16, 28, Justification::bottomLeft, 1);
  512. }
  513. void buttonClicked (Button*)
  514. {
  515. ProjectSettingsComponent* psc = findParentComponentOfClass ((ProjectSettingsComponent*) nullptr);
  516. if (psc != nullptr)
  517. psc->deleteButtonClicked (deleteButton.getName());
  518. }
  519. private:
  520. OwnedArray<PropertyComponent> properties;
  521. TextButton deleteButton;
  522. int preferredHeight;
  523. };
  524. //==============================================================================
  525. class PropertyGroupList : public Component,
  526. public ButtonListener
  527. {
  528. public:
  529. PropertyGroupList (const String& title, const String& newButtonText, bool triggerOnMouseDown)
  530. : Component (title), createNewButton (newButtonText)
  531. {
  532. addAndMakeVisible (&createNewButton);
  533. createNewButton.setColour (TextButton::buttonColourId, Colours::lightgreen.withAlpha (0.5f));
  534. createNewButton.setBounds ("right - 140, 30, parent.width - 10, top + 20");
  535. createNewButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight);
  536. createNewButton.addListener (this);
  537. createNewButton.setTriggeredOnMouseDown (triggerOnMouseDown);
  538. }
  539. int updateSize (int ourY, int width)
  540. {
  541. int y = 55;
  542. for (int i = 0; i < groups.size(); ++i)
  543. y += groups.getUnchecked(i)->updateSize (y, width);
  544. y = jmax (y, 100);
  545. setBounds (0, ourY, width, y);
  546. return y;
  547. }
  548. void paint (Graphics& g)
  549. {
  550. g.setFont (17.0f, Font::bold);
  551. g.setColour (Colours::black);
  552. g.drawFittedText (getName(), 0, 30, getWidth(), 20, Justification::centred, 1);
  553. }
  554. void clear()
  555. {
  556. groups.clear();
  557. }
  558. PropertyGroup* createGroup()
  559. {
  560. PropertyGroup* p = new PropertyGroup();
  561. groups.add (p);
  562. addAndMakeVisible (p);
  563. return p;
  564. }
  565. void buttonClicked (Button*)
  566. {
  567. ProjectSettingsComponent* psc = findParentComponentOfClass ((ProjectSettingsComponent*) nullptr);
  568. if (psc != nullptr)
  569. psc->newItemButtonClicked (createNewButton);
  570. }
  571. OwnedArray<PropertyGroup> groups;
  572. TextButton createNewButton;
  573. };
  574. Project& project;
  575. var lastProjectType;
  576. PropertyGroup mainProjectInfoPanel, modulesPanelGroup;
  577. PropertyGroupList configs, exporters;
  578. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSettingsComponent);
  579. };
  580. //==============================================================================
  581. class ProjectInformationComponent::RolloverHelpComp : public Component,
  582. private Timer
  583. {
  584. public:
  585. RolloverHelpComp()
  586. : lastComp (nullptr)
  587. {
  588. startTimer (150);
  589. }
  590. void paint (Graphics& g)
  591. {
  592. AttributedString s;
  593. s.setJustification (Justification::centredLeft);
  594. s.append (lastTip, Font (14.0f), Colour::greyLevel (0.15f));
  595. TextLayout tl;
  596. tl.createLayoutWithBalancedLineLengths (s, getWidth() - 10.0f);
  597. if (tl.getNumLines() > 3)
  598. tl.createLayout (s, getWidth() - 10.0f);
  599. tl.draw (g, getLocalBounds().toFloat());
  600. }
  601. void timerCallback()
  602. {
  603. Component* newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
  604. if (newComp != nullptr
  605. && (newComp->getTopLevelComponent() != getTopLevelComponent()
  606. || newComp->isCurrentlyBlockedByAnotherModalComponent()))
  607. newComp = nullptr;
  608. if (newComp != lastComp)
  609. {
  610. lastComp = newComp;
  611. String newTip (findTip (newComp));
  612. if (newTip != lastTip)
  613. {
  614. lastTip = newTip;
  615. repaint();
  616. }
  617. }
  618. }
  619. private:
  620. static String findTip (Component* c)
  621. {
  622. while (c != nullptr)
  623. {
  624. TooltipClient* const tc = dynamic_cast <TooltipClient*> (c);
  625. if (tc != nullptr)
  626. {
  627. const String tip (tc->getTooltip());
  628. if (tip.isNotEmpty())
  629. return tip;
  630. }
  631. c = c->getParentComponent();
  632. }
  633. return String::empty;
  634. }
  635. Component* lastComp;
  636. String lastTip;
  637. };
  638. //[/MiscUserDefs]
  639. //==============================================================================
  640. ProjectInformationComponent::ProjectInformationComponent (Project& project_)
  641. : project (project_)
  642. {
  643. addAndMakeVisible (&viewport);
  644. viewport.setComponentID ("ykdBpb");
  645. viewport.setBounds (RelativeRectangle ("8, 8, parent.width - 8, parent.height - 74"));
  646. viewport.setScrollBarThickness (16);
  647. addAndMakeVisible (&openProjectButton);
  648. openProjectButton.setComponentID ("a550a652e2666ee7");
  649. openProjectButton.setBounds (RelativeRectangle ("8, parent.height - 34, left + 227, top + 24"));
  650. openProjectButton.setButtonText ("Open Project in ");
  651. openProjectButton.addListener (this);
  652. openProjectButton.setColour (TextButton::buttonColourId, Colour (0xffddddff));
  653. addAndMakeVisible (&saveAndOpenButton);
  654. saveAndOpenButton.setComponentID ("dRGMyYx");
  655. saveAndOpenButton.setBounds (RelativeRectangle ("8, parent.height - 65, left + 227, top + 24"));
  656. saveAndOpenButton.setButtonText ("Save And Open in");
  657. saveAndOpenButton.addListener (this);
  658. saveAndOpenButton.setColour (TextButton::buttonColourId, Colour (0xffddddff));
  659. addAndMakeVisible (rollover = new RolloverHelpComp());
  660. rollover->setComponentID ("QqLJBF");
  661. rollover->setBounds (RelativeRectangle ("246, parent.height - 68, parent.width - 8, parent.height - 4"));
  662. //[UserPreSize]
  663. viewport.setViewedComponent (new ProjectSettingsComponent (project), true);
  664. #if JUCE_MAC || JUCE_WINDOWS
  665. openProjectButton.setCommandToTrigger (commandManager, CommandIDs::openInIDE, true);
  666. openProjectButton.setButtonText (commandManager->getNameOfCommand (CommandIDs::openInIDE));
  667. saveAndOpenButton.setCommandToTrigger (commandManager, CommandIDs::saveAndOpenInIDE, true);
  668. saveAndOpenButton.setButtonText (commandManager->getNameOfCommand (CommandIDs::saveAndOpenInIDE));
  669. #else
  670. openProjectButton.setVisible (false);
  671. saveAndOpenButton.setVisible (false);
  672. #endif
  673. //[/UserPreSize]
  674. setSize (808, 638);
  675. //[Constructor] You can add your own custom stuff here..
  676. project.addChangeListener (this);
  677. //[/Constructor]
  678. }
  679. ProjectInformationComponent::~ProjectInformationComponent()
  680. {
  681. //[Destructor_pre]. You can add your own custom destruction code here..
  682. project.removeChangeListener (this);
  683. //[/Destructor_pre]
  684. rollover = 0;
  685. //[Destructor]. You can add your own custom destruction code here..
  686. //[/Destructor]
  687. }
  688. //==============================================================================
  689. void ProjectInformationComponent::resized()
  690. {
  691. //[Userresized_Pre]
  692. //[/Userresized_Pre]
  693. //[Userresized_Post]
  694. //[/Userresized_Post]
  695. }
  696. void ProjectInformationComponent::buttonClicked (Button* buttonThatWasClicked)
  697. {
  698. //[UserbuttonClicked_Pre]
  699. //[/UserbuttonClicked_Pre]
  700. if (buttonThatWasClicked == &openProjectButton)
  701. {
  702. //[UserButtonCode_a550a652e2666ee7] -- add your button handler code here..
  703. //[/UserButtonCode_a550a652e2666ee7]
  704. }
  705. else if (buttonThatWasClicked == &saveAndOpenButton)
  706. {
  707. //[UserButtonCode_dRGMyYx] -- add your button handler code here..
  708. //[/UserButtonCode_dRGMyYx]
  709. }
  710. //[UserbuttonClicked_Post]
  711. //[/UserbuttonClicked_Post]
  712. }
  713. void ProjectInformationComponent::paint (Graphics& g)
  714. {
  715. //[UserPaint] Add your own custom painting code here..
  716. g.setTiledImageFill (ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, BinaryData::brushed_aluminium_pngSize),
  717. 0, 0, 1.0f);
  718. g.fillAll();
  719. drawRecessedShadows (g, getWidth(), getHeight(), 14);
  720. //[/UserPaint]
  721. }
  722. //[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
  723. void ProjectInformationComponent::changeListenerCallback (ChangeBroadcaster*)
  724. {
  725. dynamic_cast<ProjectSettingsComponent*> (viewport.getViewedComponent())->update();
  726. }
  727. //[/MiscUserCode]
  728. //==============================================================================
  729. //======================= Jucer Information Section ==========================
  730. //==============================================================================
  731. #if 0
  732. /* This section stores the metadata for this component - edit it at your own risk!
  733. JUCER_COMPONENT_METADATA_START
  734. <COMPONENT id="tO9EG1a" className="ProjectInformationComponent" width="808"
  735. height="638" background="f6f9ff" parentClasses="public Component, public ChangeListener"
  736. constructorParams="Project&amp; project_" memberInitialisers="project (project_)">
  737. <COMPONENTS>
  738. <VIEWPORT id="ykdBpb" memberName="viewport" position="8, 8, parent.width - 8, parent.height - 74"
  739. scrollBarV="1" scrollBarH="1" scrollbarWidth="16"/>
  740. <TEXTBUTTON id="a550a652e2666ee7" memberName="openProjectButton" focusOrder="0"
  741. text="Open Project in " createCallback="1" radioGroup="0" connectedLeft="0"
  742. connectedRight="0" connectedTop="0" connectedBottom="0" backgroundColour="FFDDDDFF"
  743. textColour="" backgroundColourOn="" textColourOn="" position="8, parent.height - 34, left + 227, top + 24"/>
  744. <TEXTBUTTON id="dRGMyYx" name="" memberName="saveAndOpenButton" position="8, parent.height - 65, left + 227, top + 24"
  745. text="Save And Open in" createCallback="1" radioGroup="0" connectedLeft="0"
  746. connectedRight="0" connectedTop="0" connectedBottom="0" backgroundColour="FFDDDDFF"/>
  747. <GENERICCOMPONENT id="QqLJBF" memberName="rollover" position="246, parent.height - 68, parent.width - 8, parent.height - 4"
  748. class="RolloverHelpComp"/>
  749. </COMPONENTS>
  750. <MARKERS_X/>
  751. <MARKERS_Y/>
  752. <METHODS/>
  753. </COMPONENT>
  754. JUCER_COMPONENT_METADATA_END
  755. */
  756. #endif