From 6723d9fc948b0abd71cb55b46f8c73586d8494f1 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 30 Apr 2013 20:06:29 -0400 Subject: [PATCH] Create a BWindow::AlertPosition() method and use it ...to position alert's and open/save dialogs nicely inside of the parent window, or if that is unavailable, the screen frame. AlertPosition() is private (for now) but BAlert and BFilePanel are BWindow's friends so BWindow allows those classes to touch it's privates. --- headers/os/interface/Window.h | 2 ++ src/kits/interface/Alert.cpp | 9 ++---- src/kits/interface/Window.cpp | 52 ++++++++++++++++++++++++++++++++++ src/kits/tracker/FilePanel.cpp | 10 +++++++ 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 5b1d6893fa..02b2cdeadd 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -283,6 +283,7 @@ private: struct unpack_cookie; class Shortcut; + friend class BAlert; friend class BApplication; friend class BBitmap; friend class BView; @@ -303,6 +304,7 @@ private: virtual void task_looper(); + BPoint AlertPosition(const BRect& frame); virtual BMessage* ConvertToMessage(void* raw, int32 code); void AddShortcut(uint32 key, uint32 modifiers, diff --git a/src/kits/interface/Alert.cpp b/src/kits/interface/Alert.cpp index ce513cf457..476f35312f 100644 --- a/src/kits/interface/Alert.cpp +++ b/src/kits/interface/Alert.cpp @@ -576,13 +576,10 @@ BAlert::_InitObject(const char* text, const char* button0, const char* button1, // Position the alert so that it is centered vertically but offset a bit // horizontally in the parent window's frame or, if unavailable, the // screen frame. - BWindow* window = + BWindow* parent = dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); - const BRect frame = window != NULL ? window->Frame() - : (BScreen(this)).Frame(); - - CenterIn(frame.InsetByCopy(0, frame.Height() / 2) - .OffsetBySelf(0, -frame.Height() / 4)); + const BRect frame = parent != NULL ? parent->Frame() : BScreen(this).Frame(); + MoveTo(dynamic_cast(this)->AlertPosition(frame)); } diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index a7ef4a8ffe..fd77d14d95 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -3891,6 +3891,58 @@ BWindow::_KeyboardNavigation() } +/*! + \brief Return the position of the window centered horizontally to the passed + in \a frame and vertically 3/4 from the top of \a frame. + + If the window is on the borders + + \param width The width of the window. + \param height The height of the window. + \param frame The \a frame to center the window in. + + \return The new window position. +*/ +BPoint +BWindow::AlertPosition(const BRect& frame) +{ + float width = Bounds().Width(); + float height = Bounds().Height(); + + BPoint point(frame.left + (frame.Width() / 2.0f) - (width / 2.0f), + frame.top + (frame.Height() / 4.0f) - ceil(height / 3.0f)); + + BRect screenFrame = BScreen(this).Frame(); + if (frame == screenFrame) { + // reference frame is screen frame, skip the below adjustments + return point; + } + + float borderWidth; + float tabHeight; + _GetDecoratorSize(&borderWidth, &tabHeight); + + // clip the x position within the horizontal edges of the screen + if (point.x < screenFrame.left + borderWidth) + point.x = screenFrame.left + borderWidth; + else if (point.x + width > screenFrame.right - borderWidth) + point.x = screenFrame.right - borderWidth - width; + + // lower the window down if it is covering the window tab + float tabPosition = frame.LeftTop().y + tabHeight + borderWidth; + if (point.y < tabPosition) + point.y = tabPosition; + + // clip the y position within the vertical edges of the screen + if (point.y < screenFrame.top + borderWidth) + point.y = screenFrame.top + borderWidth; + else if (point.y + height > screenFrame.bottom - borderWidth) + point.y = screenFrame.bottom - borderWidth - height; + + return point; +} + + BMessage* BWindow::ConvertToMessage(void* raw, int32 code) { diff --git a/src/kits/tracker/FilePanel.cpp b/src/kits/tracker/FilePanel.cpp index ae89580f9e..806c48f410 100644 --- a/src/kits/tracker/FilePanel.cpp +++ b/src/kits/tracker/FilePanel.cpp @@ -40,6 +40,9 @@ All rights reserved. #include #include #include +#include +#include +#include #include "AutoLock.h" #include "Commands.h" @@ -122,6 +125,13 @@ BFilePanel::Show() // window in a different workspace, reopen in current fWindow->SetWorkspaces(workspace); + // Position the file panel like an alert + BWindow* parent = + dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); + const BRect frame = parent != NULL ? parent->Frame() + : BScreen(fWindow).Frame(); + fWindow->MoveTo(dynamic_cast(fWindow)->AlertPosition(frame)); + if (!IsShowing()) fWindow->Show();