/** * @file Layout.h * @author apio (cloudapio.eu) * @brief Layout widgets to organize content. * * @copyright Copyright (c) 2023, the Luna authors. * */ #pragma once #include #include #include namespace ui { enum class AdjustHeight { No, Yes }; enum class AdjustWidth { No, Yes }; struct Margins { int left; int right; int top; int bottom; }; class HorizontalLayout final : public Widget { public: HorizontalLayout(ui::Window* window, ui::Widget* parent); void set_layout_settings(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::No) { m_margins = margins; m_adjust_height = adjust_height; m_adjust_width = adjust_width; } Result handle_mouse_move(Point position) override; Result handle_mouse_leave() override; Result handle_mouse_down(Point position, int buttons) override; Result handle_mouse_up(Point position, int buttons) override; Result handle_key_event(const ui::KeyEventRequest& request) override; Result draw(Canvas& canvas) override; template Result add_child_widget() { auto* widget = TRY(make(window(), this)); add_widget(*widget); return widget; } void recalculate_pseudo_rects() override; void recalculate_true_rects() override; void show_tree(int indent) override { os::println("%*s- ui::HorizontalLayout [%zu widgets] (%d,%d,%d,%d)", indent, "", m_widgets.size(), m_rect.pos.x, m_rect.pos.y, m_rect.width, m_rect.height); for (auto* w : m_widgets) { w->show_tree(indent + 1); } } private: Vector m_widgets; Margins m_margins { 0, 0, 0, 0 }; AdjustHeight m_adjust_height = AdjustHeight::Yes; AdjustWidth m_adjust_width = AdjustWidth::No; int m_used_width { 0 }; Result add_widget(Widget& widget); }; class VerticalLayout final : public Widget { public: VerticalLayout(ui::Window* window, ui::Widget* parent); void set_layout_settings(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::No, AdjustWidth adjust_width = AdjustWidth::Yes) { m_margins = margins; m_adjust_height = adjust_height; m_adjust_width = adjust_width; } Result handle_mouse_move(Point position) override; Result handle_mouse_leave() override; Result handle_mouse_down(Point position, int buttons) override; Result handle_mouse_up(Point position, int buttons) override; Result handle_key_event(const ui::KeyEventRequest& request) override; Result draw(Canvas& canvas) override; template Result add_child_widget() { auto* widget = TRY(make(window(), this)); add_widget(*widget); return widget; } void recalculate_pseudo_rects() override; void recalculate_true_rects() override; void show_tree(int indent) override { os::println("%*s- ui::VerticalLayout [%zu widgets] (%d,%d,%d,%d)", indent, "", m_widgets.size(), m_rect.pos.x, m_rect.pos.y, m_rect.width, m_rect.height); for (auto* w : m_widgets) { w->show_tree(indent + 1); } } private: Vector m_widgets; Margins m_margins { 0, 0, 0, 0 }; AdjustHeight m_adjust_height = AdjustHeight::No; AdjustWidth m_adjust_width = AdjustWidth::Yes; int m_used_height { 0 }; Result add_widget(Widget& widget); }; }