From 84ee95c346c714f0a7954ba671ed14fa675dd425 Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Wed, 14 Jul 2021 12:01:31 +0200 Subject: [PATCH] LibGUI: Allow to specify position on screen for Dialog window This change allows us to specify where on screen we'd like the Dialog window to be drawn. By default it's set to CenterWithinParent which may fall back to Center if parent window is unset or not visible on screen. --- Userland/Libraries/LibGUI/Dialog.cpp | 68 ++++++++++++++++++++++++---- Userland/Libraries/LibGUI/Dialog.h | 18 +++++++- 2 files changed, 76 insertions(+), 10 deletions(-) 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 }; }; }