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.

237 lines
7.5KB

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