-
Notifications
You must be signed in to change notification settings - Fork 0
/
widget.cpp
103 lines (88 loc) · 2.63 KB
/
widget.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "widget.h"
using namespace byteimage;
bool WidgetLayout::Attach::overlaps(int x, int y) const {
return (x >= this->x && x < this->x + this->w
&& y >= this->y && y < this->y + this->h);
}
WidgetLayout::~WidgetLayout() {
clear();
}
void WidgetLayout::attach(Widget* widget, int x, int y, int w, int h, bool autorelease) {
Attach attach(widget, x, y, w, h, autorelease);
widget->setDisplay(display);
widget->updateSize(w, h);
widgets.push_back(attach);
}
void WidgetLayout::remove(Widget* widget) {
bool releaseflag = false;
for (int i = 0; i < widgets.size(); i++)
if (widgets[i].widget == widget) {
if (widgets[i].autorelease) releaseflag = true;
widgets.erase(widgets.begin() + i--);
}
if (releaseflag) delete widget;
}
void WidgetLayout::clear() {
for (auto& attach : widgets)
if (attach.autorelease)
delete attach.widget;
widgets.clear();
focus = -1;
}
void WidgetLayout::setDisplay(WidgetDisplay* display) {
Widget::setDisplay(display);
for (auto& attach : widgets)
attach.widget->setDisplay(display);
}
void WidgetLayout::handleEvent(SDL_Event event) {
SDL_Event transformed;
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
for (int i = widgets.size() - 1; i >= 0; i--)
if (widgets[i].overlaps(event.button.x, event.button.y)) {
focus = i;
transformed = event;
transformed.button.x -= widgets[i].x;
transformed.button.y -= widgets[i].y;
widgets[i].widget->handleEvent(transformed);
return;
}
focus = -1;
}
else if (event.type == SDL_MOUSEMOTION && focus >= 0) {
if (widgets[focus].overlaps(event.motion.x, event.motion.y)) {
transformed = event;
transformed.motion.x -= widgets[focus].x;
transformed.motion.y -= widgets[focus].y;
widgets[focus].widget->handleEvent(transformed);
}
}
}
void WidgetLayout::render(ByteImage& canvas, int x, int y) {
for (auto& attach : widgets)
attach.widget->render(canvas, x + attach.x, y + attach.y);
}
void WidgetDisplay::handleEvent(SDL_Event event) {
if (event.type == SDL_MOUSEBUTTONDOWN
|| event.type == SDL_MOUSEBUTTONUP
|| event.type == SDL_MOUSEMOTION)
layout.handleEvent(event);
Display::handleEvent(event);
}
void WidgetDisplay::render() {
canvas.fill(0);
layout.render(canvas, 0, 0);
}
void WidgetDisplay::update() {
if (renderflag) {
render();
updateImage(canvas);
renderflag = false;
}
Display::update();
}
WidgetDisplay::WidgetDisplay(int nr, int nc, const char* title) : Display(nr, nc, title) {
canvas = ByteImage(nr, nc, 3);
layout.setDisplay(this);
layout.updateSize(nc, nr);
renderflag = 1;
}