summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui.cpp98
-rw-r--r--ui.hpp29
2 files changed, 113 insertions, 14 deletions
diff --git a/ui.cpp b/ui.cpp
index 7b5128b..a3ed71b 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -706,6 +706,10 @@ void UI::Element::on_message(const Message& msg) {
(void)msg;
}
+void UI::Element::on_add_child(Element* nch) {
+ (void)nch;
+}
+
void UI::Element::on_render() {
}
@@ -734,6 +738,7 @@ void UI::Element::add_child(Element* ch) {
}
ch->parent = this;
ui->layout_dirty = true;
+ on_add_child(ch);
}
void UI::Element::remove_child(Element* ch) {
@@ -821,12 +826,7 @@ void UI::Toolbar::on_render() {
}
UI::Button::Button(UI* ui, Element* parent, const char* label):
- Element(ui, parent) {
- text = dup_stringh(ui->heap, label);
-}
-
-UI::Button::~Button() {
- heap_free(ui->heap, text);
+ Label(ui, parent, label) {
}
UI::Rect UI::Button::layout(const Rect& avail) {
@@ -988,3 +988,89 @@ void UI::Modal::bring_to_front() {
p->remove_child(this);
p->add_child(this);
}
+
+UI::Tree::Tree(UI* ui, Element* parent, const char* label):
+ Element(ui, parent), collapsed(0), expandbtn(0), text(0) {
+ text = ui->create_element<Label>(this, label);
+}
+
+UI::Rect UI::Tree::layout(const Rect& avail) {
+ Rect cr(avail.x + ui_padding, avail.y, avail.w, avail.h);
+ Rect lr(0, avail.y, avail.w, avail.h);
+ Rect used(avail.x, avail.y, 0, 0);
+ Element* child;
+ Rect er = Rect(cr.x, cr.y, 0, 0);
+ if (expandbtn)
+ er = expandbtn->layout(cr);
+ lr.x = er.x + er.w + ui_padding;
+ Rect tr = text->layout(lr);
+ er.h += ui_padding;
+ used.h = er.h;
+ used.w = (tr.x + tr.w) - er.x;
+ cr.y += er.h;
+ cr.h -= er.h;
+ for (child = children; child; child = child->next) {
+ if (child == expandbtn || child == text) continue;
+ Rect r = child->layout(cr);
+ r.h += ui_padding;
+ cr.y += r.h;
+ cr.h -= r.h;
+ used.h += r.h;
+ }
+ used.h += ui_padding;
+ bound = used;
+ clip = used;
+ clip.clip(avail);
+ return bound;
+}
+
+void UI::Tree::on_render() {
+ if (collapsed) {
+ expandbtn->render();
+ text->render();
+ }
+}
+
+void UI::Tree::on_update() {
+ if (collapsed) {
+ expandbtn->update();
+ text->update();
+ }
+}
+
+void UI::Tree::on_add_child(Element* child) {
+ assert(collapsed == 0);
+ if (!expandbtn && text) {
+ expandbtn = (Button*)0x1;
+ expandbtn = ui->create_element<Button>(this, "-");
+ expandbtn->handler = [](Element* e, const Message& m) {
+ if (m.type == Message::Type::click) {
+ UI::Tree* t = (UI::Tree*)e->parent;
+ if (t->collapsed)
+ t->expand();
+ else
+ t->collapse();
+ }
+ return 0;
+ };
+ }
+ (void)child;
+}
+
+void UI::Tree::expand() {
+ children = collapsed;
+ collapsed = 0;
+ if (expandbtn)
+ expandbtn->set_text("-");
+}
+
+void UI::Tree::collapse() {
+ collapsed = children;
+ children = 0;
+ if (expandbtn)
+ expandbtn->set_text("+");
+}
+
+bool UI::Tree::is_leaf() const {
+ return children == 0 && collapsed == 0;
+}
diff --git a/ui.hpp b/ui.hpp
index adb1ba8..abb4f69 100644
--- a/ui.hpp
+++ b/ui.hpp
@@ -177,6 +177,7 @@ struct UI {
void update();
virtual void on_update();
virtual void on_render();
+ virtual void on_add_child(Element* nch);
virtual void on_message(const Message& msg);
void add_child(Element* ch);
@@ -204,14 +205,6 @@ struct UI {
void on_render() override;
};
- struct Button : Element {
- char* text;
- Button(UI* ui, Element* parent, const char* label);
- ~Button();
- Rect layout(const Rect& avail) override;
- void on_render() override;
- };
-
struct Label : Element {
char* text;
Label(UI* ui, Element* parent, const char* label);
@@ -222,6 +215,12 @@ struct UI {
void set_text(const char* s);
};
+ struct Button : Label {
+ Button(UI* ui, Element* parent, const char* label);
+ Rect layout(const Rect& avail) override;
+ void on_render() override;
+ };
+
struct Modal : Element {
Container* contents;
Toolbar* title_bar;
@@ -236,6 +235,20 @@ struct UI {
void on_update() override;
void bring_to_front();
};
+
+ struct Tree : Element {
+ Element* collapsed; /* <- children are moved here when it's collapsed so they stop layout'ing and rendering! */
+ Button* expandbtn;
+ Label* text;
+ Tree(UI* ui, Element* parent, const char* text);
+ Rect layout(const Rect& avail) override;
+ void on_render() override;
+ void on_update() override;
+ void on_add_child(Element* child) override;
+ void expand();
+ void collapse();
+ bool is_leaf() const;
+ };
};
#endif