From 2d314e72fee5398dee0f364b54c348994d4d13f9 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 27 Jun 2025 14:12:39 +0300 Subject: [PATCH] LibGUI: Implement basic message box --- userspace/libraries/LibGUI/CMakeLists.txt | 1 + userspace/libraries/LibGUI/MessageBox.cpp | 67 +++++++++++++++++++ .../LibGUI/include/LibGUI/MessageBox.h | 18 +++++ 3 files changed, 86 insertions(+) create mode 100644 userspace/libraries/LibGUI/MessageBox.cpp create mode 100644 userspace/libraries/LibGUI/include/LibGUI/MessageBox.h diff --git a/userspace/libraries/LibGUI/CMakeLists.txt b/userspace/libraries/LibGUI/CMakeLists.txt index 7f81b5fc..563e4e63 100644 --- a/userspace/libraries/LibGUI/CMakeLists.txt +++ b/userspace/libraries/LibGUI/CMakeLists.txt @@ -1,4 +1,5 @@ set(LIBGUI_SOURCES + MessageBox.cpp Texture.cpp Widget/Button.cpp Widget/Grid.cpp diff --git a/userspace/libraries/LibGUI/MessageBox.cpp b/userspace/libraries/LibGUI/MessageBox.cpp new file mode 100644 index 00000000..b5a4519e --- /dev/null +++ b/userspace/libraries/LibGUI/MessageBox.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include + +namespace LibGUI +{ + + BAN::ErrorOr MessageBox::create(BAN::StringView message, BAN::StringView title) + { + BAN::StringView ok_button = "OK"; + TRY(create(message, title, { &ok_button, 1 })); + return {}; + } + + BAN::ErrorOr MessageBox::create(BAN::StringView message, BAN::StringView title, BAN::Span buttons) + { + if (buttons.empty()) + return BAN::Error::from_errno(EINVAL); + + const uint32_t window_width = 300; + + auto root_widget = TRY(Widget::Widget::create({}, 0xFFFFFF, { 0, 0, window_width, 0 })); + + auto text_area = TRY(Widget::TextArea::create(root_widget, message, { 0, 0, window_width, 0})); + text_area->style().border_width = 0; + text_area->style().color_normal = Widget::Widget::color_invisible; + text_area->style().corner_radius = 0; + TRY(text_area->set_relative_geometry({ 0.0, 0.0, 1.0, 0.8 })); + text_area->show(); + + bool waiting = true; + size_t result = 0; + + auto button_area = TRY(Widget::Grid::create(root_widget, buttons.size(), 1)); + for (size_t i = 0; i < buttons.size(); i++) + { + auto button = TRY(Widget::Button::create(button_area, buttons[i])); + TRY(button_area->set_widget_position(button, i, 1, 0, 1)); + button->set_click_callback([&result, &waiting, i] { result = i; waiting = false; }); + button->show(); + } + TRY(button_area->set_relative_geometry({ 0.0, 0.8, 1.0, 0.2 })); + button_area->show(); + + const uint32_t button_height = 20; + const uint32_t window_height = text_area->get_required_height() + button_height; + + auto attributes = Window::default_attributes; + attributes.resizable = true; + + auto window = TRY(Window::create(window_width, window_height, title, attributes)); + TRY(window->set_root_widget(root_widget)); + window->set_close_window_event_callback([&waiting] { waiting = false; }); + + while (waiting) + { + window->wait_events(); + window->poll_events(); + } + + return result; + } + +} diff --git a/userspace/libraries/LibGUI/include/LibGUI/MessageBox.h b/userspace/libraries/LibGUI/include/LibGUI/MessageBox.h new file mode 100644 index 00000000..353f7206 --- /dev/null +++ b/userspace/libraries/LibGUI/include/LibGUI/MessageBox.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include + +namespace LibGUI +{ + + class MessageBox + { + public: + static BAN::ErrorOr create(BAN::StringView message, BAN::StringView title); + static BAN::ErrorOr create(BAN::StringView message, BAN::StringView title, BAN::Span buttons); + }; + +}