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.

247 lines
7.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "../../Application/jucer_Headers.h"
  20. #include "jucer_EditingPanelBase.h"
  21. #include "jucer_JucerDocumentEditor.h"
  22. //==============================================================================
  23. class EditingPanelBase::MagnifierComponent : public Component
  24. {
  25. public:
  26. MagnifierComponent (Component* comp)
  27. : scaleFactor (1.0), content (comp)
  28. {
  29. addAndMakeVisible (content);
  30. childBoundsChanged (content);
  31. }
  32. void childBoundsChanged (Component* child)
  33. {
  34. const Rectangle<int> childArea (getLocalArea (child, child->getLocalBounds()));
  35. setSize (childArea.getWidth(), childArea.getHeight());
  36. }
  37. double getScaleFactor() const { return scaleFactor; }
  38. void setScaleFactor (double newScale)
  39. {
  40. scaleFactor = newScale;
  41. content->setTransform (AffineTransform::scale ((float) scaleFactor));
  42. }
  43. private:
  44. double scaleFactor;
  45. ScopedPointer<Component> content;
  46. };
  47. //==============================================================================
  48. class ZoomingViewport : public Viewport
  49. {
  50. public:
  51. ZoomingViewport (EditingPanelBase* const p)
  52. : panel (p), isSpaceDown (false)
  53. {
  54. }
  55. void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
  56. {
  57. if (e.mods.isCtrlDown() || e.mods.isAltDown() || e.mods.isCommandDown())
  58. mouseMagnify (e, 1.0f / (1.0f - wheel.deltaY));
  59. else
  60. Viewport::mouseWheelMove (e, wheel);
  61. }
  62. void mouseMagnify (const MouseEvent& e, float factor)
  63. {
  64. panel->setZoom (panel->getZoom() * factor, e.x, e.y);
  65. }
  66. void dragKeyHeldDown (const bool isKeyDown)
  67. {
  68. if (isSpaceDown != isKeyDown)
  69. {
  70. isSpaceDown = isKeyDown;
  71. if (isSpaceDown)
  72. {
  73. DraggerOverlayComp* const dc = new DraggerOverlayComp();
  74. addAndMakeVisible (dc);
  75. dc->setBounds (getLocalBounds());
  76. }
  77. else
  78. {
  79. for (int i = getNumChildComponents(); --i >= 0;)
  80. ScopedPointer<DraggerOverlayComp> deleter (dynamic_cast<DraggerOverlayComp*> (getChildComponent (i)));
  81. }
  82. }
  83. }
  84. private:
  85. EditingPanelBase* const panel;
  86. bool isSpaceDown;
  87. //==============================================================================
  88. class DraggerOverlayComp : public Component
  89. {
  90. public:
  91. DraggerOverlayComp()
  92. {
  93. setMouseCursor (MouseCursor::DraggingHandCursor);
  94. setAlwaysOnTop (true);
  95. }
  96. void mouseDown (const MouseEvent&)
  97. {
  98. if (Viewport* viewport = findParentComponentOfClass<Viewport>())
  99. {
  100. startX = viewport->getViewPositionX();
  101. startY = viewport->getViewPositionY();
  102. }
  103. }
  104. void mouseDrag (const MouseEvent& e)
  105. {
  106. if (Viewport* viewport = findParentComponentOfClass<Viewport>())
  107. viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
  108. startX - e.getDistanceFromDragStartX()),
  109. jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
  110. startY - e.getDistanceFromDragStartY()));
  111. }
  112. private:
  113. int startX, startY;
  114. };
  115. };
  116. //==============================================================================
  117. EditingPanelBase::EditingPanelBase (JucerDocument& doc, Component* props, Component* editorComp)
  118. : document (doc),
  119. editor (editorComp),
  120. propsPanel (props)
  121. {
  122. addAndMakeVisible (viewport = new ZoomingViewport (this));
  123. addAndMakeVisible (propsPanel);
  124. viewport->setViewedComponent (magnifier = new MagnifierComponent (editor));
  125. }
  126. EditingPanelBase::~EditingPanelBase()
  127. {
  128. deleteAllChildren();
  129. }
  130. void EditingPanelBase::resized()
  131. {
  132. const int contentW = jmax (1, getWidth() - 260);
  133. propsPanel->setBounds (contentW + 4, 4, jmax (100, getWidth() - contentW - 8), getHeight() - 8);
  134. viewport->setBounds (4, 4, contentW - 8, getHeight() - 8);
  135. if (document.isFixedSize())
  136. editor->setSize (jmax (document.getInitialWidth(),
  137. roundToInt ((viewport->getWidth() - viewport->getScrollBarThickness()) / getZoom())),
  138. jmax (document.getInitialHeight(),
  139. roundToInt ((viewport->getHeight() - viewport->getScrollBarThickness()) / getZoom())));
  140. else
  141. editor->setSize (viewport->getWidth(),
  142. viewport->getHeight());
  143. }
  144. void EditingPanelBase::paint (Graphics& g)
  145. {
  146. g.fillAll (findColour (secondaryBackgroundColourId));
  147. }
  148. void EditingPanelBase::visibilityChanged()
  149. {
  150. if (isVisible())
  151. {
  152. updatePropertiesList();
  153. if (Component* p = getParentComponent())
  154. {
  155. resized();
  156. if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
  157. cdh->setViewportToLastPos (viewport, *this);
  158. resized();
  159. }
  160. }
  161. else
  162. {
  163. if (Component* p = getParentComponent())
  164. if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
  165. cdh->storeLastViewportPos (viewport, *this);
  166. }
  167. editor->setVisible (isVisible());
  168. }
  169. double EditingPanelBase::getZoom() const
  170. {
  171. return magnifier->getScaleFactor();
  172. }
  173. void EditingPanelBase::setZoom (double newScale)
  174. {
  175. setZoom (jlimit (1.0 / 8.0, 16.0, newScale),
  176. viewport->getWidth() / 2,
  177. viewport->getHeight() / 2);
  178. }
  179. void EditingPanelBase::setZoom (double newScale, int anchorX, int anchorY)
  180. {
  181. Point<int> anchor (editor->getLocalPoint (viewport, Point<int> (anchorX, anchorY)));
  182. magnifier->setScaleFactor (newScale);
  183. resized();
  184. jassert (viewport != nullptr);
  185. anchor = viewport->getLocalPoint (editor, anchor);
  186. viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
  187. viewport->getViewPositionX() + anchor.getX() - anchorX),
  188. jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
  189. viewport->getViewPositionY() + anchor.getY() - anchorY));
  190. }
  191. void EditingPanelBase::xyToTargetXY (int& x, int& y) const
  192. {
  193. Point<int> pos (editor->getLocalPoint (this, Point<int> (x, y)));
  194. x = pos.getX();
  195. y = pos.getY();
  196. }
  197. void EditingPanelBase::dragKeyHeldDown (bool isKeyDown)
  198. {
  199. ((ZoomingViewport*) viewport)->dragKeyHeldDown (isKeyDown);
  200. }