diff --git a/Userland/Libraries/LibGUI/Dialog.cpp b/Userland/Libraries/LibGUI/Dialog.cpp index adf5fa9f00..2993433d12 100644 --- a/Userland/Libraries/LibGUI/Dialog.cpp +++ b/Userland/Libraries/LibGUI/Dialog.cpp @@ -5,13 +5,15 @@ */ #include +#include #include #include namespace GUI { -Dialog::Dialog(Window* parent_window) +Dialog::Dialog(Window* parent_window, ScreenPosition screen_position) : Window(parent_window) + , m_screen_position(screen_position) { set_modal(true); set_minimizable(false); @@ -25,16 +27,64 @@ int Dialog::exec() { VERIFY(!m_event_loop); m_event_loop = make(); - if (parent() && is(parent())) { - auto& parent_window = *static_cast(parent()); - if (parent_window.is_visible()) { - center_within(parent_window); - } else { - center_on_screen(); + + auto desktop_rect = Desktop::the().rect(); + auto window_rect = rect(); + + auto top_align = [](Gfx::Rect& rect) { rect.set_y(32); }; + auto bottom_align = [this, desktop_rect](Gfx::Rect& rect) { rect.set_y(desktop_rect.height() - Desktop::the().taskbar_height() - height() - 12); }; + + auto left_align = [](Gfx::Rect& rect) { rect.set_x(12); }; + auto right_align = [this, desktop_rect](Gfx::Rect& rect) { rect.set_x(desktop_rect.width() - width() - 12); }; + + switch (m_screen_position) { + case CenterWithinParent: + if (parent() && is(parent())) { + auto& parent_window = *static_cast(parent()); + if (parent_window.is_visible()) { + window_rect.center_within(parent_window.rect()); + break; + } } - } else { - center_on_screen(); + [[fallthrough]]; // Fall back to `Center` if parent window is invalid or not visible + case Center: + window_rect.center_within(desktop_rect); + break; + case CenterLeft: + left_align(window_rect); + window_rect.center_vertically_within(desktop_rect); + break; + case CenterRight: + right_align(window_rect); + window_rect.center_vertically_within(desktop_rect); + break; + case TopLeft: + left_align(window_rect); + top_align(window_rect); + break; + case TopCenter: + window_rect.center_horizontally_within(desktop_rect); + top_align(window_rect); + break; + case TopRight: + right_align(window_rect); + top_align(window_rect); + break; + case BottomLeft: + left_align(window_rect); + bottom_align(window_rect); + break; + case BottomCenter: + window_rect.center_horizontally_within(desktop_rect); + bottom_align(window_rect); + break; + case BottomRight: + right_align(window_rect); + bottom_align(window_rect); + break; } + + set_rect(window_rect); show(); auto result = m_event_loop->exec(); m_event_loop = nullptr; diff --git a/Userland/Libraries/LibGUI/Dialog.h b/Userland/Libraries/LibGUI/Dialog.h index eb10517c6f..8fccf6ab50 100644 --- a/Userland/Libraries/LibGUI/Dialog.h +++ b/Userland/Libraries/LibGUI/Dialog.h @@ -20,6 +20,21 @@ public: ExecYes = 3, ExecNo = 4, }; + enum ScreenPosition { + CenterWithinParent = 0, + + Center = 1, + CenterLeft = 2, + CenterRight = 3, + + TopLeft = 4, + TopCenter = 5, + TopRight = 6, + + BottomLeft = 7, + BottomCenter = 8, + BottomRight = 9, + }; virtual ~Dialog() override; @@ -33,11 +48,12 @@ public: virtual void close() override; protected: - explicit Dialog(Window* parent_window); + explicit Dialog(Window* parent_window, ScreenPosition screen_position = CenterWithinParent); private: OwnPtr m_event_loop; int m_result { ExecAborted }; + int m_screen_position { CenterWithinParent }; }; }