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.

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