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.

244 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 (getOwnerView()->findColour (mainBackgroundColourId).contrasting (0.3f));
  53. g.fillPath (p);
  54. }
  55. Colour JucerTreeViewBase::getBackgroundColour() const
  56. {
  57. Colour background (getOwnerView()->findColour (mainBackgroundColourId));
  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(), area, Justification::centredLeft, 1, 0.8f);
  76. }
  77. Component* JucerTreeViewBase::createItemComponent()
  78. {
  79. return new TreeItemComponent (*this);
  80. }
  81. //==============================================================================
  82. class RenameTreeItemCallback : public ModalComponentManager::Callback,
  83. public TextEditorListener
  84. {
  85. public:
  86. RenameTreeItemCallback (JucerTreeViewBase& item_, Component& parent, const Rectangle<int>& bounds)
  87. : item (item_)
  88. {
  89. ed.setMultiLine (false, false);
  90. ed.setPopupMenuEnabled (false);
  91. ed.setSelectAllWhenFocused (true);
  92. ed.setFont (item.getFont());
  93. ed.addListener (this);
  94. ed.setText (item.getRenamingName());
  95. ed.setBounds (bounds);
  96. parent.addAndMakeVisible (&ed);
  97. ed.enterModalState (true, this);
  98. }
  99. void modalStateFinished (int resultCode)
  100. {
  101. if (resultCode != 0)
  102. item.setName (ed.getText());
  103. }
  104. void textEditorTextChanged (TextEditor&) {}
  105. void textEditorReturnKeyPressed (TextEditor& editor) { editor.exitModalState (1); }
  106. void textEditorEscapeKeyPressed (TextEditor& editor) { editor.exitModalState (0); }
  107. void textEditorFocusLost (TextEditor& editor) { editor.exitModalState (0); }
  108. private:
  109. TextEditor ed;
  110. JucerTreeViewBase& item;
  111. JUCE_DECLARE_NON_COPYABLE (RenameTreeItemCallback);
  112. };
  113. void JucerTreeViewBase::showRenameBox()
  114. {
  115. Rectangle<int> r (getItemPosition (true));
  116. r.setLeft (r.getX() + textX);
  117. r.setHeight (getItemHeight());
  118. new RenameTreeItemCallback (*this, *getOwnerView(), r);
  119. }
  120. void JucerTreeViewBase::itemClicked (const MouseEvent& e)
  121. {
  122. if (e.mods.isPopupMenu())
  123. {
  124. if (getOwnerView()->getNumSelectedItems() > 1)
  125. showMultiSelectionPopupMenu();
  126. else
  127. showPopupMenu();
  128. }
  129. }
  130. void JucerTreeViewBase::deleteItem() {}
  131. void JucerTreeViewBase::deleteAllSelectedItems() {}
  132. void JucerTreeViewBase::showDocument() {}
  133. void JucerTreeViewBase::showPopupMenu() {}
  134. void JucerTreeViewBase::showMultiSelectionPopupMenu() {}
  135. static void treeViewMenuItemChosen (int resultCode, JucerTreeViewBase* item)
  136. {
  137. item->handlePopupMenuResult (resultCode);
  138. }
  139. void JucerTreeViewBase::launchPopupMenu (PopupMenu& m)
  140. {
  141. m.showMenuAsync (PopupMenu::Options(),
  142. ModalCallbackFunction::create (treeViewMenuItemChosen, this));
  143. }
  144. void JucerTreeViewBase::handlePopupMenuResult (int)
  145. {
  146. }
  147. ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
  148. {
  149. Component* c = getOwnerView();
  150. while (c != nullptr)
  151. {
  152. ProjectContentComponent* pcc = dynamic_cast <ProjectContentComponent*> (c);
  153. if (pcc != nullptr)
  154. return pcc;
  155. c = c->getParentComponent();
  156. }
  157. return 0;
  158. }
  159. //==============================================================================
  160. class JucerTreeViewBase::ItemSelectionTimer : public Timer
  161. {
  162. public:
  163. ItemSelectionTimer (JucerTreeViewBase& owner_) : owner (owner_) {}
  164. void timerCallback() { owner.invokeShowDocument(); }
  165. private:
  166. JucerTreeViewBase& owner;
  167. JUCE_DECLARE_NON_COPYABLE (ItemSelectionTimer);
  168. };
  169. void JucerTreeViewBase::itemSelectionChanged (bool isNowSelected)
  170. {
  171. if (isNowSelected)
  172. {
  173. delayedSelectionTimer = new ItemSelectionTimer (*this);
  174. delayedSelectionTimer->startTimer (getMillisecsAllowedForDragGesture());
  175. }
  176. else
  177. {
  178. cancelDelayedSelectionTimer();
  179. }
  180. }
  181. void JucerTreeViewBase::invokeShowDocument()
  182. {
  183. cancelDelayedSelectionTimer();
  184. showDocument();
  185. }
  186. void JucerTreeViewBase::itemDoubleClicked (const MouseEvent& e)
  187. {
  188. invokeShowDocument();
  189. }
  190. void JucerTreeViewBase::cancelDelayedSelectionTimer()
  191. {
  192. delayedSelectionTimer = nullptr;
  193. }