Chesto 0.9
A declarative and element-based library for creating GUIs on homebrew'd consoles
Constraint.cpp
1#include "Constraint.hpp"
2#include "RootDisplay.hpp"
3
4namespace Chesto {
5
17Constraint::Constraint(int flags, int padding, std::vector<Element*> targets) {
18 positioningFlags |= flags;
19 paddingOffset = padding;
20 this->targets = targets;
21}
22
23void Constraint::clearFlags() {
24 positioningFlags = 0;
25}
26
27void Constraint::addFlags(int flags) {
28 positioningFlags |= flags;
29}
30
31void Constraint::clearTargets() {
32 targets.clear();
33}
34
35void Constraint::addTarget(Element* target) {
36 targets.push_back(target);
37}
38
39void Constraint::apply(Element* element) {
40 // if the vector of targets is not empty, use the first target, otherwise use parent
41 auto target = targets.empty() ? element->parent : targets[0];
42 auto isSpecificTarget = !targets.empty();
43 int posX = 0, posY = 0;
44 int width = RootDisplay::screenWidth, height = RootDisplay::screenHeight; // default to screen size, TODO: is this good?
45
46 float effectiveScale = element->getEffectiveScale();
47
48 auto paddingOffset = this->paddingOffset; // copy so we don't flicker/modify it on the fly
49
50 if (target != NULL) {
51 // For centering constraints, we want to position relative to parent's content area (0,0)
52 // For edge alignment, we use parent's position as reference
53 posX = target->x;
54 posY = target->y;
55 width = target->width;
56 height = target->height;
57
58 if (isSpecificTarget) {
59 // with an element target, we have to inverse our padding offset
60 paddingOffset = -paddingOffset;
61
62 //also, if it's top or left, we need to account for our own height/width
63 if (positioningFlags & ALIGN_TOP) posY -= (int)(element->height * effectiveScale);
64 if (positioningFlags & ALIGN_LEFT) posX -= (int)(element->width * effectiveScale);
65 // if it's bottom or right, we need to account for the target's height/width
66 if (positioningFlags & ALIGN_BOTTOM) posY += (int)(target->height * effectiveScale);
67 if (positioningFlags & ALIGN_RIGHT) posX += (int)(target->width * effectiveScale);
68 }
69 }
70
71 // padding offset needs scale too
72 int scaledPadding = (int)(paddingOffset * effectiveScale);
73
74 // look at the flags and decide what to do
75 if (positioningFlags & ALIGN_LEFT) element->x = posX + scaledPadding;
76 if (positioningFlags & ALIGN_RIGHT) element->x = posX + width - (int)(element->width * effectiveScale) - scaledPadding;
77 if (positioningFlags & ALIGN_TOP) element->y = posY + scaledPadding;
78 if (positioningFlags & ALIGN_BOTTOM) element->y = posY + height - (int)(element->height * effectiveScale) - scaledPadding;
79
80 // For centering, position relative to parent's content area (like centerHorizontallyIn)
81 if (positioningFlags & ALIGN_CENTER_HORIZONTAL) element->x = width / 2 - (int)(element->width * effectiveScale) / 2;
82 if (positioningFlags & ALIGN_CENTER_VERTICAL) element->y = height / 2 - (int)(element->height * effectiveScale) / 2;
83
84 // some manual offset constraints, that just move the element
85 if (positioningFlags & OFFSET_LEFT) element->x += paddingOffset;
86 if (positioningFlags & OFFSET_RIGHT) element->x -= paddingOffset;
87 if (positioningFlags & OFFSET_TOP) element->y += paddingOffset;
88 if (positioningFlags & OFFSET_BOTTOM) element->y -= paddingOffset;
89
90}
91
92} // namespace Chesto
Constraint(int flags, int padding=0, std::vector< Element * > targets={})
Definition: Constraint.cpp:17