neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_layout.hpp
Go to the documentation of this file.
1// i_layout.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2015, 2020 Leigh Johnston. All Rights Reserved.
5
6 This program is free software: you can redistribute it and / or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21
22#include <neogfx/neogfx.hpp>
23#include <neogfx/core/event.hpp>
26
27namespace neogfx
28{
29 class i_layout;
30 class i_spacer;
31 class i_widget;
32 class i_title_bar;
33 class i_status_bar;
34
35 typedef uint32_t layout_item_index;
36 typedef std::optional<layout_item_index> optional_layout_item_index;
37
38 enum class layout_position : uint32_t
39 {
40 None = 0x00000000,
41 Top = 0x00000001,
42 Left = 0x00000002,
43 Center = 0x00000004,
44 Right = 0x00000008,
45 Bottom = 0x00000010
46 };
47
48 enum class standard_layout : uint32_t
49 {
50 Default = 0x00000000,
51 Client = 0x00000001,
52 NonClient = 0x00000002,
53 TitleBar = 0x00000003,
54 Menu = 0x00000004,
55 Toolbar = 0x00000005,
56 Dock = 0x00000006,
57 StatusBar = 0x00000007,
58 ButtonBox = 0x00000009
59 };
60
61 struct standard_layout_not_found : std::logic_error { standard_layout_not_found() : std::logic_error{ "neogfx::standard_layout_not_found" } {} };
62
64 {
65 public:
66 struct no_title_bar : std::logic_error { no_title_bar() : std::logic_error{ "neogfx::i_standard_layout_container::no_title_bar" } {} };
67 struct no_status_bar : std::logic_error { no_status_bar() : std::logic_error{ "neogfx::i_standard_layout_container::no_status_bar" } {} };
68 struct no_client_widget : std::logic_error { no_client_widget() : std::logic_error{ "neogfx::i_standard_layout_container::no_client_widget" } {} };
69 public:
70 virtual ~i_standard_layout_container() = default;
71 public:
72 virtual bool is_widget() const = 0;
73 virtual const i_widget& as_widget() const = 0;
74 virtual i_widget& as_widget() = 0;
75 public:
76 virtual bool has_client_widget() const = 0;
77 virtual const i_widget& client_widget() const = 0;
78 virtual i_widget& client_widget() = 0;
79 virtual void set_client(i_widget& aClient) = 0;
80 virtual void set_client(i_ref_ptr<i_widget> const& aClient) = 0;
81 virtual const i_title_bar& title_bar() const = 0;
82 virtual i_title_bar& title_bar() = 0;
83 virtual void set_title_bar(i_title_bar& aTitleBar) = 0;
84 virtual void set_title_bar(i_ref_ptr<i_title_bar> const& aTitleBar) = 0;
85 virtual const i_status_bar& status_bar() const = 0;
86 virtual i_status_bar& status_bar() = 0;
87 virtual void set_status_bar(i_status_bar& aStatusBar) = 0;
88 virtual void set_status_bar(i_ref_ptr<i_status_bar> const& aStatusBar) = 0;
89 public:
90 virtual bool has_layout(standard_layout aStandardLayout) const = 0;
91 virtual const i_layout& layout(standard_layout aStandardLayout, layout_position aPosition = layout_position::None) const = 0;
92 virtual i_layout& layout(standard_layout aStandardLayout, layout_position aPosition = layout_position::None) = 0;
93 public:
95 {
97 }
103 {
105 }
110 const i_layout& menu_layout() const
111 {
113 }
119 {
120 return layout(standard_layout::Toolbar, aPosition);
121 }
127 {
128 return layout(standard_layout::Dock, aPosition);
129 }
135 {
136 return layout(standard_layout::Dock, to_position(aDockArea));
137 }
139 {
140 return layout(standard_layout::Dock, to_position(aDockArea));
141 }
142 const i_layout& client_layout() const
143 {
145 }
151 {
153 }
159 {
161 }
166 public:
168 {
169 switch (aDockArea)
170 {
171 case dock_area::None:
173 case dock_area::Top:
177 case dock_area::Left:
178 default:
180 case dock_area::Right:
182 }
183 }
184 };
185
186 enum class autoscale : uint32_t
187 {
188 Default = 0x00000000,
189 Active = 0x00000001,
190 LockFixedSize = 0x00000002
191 };
192
193 inline constexpr autoscale operator~(autoscale aLhs)
194 {
195 return static_cast<autoscale>(~static_cast<uint32_t>(aLhs));
196 }
197
198 inline constexpr autoscale operator|(autoscale aLhs, autoscale aRhs)
199 {
200 return static_cast<autoscale>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
201 }
202
203 inline constexpr autoscale operator&(autoscale aLhs, autoscale aRhs)
204 {
205 return static_cast<autoscale>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
206 }
207
208 enum class layout_direction : uint32_t
209 {
210 Unknown = 0x00000000,
211 Horizontal = 0x00000001,
212 Vertical = 0x00000002
213 };
214
216 {
217 return static_cast<layout_direction>(~static_cast<uint32_t>(aLhs));
218 }
219
221 {
222 return static_cast<layout_direction>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
223 }
224
226 {
227 return static_cast<layout_direction>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
228 }
229
230 class i_layout : public i_layout_item
231 {
232 public:
233 declare_event(layout_completed)
234 declare_event(alignment_changed)
235 public:
236 typedef i_layout abstract_type;
237 protected:
238 class item;
239 public:
240 struct bad_item_index : std::logic_error { bad_item_index() : std::logic_error("neogfx::i_layout::bad_item_index") {} };
241 struct wrong_item_type : std::logic_error { wrong_item_type() : std::logic_error("neogfx::i_layout::wrong_item_type") {} };
242 struct item_not_found : std::logic_error { item_not_found() : std::logic_error("neogfx::i_layout::item_not_found") {} };
243 struct incompatible_layouts : std::logic_error { incompatible_layouts() : std::logic_error("neogfx::i_layout::incompatible_layouts") {} };
244 public:
245 virtual ~i_layout() = default;
246 public:
247 virtual i_layout_item& add(i_layout_item& aItem) = 0;
248 virtual i_layout_item& add_at(layout_item_index aPosition, i_layout_item& aItem) = 0;
249 virtual i_layout_item& add(i_ref_ptr<i_layout_item> const& aItem) = 0;
250 virtual i_layout_item& add_at(layout_item_index aPosition, i_ref_ptr<i_layout_item> const& aItem) = 0;
251 virtual i_spacer& add_spacer() = 0;
252 virtual i_spacer& add_spacer_at(layout_item_index aPosition) = 0;
253 virtual void remove_at(layout_item_index aIndex) = 0;
254 virtual bool remove(i_layout_item& aItem) = 0;
255 virtual void remove_all() = 0;
256 virtual void move_all_to(i_layout& aDestination) = 0;
257 virtual layout_item_index count() const = 0;
258 virtual layout_item_index index_of(const i_layout_item& aItem) const = 0;
259 virtual optional_layout_item_index find(const i_layout_item& aItem) const = 0;
260 virtual bool is_widget_at(layout_item_index aIndex) const = 0;
261 virtual const i_layout_item& item_at(layout_item_index aIndex) const = 0;
263 virtual const i_widget& get_widget_at(layout_item_index aIndex) const = 0;
265 virtual const i_layout& get_layout_at(layout_item_index aIndex) const = 0;
267 public:
268 virtual layout_direction direction() const = 0;
269 virtual bool has_spacing() const = 0;
270 virtual size spacing() const = 0;
271 virtual void set_spacing(optional_size const& sSpacing, bool aUpdateLayout = true) = 0;
272 virtual bool always_use_spacing() const = 0;
273 virtual void set_always_use_spacing(bool aAlwaysUseSpacing) = 0;
274 virtual bool has_alignment() const = 0;
275 virtual neogfx::alignment alignment() const = 0;
276 virtual void set_alignment(optional_alignment const& aAlignment, bool aUpdateLayout = true) = 0;
277 virtual neogfx::autoscale autoscale() const = 0;
278 virtual void set_autoscale(neogfx::autoscale aAutoscale, bool aUpdateLayout = true) = 0;
280 virtual bool ignore_child_visibility() const = 0;
281 virtual void set_ignore_child_visibility(bool aIgnoreChildVisibility) = 0;
282 public:
283 virtual void enable(bool aEnable) = 0;
284 virtual bool enabled() const = 0;
285 virtual void layout_items(const point& aPosition, const size& aSize) = 0;
286 virtual bool invalidated() const = 0;
287 virtual void invalidate(bool aDeferLayout = true) = 0;
288 virtual void validate() = 0;
289 // helpers
290 public:
291 template <typename ItemType>
292 ItemType& add()
293 {
294 auto item = make_ref<ItemType>();
295 return static_cast<ItemType&>(add(item));
296 }
297 template <typename ItemType>
298 ItemType& add(i_ref_ptr<ItemType> const& aItem)
299 {
300 return static_cast<ItemType&>(add(to_abstract(static_pointer_cast<i_layout_item>(aItem))));
301 }
302 template <typename ItemType>
303 ItemType& add_at(layout_item_index aPosition, i_ref_ptr<ItemType> const& aItem)
304 {
305 return static_cast<ItemType&>(add_at(aPosition, to_abstract(static_pointer_cast<i_layout_item>(aItem))));
306 }
307 template <typename ItemType>
308 ItemType& add(ref_ptr<ItemType> const& aItem)
309 {
310 return static_cast<ItemType&>(add(to_abstract(static_pointer_cast<i_layout_item>(aItem))));
311 }
312 template <typename ItemType>
313 ItemType& add_at(layout_item_index aPosition, ref_ptr<ItemType> const& aItem)
314 {
315 return static_cast<ItemType&>(add_at(aPosition, to_abstract(static_pointer_cast<i_layout_item>(aItem))));
316 }
317 template <typename ItemType, typename... Args>
318 ItemType& emplace(Args&&... args)
319 {
320 auto newItem = make_ref<ItemType>(std::forward<Args>(args)...);
321 add(newItem);
322 return *newItem;
323 }
324 template <typename ItemType, typename... Args>
325 ItemType& emplace_at(layout_item_index aPosition, Args&&... args)
326 {
327 auto newItem = make_ref<ItemType>(std::forward<Args>(args)...);
328 add(newItem);
329 if (aPosition < count())
330 remove_at(aPosition);
331 add_at(aPosition, newItem);
332 return *newItem;
333 }
334 template <typename ItemType>
335 ItemType& replace_item_at(layout_item_index aPosition, ItemType&& aItem)
336 {
337 if (aPosition < count())
338 remove_at(aPosition);
339 return static_cast<ItemType&>(add_at(aPosition, aItem));
340 }
341 template <typename ItemType>
342 ItemType& replace_item_at(layout_item_index aPosition, i_ref_ptr<ItemType> const& aItem)
343 {
344 if (aPosition < count())
345 remove_at(aPosition);
346 return static_cast<ItemType&>(add_at(aPosition, static_pointer_cast<i_layout_item>(aItem)));
347 }
348 template <typename WidgetT>
349 const WidgetT& get_widget_at(layout_item_index aIndex) const
350 {
351 return static_cast<const WidgetT&>(get_widget_at(aIndex));
352 }
353 template <typename WidgetT>
355 {
356 return static_cast<WidgetT&>(get_widget_at(aIndex));
357 }
358 bool is_descendent_of(const i_layout& aAncestor) const
359 {
360 auto* l = this;
361 while (l->has_parent_layout() && &l->parent_widget() == &aAncestor.parent_widget())
362 {
363 l = &l->parent_layout();
364 if (l == &aAncestor)
365 return true;
366 }
367 return false;
368 }
369 void enable()
370 {
371 enable(true);
372 }
373 void disable()
374 {
375 enable(false);
376 }
377 };
378
379 inline size total_child_weight(const i_layout& aLayout)
380 {
381 size totalWeight;
382 for (layout_item_index itemIndex = 0; itemIndex < aLayout.count(); ++itemIndex)
383 {
384 auto const& item = aLayout.item_at(itemIndex);
385 if (!item.visible())
386 continue;
387 totalWeight += item.weight();
388 }
389 return totalWeight;
390 }
391
392 inline size calculate_relative_weight(const i_layout& aLayout, const i_layout_item& aItem)
393 {
394 size totalSize;
395 for (layout_item_index itemIndex = 0; itemIndex < aLayout.count(); ++itemIndex)
396 {
397 auto const& item = aLayout.item_at(itemIndex);
398 if (!item.visible())
399 continue;
400 totalSize += (item.has_fixed_size() ? item.fixed_size() : item.extents());
401 }
402 auto result = (aItem.has_fixed_size() ? aItem.fixed_size() : aItem.extents()) / totalSize;
403 if (std::isnan(result.cx))
404 result.cx = 1.0;
405 if (std::isnan(result.cy))
406 result.cy = 1.0;
407 return result;
408 }
409
411 {
412 public:
413 scoped_layout_items(bool aForceRefresh = false);
415 private:
416 bool iStartLayout;
417 };
418
425}
dimension_type cx
i_layout_item abstract_type
virtual const i_widget & parent_widget() const =0
virtual void enable(bool aEnable)=0
virtual neogfx::autoscale autoscale() const =0
virtual void set_spacing(optional_size const &sSpacing, bool aUpdateLayout=true)=0
virtual i_spacer & add_spacer_at(layout_item_index aPosition)=0
WidgetT & get_widget_at(layout_item_index aIndex)
Definition i_layout.hpp:354
ItemType & add(ref_ptr< ItemType > const &aItem)
Definition i_layout.hpp:308
virtual i_layout_item & add(i_ref_ptr< i_layout_item > const &aItem)=0
virtual neogfx::alignment alignment() const =0
ItemType & add_at(layout_item_index aPosition, ref_ptr< ItemType > const &aItem)
Definition i_layout.hpp:313
virtual void remove_at(layout_item_index aIndex)=0
virtual layout_direction direction() const =0
virtual const i_layout & get_layout_at(layout_item_index aIndex) const =0
virtual i_layout_item & add_at(layout_item_index aPosition, i_ref_ptr< i_layout_item > const &aItem)=0
virtual void set_alignment(optional_alignment const &aAlignment, bool aUpdateLayout=true)=0
ItemType & replace_item_at(layout_item_index aPosition, i_ref_ptr< ItemType > const &aItem)
Definition i_layout.hpp:342
virtual layout_item_index count() const =0
virtual void layout_items(const point &aPosition, const size &aSize)=0
virtual bool enabled() const =0
virtual i_widget & get_widget_at(layout_item_index aIndex)=0
virtual bool remove(i_layout_item &aItem)=0
virtual void set_ignore_child_visibility(bool aIgnoreChildVisibility)=0
ItemType & emplace_at(layout_item_index aPosition, Args &&... args)
Definition i_layout.hpp:325
ItemType & emplace(Args &&... args)
Definition i_layout.hpp:318
virtual bool is_widget_at(layout_item_index aIndex) const =0
virtual i_layout_item & item_at(layout_item_index aIndex)=0
virtual void validate()=0
virtual i_layout & get_layout_at(layout_item_index aIndex)=0
virtual i_spacer & add_spacer()=0
virtual void move_all_to(i_layout &aDestination)=0
virtual optional_layout_item_index find(const i_layout_item &aItem) const =0
virtual bool has_alignment() const =0
virtual bool has_spacing() const =0
virtual visibility_constraint child_visibility() const =0
virtual ~i_layout()=default
const WidgetT & get_widget_at(layout_item_index aIndex) const
Definition i_layout.hpp:349
ItemType & add(i_ref_ptr< ItemType > const &aItem)
Definition i_layout.hpp:298
virtual layout_item_index index_of(const i_layout_item &aItem) const =0
virtual void set_always_use_spacing(bool aAlwaysUseSpacing)=0
virtual void remove_all()=0
virtual void invalidate(bool aDeferLayout=true)=0
virtual bool always_use_spacing() const =0
virtual bool invalidated() const =0
ItemType & add_at(layout_item_index aPosition, i_ref_ptr< ItemType > const &aItem)
Definition i_layout.hpp:303
virtual void set_autoscale(neogfx::autoscale aAutoscale, bool aUpdateLayout=true)=0
virtual const i_widget & get_widget_at(layout_item_index aIndex) const =0
bool is_descendent_of(const i_layout &aAncestor) const
Definition i_layout.hpp:358
virtual size spacing() const =0
ItemType & add()
Definition i_layout.hpp:292
ItemType & replace_item_at(layout_item_index aPosition, ItemType &&aItem)
Definition i_layout.hpp:335
virtual i_layout_item & add(i_layout_item &aItem)=0
virtual bool ignore_child_visibility() const =0
virtual i_layout_item & add_at(layout_item_index aPosition, i_layout_item &aItem)=0
virtual const i_layout_item & item_at(layout_item_index aIndex) const =0
const i_layout & non_client_layout() const
Definition i_layout.hpp:94
const i_layout & dock_layout(dock_area aDockArea=dock_area::Left) const
Definition i_layout.hpp:134
virtual const i_layout & layout(standard_layout aStandardLayout, layout_position aPosition=layout_position::None) const =0
virtual void set_status_bar(i_status_bar &aStatusBar)=0
virtual ~i_standard_layout_container()=default
const i_layout & status_bar_layout() const
Definition i_layout.hpp:158
const i_layout & title_bar_layout() const
Definition i_layout.hpp:102
i_layout & toolbar_layout(layout_position aPosition=layout_position::Top)
Definition i_layout.hpp:122
virtual void set_title_bar(i_title_bar &aTitleBar)=0
static layout_position to_position(dock_area aDockArea)
Definition i_layout.hpp:167
virtual const i_widget & client_widget() const =0
virtual bool is_widget() const =0
virtual i_layout & layout(standard_layout aStandardLayout, layout_position aPosition=layout_position::None)=0
virtual void set_client(i_ref_ptr< i_widget > const &aClient)=0
const i_layout & client_layout() const
Definition i_layout.hpp:142
virtual i_widget & client_widget()=0
i_layout & dock_layout(layout_position aPosition=layout_position::Left)
Definition i_layout.hpp:130
const i_layout & dock_layout(layout_position aPosition=layout_position::Left) const
Definition i_layout.hpp:126
virtual void set_title_bar(i_ref_ptr< i_title_bar > const &aTitleBar)=0
i_layout & dock_layout(dock_area aDockArea=dock_area::Left)
Definition i_layout.hpp:138
virtual i_title_bar & title_bar()=0
virtual i_widget & as_widget()=0
virtual void set_status_bar(i_ref_ptr< i_status_bar > const &aStatusBar)=0
virtual void set_client(i_widget &aClient)=0
virtual bool has_layout(standard_layout aStandardLayout) const =0
virtual i_status_bar & status_bar()=0
const i_layout & button_box_layout() const
Definition i_layout.hpp:150
virtual bool has_client_widget() const =0
virtual const i_status_bar & status_bar() const =0
const i_layout & menu_layout() const
Definition i_layout.hpp:110
virtual const i_widget & as_widget() const =0
const i_layout & toolbar_layout(layout_position aPosition=layout_position::Top) const
Definition i_layout.hpp:118
virtual const i_title_bar & title_bar() const =0
scoped_layout_items(bool aForceRefresh=false)
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:60
size total_child_weight(const i_layout &aLayout)
Definition i_layout.hpp:379
audio_channel operator~(audio_channel lhs)
dock_area
Definition i_dock.hpp:31
visibility_constraint
uint32_t layout_item_index
Definition i_layout.hpp:35
size calculate_relative_weight(const i_layout &aLayout, const i_layout_item &aItem)
Definition i_layout.hpp:392
standard_layout
Definition i_layout.hpp:49
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:55
std::optional< layout_item_index > optional_layout_item_index
Definition i_layout.hpp:36
layout_position
Definition i_layout.hpp:39
layout_direction
Definition i_layout.hpp:209
#define declare_event(declName,...)
Definition i_event.hpp:305