diff options
Diffstat (limited to 'ui.cpp')
-rw-r--r-- | ui.cpp | 97 |
1 files changed, 69 insertions, 28 deletions
@@ -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); +} |