bWidgets
Core widget toolkit designed for Blender
Builder.h
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4
5#include "Node.h"
6#include "ScreenGraph.h"
7#include "bwWidget.h"
8
9namespace bWidgets {
10namespace bwScreenGraph {
11
23class Builder {
24 public:
31 template<typename _BuilderType = Builder> using BuildFunc = std::function<void(_BuilderType&)>;
32
33 Builder(LayoutNode& active_layout_node);
34 Builder(ScreenGraph& screen_graph);
35 virtual ~Builder() = default;
36
37 static void setLayout(LayoutNode& node, std::unique_ptr<bwLayoutInterface> layout);
38 static void setWidget(WidgetNode& node, std::unique_ptr<bwWidget> widget);
39 static auto addWidget(LayoutNode& node, std::unique_ptr<bwWidget> widget) -> bwWidget&;
40
42
46 template<typename _LayoutType, typename... _Args>
47 auto addLayout(_Args&&... __args) -> LayoutNode&
48 {
49 static_assert(std::is_base_of<bwLayoutInterface, _LayoutType>::value,
50 "Should implement bwLayoutInterface");
51
52 LayoutNode& new_node = addChildNode<LayoutNode>(_active_layout_node);
53 new_node.layout = std::make_unique<_LayoutType>(std::forward<_Args>(__args)...);
54 setActiveLayout(new_node);
55 return new_node;
56 }
57
64 template<typename _LayoutType, typename... _Args>
65 auto buildLayout(BuildFunc<> build_func, _Args&&... __args) -> LayoutNode&
66 {
67 return buildLayout<_LayoutType, Builder>(build_func, std::forward<_Args>(__args)...);
68 }
69
76 template<typename _LayoutType, typename _BuilderType, typename... _Args>
77 auto buildLayout(BuildFunc<_BuilderType> build_func, _Args&&... __args) -> LayoutNode&
78 {
79 static_assert(std::is_base_of_v<bwLayoutInterface, _LayoutType>,
80 "Should implement bwLayoutInterface");
81 static_assert(std::is_base_of_v<Builder, _BuilderType>, "Should inherit from Builder");
82
83 LayoutNode& new_node = addChildNode<LayoutNode>(_active_layout_node);
84 new_node.layout = std::make_unique<_LayoutType>(std::forward<_Args>(__args)...);
85 buildChildren(build_func, new_node);
86
87 return new_node;
88 }
89
90 template<typename _WidgetType, typename... _Args>
91 auto addWidget(_Args&&... __args) -> _WidgetType&
92 {
93 static_assert(std::is_base_of<bwWidget, _WidgetType>::value, "Should derrive from bwWidget");
94
95 WidgetNode& new_node = addChildNode<WidgetNode>(_active_layout_node);
96 new_node.widget = std::make_unique<_WidgetType>(std::forward<_Args>(__args)...);
97 new_node.handler = new_node.widget->createHandler();
98 return static_cast<_WidgetType&>(*new_node.widget);
99 }
100
101 template<typename _WidgetType, typename... _Args>
102 auto addContainer(std::unique_ptr<bwLayoutInterface> layout, _Args&&... __args) -> ContainerNode&
103 {
104 static_assert(std::is_base_of<bwWidget, _WidgetType>::value, "Should derrive from bwWidget");
105 static_assert(std::is_base_of<bwContainerWidget, _WidgetType>::value,
106 "Should derrive from bwContainerWidget");
107
108 ContainerNode& new_node = addChildNode<ContainerNode>(_active_layout_node);
109
110 setLayout(new_node, std::move(layout));
111
112 new_node.widget = std::make_unique<_WidgetType>(new_node, std::forward<_Args>(__args)...);
113 new_node.handler = new_node.widget->createHandler();
114
115 setActiveLayout(new_node);
116 return new_node;
117 }
118
124 template<typename _WidgetType, typename... _Args>
126 std::unique_ptr<bwLayoutInterface> layout,
127 _Args&&... __args) -> ContainerNode&
128 {
129 return buildContainer<_WidgetType, Builder>(
130 build_func, std::move(layout), std::forward<_Args>(__args)...);
131 }
132
148 template<typename _WidgetType, typename _BuilderType, typename... _Args>
150 std::unique_ptr<bwLayoutInterface> layout,
151 _Args&&... __args) -> ContainerNode&
152 {
153 static_assert(std::is_base_of<bwWidget, _WidgetType>::value, "Should derrive from bwWidget");
154 static_assert(std::is_base_of<bwContainerWidget, _WidgetType>::value,
155 "Should derrive from bwContainerWidget");
156 static_assert(std::is_base_of_v<Builder, _BuilderType>, "Should inherit from Builder");
157
158 ContainerNode& new_node = addChildNode<ContainerNode>(_active_layout_node);
159 setLayout(new_node, std::move(layout));
160 new_node.widget = std::make_unique<_WidgetType>(new_node, std::forward<_Args>(__args)...);
161 new_node.handler = new_node.widget->createHandler();
162 buildChildren(build_func, new_node);
163
164 return new_node;
165 }
166
193 template<typename _WidgetType, typename... _Args>
194 static auto emplaceWidget(LayoutNode& node, _Args&&... __args) -> _WidgetType&
195 {
196 static_assert(std::is_base_of<bwWidget, _WidgetType>::value, "Should derrive from bwWidget");
197
198 WidgetNode& new_node = addChildNode<WidgetNode>(node);
199 new_node.widget = std::make_unique<_WidgetType>(std::forward<_Args>(__args)...);
200 new_node.handler = new_node.widget->createHandler();
201 return static_cast<_WidgetType&>(*new_node.widget);
202 }
203
204 private:
205 template<typename _NodeType> static auto addChildNode(LayoutNode& parent_node) -> _NodeType&
206 {
207 static_assert(std::is_base_of<Node, _NodeType>::value,
208 "Should derrive from bwScreenGraph::Node");
209
210 parent_node.children.push_back(std::make_unique<_NodeType>());
211 Node& ref = *parent_node.children.back();
212 ref.parent = &parent_node;
213
214 return dynamic_cast<_NodeType&>(ref);
215 }
216
217 template<typename _BuilderType = Builder>
218 void buildChildren(BuildFunc<_BuilderType> build_func, LayoutNode& new_node)
219 {
220 LayoutNode& old_active_layout = _active_layout_node;
221 setActiveLayout(new_node);
222 build_func(static_cast<_BuilderType&>(*this));
223 setActiveLayout(old_active_layout);
224 }
225
226 /* Never null, so use a assignable reference. */
227 std::reference_wrapper<bwScreenGraph::LayoutNode> _active_layout_node;
228};
229
230} // namespace bwScreenGraph
231} // namespace bWidgets
Helper class to construct screen-graphs.
Definition: Builder.h:23
std::function< void(_BuilderType &)> BuildFunc
A callable type to build a layout.
Definition: Builder.h:31
static void setLayout(LayoutNode &node, std::unique_ptr< bwLayoutInterface > layout)
Definition: Builder.cc:16
static auto addWidget(LayoutNode &node, std::unique_ptr< bwWidget > widget) -> bwWidget &
Definition: Builder.cc:27
void setActiveLayout(bwScreenGraph::LayoutNode &)
Activate a layout node.
Definition: Builder.cc:40
static auto emplaceWidget(LayoutNode &node, _Args &&... __args) -> _WidgetType &
Add child node for a widget created in-place.
Definition: Builder.h:194
auto buildContainer(BuildFunc< _BuilderType > build_func, std::unique_ptr< bwLayoutInterface > layout, _Args &&... __args) -> ContainerNode &
Build a container node in-place using build_func.
Definition: Builder.h:149
auto addWidget(_Args &&... __args) -> _WidgetType &
Definition: Builder.h:91
auto addLayout(_Args &&... __args) -> LayoutNode &
Add and activate a child node for a layout created in-place.
Definition: Builder.h:47
auto buildContainer(BuildFunc<> build_func, std::unique_ptr< bwLayoutInterface > layout, _Args &&... __args) -> ContainerNode &
Build a container node in-place using build_func.
Definition: Builder.h:125
static void setWidget(WidgetNode &node, std::unique_ptr< bwWidget > widget)
Definition: Builder.cc:21
auto buildLayout(BuildFunc<> build_func, _Args &&... __args) -> LayoutNode &
Build a sub-layout node in-place using build_func.
Definition: Builder.h:65
Builder(LayoutNode &active_layout_node)
Definition: Builder.cc:8
auto addContainer(std::unique_ptr< bwLayoutInterface > layout, _Args &&... __args) -> ContainerNode &
Definition: Builder.h:102
auto buildLayout(BuildFunc< _BuilderType > build_func, _Args &&... __args) -> LayoutNode &
Build a sub-layout node in-place using build_func.
Definition: Builder.h:77
Node representing a widget with children.
Definition: Node.h:167
Node for aligning children to a specific layout.
Definition: Node.h:92
The base data-structure for a screen-graph node.
Definition: Node.h:36
Definition: ScreenGraph.h:12
Node representing a single widget with no children.
Definition: Node.h:133
Abstract base class that all widgets derive from.
Definition: bwWidget.h:22
Definition: bwContext.h:3