Loading...
Searching...
No Matches
AlignSVG.h
1/*
2
3MIT License
4
5Copyright (c) 2023 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31/*
32 * TreeSVG.h
33 *
34 * Created on: Nov, 2024
35 * Author: mpeura
36 */
37
38#ifndef DRAIN_ALIGN_SVG
39#define DRAIN_ALIGN_SVG
40
41#include <string>
42
43#include "drain/Enum.h"
44#include "Alignment.h"
45
46
47namespace drain {
48
49namespace image {
50
51
53
59struct AlignSVG { // : protected Align {
60
61
62 virtual
63 ~AlignSVG(){};
64
66
68 static
70
72 static
74
76 static
78
80 static
82
83 static
84 const HorzAlign UNDEFINED_HORZ;
85
86 // ----------------------
87
89
91 static
93
95 static
97
99 static
101
103 static
105
106 static
107 const VertAlign UNDEFINED_VERT;
108
109
110 enum Owner {
111 OBJECT = 0, // 0b00001111,
112 ANCHOR = 1, // 0b11110000,
113 };
114
115
118 COMPOUND, // Completed already. Internal elements are already aligned, bypass recursion.
119 FIXED, // Absolute position - do not change bbox, but traverse (align) children. (Do not adjust coordinates, but allow internal recursion.
120 INDEPENDENT, // No anchoring allowed – but inclusion by collective bounding box applies, unless NEUTRAL.
121 NEUTRAL, // Excluded from the collective bounding box – but anchoring supported, unless INDEPENDENT)
122 };
123
124
126 /*
127 * Notice that for an alignment to be complete, this function should be called twice:
128 * setting partial alignment for both owner=OBJECT and owner=ANCHOR .
129 *
130 * \tparam OBJ - enum type \c Owner or string
131 * \tparam A - enum type \c Axis or string
132 * \tparam V - enum type \c Alignment or string
133 * \param pos - enum value \c OBJ or \c REF
134 * \param axis - enum value \c HORZ or \c VERT
135 * \param value - enum value \c MAX , \c MID , or \c MIN (or string)
136 */
137 template <typename OBJ, typename A, typename V>
138 inline // in problems, rename this function, ie. remove polymorphism
139 void setAlign(const OBJ & owner, const A & axis, const V &value){
140 modifyAlign(owner, axis, value);
141 updateAlign();
142 }
143
145
154 inline
155 void setAlign(const AlignBase::Axis & axis, const AlignBase::Pos & pos, MutualAlign::Topol topol=MutualAlign::Topol::INSIDE){
156 if (pos != AlignBase::FILL){
157 modifyAlign(ANCHOR, axis, pos);
158 }
159 modifyAlign(OBJECT, axis, (topol==MutualAlign::INSIDE) ? pos : AlignBase::flip(pos));
160 updateAlign();
161 }
162
164 /*
165 * Template supports empty arg list.
166 *
167 * \tparam T - enum type \c Topol or string
168 * \tparam AX - axis enum type: Axis or const Axis
169 * \tparam A - axis enum value: HORZ, VERT or UNDEFINED_AXIS
170 * \param align - \c HorzAlign or \c VertAlign
171 */
172 template <typename ...T, typename AX, AlignBase::Axis A>
173 void setAlign(const Alignment<AX,A> & align, const T... args){
174 if (align.pos == AlignBase::FILL){
175 // Makes sense only for OBJECT, as it will be changed (and ANCHOR is never unchanged).
176 setAlign(AlignSVG::OBJECT, align.axis, align.pos);
177 }
178 else {
179 setAlign(align.axis, align.pos, args...);
180 }
181 }
182
183 // Convenience: set both horz and vert alignments (INSIDE)
184 /*
185 */
186 template <typename AX1, AlignBase::Axis A1, typename AX2, AlignBase::Axis A2>
187 void setAlign(const Alignment<AX1,A1> & align1, const Alignment<AX2,A2> & align2){
188 setAlign(align1.axis, align1.pos, MutualAlign::Topol::INSIDE);
189 setAlign(align2.axis, align2.pos, MutualAlign::Topol::INSIDE);
190 }
191
192 // Convenience: set both horz and vert alignments (INSIDE)
193 /*
194 */
195 template <typename AX1, AlignBase::Axis A1> // , typename AX2, AlignBase::Axis A2>
196 void setAlign(const CompleteAlignment<AX1,A1> & align1){
197 setAlign(align1.axis, align1.pos, align1.topol);
198 //setAlign(align2.axis, align2.pos, MutualAlign::Topol::INSIDE);
199 }
200
201
203 template <typename AX, AlignBase::Axis A>
204 void setAlign(const Alignment<AX,A> & align1, const Alignment<AX,A> & align2);
205
206
208 /*
209 * \tparam T - enum type \c Topol or string: \c INSIDE or \c OUTSIDE .
210 * \param align - Horizontal or vertical Alignment: \c LEFT|CENTER|RIGHT or \c TOP|MIDDLE|BOTTOM
211 * \param topol - \c INSIDE or \c OUTSIDE
212 */
213 template <typename T>
214 void setAlign(const std::string & align, const T & topol){
215 const Alignment<> & a = Enum<Alignment<> >::getValue(align, false);
216 const MutualAlign::Topol & t = Enum<MutualAlign::Topol>::getValue(topol, false);
217 //const Alignment<> & a = Enum<Alignment<> >::getValue(align, false);
218 setAlign(a.axis, a.pos, t);
219 }
220
221 /* "TODO"
222 void setAlign(const CompleteAlignment<> & align){
223 }
224 */
225
227
229 void setAlign(const std::string & align);
230 // Note: no mixed type, ANCHOR:LEFT
231
232 void setAlign(AlignClass cls){
233 setAlignClass(cls);
234 }
235
236protected:
237 virtual
238 void setAlignClass(AlignClass cls) = 0;
239
240public:
242 bool isAligned() const;
243
244 void resetAlign();
245
246 void swapAlign(AlignSVG & align);
247
249 /*
250 * \tparam P - enum type Owner \c REF or \c OBJ , or respective string.
251 * \tparam A - enum type axis_t \c HORZ or \c VERT , or respective string.
252 * \param pos - target object \c OBJ or referred anchor object \c REF
253 * \param axis - horizontal \c HORZ or vertical \c AXIS .
254 */
255 template <typename P, typename A>
256 AlignBase::Pos & getAlignPos(const P & pos, const A & axis);
257
258
260 /*
261 * \tparam P - enum type Owner \c REF or \c OBJ , or respective string.
262 * \tparam A - enum type axis_t \c HORZ or \c VERT , or respective string.
263 * \param pos - target object \c OBJ or referred anchor object \c REF
264 * \param axis - horizontal \c HORZ or vertical \c AXIS .
265 *
266 */
267 template <typename P, typename A>
268 const AlignBase::Pos & getAlignPos(const P & pos, const A & axis) const;
269
273 void confToStream(std::ostream & ostr) const;
274
275 inline
276 const std::string & getAlignStr() const {
277 return alignStr;
278 }
279
280 void swapAlign();
281 /*
283 template <typename ...TT>
284 bool isAlignSet(const TT... args) const {
285 bitvect_t v = combineAlign(args...);
286 return (alignment & v) == v;
287 }
288
289 */
290
291protected:
292
293 // Future extension
294 typedef int bitvect_t; // or int_t ?
295
296 // Future extension
297 mutable
298 bitvect_t alignment = 0;
299
300 std::string alignStr;
301
303 template <typename P, typename A, typename V>
304 void modifyAlign(const P & owner, const A & axis, const V &value){
305 getAlignPos(owner, axis) = Enum<AlignBase::Pos>::getValue(value, false);
306 }
307
308
309 void updateAlignStr();
310
311 virtual inline
312 void updateAlign(){
313 updateAlignStr();
314 };
315
316
317 typedef std::vector<AlignBase::Pos> align_vect_t;
318 typedef std::vector<align_vect_t > align_conf_t;
319
320 align_conf_t alignments = align_conf_t(2, align_vect_t(2, AlignBase::Pos::UNDEFINED_POS));
321
323
324
325};
326
327}
328
329// const drain::Enum<AlignSVG::Owner>::dict_t drain::Enum<AlignSVG::Owner>::dict;
330DRAIN_ENUM_DICT(image::AlignSVG::Owner);
331DRAIN_ENUM_DICT(image::AlignSVG::AlignClass);
332DRAIN_ENUM_DICT(image::Alignment<>);
333
334DRAIN_ENUM_DICT(image::AlignSVG::HorzAlign);
335DRAIN_ENUM_DICT(image::AlignSVG::VertAlign);
336
337// NEW
338
339}
340
341//DRAIN_ENUM_OSTREAM(drain::image::Alignment<>);
342
343// template <>
344
345// DRAIN_ENUM_OSTREAM(drain::image::Alignment<>);
346
347namespace drain {
348/*
349*/
350
351namespace image {
352
353DRAIN_ENUM_OSTREAM(AlignSVG::Owner)
354DRAIN_ENUM_OSTREAM(AlignSVG::AlignClass)
355
356DRAIN_ENUM_OSTREAM(drain::image::Alignment<>)
357DRAIN_ENUM_OSTREAM(drain::image::AlignSVG::HorzAlign)
358DRAIN_ENUM_OSTREAM(drain::image::AlignSVG::VertAlign)
359
360template <>
361inline
362void AlignSVG::HorzAlign::reset(){
363 // axis = AlignBase::Axis::UNDEFINED_AXIS;
364 pos = AlignBase::Pos::UNDEFINED_POS;
365}
366
367template <>
368inline
369void AlignSVG::VertAlign::reset(){
370 // axis = AlignBase::Axis::UNDEFINED_AXIS;
371 pos = AlignBase::Pos::UNDEFINED_POS;
372}
373
374
376/*
377template <>
378const drain::Enum<AlignSVG::HorzAlign>::dict_t drain::Enum<AlignSVG::HorzAlign>::dict;
379
381template <>
382const drain::Enum<AlignSVG::VertAlign>::dict_t drain::Enum<AlignSVG::VertAlign>::dict;
383
385template <>
386const drain::Enum<Alignment<> >::dict_t drain::Enum<Alignment<> >::dict;
387*/
388
389
390
391
392template <typename OBJ, typename A>
393AlignBase::Pos & AlignSVG::getAlignPos(const OBJ & owner, const A & axis){
394 const AlignSVG::Owner p = Enum<AlignSVG::Owner>::getValue(owner, false); // raise error
395 const AlignBase::Axis a = Enum<AlignBase::Axis>::getValue(axis, false); // raise error
396 return alignments[p][a];
397}
398
399template <typename OBJ, typename A>
400const AlignBase::Pos & AlignSVG::getAlignPos(const OBJ & owner, const A & axis) const {
401 const AlignSVG::Owner p = Enum<AlignSVG::Owner>::getValue(owner, false); // raise error
402 const AlignBase::Axis a = Enum<AlignBase::Axis>::getValue(axis, false); // raise error
403 return alignments[p][a];
404}
405
406
407} // image::
408
409
410DRAIN_TYPENAME(image::AlignSVG::HorzAlign);
411DRAIN_TYPENAME(image::AlignSVG::VertAlign);
412
413// NEW
414/*
415DRAIN_ENUM_DICT(image::AlignSVG::AlignClass);
416DRAIN_ENUM_DICT(image::Alignment<>);
417*/
418
419} // drain::
420
421// DRAIN_ENUM_OSTREAM(drain::image::Alignment<>);
422// DRAIN_ENUM_OSTREAM(drain::image::AlignSVG::Owner);
423
424
425inline
426std::ostream & operator<<(std::ostream &ostr, const drain::image::AlignSVG & align){
427 //return ostr << align.axis << '_' << align.pos; // enums resolved above
428 align.confToStream(ostr);
429 return ostr; // << "UNDER CONSTR..."; // RESOLVE!
430}
431
432
433
434#endif // DRAIN_ALIGN_SVG_H_
435
Definition Data.h:1473
std::ostream & operator<<(std::ostream &ostr, const PlainData< DT > &d)
Definition Data.h:631
A container for a static dictionary of enumeration values.
Definition Enum.h:51
static E getValue(const E &value, bool lenient=true)
Convenience for object.set(...) like commands.
Definition Enum.h:96
static Axis flip(Axis axis)
supporting simultaneous HORZ|VERT
Definition Alignment.h:83
Pos
Reference position at Axis (HORZ or VERT)
Definition Alignment.h:55
User-friendly programming interface for alignment considering two elements.
Definition AlignSVG.h:59
static const HorzAlign LEFT
Alias for {HORZ:MIN}.
Definition AlignSVG.h:69
const AlignBase::Pos & getAlignPos(const P &pos, const A &axis) const
Return alignment setting of an object along horizontal or vertical axis .
static const VertAlign MIDDLE
Alias for {VERT:MID}.
Definition AlignSVG.h:96
void setAlign(const std::string &align, const T &topol)
High-level, user friendlier interface for setting the alignments for both OBJECT itself and its ANCHO...
Definition AlignSVG.h:214
void setAlign(const OBJ &owner, const A &axis, const V &value)
Low-level, "atomic" setter of alignment for OBJECT itself or its ANCHOR object.
Definition AlignSVG.h:139
AlignClass
Moved from Layput.
Definition AlignSVG.h:117
void setAlign(const AlignBase::Axis &axis, const AlignBase::Pos &pos, MutualAlign::Topol topol=MutualAlign::Topol::INSIDE)
Set a single alignment setting. "Intermediate-level": axis and pos are given separately.
Definition AlignSVG.h:155
void confToStream(std::ostream &ostr) const
Definition AlignSVG.cpp:163
bool isAligned() const
Returns true, if any setting is set...
Definition AlignSVG.cpp:235
static const HorzAlign RIGHT
Alias for {HORZ:MAX}.
Definition AlignSVG.h:77
static const HorzAlign HORZ_FILL
Alias for {HORZ:FILL}.
Definition AlignSVG.h:81
void setAlign(const Alignment< AX, A > &align1, const Alignment< AX, A > &align2)
Compiler trap: unimplemented for two of same kind: either HorzAlign or VertAlign twice.
void modifyAlign(const P &owner, const A &axis, const V &value)
Change alignment configuration without updating the alignStr.
Definition AlignSVG.h:304
static const VertAlign VERT_FILL
Alias for {VERT:FILL}.
Definition AlignSVG.h:104
static const VertAlign BOTTOM
Alias for {VERT:MAX}.
Definition AlignSVG.h:100
void setAlign(const Alignment< AX, A > &align, const T... args)
NEW High-level, user friendlier interface for setting INSIDE the alignments for both OBJECT itself an...
Definition AlignSVG.h:173
static const HorzAlign CENTER
Alias for {HORZ:MID}.
Definition AlignSVG.h:73
AlignBase::Pos & getAlignPos(const P &pos, const A &axis)
Return alignment setting of an object along horizontal or vertical axis .
static const VertAlign TOP
Alias for {VERT:MIN}.
Definition AlignSVG.h:92
Container for Axis and Pos.
Definition Alignment.h:126
"Alternative" partial alignment configuration for single object. Partial means that either OBJECT its...
Definition Alignment.h:245