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:
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user