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.

206 lines
7.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 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. #ifndef __JUCER_COORDINATEPROPERTYCOMPONENT_H_1128AA3D__
  19. #define __JUCER_COORDINATEPROPERTYCOMPONENT_H_1128AA3D__
  20. //==============================================================================
  21. class CoordinatePropertyComponent : public PropertyComponent,
  22. public ButtonListener,
  23. public Value::Listener
  24. {
  25. public:
  26. //==============================================================================
  27. CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder* nameSource_, const String& name,
  28. const Value& coordValue_, bool isHorizontal_)
  29. : PropertyComponent (name, 40), nameSource (nameSource_),
  30. coordValue (coordValue_),
  31. textValue (Value (new CoordEditableValueSource (coordValue_, isHorizontal_))),
  32. isHorizontal (isHorizontal_)
  33. {
  34. addAndMakeVisible (label = new Label (String::empty, String::empty));
  35. label->setEditable (true, true, false);
  36. label->setColour (Label::backgroundColourId, Colours::white);
  37. label->setColour (Label::outlineColourId, findColour (ComboBox::outlineColourId));
  38. label->getTextValue().referTo (textValue);
  39. addAndMakeVisible (proportionButton = new TextButton ("%"));
  40. proportionButton->addButtonListener (this);
  41. addAndMakeVisible (anchorButton1 = new TextButton (String::empty));
  42. anchorButton1->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom);
  43. anchorButton1->setTriggeredOnMouseDown (true);
  44. anchorButton1->addButtonListener (this);
  45. addAndMakeVisible (anchorButton2 = new TextButton (String::empty));
  46. anchorButton2->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom);
  47. anchorButton2->setTriggeredOnMouseDown (true);
  48. anchorButton2->addButtonListener (this);
  49. coordValue.addListener (this);
  50. valueChanged (coordValue);
  51. }
  52. ~CoordinatePropertyComponent()
  53. {
  54. coordValue.removeListener (this);
  55. deleteAllChildren();
  56. }
  57. void resized()
  58. {
  59. const Rectangle<int> r (getLookAndFeel().getPropertyComponentContentPosition (*this));
  60. label->setBounds (r.getX(), r.getY(), r.getWidth() / 2, r.getHeight() / 2);
  61. proportionButton->setBounds (r.getX() + r.getWidth() / 2, r.getY(),
  62. r.getWidth() / 2, r.getHeight() / 2);
  63. if (anchorButton2->isVisible())
  64. {
  65. anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
  66. anchorButton2->setBounds (r.getX() + r.getWidth() / 2, r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
  67. }
  68. else
  69. {
  70. anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth(), r.getHeight() / 2);
  71. }
  72. }
  73. void refresh() {}
  74. void buttonClicked (Button* button)
  75. {
  76. RelativeCoordinate coord (getCoordinate());
  77. if (button == proportionButton)
  78. {
  79. coord.toggleProportionality (nameSource, isHorizontal);
  80. coordValue = coord.toString();
  81. }
  82. else if (button == anchorButton1)
  83. {
  84. const String marker (pickMarker (anchorButton1, coord.getAnchorName1(), true));
  85. if (marker.isNotEmpty())
  86. {
  87. coord.changeAnchor1 (marker, nameSource);
  88. coordValue = coord.toString();
  89. }
  90. }
  91. else if (button == anchorButton2)
  92. {
  93. const String marker (pickMarker (anchorButton2, coord.getAnchorName2(), false));
  94. if (marker.isNotEmpty())
  95. {
  96. coord.changeAnchor2 (marker, nameSource);
  97. coordValue = coord.toString();
  98. }
  99. }
  100. }
  101. void valueChanged (Value&)
  102. {
  103. RelativeCoordinate coord (getCoordinate());
  104. anchorButton1->setButtonText (coord.getAnchorName1());
  105. anchorButton2->setVisible (coord.isProportional());
  106. anchorButton2->setButtonText (coord.getAnchorName2());
  107. resized();
  108. }
  109. const RelativeCoordinate getCoordinate() const
  110. {
  111. return RelativeCoordinate (coordValue.toString(), isHorizontal);
  112. }
  113. virtual const String pickMarker (TextButton* button, const String& currentMarker, bool isAnchor1) = 0;
  114. protected:
  115. RelativeCoordinate::NamedCoordinateFinder* nameSource;
  116. Value coordValue, textValue;
  117. Label* label;
  118. TextButton* proportionButton;
  119. TextButton* anchorButton1;
  120. TextButton* anchorButton2;
  121. bool isHorizontal;
  122. //==============================================================================
  123. class CoordEditableValueSource : public Value::ValueSource,
  124. public Value::Listener
  125. {
  126. public:
  127. CoordEditableValueSource (const Value& sourceValue_, bool isHorizontal_)
  128. : sourceValue (sourceValue_), isHorizontal (isHorizontal_)
  129. {
  130. sourceValue.addListener (this);
  131. }
  132. ~CoordEditableValueSource() {}
  133. const var getValue() const
  134. {
  135. RelativeCoordinate coord (sourceValue.toString(), isHorizontal);
  136. if (coord.isProportional())
  137. return String (coord.getEditableNumber()) + "%";
  138. return coord.getEditableNumber();
  139. }
  140. void setValue (const var& newValue)
  141. {
  142. RelativeCoordinate coord (sourceValue.toString(), isHorizontal);
  143. coord.setEditableNumber ((double) newValue);
  144. const String newVal (coord.toString());
  145. if (sourceValue != newVal)
  146. sourceValue = newVal;
  147. }
  148. void valueChanged (Value&)
  149. {
  150. sendChangeMessage (true);
  151. }
  152. //==============================================================================
  153. juce_UseDebuggingNewOperator
  154. protected:
  155. Value sourceValue;
  156. bool isHorizontal;
  157. CoordEditableValueSource (const CoordEditableValueSource&);
  158. const CoordEditableValueSource& operator= (const CoordEditableValueSource&);
  159. };
  160. };
  161. #endif // __JUCER_COORDINATEPROPERTYCOMPONENT_H_1128AA3D__