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.

246 lines
7.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "jucer_JucerTreeViewBase.h"
  19. #include "../Project/jucer_ProjectContentComponent.h"
  20. //==============================================================================
  21. JucerTreeViewBase::JucerTreeViewBase()
  22. : textX (0)
  23. {
  24. setLinesDrawnForSubItems (false);
  25. }
  26. void JucerTreeViewBase::refreshSubItems()
  27. {
  28. WholeTreeOpennessRestorer openness (*this);
  29. clearSubItems();
  30. addSubItems();
  31. }
  32. Font JucerTreeViewBase::getFont() const
  33. {
  34. return Font (getItemHeight() * 0.6f);
  35. }
  36. void JucerTreeViewBase::paintItem (Graphics& g, int width, int height)
  37. {
  38. if (isSelected())
  39. g.fillAll (getOwnerView()->findColour (treeviewHighlightColourId));
  40. }
  41. float JucerTreeViewBase::getIconSize() const
  42. {
  43. return jmin (getItemHeight() - 4.0f, 18.0f);
  44. }
  45. void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver)
  46. {
  47. Path p;
  48. if (isOpen())
  49. p.addTriangle (width * 0.2f, height * 0.25f, width * 0.8f, height * 0.25f, width * 0.5f, height * 0.75f);
  50. else
  51. p.addTriangle (width * 0.25f, height * 0.25f, width * 0.8f, height * 0.5f, width * 0.25f, height * 0.75f);
  52. g.setColour (getContrastingColour (0.3f));
  53. g.fillPath (p);
  54. }
  55. Colour JucerTreeViewBase::getBackgroundColour() const
  56. {
  57. Colour background (getOwnerView()->findColour (projectPanelBackgroundColourId));
  58. if (isSelected())
  59. background = background.overlaidWith (getOwnerView()->findColour (treeviewHighlightColourId));
  60. return background;
  61. }
  62. Colour JucerTreeViewBase::getContrastingColour (float contrast) const
  63. {
  64. return getBackgroundColour().contrasting (contrast);
  65. }
  66. Colour JucerTreeViewBase::getContrastingColour (const Colour& target, float minContrast) const
  67. {
  68. return getBackgroundColour().contrasting (target, minContrast);
  69. }
  70. void JucerTreeViewBase::paintContent (Graphics& g, const Rectangle<int>& area)
  71. {
  72. g.setFont (getFont());
  73. g.setColour (isMissing() ? getContrastingColour (Colours::red, 0.8f)
  74. : getContrastingColour (0.8f));
  75. g.drawFittedText (getDisplayName(),
  76. area.getX(), area.getY(), area.getWidth(), area.getHeight(),
  77. Justification::centredLeft, 1, 0.8f);
  78. }
  79. Component* JucerTreeViewBase::createItemComponent()
  80. {
  81. return new TreeItemComponent (*this);
  82. }
  83. //==============================================================================
  84. class RenameTreeItemCallback : public ModalComponentManager::Callback,
  85. public TextEditorListener
  86. {
  87. public:
  88. RenameTreeItemCallback (JucerTreeViewBase& item_, Component& parent, const Rectangle<int>& bounds)
  89. : item (item_)
  90. {
  91. ed.setMultiLine (false, false);
  92. ed.setPopupMenuEnabled (false);
  93. ed.setSelectAllWhenFocused (true);
  94. ed.setFont (item.getFont());
  95. ed.addListener (this);
  96. ed.setText (item.getRenamingName());
  97. ed.setBounds (bounds);
  98. parent.addAndMakeVisible (&ed);
  99. ed.enterModalState (true, this);
  100. }
  101. void modalStateFinished (int resultCode)
  102. {
  103. if (resultCode != 0)
  104. item.setName (ed.getText());
  105. }
  106. void textEditorTextChanged (TextEditor&) {}
  107. void textEditorReturnKeyPressed (TextEditor& editor) { editor.exitModalState (1); }
  108. void textEditorEscapeKeyPressed (TextEditor& editor) { editor.exitModalState (0); }
  109. void textEditorFocusLost (TextEditor& editor) { editor.exitModalState (0); }
  110. private:
  111. TextEditor ed;
  112. JucerTreeViewBase& item;
  113. JUCE_DECLARE_NON_COPYABLE (RenameTreeItemCallback);
  114. };
  115. void JucerTreeViewBase::showRenameBox()
  116. {
  117. Rectangle<int> r (getItemPosition (true));
  118. r.setLeft (r.getX() + textX);
  119. r.setHeight (getItemHeight());
  120. new RenameTreeItemCallback (*this, *getOwnerView(), r);
  121. }
  122. void JucerTreeViewBase::itemClicked (const MouseEvent& e)
  123. {
  124. if (e.mods.isPopupMenu())
  125. {
  126. if (getOwnerView()->getNumSelectedItems() > 1)
  127. showMultiSelectionPopupMenu();
  128. else
  129. showPopupMenu();
  130. }
  131. }
  132. void JucerTreeViewBase::deleteItem() {}
  133. void JucerTreeViewBase::deleteAllSelectedItems() {}
  134. void JucerTreeViewBase::showDocument() {}
  135. void JucerTreeViewBase::showPopupMenu() {}
  136. void JucerTreeViewBase::showMultiSelectionPopupMenu() {}
  137. static void treeViewMenuItemChosen (int resultCode, JucerTreeViewBase* item)
  138. {
  139. item->handlePopupMenuResult (resultCode);
  140. }
  141. void JucerTreeViewBase::launchPopupMenu (PopupMenu& m)
  142. {
  143. m.showMenuAsync (PopupMenu::Options(),
  144. ModalCallbackFunction::create (treeViewMenuItemChosen, this));
  145. }
  146. void JucerTreeViewBase::handlePopupMenuResult (int)
  147. {
  148. }
  149. ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
  150. {
  151. Component* c = getOwnerView();
  152. while (c != nullptr)
  153. {
  154. ProjectContentComponent* pcc = dynamic_cast <ProjectContentComponent*> (c);
  155. if (pcc != nullptr)
  156. return pcc;
  157. c = c->getParentComponent();
  158. }
  159. return 0;
  160. }
  161. //==============================================================================
  162. class JucerTreeViewBase::ItemSelectionTimer : public Timer
  163. {
  164. public:
  165. ItemSelectionTimer (JucerTreeViewBase& owner_) : owner (owner_) {}
  166. void timerCallback() { owner.invokeShowDocument(); }
  167. private:
  168. JucerTreeViewBase& owner;
  169. JUCE_DECLARE_NON_COPYABLE (ItemSelectionTimer);
  170. };
  171. void JucerTreeViewBase::itemSelectionChanged (bool isNowSelected)
  172. {
  173. if (isNowSelected)
  174. {
  175. delayedSelectionTimer = new ItemSelectionTimer (*this);
  176. delayedSelectionTimer->startTimer (getMillisecsAllowedForDragGesture());
  177. }
  178. else
  179. {
  180. cancelDelayedSelectionTimer();
  181. }
  182. }
  183. void JucerTreeViewBase::invokeShowDocument()
  184. {
  185. cancelDelayedSelectionTimer();
  186. showDocument();
  187. }
  188. void JucerTreeViewBase::itemDoubleClicked (const MouseEvent& e)
  189. {
  190. invokeShowDocument();
  191. }
  192. void JucerTreeViewBase::cancelDelayedSelectionTimer()
  193. {
  194. delayedSelectionTimer = nullptr;
  195. }