1#include "RootDisplay.hpp"
3#include "Constraint.hpp"
4#include "Animation.hpp"
27 if (event->
touchIn(0, 0, 400, 240))
return ret;
33 ret |= onTouchDown(event);
34 ret |= onTouchDrag(event);
35 ret |= onTouchUp(event);
39 for (
int x = 0; x < this->
elements.size(); x++)
40 if (this->
elements.size() > x && this->elements[x])
41 ret |= this->
elements[x]->process(event);
52 if (RootDisplay::idleCursorPulsing) {
66 this->recalcPosition(
parent);
69 if (this->hasBackground) {
71 this->renderBackground(
true);
73 else if (RootDisplay::isDebug) {
74 backgroundColor = randomColor();
75 this->renderBackground(
false);
81 subelement->render(
this);
84 CST_Renderer* renderer = getRenderer();
89 auto marginSpacing = cornerRadius > 0 ? 0 : 5;
90 CST_Rect d = { this->xAbs - marginSpacing, this->yAbs - marginSpacing, this->
width + marginSpacing*2, this->height + marginSpacing*2 };
91 if (cornerRadius > 0) {
93 CST_roundedBoxRGBA(renderer, d.x, d.y, d.x + d.w, d.y + d.h,
94 cornerRadius, 0x10, 0xD9, 0xD9, 0x40);
96 CST_SetDrawBlend(renderer,
true);
97 CST_SetDrawColorRGBA(renderer, 0x10, 0xD9, 0xD9, 0x40);
98 CST_FillRect(renderer, &d);
104 auto marginSpacing = cornerRadius > 0 ? 0 : 5;
105 CST_Rect d = { this->xAbs - marginSpacing, this->yAbs - marginSpacing, this->
width + marginSpacing*2, this->height + marginSpacing*2 };
108 int ticks = CST_GetTicks() / 100;
109 int pulseState = ticks % 20;
110 if (pulseState > 9) {
111 pulseState = 19 - pulseState;
114 if (!RootDisplay::idleCursorPulsing) {
120 auto decreaser = cornerRadius > 0 ? 0 : -2;
121 for (
int x = decreaser; x <= 3; x++)
125 int g = 0xD9 - 0x01 * pulseState;
126 int b = 0xD9 - 0x01 * pulseState;
127 int edgeMod = x==1 ? 0 : abs(x);
128 int a = fmax(0x0, 0xFF - 0x10 * pulseState * edgeMod);
129 CST_roundedRectangleRGBA(renderer, d.x + x, d.y + x, d.x + d.w - x, d.y + d.h - x, cornerRadius, r, g, b, a);
133 CST_roundedRectangleRGBA(renderer, d.x, d.y, d.x + d.w, d.y + d.h, cornerRadius, 0x10, 0xD9, 0xD9, 0xFF);
135 CST_roundedRectangleRGBA(renderer, d.x + 1, d.y + 1, d.x + d.w - 1, d.y + d.h - 1, cornerRadius, 0x10, 0xD9, 0xD9, 0xFF);
140void Element::recalcPosition(
Element* parent) {
142 if (
parent && !isAbsolute)
144 this->xAbs =
parent->xAbs + this->x;
145 this->yAbs =
parent->yAbs + this->y;
147 this->xAbs = this->x;
148 this->yAbs = this->y;
154 constraint->apply(
this);
159 if (animations.size() > 0) {
160 std::vector<Animation*> toRemove;
166 bool finished = animation->step();
168 toRemove.push_back(animation);
172 animations.erase(std::remove(animations.begin(), animations.end(), animation), animations.end());
178CST_Rect Element::getBounds()
188void Element::renderBackground(
bool fill) {
189 CST_Renderer* renderer = getRenderer();
190 CST_Rect bounds = getBounds();
191 auto r = backgroundColor.r * 0xFF;
192 auto g = backgroundColor.g * 0xFF;
193 auto b = backgroundColor.b * 0xFF;
195 if (cornerRadius > 0) {
196 const auto renderRect = fill ? CST_roundedBoxRGBA : CST_roundedRectangleRGBA;
197 renderRect(renderer, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h,
198 cornerRadius, backgroundColor.r * 0xFF, backgroundColor.g * 0xFF, backgroundColor.b * 0xFF, 0xFF);
200 CST_SetDrawColorRGBA(renderer, r, g, b, 0xFF);
201 const auto renderRect = fill ? CST_FillRect : CST_DrawRect;
202 renderRect(renderer, &bounds);
214 if (!event->isTouchDown())
217 if (!event->
touchIn(this->xAbs, this->yAbs, this->width, this->height))
223 this->lastMouseX =
event->xPos;
236 if (!event->isTouchDrag())
241 if (event->
touchIn(this->xAbs, this->yAbs, this->width, this->height)) {
248 CST_LowRumble(event, 200);
251 CST_SetCursor(CST_CURSOR_HAND);
258 if (initialElasticCounter != NO_HIGHLIGHT) {
260 CST_SetCursor(CST_CURSOR_ARROW);
268 int TRESHOLD = 40 / SCALER / SCALER;
272 if (this->
dragging && (abs(event->yPos - this->lastMouseY) >= TRESHOLD || abs(event->xPos - this->lastMouseX) >= TRESHOLD))
277 if (prevElasticCounter != NO_HIGHLIGHT) {
279 CST_SetCursor(CST_CURSOR_ARROW);
288 if (!event->isTouchUp())
299 if (event->
touchIn(this->xAbs, this->yAbs, this->width, this->height))
309 if (actionWithEvents != NULL) {
310 this->actionWithEvents(event);
328void Element::append(
Element *element)
336void Element::remove(
Element *element)
343void Element::wipeAll(
bool delSelf)
347 child->wipeAll(
true);
351 if (delSelf && !isProtected) {
356void Element::removeAll(
bool moveToTrash)
361 RootDisplay::mainDisplay->trash.push_back(e);
371 this->elements.push_back(child);
373 child->recalcPosition(
this);
377Element* Element::setPosition(
int x,
int y)
383Element* Element::setAction(std::function<
void()> func)
397 this->y =
parent->height / 2 - this->height / 2;
403 return centerHorizontallyIn(
parent)->centerVerticallyIn(
parent);
406Element* Element::setAbsolute(
bool isAbs)
412CST_Renderer* Element::getRenderer() {
413 return RootDisplay::renderer;
416Element* Element::constrain(
int flags,
int padding)
418 constraints.push_back(
new Constraint(flags, padding));
424 std::function<
void(
float)> onStep,
425 std::function<
void()> onFinish
428 CST_GetTicks(), duration, onStep, onFinish)
435Element* Element::moveToFront() {
443Element* Element::setTouchable(
bool touchable)
451 CST_Texture* target = SDL_CreateTexture(getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
width, height);
454 SDL_SetRenderTarget(getRenderer(), target);
457 SDL_SetRenderDrawColor(getRenderer(), 255, 255, 255, 255);
458 SDL_RenderClear(getRenderer());
464 SDL_SetRenderTarget(getRenderer(), NULL);
467 CST_SavePNG(target, path.c_str());
virtual bool process(InputEvents *event)
process any input that is received for this element
bool hidden
whether this element should skip rendering or not
bool dragging
whether or not this element is currently being dragged
bool touchable
whether or not this element can be touched (highlights bounds)
void screenshot(std::string path)
Take a screenshot of this element and its children, and save it to the given path.
std::function< void()> action
the action to call (from binded callback) on touch or button selection https://stackoverflow....
int futureRedrawCounter
whether this element needs a redraw for the next X redraws (decreases each time) (0 is no redraws)
int elasticCounter
how much time is left in an elastic-type flick/scroll set by the last distance traveled in a scroll,...
virtual void render(Element *parent)
display the current state of the display
int lastMouseY
the last Y, X coordinate of the mouse (from a drag probably)
void position(int x, int y)
position the element
bool needsRedraw
whether or not this element needs the screen redrawn next time it's processed
int width
width and height of this element (must be manually set, isn't usually calculated (but is in some case...
Element * parent
the parent element (can sometimes be null if it isn't set)
std::vector< Element * > elements
visible GUI child elements of this element