summaryrefslogtreecommitdiff
path: root/ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui.cpp')
-rw-r--r--ui.cpp97
1 files changed, 69 insertions, 28 deletions
diff --git a/ui.cpp b/ui.cpp
index 2ed1c7b..8a292c7 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -644,7 +644,7 @@ UI::Element* UI::alloc_element(size_t size) {
UI::Element::Element(UI* ui, Element* parent):
ui(ui),
- parent(parent),
+ parent(0),
children(0),
next(0),
handler(0),
@@ -723,6 +723,8 @@ void UI::Element::enable() {
}
void UI::Element::add_child(Element* ch) {
+ assert(ch->parent == 0);
+ assert(ch->next == 0);
if (!children)
children = ch;
else {
@@ -730,6 +732,7 @@ void UI::Element::add_child(Element* ch) {
for (; child && child->next; child = child->next);
child->next = ch;
}
+ ch->parent = this;
ui->layout_dirty = true;
}
@@ -743,6 +746,8 @@ void UI::Element::remove_child(Element* ch) {
prev->next = ch->next;
else
children = ch->next;
+ ch->next = 0;
+ ch->parent = 0;
}
void UI::Element::message(const Message& msg) {
@@ -760,8 +765,6 @@ UI::Rect UI::Container::layout(const Rect& avail) {
Rect used = avail;
used.w = used.h = 0;
bound = avail;
- clip = avail;
- clip.clip(ui->area);
for (child = children; child; child = child->next) {
int h;
Rect r = child->layout(area);
@@ -772,7 +775,17 @@ UI::Rect UI::Container::layout(const Rect& avail) {
used.h += h;
}
bound = used;
- return used;
+ bound.clip(avail);
+ clip = bound;
+ clip.clip(ui->area);
+ if (clip.x == 0 && clip.y == 0 && clip.w == 300 && clip.h == 80) {
+ return bound;
+ }
+ return bound;
+}
+
+void UI::Container::on_render() {
+ ui->mesh.set_clip(clip);
}
UI::Toolbar::Toolbar(UI* ui, Element* parent):
@@ -801,12 +814,8 @@ UI::Rect UI::Toolbar::layout(const Rect& avail) {
void UI::Toolbar::on_render() {
ui->mesh.set_clip(clip);
- ui->mesh.add_rect(
- ui,
- bound.x,
- bound.y,
- bound.w,
- bound.h,
+ ui->draw_container(
+ bound,
0xa7a7a7
);
}
@@ -837,19 +846,20 @@ UI::Rect UI::Button::layout(const Rect& avail) {
void UI::Button::on_render() {
Colour tc = 0x000000;
+ int toff[] = { 0, 0 };
if (flags & Flags::disabled)
tc = 0x4f4f4f;
- if (this == ui->hovered)
- ui->draw_container(bound, 0xf0f8ff);
- else if (this == ui->hot)
+ if (this == ui->hot) {
+ toff[0] = 1;
+ toff[1] = 1;
ui->draw_containeri(bound, 0xffffff);
- else
+ } else
ui->draw_container(bound, 0xffffff);
ui->mesh.set_clip(clip);
ui->mesh.add_text(
ui,
- bound.x + ui_padding,
- bound.y + ui_padding,
+ bound.x + ui_padding + toff[0],
+ bound.y + ui_padding + toff[1],
text,
tc
);
@@ -890,30 +900,43 @@ void UI::Label::on_render() {
);
}
-static int drag_handler(UI::Modal* modal, const UI::Message& msg) {
- if (msg.type == UI::Message::Type::activate) {
- const App& app = *modal->ui->app;
- const UI::Rect& tb = modal->title_bar->bound;
- modal->dragging = true;
- modal->drag_offset[0] = app.mx - tb.x;
- modal->drag_offset[1] = app.my - tb.y;
+void UI::Label::set_text(const char* s) {
+ heap_free(ui->heap, text);
+ text = dup_stringh(ui->heap, s);
+ ui->layout_dirty = 1;
+}
+
+static int title_handler(UI::Modal* modal, const UI::Message& msg) {
+ switch (msg.type) {
+ case UI::Message::Type::activate: {
+ const App& app = *modal->ui->app;
+ const UI::Rect& tb = modal->title_bar->bound;
+ modal->dragging = true;
+ modal->drag_offset[0] = app.mx - tb.x;
+ modal->drag_offset[1] = app.my - tb.y;
+ modal->bring_to_front();
+ } break;
+ case UI::Message::Type::deactivate:
+ modal->dragging = false;
+ break;
+ default: return 0;
}
- if (msg.type == UI::Message::Type::deactivate)
- modal->dragging = false;
return 0;
};
UI::Modal::Modal(UI* ui, Element* parent, const char* text):
Element(ui, parent), dragging(false) {
+ pos[0] = 0;
+ pos[1] = 0;
contents = ui->create_element<Container>(this);
title_bar = ui->create_element<Toolbar>(contents);
title_bar->handler = [](Element* e, const Message& m) {
- return drag_handler((Modal*)e->parent->parent, m);
+ return title_handler((Modal*)e->parent->parent, m);
};
close = ui->create_element<Button>(title_bar, "x");
title = ui->create_element<Label>(title_bar, text);
title->handler = [](Element* e, const Message& m) {
- return drag_handler((Modal*)e->parent->parent->parent, m);
+ return title_handler((Modal*)e->parent->parent->parent, m);
};
close->handler = [](Element* e, const Message& m) {
if (m.type == Message::Type::click)
@@ -923,15 +946,25 @@ UI::Modal::Modal(UI* ui, Element* parent, const char* text):
}
UI::Rect UI::Modal::layout(const Rect& avail) {
- UI::Rect content_size = contents->layout(avail);
+ Rect r = avail;
+ if (pos[0] && pos[1]) {
+ r.x = pos[0];
+ r.y = pos[1];
+ }
+ UI::Rect content_size = contents->layout(r);
title_bar->layout(content_size);
bound = content_size;
clip = content_size;
clip.clip(ui->area);
+ if (!pos[0] && !pos[1]) {
+ pos[0] = bound.x;
+ pos[1] = bound.y;
+ }
return content_size;
}
void UI::Modal::on_render() {
+ ui->mesh.set_clip(clip);
ui->draw_container(
contents->bound,
Colour(0xffffff, 0x80)
@@ -944,6 +977,14 @@ void UI::Modal::on_update() {
Rect avail = bound;
avail.x = app.mx - drag_offset[0];
avail.y = app.my - drag_offset[1];
+ pos[0] = avail.x;
+ pos[1] = avail.y;
layout(avail);
}
}
+
+void UI::Modal::bring_to_front() {
+ Element* p = parent;
+ p->remove_child(this);
+ p->add_child(this);
+}