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.

294 lines
12KB

  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 "../JuceDemoHeader.h"
  20. // these classes are C++11-only
  21. #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS
  22. struct DemoFlexPanel : public juce::Component
  23. {
  24. DemoFlexPanel (juce::Colour col, FlexItem& item) : flexItem (item), colour (col)
  25. {
  26. int x = 70;
  27. int y = 3;
  28. setupTextEditor (flexOrderEditor, { x, y, 20, 18 }, "0", [this]() { flexItem.order = (int) flexOrderEditor.getText().getFloatValue(); });
  29. addLabel ("order", flexOrderEditor);
  30. y += 20;
  31. setupTextEditor (flexGrowEditor, { x, y, 20, 18 }, "0", [this]() { flexItem.flexGrow = flexGrowEditor.getText().getFloatValue(); });
  32. addLabel ("flex-grow", flexGrowEditor);
  33. y += 20;
  34. setupTextEditor (flexShrinkEditor, { x, y, 20, 18 }, "1", [this]() { flexItem.flexShrink = flexShrinkEditor.getText().getFloatValue(); });
  35. addLabel ("flex-shrink", flexShrinkEditor);
  36. y += 20;
  37. setupTextEditor (flexBasisEditor, { x, y, 33, 18 }, "100", [this]() { flexItem.flexBasis = flexBasisEditor.getText().getFloatValue(); });
  38. addLabel ("flex-basis", flexBasisEditor);
  39. y += 20;
  40. alignSelfCombo.addItem ("auto", 1);
  41. alignSelfCombo.addItem ("flex-start", 2);
  42. alignSelfCombo.addItem ("flex-end", 3);
  43. alignSelfCombo.addItem ("center", 4);
  44. alignSelfCombo.addItem ("stretch", 5);
  45. alignSelfCombo.setBounds (x, y, 90, 18);
  46. alignSelfCombo.onChange = [this] { updateAssignSelf(); };
  47. alignSelfCombo.setSelectedId (5);
  48. alignSelfCombo.setColour (ComboBox::outlineColourId, Colours::transparentBlack);
  49. addAndMakeVisible (alignSelfCombo);
  50. addLabel ("align-self", alignSelfCombo);
  51. }
  52. void setupTextEditor (TextEditor& te, Rectangle<int> b, StringRef initialText, std::function<void()> updateFn)
  53. {
  54. te.setBounds (b);
  55. te.setText (initialText);
  56. te.onTextChange = [this, updateFn]()
  57. {
  58. updateFn();
  59. if (auto parent = getParentComponent())
  60. parent->resized();
  61. };
  62. addAndMakeVisible (te);
  63. }
  64. void addLabel (const String& name, Component& target)
  65. {
  66. auto label = new Label (name, name);
  67. label->attachToComponent (&target, true);
  68. labels.add (label);
  69. addAndMakeVisible (label);
  70. }
  71. void updateAssignSelf()
  72. {
  73. switch (alignSelfCombo.getSelectedId())
  74. {
  75. case 1: flexItem.alignSelf = FlexItem::AlignSelf::autoAlign; break;
  76. case 2: flexItem.alignSelf = FlexItem::AlignSelf::flexStart; break;
  77. case 3: flexItem.alignSelf = FlexItem::AlignSelf::flexEnd; break;
  78. case 4: flexItem.alignSelf = FlexItem::AlignSelf::center; break;
  79. case 5: flexItem.alignSelf = FlexItem::AlignSelf::stretch; break;
  80. }
  81. if (auto parent = getParentComponent())
  82. parent->resized();
  83. }
  84. void paint (Graphics& g) override
  85. {
  86. auto r = getLocalBounds();
  87. g.setColour (colour);
  88. g.fillRect (r);
  89. g.setColour (Colours::black);
  90. g.drawFittedText ("w: " + String (r.getWidth()) + newLine + "h: " + String (r.getHeight()),
  91. r.reduced (4), Justification::bottomRight, 2);
  92. }
  93. void lookAndFeelChanged() override
  94. {
  95. flexOrderEditor.applyFontToAllText (flexOrderEditor.getFont());
  96. flexGrowEditor.applyFontToAllText (flexGrowEditor.getFont());
  97. flexShrinkEditor.applyFontToAllText (flexShrinkEditor.getFont());
  98. flexBasisEditor.applyFontToAllText (flexBasisEditor.getFont());
  99. }
  100. FlexItem& flexItem;
  101. TextEditor flexOrderEditor, flexGrowEditor, flexShrinkEditor, flexBasisEditor;
  102. ComboBox alignSelfCombo;
  103. juce::Colour colour;
  104. OwnedArray<Label> labels;
  105. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DemoFlexPanel)
  106. };
  107. //==============================================================================
  108. struct FlexBoxDemo : public juce::Component
  109. {
  110. FlexBoxDemo()
  111. {
  112. setupPropertiesPanel();
  113. setupFlexBoxItems();
  114. }
  115. void resized() override
  116. {
  117. flexBox.performLayout (getFlexBoxBounds());
  118. }
  119. Rectangle<float> getFlexBoxBounds() const
  120. {
  121. return getLocalBounds().withTrimmedLeft (300)
  122. .reduced (10)
  123. .toFloat();
  124. }
  125. void paint (Graphics& g) override
  126. {
  127. g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,
  128. Colours::lightgrey));
  129. g.setColour (Colours::white);
  130. g.fillRect (getFlexBoxBounds());
  131. }
  132. void setupPropertiesPanel()
  133. {
  134. auto directionGroup = addControl (new GroupComponent ("direction", "flex-direction"));
  135. directionGroup->setBounds (10, 30, 140, 110);
  136. int i = 0;
  137. int groupID = 1234;
  138. int leftMargin = 15;
  139. int topMargin = 45;
  140. createToggleButton ("row", groupID, leftMargin, topMargin + i++ * 22, true, [this]() { flexBox.flexDirection = FlexBox::Direction::row; }).setToggleState (true, dontSendNotification);
  141. createToggleButton ("row-reverse", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.flexDirection = FlexBox::Direction::rowReverse; });
  142. createToggleButton ("column", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.flexDirection = FlexBox::Direction::column; });
  143. createToggleButton ("column-reverse", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.flexDirection = FlexBox::Direction::columnReverse; });
  144. auto wrapGroup = addControl (new GroupComponent ("wrap", "flex-wrap"));
  145. wrapGroup->setBounds (160, 30, 140, 110);
  146. i = 0;
  147. ++groupID;
  148. leftMargin = 165;
  149. createToggleButton ("nowrap", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.flexWrap = FlexBox::Wrap::noWrap; });
  150. createToggleButton ("wrap", groupID, leftMargin, topMargin + i++ * 22, true, [this]() { flexBox.flexWrap = FlexBox::Wrap::wrap; });
  151. createToggleButton ("wrap-reverse", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.flexWrap = FlexBox::Wrap::wrapReverse; });
  152. auto justifyGroup = addControl (new GroupComponent ("justify", "justify-content"));
  153. justifyGroup->setBounds (10, 150, 140, 140);
  154. i = 0;
  155. ++groupID;
  156. leftMargin = 15;
  157. topMargin = 165;
  158. createToggleButton ("flex-start", groupID, leftMargin, topMargin + i++ * 22, true, [this]() { flexBox.justifyContent = FlexBox::JustifyContent::flexStart; });
  159. createToggleButton ("flex-end", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.justifyContent = FlexBox::JustifyContent::flexEnd; });
  160. createToggleButton ("center", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.justifyContent = FlexBox::JustifyContent::center; });
  161. createToggleButton ("space-between", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.justifyContent = FlexBox::JustifyContent::spaceBetween; });
  162. createToggleButton ("space-around", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.justifyContent = FlexBox::JustifyContent::spaceAround; });
  163. auto alignGroup = addControl (new GroupComponent ("align", "align-items"));
  164. alignGroup->setBounds (160, 150, 140, 140);
  165. i = 0;
  166. ++groupID;
  167. leftMargin = 165;
  168. topMargin = 165;
  169. createToggleButton ("stretch", groupID, leftMargin, topMargin + i++ * 22, true, [this]() { flexBox.alignItems = FlexBox::AlignItems::stretch; });
  170. createToggleButton ("flex-start", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignItems = FlexBox::AlignItems::flexStart; });
  171. createToggleButton ("flex-end", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignItems = FlexBox::AlignItems::flexEnd; });
  172. createToggleButton ("center", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignItems = FlexBox::AlignItems::center; });
  173. auto alignContentGroup = addControl (new GroupComponent ("content", "align-content"));
  174. alignContentGroup->setBounds (10, 300, 140, 160);
  175. i = 0;
  176. ++groupID;
  177. leftMargin = 15;
  178. topMargin = 315;
  179. createToggleButton ("stretch", groupID, leftMargin, topMargin + i++ * 22, true, [this]() { flexBox.alignContent = FlexBox::AlignContent::stretch; });
  180. createToggleButton ("flex-start", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignContent = FlexBox::AlignContent::flexStart; });
  181. createToggleButton ("flex-end", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignContent = FlexBox::AlignContent::flexEnd; });
  182. createToggleButton ("center", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignContent = FlexBox::AlignContent::center; });
  183. createToggleButton ("space-between", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignContent = FlexBox::AlignContent::spaceBetween; });
  184. createToggleButton ("space-around", groupID, leftMargin, topMargin + i++ * 22, false, [this]() { flexBox.alignContent = FlexBox::AlignContent::spaceAround; });
  185. }
  186. void setupFlexBoxItems()
  187. {
  188. addItem (Colours::orange);
  189. addItem (Colours::aqua);
  190. addItem (Colours::lightcoral);
  191. addItem (Colours::aquamarine);
  192. addItem (Colours::forestgreen);
  193. }
  194. void addItem (Colour colour)
  195. {
  196. flexBox.items.add (FlexItem (100, 150)
  197. .withMargin (10)
  198. .withWidth (200));
  199. auto& flexItem = flexBox.items.getReference (flexBox.items.size() - 1);
  200. auto panel = panels.add (new DemoFlexPanel (colour, flexItem));
  201. flexItem.associatedComponent = panel;
  202. addAndMakeVisible (panel);
  203. }
  204. ToggleButton& createToggleButton (StringRef text, int groupID, int x, int y, bool toggleOn, std::function<void()> fn)
  205. {
  206. auto* tb = buttons.add (new ToggleButton());
  207. tb->setButtonText (text);
  208. tb->setRadioGroupId (groupID);
  209. tb->setToggleState (toggleOn, dontSendNotification);
  210. tb->onClick = fn;
  211. tb->setBounds (x, y, 130, 22);
  212. addAndMakeVisible (tb);
  213. return *tb;
  214. }
  215. template <typename ComponentType>
  216. ComponentType* addControl (ComponentType* newControlComp)
  217. {
  218. controls.add (newControlComp);
  219. addAndMakeVisible (newControlComp);
  220. return newControlComp;
  221. }
  222. FlexBox flexBox;
  223. OwnedArray<DemoFlexPanel> panels;
  224. OwnedArray<Component> controls;
  225. OwnedArray<ToggleButton> buttons;
  226. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlexBoxDemo)
  227. };
  228. // This static object will register this demo type in a global list of demos..
  229. static JuceDemoType<FlexBoxDemo> demo ("10 Components: FlexBox");
  230. #endif