neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_anchor.hpp
Go to the documentation of this file.
1// i_anchor.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2018, 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 <functional>
27
28namespace neogfx
29{
30 enum class anchor_constraint_function : uint32_t
31 {
32 Invalid = 0x00000000,
33
34 Identity = 0x00000001,
35 Equal = 0x00000002,
36 Min = 0x00000003,
37 Max = 0x00000004,
38 Custom = 0x00001000, // todo
39
40 X = 0x00010000,
41 Y = 0x00020000,
42 Z = 0x00040000,
43 W = 0x00080000,
44
45 CX = X,
46 CY = Y,
47
52 EqualX = Equal | X,
53 EqualY = Equal | Y,
54 EqualZ = Equal | Z,
55 EqualW = Equal | W,
56 MinX = Min | X,
57 MinY = Min | Y,
58 MinZ = Min | Z,
59 MinW = Min | W,
60 MaxX = Max | X,
61 MaxY = Max | Y,
62 MaxZ = Max | Z,
63 MaxW = Max | W,
64
67 EqualCX = Equal | CX,
68 EqualCY = Equal | CY,
69 MinCX = Min | CX,
70 MinCY = Min | CY,
71 MaxCX = Max | CX,
72 MaxCY = Max | CY,
73
74 FUNCTION_MASK = 0x0000FFFF,
75 ARGUMENT_MASK = 0x00FF0000
76 };
77
79 {
80 return static_cast<anchor_constraint_function>(~static_cast<uint32_t>(lhs));
81 }
82
84 {
85 return static_cast<anchor_constraint_function>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs));
86 }
87
89 {
90 return static_cast<anchor_constraint_function>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
91 }
92}
93
101
102namespace neogfx
103{
104 template <typename T>
105 class anchor_constraint : public std::function<T(const T&, const T&)>
106 {
107 typedef std::function<T(const T&, const T&)> base_type;
108 public:
109 typedef T value_type;
110 public:
111 using base_type::base_type;
112 public:
113 static anchor_constraint<T> identity;
114 static anchor_constraint<T> identity_x;
115 static anchor_constraint<T> identity_y;
116 static anchor_constraint<T> equal;
117 static anchor_constraint<T> equal_x;
118 static anchor_constraint<T> equal_y;
119 static anchor_constraint<T> min;
120 static anchor_constraint<T> min_x;
121 static anchor_constraint<T> min_y;
122 static anchor_constraint<T> max;
123 static anchor_constraint<T> max_x;
124 static anchor_constraint<T> max_y;
125 };
126
127 template <typename T>
128 inline T constraint_x(const T& value)
129 {
130 return value;
131 }
132
133 template <typename T>
134 inline T constraint_y(const T& value)
135 {
136 return value;
137 }
138
139 template <typename T>
140 inline T constraint_x(const basic_point<T>& value)
141 {
142 return value.x;
143 }
144
145 template <typename T>
146 inline T constraint_y(const basic_point<T>& value)
147 {
148 return value.y;
149 }
150
151 template <typename T>
152 inline T constraint_x(const basic_size<T>& value)
153 {
154 return value.cx;
155 }
156
157 template <typename T>
158 inline T constraint_y(const basic_size<T>& value)
159 {
160 return value.cy;
161 }
162
163 template <typename T>
164 inline T constraint_x(const basic_box_areas<T>& value)
165 {
166 return value.size().cx;
167 }
168
169 template <typename T>
170 inline T constraint_y(const basic_box_areas<T>& value)
171 {
172 return value.size().cy;
173 }
174
175 template <typename T>
176 anchor_constraint<T> anchor_constraint<T>::identity = [](const T& lhs, const T&) -> T
177 {
178 return lhs;
179 };
180 template <typename T>
181 anchor_constraint<T> anchor_constraint<T>::identity_x = [](const T& lhs, const T& rhs) -> T
182 {
183 return T{ constraint_x(lhs), constraint_y(rhs) };
184 };
185 template <typename T>
186 anchor_constraint<T> anchor_constraint<T>::identity_y = [](const T& lhs, const T& rhs) -> T
187 {
188 return T{ constraint_x(rhs), constraint_y(lhs) };
189 };
190
191 template <typename T>
192 anchor_constraint<T> anchor_constraint<T>::equal = [](const T&, const T& rhs) -> T
193 {
194 return rhs;
195 };
196 template <typename T>
197 anchor_constraint<T> anchor_constraint<T>::equal_x = [](const T& lhs, const T& rhs) -> T
198 {
199 return T{ constraint_x(rhs), constraint_y(lhs) };
200 };
201 template <typename T>
202 anchor_constraint<T> anchor_constraint<T>::equal_y = [](const T& lhs, const T& rhs) -> T
203 {
204 return T{ constraint_x(lhs), constraint_y(rhs) };
205 };
206
207 template <typename T>
208 anchor_constraint<T> anchor_constraint<T>::min = [](const T& lhs, const T& rhs) -> T
209 {
210 return std::min(lhs, rhs);
211 };
212 template <typename T>
213 anchor_constraint<T> anchor_constraint<T>::min_x = [](const T& lhs, const T& rhs) -> T
214 {
215 return T{ std::min(constraint_x(lhs), constraint_x(rhs)), constraint_y(lhs) };
216 };
217 template <typename T>
218 anchor_constraint<T> anchor_constraint<T>::min_y = [](const T& lhs, const T& rhs) -> T
219 {
220 return T{ constraint_x(lhs), std::min(constraint_y(lhs), constraint_y(rhs)) };
221 };
222
223 template <typename T>
224 anchor_constraint<T> anchor_constraint<T>::max = [](const T& lhs, const T& rhs) -> T
225 {
226 return std::max(lhs, rhs);
227 };
228 template <typename T>
229 anchor_constraint<T> anchor_constraint<T>::max_x = [](const T& lhs, const T& rhs) -> T
230 {
231 return T{ std::max(constraint_x(lhs), constraint_x(rhs)), constraint_y(lhs) };
232 };
233 template <typename T>
234 anchor_constraint<T> anchor_constraint<T>::max_y = [](const T& lhs, const T& rhs) -> T
235 {
236 return T{ constraint_x(lhs), std::max(constraint_y(lhs), constraint_y(rhs)) };
237 };
238
239 struct anchor_property_has_no_value : std::logic_error { anchor_property_has_no_value() : std::logic_error{ "neogfx::anchor_property_has_no_value" } {} };
240
241 class i_anchorable;
242
243 class i_anchor
244 {
245 // construction
246 public:
247 virtual ~i_anchor() = default;
248 // meta
249 public:
250 virtual i_anchorable& owner() const = 0;
251 virtual const i_string& name() const = 0;
252 virtual const i_property& property() const = 0;
253 virtual i_property& property() = 0;
254 virtual bool active() const noexcept = 0;
255 virtual bool calculator_overriden() const noexcept = 0;
256 virtual bool calculating() const noexcept = 0;
257 // operations
258 public:
259 virtual void constrain(i_anchor& aRhs, anchor_constraint_function aLhsFunction, anchor_constraint_function aRhsFunction) = 0;
260 virtual void constrain(i_anchor& aOther, anchor_constraint_function aOtherFunction) = 0;
261 };
262
263 template <typename T, typename PVT, typename... CalculatorArgs>
264 class i_calculating_anchor : public i_anchor
265 {
266 typedef i_calculating_anchor<T, PVT, CalculatorArgs...> self_type;
267 public:
268 typedef self_type abstract_type;
269 typedef T value_type;
270 typedef PVT property_value_type;
271 typedef anchor_constraint<value_type> constraint;
272 public:
273 virtual bool property_set() const = 0;
274 virtual value_type const& property_value() const = 0;
275 virtual value_type& property_value() = 0;
276 virtual void add_constraint(const constraint& aConstraint, abstract_type& aOtherAnchor) = 0;
277 virtual void add_constraint(const constraint& aConstraint, std::shared_ptr<abstract_type> aOtherAnchor) = 0;
278 public:
279 virtual value_type evaluate_constraints(const CalculatorArgs&... aArgs) const = 0;
280 virtual value_type calculate(const CalculatorArgs&... aArgs) const = 0;
281 };
282
283 namespace detail
284 {
285 template <template<typename, typename, typename...> class Anchor, typename PVT, typename Callable>
286 struct abstract_anchor_callable_function_cracker;
287 template <template<typename, typename, typename...> class Anchor, typename PVT, typename R, typename C, typename... Args>
288 struct abstract_anchor_callable_function_cracker<Anchor, PVT, R(C::*)(Args...) const>
289 {
290 typedef Anchor<R, PVT, Args...> type;
291 typedef R(C::* callable_type)(Args...) const;
292 typedef PVT property_value_type;
293 typedef R value_type;
294 typedef C class_type;
295 };
296 template <template<typename, typename, typename...> class Anchor, typename PVT, typename R, typename C, typename... Args>
297 struct abstract_anchor_callable_function_cracker<Anchor, PVT, R(C::*)(Args...)>
298 {
299 typedef Anchor<R, PVT, Args...> type;
300 typedef R(C::* callable_type)(Args...);
301 typedef PVT property_value_type;
302 typedef R value_type;
303 typedef C class_type;
304 };
305 }
306
307 template <typename Property>
308 using i_anchor_t = typename detail::abstract_anchor_callable_function_cracker<i_calculating_anchor, typename Property::value_type, typename Property::calculator_function_type>::type;
309}
#define end_declare_enum(enumName)
Definition i_enum.hpp:62
#define declare_enum_string(enumName, enumEnumerator)
Definition i_enum.hpp:59
#define begin_declare_enum(enumName)
Definition i_enum.hpp:52
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:60
anchor_constraint_function
Definition i_anchor.hpp:31
audio_channel operator~(audio_channel lhs)
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:55
Definition plf_hive.h:79