From f71cb4ee09b1b410137100acb5d44b0c85598a72 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 15 Aug 2023 13:01:41 +0200 Subject: [PATCH] libui: Add VerticalLayout --- apps/gclient.cpp | 2 +- libui/include/ui/Layout.h | 18 ++++++++++++ libui/src/Layout.cpp | 58 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/apps/gclient.cpp b/apps/gclient.cpp index 86bf30bf..23821081 100644 --- a/apps/gclient.cpp +++ b/apps/gclient.cpp @@ -42,7 +42,7 @@ Result luna_main(int argc, char** argv) ColorWidget blue(ui::BLUE); layout.add_widget(blue); - ui::HorizontalLayout sublayout(ui::AdjustHeight::No, ui::AdjustWidth::Yes); + ui::VerticalLayout sublayout; layout.add_widget(sublayout); ColorWidget red(ui::RED); diff --git a/libui/include/ui/Layout.h b/libui/include/ui/Layout.h index 98ce132e..83cb0fef 100644 --- a/libui/include/ui/Layout.h +++ b/libui/include/ui/Layout.h @@ -42,4 +42,22 @@ namespace ui AdjustWidth m_adjust_width; int m_used_width; }; + + class VerticalLayout final : public Widget + { + public: + VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); + + Result handle_mousemove(Point position) override; + + Result draw(Canvas& canvas) override; + + Result add_widget(Widget& widget); + + private: + Vector m_widgets; + AdjustHeight m_adjust_height; + AdjustWidth m_adjust_width; + int m_used_height; + }; } diff --git a/libui/src/Layout.cpp b/libui/src/Layout.cpp index 9d5d124b..4eeca17f 100644 --- a/libui/src/Layout.cpp +++ b/libui/src/Layout.cpp @@ -69,4 +69,62 @@ namespace ui return {}; } + + VerticalLayout::VerticalLayout(AdjustHeight adjust_height, AdjustWidth adjust_width) + : m_adjust_height(adjust_height), m_adjust_width(adjust_width) + { + } + + Result VerticalLayout::handle_mousemove(Point position) + { + for (auto widget : m_widgets) + { + if (widget->rect().contains(position)) return widget->handle_mousemove(position); + } + + return ui::EventResult::DidNotHandle; + } + + Result VerticalLayout::draw(Canvas& canvas) + { + for (auto widget : m_widgets) + { + ui::Rect rect = { m_rect.relative(widget->rect().pos), widget->rect().width, widget->rect().height }; + auto subcanvas = canvas.subcanvas(rect); + TRY(widget->draw(subcanvas)); + } + + return {}; + } + + Result VerticalLayout::add_widget(Widget& widget) + { + TRY(m_widgets.try_append(&widget)); + + if (m_adjust_height == AdjustHeight::No) + { + widget.rect().pos.y = m_rect.pos.y + m_used_height; + m_used_height += widget.rect().height; + } + else + { + int used_height = 0; + div_t result = div(m_rect.height, (int)m_widgets.size()); + for (auto w : m_widgets) + { + w->rect().pos.y = m_rect.pos.y + used_height; + w->rect().height = result.quot; + used_height += result.quot; + } + m_widgets[m_widgets.size() - 1]->rect().height += result.rem; + } + + widget.rect().pos.x = m_rect.pos.x; + + if (m_adjust_width == AdjustWidth::Yes) { widget.rect().width = m_rect.width; } + + widget.set_parent(this); + + return {}; + } }