Refactoring of the Window class. Move window behaviour into separate WindowBehaviour class.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37524 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,505 @@
|
||||
#include "DefaultWindowBehaviour.h"
|
||||
|
||||
#include "Desktop.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "Window.h"
|
||||
|
||||
|
||||
//#define DEBUG_WINDOW_CLICK
|
||||
|
||||
#ifdef DEBUG_WINDOW_CLICK
|
||||
# define STRACE_CLICK(x) printf x
|
||||
#else
|
||||
# define STRACE_CLICK(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
DefaultWindowBehaviour::DefaultWindowBehaviour(Window* window,
|
||||
Decorator* decorator)
|
||||
:
|
||||
fWindow(window),
|
||||
fDecorator(decorator),
|
||||
|
||||
fIsClosing(false),
|
||||
fIsMinimizing(false),
|
||||
fIsZooming(false),
|
||||
fIsSlidingTab(false),
|
||||
fActivateOnMouseUp(false),
|
||||
|
||||
fLastMousePosition(0.0f, 0.0f),
|
||||
fMouseMoveDistance(0.0f),
|
||||
fLastMoveTime(0),
|
||||
fLastSnapTime(0)
|
||||
{
|
||||
fDesktop = fWindow->Desktop();
|
||||
}
|
||||
|
||||
|
||||
DefaultWindowBehaviour::~DefaultWindowBehaviour()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static const bigtime_t kWindowActivationTimeout = 500000LL;
|
||||
|
||||
|
||||
bool
|
||||
DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
||||
{
|
||||
int32 modifiers = _ExtractModifiers(message);
|
||||
bool inBorderRegion = fWindow->BorderRegion().Contains(where);
|
||||
bool windowModifier =
|
||||
(fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
|
||||
&& (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
|
||||
| B_SHIFT_KEY)) == (B_COMMAND_KEY | B_CONTROL_KEY);
|
||||
click_type action = CLICK_NONE;
|
||||
|
||||
if (windowModifier || inBorderRegion) {
|
||||
// clicking Window visible area
|
||||
|
||||
int32 buttons = _ExtractButtons(message);
|
||||
|
||||
if (inBorderRegion)
|
||||
action = _ActionFor(message, buttons, modifiers);
|
||||
else {
|
||||
if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
|
||||
action = CLICK_MOVE_TO_BACK;
|
||||
else if ((fWindow->Flags() & B_NOT_MOVABLE) == 0
|
||||
&& fDecorator != NULL)
|
||||
action = CLICK_DRAG;
|
||||
else {
|
||||
// pass click on to the application
|
||||
windowModifier = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DesktopSettings desktopSettings(fDesktop);
|
||||
if (windowModifier || inBorderRegion) {
|
||||
if (!desktopSettings.AcceptFirstClick()) {
|
||||
// Ignore clicks on decorator buttons if the
|
||||
// non-floating window doesn't have focus
|
||||
if (!fWindow->IsFocus() && !fWindow->IsFloating()
|
||||
&& action != CLICK_MOVE_TO_BACK
|
||||
&& action != CLICK_RESIZE && action != CLICK_SLIDE_TAB)
|
||||
action = CLICK_DRAG;
|
||||
}
|
||||
|
||||
// set decorator internals
|
||||
switch (action) {
|
||||
case CLICK_CLOSE:
|
||||
fIsClosing = true;
|
||||
STRACE_CLICK(("===> CLICK_CLOSE\n"));
|
||||
break;
|
||||
|
||||
case CLICK_ZOOM:
|
||||
fIsZooming = true;
|
||||
STRACE_CLICK(("===> CLICK_ZOOM\n"));
|
||||
break;
|
||||
|
||||
case CLICK_MINIMIZE:
|
||||
if ((fWindow->Flags() & B_NOT_MINIMIZABLE) == 0) {
|
||||
fIsMinimizing = true;
|
||||
STRACE_CLICK(("===> CLICK_MINIMIZE\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case CLICK_DRAG:
|
||||
fIsDragging = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_DRAG\n"));
|
||||
break;
|
||||
|
||||
case CLICK_RESIZE:
|
||||
fIsResizing = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_RESIZE\n"));
|
||||
break;
|
||||
|
||||
case CLICK_SLIDE_TAB:
|
||||
fIsSlidingTab = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_SLIDE_TAB\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fDecorator != NULL) {
|
||||
// redraw decorator
|
||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
||||
fWindow->GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming)
|
||||
fDecorator->SetZoom(true);
|
||||
else if (fIsClosing)
|
||||
fDecorator->SetClose(true);
|
||||
else if (fIsMinimizing)
|
||||
fDecorator->SetMinimize(true);
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
|
||||
fWindow->RegionPool()->Recycle(visibleBorder);
|
||||
}
|
||||
|
||||
if (action == CLICK_MOVE_TO_BACK) {
|
||||
if (desktopSettings.MouseMode() == B_CLICK_TO_FOCUS_MOUSE) {
|
||||
bool covered = true;
|
||||
BRegion fullRegion;
|
||||
fWindow->GetFullRegion(&fullRegion);
|
||||
if (fullRegion == fWindow->VisibleRegion()) {
|
||||
// window is overlapped.
|
||||
covered = false;
|
||||
}
|
||||
if (fWindow != fDesktop->FrontWindow() && covered)
|
||||
fDesktop->ActivateWindow(fWindow);
|
||||
else
|
||||
fDesktop->SendWindowBehind(fWindow);
|
||||
} else
|
||||
fDesktop->SendWindowBehind(fWindow);
|
||||
} else {
|
||||
fDesktop->SetMouseEventWindow(fWindow);
|
||||
|
||||
// activate window if in click to activate mode, else only focus it
|
||||
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE)
|
||||
fDesktop->ActivateWindow(fWindow);
|
||||
else {
|
||||
fDesktop->SetFocusWindow(fWindow);
|
||||
if (desktopSettings.MouseMode() == B_FOCUS_FOLLOWS_MOUSE
|
||||
&& (action == CLICK_DRAG || action == CLICK_RESIZE)) {
|
||||
fActivateOnMouseUp = true;
|
||||
fMouseMoveDistance = 0.0f;
|
||||
fLastMoveTime = system_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
|
||||
{
|
||||
bool invalidate = false;
|
||||
if (fDecorator) {
|
||||
click_type action = _ActionFor(message);
|
||||
|
||||
// redraw decorator
|
||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
||||
fWindow->GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming) {
|
||||
fIsZooming = false;
|
||||
fDecorator->SetZoom(false);
|
||||
if (action == CLICK_ZOOM) {
|
||||
invalidate = true;
|
||||
fWindow->ServerWindow()->NotifyZoom();
|
||||
}
|
||||
}
|
||||
if (fIsClosing) {
|
||||
fIsClosing = false;
|
||||
fDecorator->SetClose(false);
|
||||
if (action == CLICK_CLOSE) {
|
||||
invalidate = true;
|
||||
fWindow->ServerWindow()->NotifyQuitRequested();
|
||||
}
|
||||
}
|
||||
if (fIsMinimizing) {
|
||||
fIsMinimizing = false;
|
||||
fDecorator->SetMinimize(false);
|
||||
if (action == CLICK_MINIMIZE) {
|
||||
invalidate = true;
|
||||
fWindow->ServerWindow()->NotifyMinimize(true);
|
||||
}
|
||||
}
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
|
||||
fWindow->RegionPool()->Recycle(visibleBorder);
|
||||
|
||||
int32 buttons;
|
||||
if (message->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = 0;
|
||||
|
||||
// if the primary mouse button is released, stop
|
||||
// dragging/resizing/sliding
|
||||
if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0) {
|
||||
fIsDragging = false;
|
||||
fIsResizing = false;
|
||||
fIsSlidingTab = false;
|
||||
}
|
||||
}
|
||||
|
||||
// in FFM mode, activate the window and bring it
|
||||
// to front in case this was a drag click but the
|
||||
// mouse was not moved
|
||||
if (fActivateOnMouseUp) {
|
||||
fActivateOnMouseUp = false;
|
||||
// on R5, there is a time window for this feature
|
||||
// ie, click and press too long, nothing will happen
|
||||
if (system_time() - fLastMoveTime < kWindowActivationTimeout)
|
||||
fDesktop->ActivateWindow(fWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultWindowBehaviour::MouseMoved(BMessage *message, BPoint where, bool isFake)
|
||||
{
|
||||
#if 0
|
||||
if (fDecorator != NULL && fWindow->TopView() != NULL) {
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(&fWindow->VisibleRegion());
|
||||
|
||||
fWindow->TopView()->MarkAt(engine, where);
|
||||
engine->UnlockParallelAccess();
|
||||
}
|
||||
#endif
|
||||
// limit the rate at which "mouse moved" events
|
||||
// are handled that move or resize the window
|
||||
bigtime_t now = 0;
|
||||
if (fIsDragging || fIsResizing) {
|
||||
now = system_time();
|
||||
if (now - fLastMoveTime < 13333) {
|
||||
// TODO: add a "timed event" to query for
|
||||
// the then current mouse position
|
||||
return;
|
||||
}
|
||||
if (fActivateOnMouseUp) {
|
||||
if (now - fLastMoveTime >= kWindowActivationTimeout) {
|
||||
// This click is too long already for window activation.
|
||||
fActivateOnMouseUp = false;
|
||||
}
|
||||
} else
|
||||
fLastMoveTime = now;
|
||||
}
|
||||
|
||||
if (fDecorator) {
|
||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
||||
fWindow->GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming) {
|
||||
fDecorator->SetZoom(_ActionFor(message) == CLICK_ZOOM);
|
||||
} else if (fIsClosing) {
|
||||
fDecorator->SetClose(_ActionFor(message) == CLICK_CLOSE);
|
||||
} else if (fIsMinimizing) {
|
||||
fDecorator->SetMinimize(_ActionFor(message) == CLICK_MINIMIZE);
|
||||
}
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
fWindow->RegionPool()->Recycle(visibleBorder);
|
||||
}
|
||||
|
||||
BPoint delta = where - fLastMousePosition;
|
||||
// NOTE: "delta" is later used to change fLastMousePosition.
|
||||
// If for some reason no change should take effect, delta
|
||||
// is to be set to (0, 0) so that fLastMousePosition is not
|
||||
// adjusted. This way the relative mouse position to the
|
||||
// item being changed (border during resizing, tab during
|
||||
// sliding...) stays fixed when the mouse is moved so that
|
||||
// changes are taking effect again.
|
||||
|
||||
// If the window was moved enough, it doesn't come to
|
||||
// the front in FFM mode when the mouse is released.
|
||||
if (fActivateOnMouseUp) {
|
||||
fMouseMoveDistance += delta.x * delta.x + delta.y * delta.y;
|
||||
if (fMouseMoveDistance > 16.0f)
|
||||
fActivateOnMouseUp = false;
|
||||
else
|
||||
delta = B_ORIGIN;
|
||||
}
|
||||
|
||||
// moving
|
||||
if (fIsDragging) {
|
||||
if (!(fWindow->Flags() & B_NOT_MOVABLE)) {
|
||||
BPoint oldLeftTop = fWindow->Frame().LeftTop();
|
||||
|
||||
_AlterDeltaForSnap(delta, now);
|
||||
fDesktop->MoveWindowBy(fWindow, delta.x, delta.y);
|
||||
|
||||
// constrain delta to true change in position
|
||||
delta = fWindow->Frame().LeftTop() - oldLeftTop;
|
||||
} else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
// resizing
|
||||
if (fIsResizing) {
|
||||
if (!(fWindow->Flags() & B_NOT_RESIZABLE)) {
|
||||
if (fWindow->Flags() & B_NOT_V_RESIZABLE)
|
||||
delta.y = 0;
|
||||
if (fWindow->Flags() & B_NOT_H_RESIZABLE)
|
||||
delta.x = 0;
|
||||
|
||||
BPoint oldRightBottom = fWindow->Frame().RightBottom();
|
||||
|
||||
fDesktop->ResizeWindowBy(fWindow, delta.x, delta.y);
|
||||
|
||||
// constrain delta to true change in size
|
||||
delta = fWindow->Frame().RightBottom() - oldRightBottom;
|
||||
} else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
// sliding tab
|
||||
if (fIsSlidingTab) {
|
||||
float loc = fWindow->TabLocation();
|
||||
// TODO: change to [0:1]
|
||||
loc += delta.x;
|
||||
if (fDesktop->SetWindowTabLocation(fWindow, loc))
|
||||
delta.y = 0;
|
||||
else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
|
||||
// NOTE: fLastMousePosition is currently only
|
||||
// used for window moving/resizing/sliding the tab
|
||||
fLastMousePosition += delta;
|
||||
|
||||
// change focus in FFM mode
|
||||
DesktopSettings desktopSettings(fDesktop);
|
||||
if (desktopSettings.FocusFollowsMouse()
|
||||
&& !fWindow->IsFocus() && !(fWindow->Flags() & B_AVOID_FOCUS)) {
|
||||
// If the mouse move is a fake one, we set the focus to NULL, which
|
||||
// will cause the window that had focus last to retrieve it again - this
|
||||
// makes FFM much nicer to use with the keyboard.
|
||||
fDesktop->SetFocusWindow(isFake ? NULL : fWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
DefaultWindowBehaviour::_ExtractButtons(const BMessage* message) const
|
||||
{
|
||||
int32 buttons;
|
||||
if (message->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = 0;
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
DefaultWindowBehaviour::_ExtractModifiers(const BMessage* message) const
|
||||
{
|
||||
int32 modifiers;
|
||||
if (message->FindInt32("modifiers", &modifiers) != B_OK)
|
||||
modifiers = 0;
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
click_type
|
||||
DefaultWindowBehaviour::_ActionFor(const BMessage* message) const
|
||||
{
|
||||
if (fDecorator == NULL)
|
||||
return CLICK_NONE;
|
||||
|
||||
int32 buttons = _ExtractButtons(message);
|
||||
int32 modifiers = _ExtractModifiers(message);
|
||||
return _ActionFor(message, buttons, modifiers);
|
||||
}
|
||||
|
||||
|
||||
click_type
|
||||
DefaultWindowBehaviour::_ActionFor(const BMessage* message, int32 buttons,
|
||||
int32 modifiers) const
|
||||
{
|
||||
if (fDecorator == NULL)
|
||||
return CLICK_NONE;
|
||||
|
||||
BPoint where;
|
||||
if (message->FindPoint("where", &where) != B_OK)
|
||||
return CLICK_NONE;
|
||||
|
||||
return fDecorator->Clicked(where, buttons, modifiers);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultWindowBehaviour::_AlterDeltaForSnap(BPoint& delta, bigtime_t now)
|
||||
{
|
||||
// Alter the delta (which is a proposed offset used while dragging a
|
||||
// window) so that the frame of the window 'snaps' to the edges of the
|
||||
// screen.
|
||||
|
||||
const bigtime_t kSnappingDuration = 1500000LL;
|
||||
const bigtime_t kSnappingPause = 3000000LL;
|
||||
const float kSnapDistance = 8.0f;
|
||||
|
||||
if (now - fLastSnapTime > kSnappingDuration
|
||||
&& now - fLastSnapTime < kSnappingPause) {
|
||||
// Maintain a pause between snapping.
|
||||
return;
|
||||
}
|
||||
|
||||
BRect frame = fWindow->Frame();
|
||||
BPoint offsetWithinFrame;
|
||||
// TODO: Perhaps obtain the usable area (not covered by the Deskbar)?
|
||||
BRect screenFrame = fWindow->Screen()->Frame();
|
||||
|
||||
if (fDecorator) {
|
||||
BRegion reg;
|
||||
fDecorator->GetFootprint(®);
|
||||
frame = reg.Frame();
|
||||
offsetWithinFrame.x = fWindow->Frame().left - frame.left;
|
||||
offsetWithinFrame.y = fWindow->Frame().top - frame.top;
|
||||
}
|
||||
|
||||
frame.OffsetBy(delta);
|
||||
|
||||
float leftDist = fabs(frame.left - screenFrame.left);
|
||||
float topDist = fabs(frame.top - screenFrame.top);
|
||||
float rightDist = fabs(frame.right - screenFrame.right);
|
||||
float bottomDist = fabs(frame.bottom - screenFrame.bottom);
|
||||
|
||||
bool snapped = false;
|
||||
if (leftDist < kSnapDistance || rightDist < kSnapDistance) {
|
||||
snapped = true;
|
||||
if (leftDist < rightDist) {
|
||||
frame.right -= frame.left;
|
||||
frame.left = 0.0f;
|
||||
} else {
|
||||
frame.left -= frame.right - screenFrame.right;
|
||||
frame.right = screenFrame.right;
|
||||
}
|
||||
}
|
||||
|
||||
if (topDist < kSnapDistance || bottomDist < kSnapDistance) {
|
||||
snapped = true;
|
||||
if (topDist < bottomDist) {
|
||||
frame.bottom -= frame.top;
|
||||
frame.top = 0.0f;
|
||||
} else {
|
||||
frame.top -= frame.bottom - screenFrame.bottom;
|
||||
frame.bottom = screenFrame.bottom;
|
||||
}
|
||||
}
|
||||
if (snapped && now - fLastSnapTime > kSnappingPause)
|
||||
fLastSnapTime = now;
|
||||
|
||||
|
||||
frame.top += offsetWithinFrame.y;
|
||||
frame.left += offsetWithinFrame.x;
|
||||
|
||||
delta.y = frame.top - fWindow->Frame().top;
|
||||
delta.x = frame.left - fWindow->Frame().left;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef DEFAULT_WINDOW_BEHAVIOUR_H
|
||||
#define DEFAULT_WINDOW_BEHAVIOUR_H
|
||||
|
||||
|
||||
#include "WindowBehaviour.h"
|
||||
|
||||
#include "Decorator.h"
|
||||
|
||||
|
||||
class Desktop;
|
||||
class Window;
|
||||
|
||||
|
||||
class DefaultWindowBehaviour : public WindowBehaviour
|
||||
{
|
||||
public:
|
||||
DefaultWindowBehaviour(Window* window,
|
||||
Decorator* decorator);
|
||||
virtual ~DefaultWindowBehaviour();
|
||||
|
||||
virtual bool MouseDown(BMessage* message, BPoint where);
|
||||
virtual void MouseUp(BMessage* message, BPoint where);
|
||||
virtual void MouseMoved(BMessage *message, BPoint where,
|
||||
bool isFake);
|
||||
|
||||
protected:
|
||||
Window* fWindow;
|
||||
Decorator* fDecorator;
|
||||
Desktop* fDesktop;
|
||||
|
||||
bool fIsClosing : 1;
|
||||
bool fIsMinimizing : 1;
|
||||
bool fIsZooming : 1;
|
||||
bool fIsSlidingTab : 1;
|
||||
bool fActivateOnMouseUp : 1;
|
||||
|
||||
BPoint fLastMousePosition;
|
||||
float fMouseMoveDistance;
|
||||
bigtime_t fLastMoveTime;
|
||||
bigtime_t fLastSnapTime;
|
||||
|
||||
private:
|
||||
int32 _ExtractButtons(const BMessage* message) const;
|
||||
int32 _ExtractModifiers(const BMessage* message) const;
|
||||
click_type _ActionFor(const BMessage* message) const;
|
||||
click_type _ActionFor(const BMessage* message, int32 buttons,
|
||||
int32 modifiers) const;
|
||||
|
||||
void _AlterDeltaForSnap(BPoint& delta,
|
||||
bigtime_t now);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -21,6 +21,7 @@ Server app_server :
|
||||
DecorManager.cpp
|
||||
Decorator.cpp
|
||||
DefaultDecorator.cpp
|
||||
DefaultWindowBehaviour.cpp
|
||||
Desktop.cpp
|
||||
DesktopSettings.cpp
|
||||
DirectWindowInfo.cpp
|
||||
@@ -57,6 +58,7 @@ Server app_server :
|
||||
View.cpp
|
||||
VirtualScreen.cpp
|
||||
Window.cpp
|
||||
WindowBehaviour.cpp
|
||||
WindowList.cpp
|
||||
Workspace.cpp
|
||||
WorkspacesView.cpp
|
||||
|
||||
+28
-463
@@ -16,6 +16,7 @@
|
||||
#include "Decorator.h"
|
||||
#include "DecorManager.h"
|
||||
#include "Desktop.h"
|
||||
#include "DefaultWindowBehaviour.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "HWInterface.h"
|
||||
#include "MessagePrivate.h"
|
||||
@@ -39,7 +40,6 @@
|
||||
|
||||
// Toggle debug output
|
||||
//#define DEBUG_WINDOW
|
||||
//#define DEBUG_WINDOW_CLICK
|
||||
|
||||
#ifdef DEBUG_WINDOW
|
||||
# define STRACE(x) printf x
|
||||
@@ -47,12 +47,6 @@
|
||||
# define STRACE(x) ;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_WINDOW_CLICK
|
||||
# define STRACE_CLICK(x) printf x
|
||||
#else
|
||||
# define STRACE_CLICK(x) ;
|
||||
#endif
|
||||
|
||||
// IMPORTANT: nested LockSingleWindow()s are not supported (by MultiLocker)
|
||||
|
||||
using std::nothrow;
|
||||
@@ -96,25 +90,13 @@ Window::Window(const BRect& frame, const char *name,
|
||||
|
||||
fRegionPool(),
|
||||
|
||||
fIsClosing(false),
|
||||
fIsMinimizing(false),
|
||||
fIsZooming(false),
|
||||
fIsResizing(false),
|
||||
fIsSlidingTab(false),
|
||||
fIsDragging(false),
|
||||
fActivateOnMouseUp(false),
|
||||
|
||||
fWindowBehaviour(NULL),
|
||||
fDecorator(NULL),
|
||||
fTopView(NULL),
|
||||
fWindow(window),
|
||||
fDrawingEngine(drawingEngine),
|
||||
fDesktop(window->Desktop()),
|
||||
|
||||
fLastMousePosition(0.0f, 0.0f),
|
||||
fMouseMoveDistance(0.0f),
|
||||
fLastMoveTime(0),
|
||||
fLastSnapTime(0),
|
||||
|
||||
fCurrentUpdateSession(&fUpdateSessions[0]),
|
||||
fPendingUpdateSession(&fUpdateSessions[1]),
|
||||
fUpdateRequested(false),
|
||||
@@ -154,6 +136,8 @@ Window::Window(const BRect& frame, const char *name,
|
||||
&fMaxWidth, &fMaxHeight);
|
||||
}
|
||||
}
|
||||
fWindowBehaviour = new (std::nothrow)DefaultWindowBehaviour(this,
|
||||
fDecorator);
|
||||
|
||||
// do we need to change our size to let the decorator fit?
|
||||
// _ResizeBy() will adapt the frame for validity before resizing
|
||||
@@ -187,6 +171,7 @@ Window::~Window()
|
||||
delete fTopView;
|
||||
}
|
||||
|
||||
delete fWindowBehaviour;
|
||||
delete fDecorator;
|
||||
|
||||
delete fDrawingEngine;
|
||||
@@ -196,7 +181,7 @@ Window::~Window()
|
||||
status_t
|
||||
Window::InitCheck() const
|
||||
{
|
||||
if (!fDrawingEngine)
|
||||
if (!fDrawingEngine || !fWindowBehaviour)
|
||||
return B_NO_MEMORY;
|
||||
// TODO: anything else?
|
||||
return B_OK;
|
||||
@@ -775,9 +760,6 @@ Window::EnableUpdateRequests()
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static const bigtime_t kWindowActivationTimeout = 500000LL;
|
||||
|
||||
|
||||
void
|
||||
Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken)
|
||||
{
|
||||
@@ -787,136 +769,8 @@ Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken)
|
||||
if (!fBorderRegionValid)
|
||||
GetBorderRegion(&fBorderRegion);
|
||||
|
||||
int32 modifiers = _ExtractModifiers(message);
|
||||
bool inBorderRegion = fBorderRegion.Contains(where);
|
||||
bool windowModifier = (fFlags & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
|
||||
&& (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
|
||||
| B_SHIFT_KEY)) == (B_COMMAND_KEY | B_CONTROL_KEY);
|
||||
click_type action = CLICK_NONE;
|
||||
|
||||
if (windowModifier || inBorderRegion) {
|
||||
// clicking Window visible area
|
||||
|
||||
int32 buttons = _ExtractButtons(message);
|
||||
|
||||
if (inBorderRegion)
|
||||
action = _ActionFor(message, buttons, modifiers);
|
||||
else {
|
||||
if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
|
||||
action = CLICK_MOVE_TO_BACK;
|
||||
else if ((fFlags & B_NOT_MOVABLE) == 0 && fDecorator != NULL)
|
||||
action = CLICK_DRAG;
|
||||
else {
|
||||
// pass click on to the application
|
||||
windowModifier = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (windowModifier || inBorderRegion) {
|
||||
if (!desktopSettings.AcceptFirstClick()) {
|
||||
// Ignore clicks on decorator buttons if the
|
||||
// non-floating window doesn't have focus
|
||||
if (!IsFocus() && !IsFloating() && action != CLICK_MOVE_TO_BACK
|
||||
&& action != CLICK_RESIZE && action != CLICK_SLIDE_TAB)
|
||||
action = CLICK_DRAG;
|
||||
}
|
||||
|
||||
// set decorator internals
|
||||
switch (action) {
|
||||
case CLICK_CLOSE:
|
||||
fIsClosing = true;
|
||||
STRACE_CLICK(("===> CLICK_CLOSE\n"));
|
||||
break;
|
||||
|
||||
case CLICK_ZOOM:
|
||||
fIsZooming = true;
|
||||
STRACE_CLICK(("===> CLICK_ZOOM\n"));
|
||||
break;
|
||||
|
||||
case CLICK_MINIMIZE:
|
||||
if ((Flags() & B_NOT_MINIMIZABLE) == 0) {
|
||||
fIsMinimizing = true;
|
||||
STRACE_CLICK(("===> CLICK_MINIMIZE\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case CLICK_DRAG:
|
||||
fIsDragging = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_DRAG\n"));
|
||||
break;
|
||||
|
||||
case CLICK_RESIZE:
|
||||
fIsResizing = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_RESIZE\n"));
|
||||
break;
|
||||
|
||||
case CLICK_SLIDE_TAB:
|
||||
fIsSlidingTab = true;
|
||||
fLastMousePosition = where;
|
||||
STRACE_CLICK(("===> CLICK_SLIDE_TAB\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fDecorator != NULL) {
|
||||
// redraw decorator
|
||||
BRegion* visibleBorder = fRegionPool.GetRegion();
|
||||
GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming)
|
||||
fDecorator->SetZoom(true);
|
||||
else if (fIsClosing)
|
||||
fDecorator->SetClose(true);
|
||||
else if (fIsMinimizing)
|
||||
fDecorator->SetMinimize(true);
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
|
||||
fRegionPool.Recycle(visibleBorder);
|
||||
}
|
||||
|
||||
if (action == CLICK_MOVE_TO_BACK) {
|
||||
if (desktopSettings.MouseMode() == B_CLICK_TO_FOCUS_MOUSE) {
|
||||
bool covered = true;
|
||||
BRegion fullRegion;
|
||||
GetFullRegion(&fullRegion);
|
||||
if (fullRegion == VisibleRegion()) {
|
||||
// window is overlapped.
|
||||
covered = false;
|
||||
}
|
||||
if (this != fDesktop->FrontWindow() && covered)
|
||||
fDesktop->ActivateWindow(this);
|
||||
else
|
||||
fDesktop->SendWindowBehind(this);
|
||||
} else
|
||||
fDesktop->SendWindowBehind(this);
|
||||
} else {
|
||||
fDesktop->SetMouseEventWindow(this);
|
||||
|
||||
// activate window if in click to activate mode, else only focus it
|
||||
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE)
|
||||
fDesktop->ActivateWindow(this);
|
||||
else {
|
||||
fDesktop->SetFocusWindow(this);
|
||||
if (desktopSettings.MouseMode() == B_FOCUS_FOLLOWS_MOUSE
|
||||
&& (action == CLICK_DRAG || action == CLICK_RESIZE)) {
|
||||
fActivateOnMouseUp = true;
|
||||
fMouseMoveDistance = 0.0f;
|
||||
fLastMoveTime = system_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool eventEaten = fWindowBehaviour->MouseDown(message, where);
|
||||
if (!eventEaten) {
|
||||
// click was inside the window contents
|
||||
if (View* view = ViewAt(where)) {
|
||||
if (HasModal())
|
||||
@@ -957,71 +811,7 @@ Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken)
|
||||
void
|
||||
Window::MouseUp(BMessage* message, BPoint where, int32* _viewToken)
|
||||
{
|
||||
bool invalidate = false;
|
||||
if (fDecorator) {
|
||||
click_type action = _ActionFor(message);
|
||||
|
||||
// redraw decorator
|
||||
BRegion* visibleBorder = fRegionPool.GetRegion();
|
||||
GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming) {
|
||||
fIsZooming = false;
|
||||
fDecorator->SetZoom(false);
|
||||
if (action == CLICK_ZOOM) {
|
||||
invalidate = true;
|
||||
fWindow->NotifyZoom();
|
||||
}
|
||||
}
|
||||
if (fIsClosing) {
|
||||
fIsClosing = false;
|
||||
fDecorator->SetClose(false);
|
||||
if (action == CLICK_CLOSE) {
|
||||
invalidate = true;
|
||||
fWindow->NotifyQuitRequested();
|
||||
}
|
||||
}
|
||||
if (fIsMinimizing) {
|
||||
fIsMinimizing = false;
|
||||
fDecorator->SetMinimize(false);
|
||||
if (action == CLICK_MINIMIZE) {
|
||||
invalidate = true;
|
||||
fWindow->NotifyMinimize(true);
|
||||
}
|
||||
}
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
|
||||
fRegionPool.Recycle(visibleBorder);
|
||||
|
||||
int32 buttons;
|
||||
if (message->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = 0;
|
||||
|
||||
// if the primary mouse button is released, stop
|
||||
// dragging/resizing/sliding
|
||||
if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0) {
|
||||
fIsDragging = false;
|
||||
fIsResizing = false;
|
||||
fIsSlidingTab = false;
|
||||
}
|
||||
}
|
||||
|
||||
// in FFM mode, activate the window and bring it
|
||||
// to front in case this was a drag click but the
|
||||
// mouse was not moved
|
||||
if (fActivateOnMouseUp) {
|
||||
fActivateOnMouseUp = false;
|
||||
// on R5, there is a time window for this feature
|
||||
// ie, click and press too long, nothing will happen
|
||||
if (system_time() - fLastMoveTime < kWindowActivationTimeout)
|
||||
fDesktop->ActivateWindow(this);
|
||||
}
|
||||
fWindowBehaviour->MouseUp(message, where);
|
||||
|
||||
if (View* view = ViewAt(where)) {
|
||||
if (HasModal())
|
||||
@@ -1037,17 +827,6 @@ void
|
||||
Window::MouseMoved(BMessage *message, BPoint where, int32* _viewToken,
|
||||
bool isLatestMouseMoved, bool isFake)
|
||||
{
|
||||
#if 0
|
||||
if (fDecorator != NULL && fTopView != NULL) {
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(&VisibleRegion());
|
||||
|
||||
fTopView->MarkAt(engine, where);
|
||||
engine->UnlockParallelAccess();
|
||||
}
|
||||
#endif
|
||||
|
||||
View* view = ViewAt(where);
|
||||
if (view != NULL)
|
||||
*_viewToken = view->Token();
|
||||
@@ -1056,119 +835,7 @@ Window::MouseMoved(BMessage *message, BPoint where, int32* _viewToken,
|
||||
if (!isLatestMouseMoved)
|
||||
return;
|
||||
|
||||
// limit the rate at which "mouse moved" events
|
||||
// are handled that move or resize the window
|
||||
bigtime_t now = 0;
|
||||
if (fIsDragging || fIsResizing) {
|
||||
now = system_time();
|
||||
if (now - fLastMoveTime < 13333) {
|
||||
// TODO: add a "timed event" to query for
|
||||
// the then current mouse position
|
||||
return;
|
||||
}
|
||||
if (fActivateOnMouseUp) {
|
||||
if (now - fLastMoveTime >= kWindowActivationTimeout) {
|
||||
// This click is too long already for window activation.
|
||||
fActivateOnMouseUp = false;
|
||||
}
|
||||
} else
|
||||
fLastMoveTime = now;
|
||||
}
|
||||
|
||||
if (fDecorator) {
|
||||
BRegion* visibleBorder = fRegionPool.GetRegion();
|
||||
GetBorderRegion(visibleBorder);
|
||||
visibleBorder->IntersectWith(&VisibleRegion());
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
if (fIsZooming) {
|
||||
fDecorator->SetZoom(_ActionFor(message) == CLICK_ZOOM);
|
||||
} else if (fIsClosing) {
|
||||
fDecorator->SetClose(_ActionFor(message) == CLICK_CLOSE);
|
||||
} else if (fIsMinimizing) {
|
||||
fDecorator->SetMinimize(_ActionFor(message) == CLICK_MINIMIZE);
|
||||
}
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
fRegionPool.Recycle(visibleBorder);
|
||||
}
|
||||
|
||||
BPoint delta = where - fLastMousePosition;
|
||||
// NOTE: "delta" is later used to change fLastMousePosition.
|
||||
// If for some reason no change should take effect, delta
|
||||
// is to be set to (0, 0) so that fLastMousePosition is not
|
||||
// adjusted. This way the relative mouse position to the
|
||||
// item being changed (border during resizing, tab during
|
||||
// sliding...) stays fixed when the mouse is moved so that
|
||||
// changes are taking effect again.
|
||||
|
||||
// If the window was moved enough, it doesn't come to
|
||||
// the front in FFM mode when the mouse is released.
|
||||
if (fActivateOnMouseUp) {
|
||||
fMouseMoveDistance += delta.x * delta.x + delta.y * delta.y;
|
||||
if (fMouseMoveDistance > 16.0f)
|
||||
fActivateOnMouseUp = false;
|
||||
else
|
||||
delta = B_ORIGIN;
|
||||
}
|
||||
|
||||
// moving
|
||||
if (fIsDragging) {
|
||||
if (!(Flags() & B_NOT_MOVABLE)) {
|
||||
BPoint oldLeftTop = fFrame.LeftTop();
|
||||
|
||||
_AlterDeltaForSnap(delta, now);
|
||||
fDesktop->MoveWindowBy(this, delta.x, delta.y);
|
||||
|
||||
// constrain delta to true change in position
|
||||
delta = fFrame.LeftTop() - oldLeftTop;
|
||||
} else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
// resizing
|
||||
if (fIsResizing) {
|
||||
if (!(Flags() & B_NOT_RESIZABLE)) {
|
||||
if (Flags() & B_NOT_V_RESIZABLE)
|
||||
delta.y = 0;
|
||||
if (Flags() & B_NOT_H_RESIZABLE)
|
||||
delta.x = 0;
|
||||
|
||||
BPoint oldRightBottom = fFrame.RightBottom();
|
||||
|
||||
fDesktop->ResizeWindowBy(this, delta.x, delta.y);
|
||||
|
||||
// constrain delta to true change in size
|
||||
delta = fFrame.RightBottom() - oldRightBottom;
|
||||
} else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
// sliding tab
|
||||
if (fIsSlidingTab) {
|
||||
float loc = TabLocation();
|
||||
// TODO: change to [0:1]
|
||||
loc += delta.x;
|
||||
if (fDesktop->SetWindowTabLocation(this, loc))
|
||||
delta.y = 0;
|
||||
else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
|
||||
// NOTE: fLastMousePosition is currently only
|
||||
// used for window moving/resizing/sliding the tab
|
||||
fLastMousePosition += delta;
|
||||
|
||||
// change focus in FFM mode
|
||||
DesktopSettings desktopSettings(fDesktop);
|
||||
if (desktopSettings.FocusFollowsMouse()
|
||||
&& !IsFocus() && !(Flags() & B_AVOID_FOCUS)) {
|
||||
// If the mouse move is a fake one, we set the focus to NULL, which
|
||||
// will cause the window that had focus last to retrieve it again - this
|
||||
// makes FFM much nicer to use with the keyboard.
|
||||
fDesktop->SetFocusWindow(isFake ? NULL : this);
|
||||
}
|
||||
fWindowBehaviour->MouseMoved(message, where, isFake);
|
||||
|
||||
// mouse cursor
|
||||
|
||||
@@ -1182,77 +849,6 @@ Window::MouseMoved(BMessage *message, BPoint where, int32* _viewToken,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Window::_AlterDeltaForSnap(BPoint& delta, bigtime_t now)
|
||||
{
|
||||
// Alter the delta (which is a proposed offset used while dragging a
|
||||
// window) so that the frame of the window 'snaps' to the edges of the
|
||||
// screen.
|
||||
|
||||
const bigtime_t kSnappingDuration = 1500000LL;
|
||||
const bigtime_t kSnappingPause = 3000000LL;
|
||||
const float kSnapDistance = 8.0f;
|
||||
|
||||
if (now - fLastSnapTime > kSnappingDuration
|
||||
&& now - fLastSnapTime < kSnappingPause) {
|
||||
// Maintain a pause between snapping.
|
||||
return;
|
||||
}
|
||||
|
||||
BRect frame = fFrame;
|
||||
BPoint offsetWithinFrame;
|
||||
// TODO: Perhaps obtain the usable area (not covered by the Deskbar)?
|
||||
BRect screenFrame = Screen()->Frame();
|
||||
|
||||
if (fDecorator) {
|
||||
BRegion reg;
|
||||
fDecorator->GetFootprint(®);
|
||||
frame = reg.Frame();
|
||||
offsetWithinFrame.x = fFrame.left - frame.left;
|
||||
offsetWithinFrame.y = fFrame.top - frame.top;
|
||||
}
|
||||
|
||||
frame.OffsetBy(delta);
|
||||
|
||||
float leftDist = fabs(frame.left - screenFrame.left);
|
||||
float topDist = fabs(frame.top - screenFrame.top);
|
||||
float rightDist = fabs(frame.right - screenFrame.right);
|
||||
float bottomDist = fabs(frame.bottom - screenFrame.bottom);
|
||||
|
||||
bool snapped = false;
|
||||
if (leftDist < kSnapDistance || rightDist < kSnapDistance) {
|
||||
snapped = true;
|
||||
if (leftDist < rightDist) {
|
||||
frame.right -= frame.left;
|
||||
frame.left = 0.0f;
|
||||
} else {
|
||||
frame.left -= frame.right - screenFrame.right;
|
||||
frame.right = screenFrame.right;
|
||||
}
|
||||
}
|
||||
|
||||
if (topDist < kSnapDistance || bottomDist < kSnapDistance) {
|
||||
snapped = true;
|
||||
if (topDist < bottomDist) {
|
||||
frame.bottom -= frame.top;
|
||||
frame.top = 0.0f;
|
||||
} else {
|
||||
frame.top -= frame.bottom - screenFrame.bottom;
|
||||
frame.bottom = screenFrame.bottom;
|
||||
}
|
||||
}
|
||||
if (snapped && now - fLastSnapTime > kSnappingPause)
|
||||
fLastSnapTime = now;
|
||||
|
||||
|
||||
frame.top += offsetWithinFrame.y;
|
||||
frame.left += offsetWithinFrame.x;
|
||||
|
||||
delta.y = frame.top - fFrame.top;
|
||||
delta.x = frame.left - fFrame.left;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -1375,6 +971,24 @@ Window::IsVisible() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::IsDragging() const
|
||||
{
|
||||
if (!fWindowBehaviour)
|
||||
return false;
|
||||
return fWindowBehaviour->IsDragging();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::IsResizing() const
|
||||
{
|
||||
if (!fWindowBehaviour)
|
||||
return false;
|
||||
return fWindowBehaviour->IsResizing();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Window::SetSizeLimits(int32 minWidth, int32 maxWidth, int32 minHeight,
|
||||
int32 maxHeight)
|
||||
@@ -2226,53 +1840,6 @@ Window::_UpdateContentRegion()
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Window::_ExtractButtons(const BMessage* message) const
|
||||
{
|
||||
int32 buttons;
|
||||
if (message->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = 0;
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Window::_ExtractModifiers(const BMessage* message) const
|
||||
{
|
||||
int32 modifiers;
|
||||
if (message->FindInt32("modifiers", &modifiers) != B_OK)
|
||||
modifiers = 0;
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
click_type
|
||||
Window::_ActionFor(const BMessage* message) const
|
||||
{
|
||||
if (fDecorator == NULL)
|
||||
return CLICK_NONE;
|
||||
|
||||
int32 buttons = _ExtractButtons(message);
|
||||
int32 modifiers = _ExtractModifiers(message);
|
||||
return _ActionFor(message, buttons, modifiers);
|
||||
}
|
||||
|
||||
|
||||
click_type
|
||||
Window::_ActionFor(const BMessage* message, int32 buttons,
|
||||
int32 modifiers) const
|
||||
{
|
||||
if (fDecorator == NULL)
|
||||
return CLICK_NONE;
|
||||
|
||||
BPoint where;
|
||||
if (message->FindPoint("where", &where) != B_OK)
|
||||
return CLICK_NONE;
|
||||
|
||||
return fDecorator->Clicked(where, buttons, modifiers);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Window::_ObeySizeLimits()
|
||||
{
|
||||
@@ -2370,5 +1937,3 @@ Window::UpdateSession::AddCause(uint8 cause)
|
||||
{
|
||||
fCause |= cause;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ class Desktop;
|
||||
class DrawingEngine;
|
||||
class EventDispatcher;
|
||||
class Screen;
|
||||
class WindowBehaviour;
|
||||
class WorkspacesView;
|
||||
|
||||
// TODO: move this into a proper place
|
||||
@@ -169,10 +170,12 @@ public:
|
||||
|
||||
void SetCurrentWorkspace(int32 index)
|
||||
{ fCurrentWorkspace = index; }
|
||||
int32 CurrentWorkspace() const
|
||||
{ return fCurrentWorkspace; }
|
||||
bool IsVisible() const;
|
||||
|
||||
bool IsDragging() const { return fIsDragging; }
|
||||
bool IsResizing() const { return fIsResizing; }
|
||||
bool IsDragging() const;
|
||||
bool IsResizing() const;
|
||||
|
||||
void SetSizeLimits(int32 minWidth, int32 maxWidth,
|
||||
int32 minHeight, int32 maxHeight);
|
||||
@@ -244,6 +247,7 @@ public:
|
||||
static uint32 ValidWindowFlags();
|
||||
static uint32 ValidWindowFlags(window_feel feel);
|
||||
|
||||
BRegion& BorderRegion() { return fBorderRegion; }
|
||||
protected:
|
||||
void _ShiftPartOfRegion(BRegion* region,
|
||||
BRegion* regionToShift, int32 xOffset,
|
||||
@@ -260,20 +264,9 @@ protected:
|
||||
|
||||
void _UpdateContentRegion();
|
||||
|
||||
int32 _ExtractButtons(
|
||||
const BMessage* message) const;
|
||||
int32 _ExtractModifiers(
|
||||
const BMessage* message) const;
|
||||
click_type _ActionFor(const BMessage* message) const;
|
||||
click_type _ActionFor(const BMessage* message,
|
||||
int32 buttons, int32 modifiers) const;
|
||||
|
||||
void _ObeySizeLimits();
|
||||
void _PropagatePosition();
|
||||
|
||||
void _AlterDeltaForSnap(BPoint& delta,
|
||||
bigtime_t now);
|
||||
|
||||
BString fTitle;
|
||||
// TODO: no fp rects anywhere
|
||||
BRect fFrame;
|
||||
@@ -309,26 +302,13 @@ protected:
|
||||
|
||||
BObjectList<Window> fSubsets;
|
||||
|
||||
// TODO: remove those some day (let the decorator handle that stuff)
|
||||
bool fIsClosing : 1;
|
||||
bool fIsMinimizing : 1;
|
||||
bool fIsZooming : 1;
|
||||
bool fIsResizing : 1;
|
||||
bool fIsSlidingTab : 1;
|
||||
bool fIsDragging : 1;
|
||||
bool fActivateOnMouseUp : 1;
|
||||
|
||||
WindowBehaviour* fWindowBehaviour;
|
||||
::Decorator* fDecorator;
|
||||
View* fTopView;
|
||||
::ServerWindow* fWindow;
|
||||
DrawingEngine* fDrawingEngine;
|
||||
::Desktop* fDesktop;
|
||||
|
||||
BPoint fLastMousePosition;
|
||||
float fMouseMoveDistance;
|
||||
bigtime_t fLastMoveTime;
|
||||
bigtime_t fLastSnapTime;
|
||||
|
||||
// The synchronization, which client drawing commands
|
||||
// belong to the redraw of which dirty region is handled
|
||||
// through an UpdateSession. When the client has
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "WindowBehaviour.h"
|
||||
|
||||
|
||||
WindowBehaviour::WindowBehaviour()
|
||||
:
|
||||
fIsResizing(false),
|
||||
fIsDragging(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
WindowBehaviour::~WindowBehaviour()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef WINDOW_BEHAVIOUR_H
|
||||
#define WINDOW_BEHAVIOUR_H
|
||||
|
||||
|
||||
#include <Region.h>
|
||||
|
||||
|
||||
class BMessage;
|
||||
|
||||
|
||||
class WindowBehaviour
|
||||
{
|
||||
public:
|
||||
WindowBehaviour();
|
||||
virtual ~WindowBehaviour();
|
||||
|
||||
//! \return true if event was a WindowBehaviour event and should be discard
|
||||
virtual bool MouseDown(BMessage* message, BPoint where) = 0;
|
||||
virtual void MouseUp(BMessage* message, BPoint where) = 0;
|
||||
virtual void MouseMoved(BMessage *message, BPoint where,
|
||||
bool isFake) = 0;
|
||||
|
||||
bool IsDragging() const { return fIsDragging; }
|
||||
bool IsResizing() const { return fIsResizing; }
|
||||
|
||||
protected:
|
||||
bool fIsResizing : 1;
|
||||
bool fIsDragging : 1;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user