Krotos Modules 3
Loading...
Searching...
No Matches
CustomLayout.cpp
Go to the documentation of this file.
1#include "CustomLayout.h"
2
3namespace krotos
4{
5 const Identifier CustomLayout::Tag::layout = "LAYOUT";
6 const Identifier CustomLayout::Tag::slot = "SLOT";
7
8 const Identifier CustomLayout::Property::name = "name";
9 const Identifier CustomLayout::Property::index = "index";
10 const Identifier CustomLayout::Property::bounds = "bounds";
11
12 const String CustomLayout::FileExtension = "clf";
13 const Rectangle<int> CustomLayout::DefaultSize = Rectangle<int>{50, 50, 100, 100};
14
15 CustomLayout::CustomLayout() : m_layoutTree(CustomLayout::Tag::layout)
16 {
17 // Add Listener for layout tree. This is required for creating & destroying slots.
18 m_layoutTree.addListener(this);
19 }
20
21 CustomLayout::~CustomLayout() { m_layoutTree.removeListener(this); }
22
24 {
25 if (m_autoLayout)
26 {
27
28 auto bounds = getLocalBounds();
29
30 FlexBox fb = m_flexSettings;
31 FlexItem::Margin margin = m_flexMargin;
32
33 for (auto& c : m_components)
34 {
35 auto componentBounds =
36 Rectangle<int>::fromString(m_layoutTree.getChildWithProperty(Property::name, c->getName())
38 .toString());
39
41 componentBounds = getAutoLayoutBoundsFromType(c->getName(), componentBounds);
42
43 auto flex = FlexItem(*c)
44 .withMargin(margin)
45 .withHeight((float)componentBounds.getHeight())
46 .withWidth((float)componentBounds.getWidth())
47 .withOrder(static_cast<int>(componentBounds.getHeight() / 10) * -1);
48
49 fb.items.add(flex);
50 }
51
52 fb.performLayout(bounds);
53 }
54 else
55 {
56 for (auto c : m_components)
57 {
58 auto componentBounds =
59 Rectangle<int>::fromString(m_layoutTree.getChildWithProperty(Property::name, c->getName())
61 .toString());
62
63 c->setBounds(componentBounds);
64 }
65 }
66 }
67
69 {
70 saveLayout();
71
72 return m_layoutTree;
73 }
74
75 void CustomLayout::resetLayoutTree(const ValueTree& layoutTree)
76 {
77 m_layoutTree.removeAllChildren(nullptr);
78 m_layoutTree.copyPropertiesAndChildrenFrom(layoutTree, nullptr);
79 setLayoutTree(layoutTree);
80 }
81
82 void CustomLayout::addSlot(const String& name, const Rectangle<int>& bounds)
83 {
84 ValueTree slotTree{CustomLayout::Tag::slot,
85 {
88 {CustomLayout::Property::bounds, bounds.toString()},
89 }};
90
91 m_layoutTree.appendChild(slotTree, nullptr);
92 }
93
94 void CustomLayout::addComponent(Component& component, Rectangle<int> bounds)
95 {
96 addSlot(component.getComponentID(), bounds);
97
98 m_components.getLast()->addAndMakeVisible(component);
99 m_components.getLast()->resized();
100 }
101
102 void CustomLayout::addComponent(Component& component, ValueTree slot)
103 {
104 jassert(slot.hasType(Tag::slot));
105
106 if (slot.hasType(Tag::slot))
107 {
108 auto name = slot[Property::name].toString();
109 auto index = slot[Property::index];
110 auto bounds = Rectangle<int>::fromString(slot[Property::bounds].toString());
111
112 // Try to find existing slot.
113 for (auto c : m_components)
114 {
115 if (c->getName() == name)
116 {
117 c->addAndMakeVisible(component);
118 c->resized();
119
120 // Success, return.
121 return;
122 }
123 }
124
125 // No existing slot found, add a new one.
126 addComponent(component, bounds);
127 }
128 }
129
131 {
132 // Remove the component from the tree.
133 // The component is then removed in the valueTreeChildRemoved callback.
134 m_layoutTree.removeChild(index, nullptr);
135 }
136
137 void CustomLayout::setEditModeActive(bool isEditModeActive)
138 {
140
141 for (auto c : m_components)
142 {
143 dynamic_cast<ResizableComponent*>(c)->setResizable(m_editable);
144 }
145 }
146
148 {
149 if (!m_autoLayout)
150 {
151 for (int i = 0; i < m_components.size(); ++i)
152 {
153 auto bounds = m_components[i]->getBounds();
154
155 m_layoutTree.getChildWithProperty(Property::name, m_components[i]->getName())
156 .setProperty(CustomLayout::Property::bounds, bounds.toString(), nullptr);
157 }
158 }
159 }
160
161 Component* CustomLayout::createAndAddResizableComponent(String name, Rectangle<int> bounds)
162 {
163 auto comp = new ResizableComponent(name);
164 m_components.add(comp);
165
166 comp->setResizable(isEditModeActive());
167
168 comp->setBounds(bounds);
169
170 addAndMakeVisible(comp);
171
172 resized();
173
174 // Add listener to save bounds to tree when component is resized.
175 // See componentMovedOrResized()
176 comp->addComponentListener(this);
177
178 return comp;
179 }
180
181 void CustomLayout::valueTreeChildAdded(ValueTree& /*parentTree*/, ValueTree& childWhichHasBeenAdded)
182 {
183 String name = childWhichHasBeenAdded.getProperty(CustomLayout::Property::name);
184 String bounds = childWhichHasBeenAdded.getProperty(CustomLayout::Property::bounds);
185
186 createAndAddResizableComponent(name, Rectangle<int>::fromString(bounds));
187 }
188
189 void CustomLayout::valueTreeChildRemoved(ValueTree& /*parentTree*/, ValueTree& childWhichHasBeenRemoved,
190 int /*indexFromWhichChildWasRemoved*/)
191 {
192 String name = childWhichHasBeenRemoved.getProperty(CustomLayout::Property::name);
193
194 for (auto c : m_components)
195 if (c->getName() == name)
196 m_components.remove(m_components.indexOf(c));
197 }
198
199 void CustomLayout::valueTreePropertyChanged(ValueTree& /*treeWhosePropertyHasChanged*/,
200 const Identifier& /*property*/)
201 {
202 }
203
204 void CustomLayout::valueTreeRedirected(ValueTree& treeWhichHasBeenChanged)
205 {
206 if (treeRedirected)
207 {
209 }
210 }
211
212 void CustomLayout::componentMovedOrResized(Component& component, bool /*wasMoved*/, bool /*wasResized*/)
213 {
214 if (!m_autoLayout)
215 {
216 auto idx = m_components.indexOf(&component);
217 auto newBounds = m_components[idx]->getBounds();
218
219 // Save bounds as proportions relative to local bounds
220 auto bounds = newBounds;
221
222 auto nodeToUpdate = m_layoutTree.getChildWithProperty(Property::name, component.getName());
223 nodeToUpdate.setProperty(Property::bounds, bounds.toString(), nullptr);
224 }
225 }
226
227 void CustomLayout::configureAutoLayout(FlexBox flexboxSettings, FlexItem::Margin flexMargin)
228 {
229 m_flexSettings = flexboxSettings;
230 m_flexMargin = flexMargin;
231 }
232
233} // namespace krotos
Definition CustomLayout.h:14
void resized() override
Definition CustomLayout.cpp:23
void configureAutoLayout(FlexBox flexboxSettings, FlexItem::Margin margin)
Definition CustomLayout.cpp:227
std::function< Rectangle< int >(String componentType, Rectangle< int > currentBounds)> getAutoLayoutBoundsFromType
Used to look up what bounds should be used for a given component type when using auto layout....
Definition CustomLayout.h:134
~CustomLayout()
Definition CustomLayout.cpp:21
void setLayoutTree(const ValueTree &layoutTree)
Definition CustomLayout.h:52
void valueTreePropertyChanged(ValueTree &treeWhosePropertyHasChanged, const Identifier &property) override
Definition CustomLayout.cpp:199
ValueTree & getLayoutTree()
Definition CustomLayout.cpp:68
static const String FileExtension
Definition CustomLayout.h:31
FlexBox m_flexSettings
Definition CustomLayout.h:147
ValueTree m_layoutTree
Definition CustomLayout.h:142
void valueTreeRedirected(ValueTree &treeWhichHasBeenChanged)
Definition CustomLayout.cpp:204
bool m_editable
Definition CustomLayout.h:144
void valueTreeChildAdded(ValueTree &parentTree, ValueTree &childWhichHasBeenAdded) override
Definition CustomLayout.cpp:181
static const Rectangle< int > DefaultSize
Definition CustomLayout.h:32
CustomLayout()
Definition CustomLayout.cpp:15
void addComponent(Component &component, Rectangle< int > bounds=CustomLayout::DefaultSize)
Definition CustomLayout.cpp:94
void saveLayout()
Definition CustomLayout.cpp:147
void resetLayoutTree(const ValueTree &layoutTree)
Definition CustomLayout.cpp:75
FlexItem::Margin m_flexMargin
Definition CustomLayout.h:148
void componentMovedOrResized(Component &component, bool wasMoved, bool wasResized) override
Definition CustomLayout.cpp:212
void valueTreeChildRemoved(ValueTree &parentTree, ValueTree &childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved) override
Definition CustomLayout.cpp:189
OwnedArray< Component > m_components
Definition CustomLayout.h:141
bool m_autoLayout
Definition CustomLayout.h:146
void addSlot(const String &name, const Rectangle< int > &bounds)
Definition CustomLayout.cpp:82
bool isEditModeActive()
Definition CustomLayout.h:111
void removeComponent(int index)
Definition CustomLayout.cpp:130
std::function< void()> treeRedirected
Definition CustomLayout.h:138
Component * createAndAddResizableComponent(String name, Rectangle< int > bounds)
Definition CustomLayout.cpp:161
void setEditModeActive(bool isEditModeActive)
Definition CustomLayout.cpp:137
Definition ResizableComponent.h:15
Definition AirAbsorptionFilter.cpp:2
static const Identifier name
Definition CustomLayout.h:26
static const Identifier index
Definition CustomLayout.h:27
static const Identifier bounds
Definition CustomLayout.h:28
Definition CustomLayout.h:19
static const Identifier slot
Definition CustomLayout.h:21
static const Identifier layout
Definition CustomLayout.h:20