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.
This commit is contained in:
John Scipione
2013-04-30 20:15:32 -04:00
parent f74ff8d324
commit 6723d9fc94
4 changed files with 67 additions and 6 deletions
+2
View File
@@ -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,
+3 -6
View File
@@ -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<BWindow*>(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<BWindow*>(this)->AlertPosition(frame));
}
+52
View File
@@ -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)
{
+10
View File
@@ -40,6 +40,9 @@ All rights reserved.
#include <BeBuild.h>
#include <Debug.h>
#include <FilePanel.h>
#include <Looper.h>
#include <Screen.h>
#include <Window.h>
#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<BWindow*>(BLooper::LooperForThread(find_thread(NULL)));
const BRect frame = parent != NULL ? parent->Frame()
: BScreen(fWindow).Frame();
fWindow->MoveTo(dynamic_cast<BWindow*>(fWindow)->AlertPosition(frame));
if (!IsShowing())
fWindow->Show();