Added my 2 widget classes, with some notes. They are not in the build yet either.

This commit is contained in:
Relintai 2021-11-13 12:26:47 +01:00
parent a02c8c63fd
commit 393650ad6d
4 changed files with 207 additions and 0 deletions

89
core/widgets/button.cpp Normal file
View File

@ -0,0 +1,89 @@
#include "button.h"
#include "math.h"
void Button::_event(const SDL_Event &ev) {
if (state == BUTTON_STATE_OFF) {
return;
}
switch (ev.type) {
case SDL_MOUSEMOTION: {
int x = ev.motion.x;
int y = ev.motion.y;
if (rect.x < x && rect.x + rect.w > x && rect.y < y && rect.y + rect.w > y) {
state = BUTTON_STATE_HOVER;
} else {
state = BUTTON_STATE_UP;
}
break;
}
case SDL_MOUSEBUTTONDOWN: {
int x = ev.motion.x;
int y = ev.motion.y;
if (rect.x < x && rect.x + rect.w > x && rect.y < y && rect.y + rect.w > y) {
state = BUTTON_STATE_DOWN;
}
break;
}
case SDL_MOUSEBUTTONUP: {
int x = ev.motion.x;
int y = ev.motion.y;
if (rect.x < x && rect.x + rect.w > x && rect.y < y && rect.y + rect.w > y) {
state = BUTTON_STATE_HOVER;
if (on_click) {
on_click();
}
} else {
state = BUTTON_STATE_UP;
}
break;
}
}
}
void Button::_update(float delta) {
}
void Button::_render() {
if (state == BUTTON_STATE_UP) {
if (up) {
up->set_transform(rect);
up->draw();
}
} else if (state == BUTTON_STATE_HOVER) {
if (hover) {
hover->set_transform(rect);
hover->draw();
}
} else if (state == BUTTON_STATE_DOWN) {
if (down) {
down->set_transform(rect);
down->draw();
}
} else if (state == BUTTON_STATE_OFF) {
if (off) {
off->set_transform(rect);
off->draw();
}
}
}
Button::Button() : Widget() {
state = BUTTON_STATE_UP;
up = nullptr;
down = nullptr;
hover = nullptr;
off = nullptr;
}
Button::~Button() {
}

40
core/widgets/button.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef BUTTON_H
#define BUTTON_H
#include "widget.h"
#include <SDL.h>
#include "core/rect2.h"
#include "renderer/sprite.h"
#include <functional>
class Button : public Widget {
public:
enum ButtonState {
BUTTON_STATE_UP,
BUTTON_STATE_HOVER,
BUTTON_STATE_DOWN,
BUTTON_STATE_OFF,
};
void _event(const SDL_Event &ev);
void _update(float delta);
void _render();
std::function<void(void)> on_click;
Button();
virtual ~Button();
ButtonState state;
Sprite *up;
Sprite *down;
Sprite *hover;
Sprite *off;
};
#endif

26
core/widgets/widget.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "widget.h"
void Widget::event(const SDL_Event &ev) {
_event(ev);
}
void Widget::update(float delta) {
_update(delta);
}
void Widget::render() {
_render();
}
void Widget::_event(const SDL_Event &ev) {
}
void Widget::_update(float delta) {
}
void Widget::_render() {
}
Widget::Widget() {
min_size = 0;
stretch_flags = STRETCH_OFF;
stretch_ratio = 1;
}
Widget::~Widget() {
}

52
core/widgets/widget.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <SDL.h>
#include "core/rect2.h"
#include "core/vector.h"
//remove sdl dependency
//should use my own events
//render should have a parameter for the current renderer
//it couls store state in a different class -> it could be a mix between an immediate mode gui and normal oop gui
//Or maybe the state could be stored separately? Or have support for storing the state in widgets, and also in a separate data object. Also needs to be fast.
//Or just support using state from (also adding a deafult state to) an HTTPRequest
//it sould do it's layout in a normalized coordinate system
//the renderer can turn it to what it needs
//Shold probably have a widget renderer that encapsulates a normal renderer
//could have 2 type of renderers -> one for httprequests and a normal one
class Widget {
public:
enum StretchFlags {
STRETCH_HORIZONTAL = 1 << 0,
STRETCH_VERTICAL = 1 << 1,
STRETCH_OFF = 0,
STRETCH_BOTH = STRETCH_HORIZONTAL | STRETCH_VERTICAL,
};
void event(const SDL_Event &ev);
void update(float delta);
void render();
virtual void _event(const SDL_Event &ev);
virtual void _update(float delta);
virtual void _render();
Widget();
virtual ~Widget();
float min_size;
int stretch_flags;
float stretch_ratio;
Rect2 rect;
private:
Vector<Widget *> _children;
};
#endif