Place the button description window near the mouse and to

the side of the pad window that has enough room (preferring
right/bottom side of pad). The algorithm doesn't strictly
prevent the window to be placed outside of the screen in any
and all situations, but it should work pretty well in
practice.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42975 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2011-10-29 19:31:29 +00:00
parent e9e53773c9
commit 3f2e30c0a0
6 changed files with 102 additions and 46 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006-2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -22,7 +22,8 @@
App::App()
:
BApplication("application/x-vnd.Haiku-LaunchBox"),
fSettingsChanged(false)
fSettingsChanged(false),
fNamePanelSize(200, 50)
{
SetPulseRate(3000000);
}
@ -47,7 +48,7 @@ App::ReadyToRun()
bool windowAdded = false;
BRect frame(50.0, 50.0, 65.0, 100.0);
BMessage settings('sett');
BMessage settings;
status_t status = load_settings(&settings, "main_settings", "LaunchBox");
if (status >= B_OK) {
BMessage windowMessage;
@ -65,8 +66,11 @@ App::ReadyToRun()
frame.OffsetBy(10.0, 10.0);
windowMessage.MakeEmpty();
}
BSize size;
if (settings.FindSize("name panel size", &size) == B_OK)
fNamePanelSize = size;
}
if (!windowAdded) {
MainWindow* window = new MainWindow(B_TRANSLATE("Pad 1"), frame, true);
window->Show();
@ -110,6 +114,28 @@ App::Pulse()
}
void
App::SetNamePanelSize(const BSize& size)
{
if (Lock()) {
fNamePanelSize = size;
Unlock();
}
}
BSize
App::NamePanelSize()
{
BSize size;
if (Lock()) {
size = fNamePanelSize;
Unlock();
}
return size;
}
void
App::_StoreSettingsIfNeeded()
{
@ -127,6 +153,8 @@ App::_StoreSettingsIfNeeded()
}
}
}
settings.AddSize("name panel size", fNamePanelSize);
save_settings(&settings, "main_settings", "LaunchBox");
fSettingsChanged = false;

View File

@ -1,15 +1,19 @@
/*
* Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006-2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef APP_H
#define APP_H
#include <Application.h>
#include <List.h>
#include <Size.h>
class MainWindow;
class App : public BApplication {
public:
App();
@ -20,10 +24,16 @@ public:
virtual void MessageReceived(BMessage* message);
virtual void Pulse();
void SetNamePanelSize(const BSize& size);
BSize NamePanelSize();
private:
void _StoreSettingsIfNeeded();
bool fSettingsChanged;
BSize fNamePanelSize;
};
#endif // APP_H

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006 - 2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006 - 2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -20,6 +20,7 @@
#include "support.h"
#include "App.h"
#include "LaunchButton.h"
#include "NamePanel.h"
#include "PadView.h"
@ -36,7 +37,6 @@ MainWindow::MainWindow(const char* name, BRect frame, bool addDefaultButtons)
B_ALL_WORKSPACES),
fSettings(new BMessage('sett')),
fPadView(new PadView("pad view")),
fNamePanelFrame(-1000.0, -1000.0, -800.0, -900.0),
fAutoRaise(false),
fShowOnAllWorkspaces(true)
{
@ -65,7 +65,6 @@ MainWindow::MainWindow(const char* name, BRect frame, BMessage* settings)
B_ALL_WORKSPACES),
fSettings(settings),
fPadView(new PadView("pad view")),
fNamePanelFrame(-1000.0, -1000.0, -900.0, -900.0),
fAutoRaise(false),
fShowOnAllWorkspaces(true)
{
@ -206,17 +205,52 @@ MainWindow::MessageReceived(BMessage* message)
if (message->FindString("name", &name) >= B_OK) {
// message comes from a previous name panel
button->SetDescription(name);
message->FindRect("frame", &fNamePanelFrame);
BRect namePanelFrame;
if (message->FindRect("frame", &namePanelFrame) == B_OK) {
((App*)be_app)->SetNamePanelSize(
namePanelFrame.Size());
}
} else {
// message comes from pad view
entry_ref* ref = button->Ref();
if (ref) {
BString helper(B_TRANSLATE("Description for '%3'"));
helper.ReplaceFirst("%3", ref->name);
make_sure_frame_is_on_screen(fNamePanelFrame, this);
new NamePanel(helper.String(), button->Description(),
this, this, new BMessage(*message),
fNamePanelFrame);
// Place the name panel besides the pad, but give it
// the user configured size.
BPoint origin = B_ORIGIN;
BSize size = ((App*)be_app)->NamePanelSize();
NamePanel* panel = new NamePanel(helper.String(),
button->Description(), this, this,
new BMessage(*message), size);
panel->Layout(true);
size = panel->Frame().Size();
BScreen screen(this);
BPoint mousePos;
uint32 buttons;
fPadView->GetMouse(&mousePos, &buttons, false);
fPadView->ConvertToScreen(&mousePos);
if (fPadView->Orientation() == B_HORIZONTAL) {
// Place above or below the pad
origin.x = mousePos.x - size.width / 2;
if (screen.Frame().bottom - Frame().bottom
> size.height + 20) {
origin.y = Frame().bottom + 10;
} else {
origin.y = Frame().top - 10 - size.height;
}
} else {
// Place left or right of the pad
origin.y = mousePos.y - size.height / 2;
if (screen.Frame().right - Frame().right
> size.width + 20) {
origin.x = Frame().right + 10;
} else {
origin.x = Frame().left - 10 - size.width;
}
}
panel->MoveTo(origin);
panel->Show();
}
}
}
@ -344,14 +378,6 @@ MainWindow::LoadSettings(const BMessage* message)
}
}
// restore name panel frame
if (message->FindRect("name panel frame", &frame) == B_OK) {
if (frame.IsValid()) {
make_sure_frame_is_on_screen(frame, this);
fNamePanelFrame = frame;
}
}
// restore window look
window_look look;
if (message->FindInt32("window look", (int32*)&look) == B_OK)
@ -429,14 +455,10 @@ MainWindow::SaveSettings(BMessage* message)
if (message->ReplaceFloat("border distance", fBorderDist) != B_OK)
message->AddFloat("border distance", fBorderDist);
// store window frame
// store window frame and look
if (message->ReplaceRect("window frame", Frame()) != B_OK)
message->AddRect("window frame", Frame());
// store name panel frame
if (message->ReplaceRect("name panel frame", fNamePanelFrame) != B_OK)
message->AddRect("name panel frame", fNamePanelFrame);
if (message->ReplaceInt32("window look", Look()) != B_OK)
message->AddInt32("window look", Look());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006-2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef MAIN_WINDOW_H
@ -73,8 +73,6 @@ private:
BPoint fScreenPosition;
// not really the position, 0...1 = left...right
BRect fNamePanelFrame;
bool fAutoRaise;
bool fShowOnAllWorkspaces;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006-2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -15,16 +15,18 @@
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "LaunchBox"
enum {
MSG_PANEL_OK,
MSG_PANEL_CANCEL,
};
// constructor
NamePanel::NamePanel(const char* label, const char* text, BWindow* window,
BHandler* target, BMessage* message, BRect frame)
BHandler* target, BMessage* message, const BSize& size)
:
Panel(frame, B_TRANSLATE("Name Panel"),
Panel(BRect(B_ORIGIN, size), B_TRANSLATE("Name Panel"),
B_MODAL_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_NOT_V_RESIZABLE
| B_AUTO_UPDATE_SIZE_LIMITS),
@ -37,6 +39,10 @@ NamePanel::NamePanel(const char* label, const char* text, BWindow* window,
BButton* cancelButton = new BButton(B_TRANSLATE("Cancel"),
new BMessage(MSG_PANEL_CANCEL));
fNameTC = new BTextControl(label, text, NULL);
BLayoutItem* inputItem = fNameTC->CreateTextViewLayoutItem();
inputItem->SetExplicitMinSize(
BSize(fNameTC->StringWidth("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
B_SIZE_UNSET));
BLayoutBuilder::Group<>(this, B_VERTICAL, 10)
.AddGlue()
@ -47,7 +53,7 @@ NamePanel::NamePanel(const char* label, const char* text, BWindow* window,
// text control
.Add(fNameTC->CreateLabelLayoutItem())
.Add(fNameTC->CreateTextViewLayoutItem())
.Add(inputItem)
.AddStrut(5)
.End()
@ -74,11 +80,6 @@ NamePanel::NamePanel(const char* label, const char* text, BWindow* window,
}
AddToSubset(fWindow);
if (!frame.IsValid())
CenterOnScreen();
Show();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2006-2011, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef NAME_PANEL_H
@ -11,12 +11,9 @@ class BTextControl;
class NamePanel : public Panel {
public:
NamePanel(const char* label,
const char* text,
BWindow* window,
BHandler* target,
BMessage* message,
BRect frame = BRect(-1000.0, -1000.0, -900.0, -900.0));
NamePanel(const char* label, const char* text,
BWindow* window, BHandler* target,
BMessage* message, const BSize& size);
virtual ~NamePanel();
virtual void MessageReceived(BMessage *message);