* Refactored the MouseMoved(), MouseUp(), and part of the MouseDown() code
into newly introduced state classes. * Fixed the right-click-while dragging behavior, I broke in r39602. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39608 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -34,51 +34,484 @@
|
|||||||
static const bigtime_t kWindowActivationTimeout = 500000LL;
|
static const bigtime_t kWindowActivationTimeout = 500000LL;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - State
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::State {
|
||||||
|
State(DefaultWindowBehaviour& behavior)
|
||||||
|
:
|
||||||
|
fBehavior(behavior),
|
||||||
|
fWindow(behavior.fWindow),
|
||||||
|
fDesktop(behavior.fDesktop)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~State()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void EnterState(State* previousState)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MouseDown(BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseUp(BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpateFFMFocus(bool isFake)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DefaultWindowBehaviour& fBehavior;
|
||||||
|
Window* fWindow;
|
||||||
|
Desktop* fDesktop;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - MouseTrackingState
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::MouseTrackingState : State {
|
||||||
|
MouseTrackingState(DefaultWindowBehaviour& behavior, BPoint where,
|
||||||
|
bool activateOnMouseUp, bool minimizeCheckOnMouseUp)
|
||||||
|
:
|
||||||
|
State(behavior),
|
||||||
|
fActivateOnMouseUp(activateOnMouseUp),
|
||||||
|
fMinimizeCheckOnMouseUp(minimizeCheckOnMouseUp),
|
||||||
|
fLastMousePosition(where),
|
||||||
|
fMouseMoveDistance(0),
|
||||||
|
fLastMoveTime(system_time())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseUp(BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
// ignore, if it's not the primary mouse button
|
||||||
|
int32 buttons = message->FindInt32("buttons");
|
||||||
|
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fMinimizeCheckOnMouseUp) {
|
||||||
|
// If the modifiers haven't changed in the meantime and not too
|
||||||
|
// much time has elapsed, we're supposed to minimize the window.
|
||||||
|
fMinimizeCheckOnMouseUp = false;
|
||||||
|
if (message->FindInt32("modifiers") == fBehavior.fLastModifiers
|
||||||
|
&& (fWindow->Flags() & B_NOT_MINIMIZABLE) == 0
|
||||||
|
&& system_time() - fLastMoveTime
|
||||||
|
< kWindowActivationTimeout) {
|
||||||
|
fWindow->ServerWindow()->NotifyMinimize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
fBehavior._NextState(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
|
||||||
|
{
|
||||||
|
// Limit the rate at which "mouse moved" events are handled that move
|
||||||
|
// or resize the window. At the moment this affects also tab sliding,
|
||||||
|
// but 1/75 s is a pretty fine granularity anyway, so don't bother.
|
||||||
|
bigtime_t now = system_time();
|
||||||
|
if (now - fLastMoveTime < 13333) {
|
||||||
|
// TODO: add a "timed event" to query for
|
||||||
|
// the then current mouse position
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fActivateOnMouseUp || fMinimizeCheckOnMouseUp) {
|
||||||
|
if (now - fLastMoveTime >= kWindowActivationTimeout) {
|
||||||
|
// This click is too long already for window activation/
|
||||||
|
// minimizing.
|
||||||
|
fActivateOnMouseUp = false;
|
||||||
|
fMinimizeCheckOnMouseUp = false;
|
||||||
|
fLastMoveTime = now;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
fLastMoveTime = now;
|
||||||
|
|
||||||
|
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 || fMinimizeCheckOnMouseUp) {
|
||||||
|
fMouseMoveDistance += delta.x * delta.x + delta.y * delta.y;
|
||||||
|
if (fMouseMoveDistance > 16.0f) {
|
||||||
|
fActivateOnMouseUp = false;
|
||||||
|
fMinimizeCheckOnMouseUp = false;
|
||||||
|
} else
|
||||||
|
delta = B_ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform the action (this also updates the delta)
|
||||||
|
MouseMovedAction(delta, now);
|
||||||
|
|
||||||
|
// set the new mouse position
|
||||||
|
fLastMousePosition += delta;
|
||||||
|
|
||||||
|
// update the FFM focus
|
||||||
|
UpateFFMFocus(isFake);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMovedAction(BPoint& delta, bigtime_t now) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool fActivateOnMouseUp : 1;
|
||||||
|
bool fMinimizeCheckOnMouseUp : 1;
|
||||||
|
|
||||||
|
BPoint fLastMousePosition;
|
||||||
|
float fMouseMoveDistance;
|
||||||
|
bigtime_t fLastMoveTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DragState
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::DragState : MouseTrackingState {
|
||||||
|
DragState(DefaultWindowBehaviour& behavior, BPoint where,
|
||||||
|
bool activateOnMouseUp, bool minimizeCheckOnMouseUp)
|
||||||
|
:
|
||||||
|
MouseTrackingState(behavior, where, activateOnMouseUp,
|
||||||
|
minimizeCheckOnMouseUp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MouseDown(BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
// right-click while dragging shall bring the window to front
|
||||||
|
int32 buttons = message->FindInt32("buttons");
|
||||||
|
if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
|
||||||
|
if (fWindow == fDesktop->BackWindow())
|
||||||
|
fDesktop->ActivateWindow(fWindow);
|
||||||
|
else
|
||||||
|
fDesktop->SendWindowBehind(fWindow);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseTrackingState::MouseDown(message, where);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _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();
|
||||||
|
|
||||||
|
Decorator* decorator = fWindow->Decorator();
|
||||||
|
if (decorator) {
|
||||||
|
frame = decorator->GetFootprint().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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bigtime_t fLastSnapTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ResizeState
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::ResizeState : MouseTrackingState {
|
||||||
|
ResizeState(DefaultWindowBehaviour& behavior, BPoint where,
|
||||||
|
bool activateOnMouseUp)
|
||||||
|
:
|
||||||
|
MouseTrackingState(behavior, where, activateOnMouseUp, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - SlideTabState
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::SlideTabState : MouseTrackingState {
|
||||||
|
SlideTabState(DefaultWindowBehaviour& behavior, BPoint where)
|
||||||
|
:
|
||||||
|
MouseTrackingState(behavior, where, false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DecoratorButtonState
|
||||||
|
|
||||||
|
|
||||||
|
struct DefaultWindowBehaviour::DecoratorButtonState : State {
|
||||||
|
DecoratorButtonState(DefaultWindowBehaviour& behavior, Region button)
|
||||||
|
:
|
||||||
|
State(behavior),
|
||||||
|
fButton(button)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void EnterState(State* previousState)
|
||||||
|
{
|
||||||
|
_RedrawDecorator(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseUp(BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
// ignore, if it's not the primary mouse button
|
||||||
|
int32 buttons = message->FindInt32("buttons");
|
||||||
|
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// redraw the decorator
|
||||||
|
if (Decorator* decorator = fWindow->Decorator()) {
|
||||||
|
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
||||||
|
fWindow->GetBorderRegion(visibleBorder);
|
||||||
|
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
||||||
|
|
||||||
|
DrawingEngine* engine = decorator->GetDrawingEngine();
|
||||||
|
engine->LockParallelAccess();
|
||||||
|
engine->ConstrainClippingRegion(visibleBorder);
|
||||||
|
|
||||||
|
switch (fButton) {
|
||||||
|
case REGION_CLOSE_BUTTON:
|
||||||
|
decorator->SetClose(false);
|
||||||
|
if (fBehavior._RegionFor(message) == REGION_CLOSE_BUTTON)
|
||||||
|
fWindow->ServerWindow()->NotifyQuitRequested();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGION_ZOOM_BUTTON:
|
||||||
|
decorator->SetZoom(false);
|
||||||
|
if (fBehavior._RegionFor(message) == REGION_ZOOM_BUTTON)
|
||||||
|
fWindow->ServerWindow()->NotifyZoom();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGION_MINIMIZE_BUTTON:
|
||||||
|
decorator->SetMinimize(false);
|
||||||
|
if (fBehavior._RegionFor(message) == REGION_MINIMIZE_BUTTON)
|
||||||
|
fWindow->ServerWindow()->NotifyMinimize(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine->UnlockParallelAccess();
|
||||||
|
|
||||||
|
fWindow->RegionPool()->Recycle(visibleBorder);
|
||||||
|
}
|
||||||
|
|
||||||
|
fBehavior._NextState(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
|
||||||
|
{
|
||||||
|
_RedrawDecorator(message);
|
||||||
|
|
||||||
|
// update the FFM focus
|
||||||
|
UpateFFMFocus(isFake);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _RedrawDecorator(const BMessage* message)
|
||||||
|
{
|
||||||
|
if (Decorator* decorator = fWindow->Decorator()) {
|
||||||
|
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
||||||
|
fWindow->GetBorderRegion(visibleBorder);
|
||||||
|
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
||||||
|
|
||||||
|
DrawingEngine* engine = decorator->GetDrawingEngine();
|
||||||
|
engine->LockParallelAccess();
|
||||||
|
engine->ConstrainClippingRegion(visibleBorder);
|
||||||
|
|
||||||
|
Region hitRegion = message != NULL
|
||||||
|
? fBehavior._RegionFor(message) : fButton;
|
||||||
|
|
||||||
|
switch (fButton) {
|
||||||
|
case REGION_CLOSE_BUTTON:
|
||||||
|
decorator->SetClose(hitRegion == REGION_CLOSE_BUTTON);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGION_ZOOM_BUTTON:
|
||||||
|
decorator->SetZoom(hitRegion == REGION_ZOOM_BUTTON);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGION_MINIMIZE_BUTTON:
|
||||||
|
decorator->SetMinimize(hitRegion == REGION_MINIMIZE_BUTTON);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine->UnlockParallelAccess();
|
||||||
|
fWindow->RegionPool()->Recycle(visibleBorder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Region fButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DefaultWindowBehaviour
|
||||||
|
|
||||||
|
|
||||||
DefaultWindowBehaviour::DefaultWindowBehaviour(Window* window)
|
DefaultWindowBehaviour::DefaultWindowBehaviour(Window* window)
|
||||||
:
|
:
|
||||||
fWindow(window),
|
fWindow(window),
|
||||||
|
fDesktop(window->Desktop()),
|
||||||
fIsClosing(false),
|
fState(NULL),
|
||||||
fIsMinimizing(false),
|
|
||||||
fIsZooming(false),
|
|
||||||
fIsSlidingTab(false),
|
|
||||||
fActivateOnMouseUp(false),
|
|
||||||
fMinimizeCheckOnMouseUp(false),
|
|
||||||
|
|
||||||
fLastMousePosition(0.0f, 0.0f),
|
|
||||||
fMouseMoveDistance(0.0f),
|
|
||||||
fLastMoveTime(0),
|
|
||||||
fLastSnapTime(0),
|
|
||||||
fLastModifiers(0),
|
fLastModifiers(0),
|
||||||
fResetClickCount(0)
|
fResetClickCount(0)
|
||||||
{
|
{
|
||||||
fDesktop = fWindow->Desktop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DefaultWindowBehaviour::~DefaultWindowBehaviour()
|
DefaultWindowBehaviour::~DefaultWindowBehaviour()
|
||||||
{
|
{
|
||||||
|
delete fState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
||||||
{
|
{
|
||||||
Decorator* decorator = fWindow->Decorator();
|
|
||||||
|
|
||||||
bool inBorderRegion = false;
|
|
||||||
if (decorator != NULL)
|
|
||||||
inBorderRegion = decorator->GetFootprint().Contains(where);
|
|
||||||
|
|
||||||
int32 modifiers = message->FindInt32("modifiers");
|
|
||||||
bool windowModifier = _IsWindowModifier(modifiers);
|
|
||||||
|
|
||||||
// Get the click count and reset it, if the modifiers changed in the
|
// Get the click count and reset it, if the modifiers changed in the
|
||||||
// meantime.
|
// meantime.
|
||||||
// TODO: This should be done in a better place (e.g. the input server). It
|
// TODO: This should be done in a better place (e.g. the input server). It
|
||||||
// should also reset clicks after mouse movement (which we don't do here
|
// should also reset clicks after mouse movement (which we don't do here
|
||||||
// either -- though that's probably acceptable).
|
// either -- though that's probably acceptable).
|
||||||
int32 clickCount = message->FindInt32("clicks");
|
int32 clickCount = message->FindInt32("clicks");
|
||||||
|
int32 modifiers = message->FindInt32("modifiers");
|
||||||
if (clickCount <= 1) {
|
if (clickCount <= 1) {
|
||||||
fResetClickCount = 0;
|
fResetClickCount = 0;
|
||||||
} else if (modifiers != fLastModifiers
|
} else if (modifiers != fLastModifiers
|
||||||
@@ -89,9 +522,23 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
|||||||
clickCount -= fResetClickCount;
|
clickCount -= fResetClickCount;
|
||||||
fLastModifiers = modifiers;
|
fLastModifiers = modifiers;
|
||||||
|
|
||||||
|
// if a state is active, let it do the job
|
||||||
|
if (fState != NULL)
|
||||||
|
return fState->MouseDown(message, where);
|
||||||
|
|
||||||
|
// No state active yet -- determine the click region and decide what to do.
|
||||||
|
|
||||||
|
Decorator* decorator = fWindow->Decorator();
|
||||||
|
|
||||||
Region hitRegion = REGION_NONE;
|
Region hitRegion = REGION_NONE;
|
||||||
click_type action = CLICK_NONE;
|
click_type action = CLICK_NONE;
|
||||||
|
|
||||||
|
bool inBorderRegion = false;
|
||||||
|
if (decorator != NULL)
|
||||||
|
inBorderRegion = decorator->GetFootprint().Contains(where);
|
||||||
|
|
||||||
|
bool windowModifier = _IsWindowModifier(modifiers);
|
||||||
|
|
||||||
if (windowModifier || inBorderRegion) {
|
if (windowModifier || inBorderRegion) {
|
||||||
// click on the window decorator or we have the window modifier keys
|
// click on the window decorator or we have the window modifier keys
|
||||||
// held
|
// held
|
||||||
@@ -184,94 +631,57 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
|||||||
action = CLICK_DRAG;
|
action = CLICK_DRAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set decorator internals
|
bool activateOnMouseUp = false;
|
||||||
|
if (action != CLICK_MOVE_TO_BACK) {
|
||||||
|
// 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);
|
||||||
|
activateOnMouseUp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch to the new state
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CLICK_CLOSE:
|
case CLICK_CLOSE:
|
||||||
fIsClosing = true;
|
|
||||||
STRACE_CLICK(("===> CLICK_CLOSE\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLICK_ZOOM:
|
case CLICK_ZOOM:
|
||||||
fIsZooming = true;
|
|
||||||
STRACE_CLICK(("===> CLICK_ZOOM\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLICK_MINIMIZE:
|
case CLICK_MINIMIZE:
|
||||||
if ((fWindow->Flags() & B_NOT_MINIMIZABLE) == 0) {
|
_NextState(
|
||||||
fIsMinimizing = true;
|
new (std::nothrow) DecoratorButtonState(*this, hitRegion));
|
||||||
STRACE_CLICK(("===> CLICK_MINIMIZE\n"));
|
STRACE_CLICK(("===> CLICK_CLOSE/ZOOM/MINIMIZE\n"));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLICK_DRAG:
|
case CLICK_DRAG:
|
||||||
fIsDragging = true;
|
_NextState(new (std::nothrow) DragState(*this, where,
|
||||||
fLastMousePosition = where;
|
activateOnMouseUp, clickCount == 2));
|
||||||
STRACE_CLICK(("===> CLICK_DRAG\n"));
|
STRACE_CLICK(("===> CLICK_DRAG\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLICK_RESIZE:
|
case CLICK_RESIZE:
|
||||||
fIsResizing = true;
|
_NextState(new (std::nothrow) ResizeState(*this, where,
|
||||||
fLastMousePosition = where;
|
activateOnMouseUp));
|
||||||
STRACE_CLICK(("===> CLICK_RESIZE\n"));
|
STRACE_CLICK(("===> CLICK_RESIZE\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLICK_SLIDE_TAB:
|
case CLICK_SLIDE_TAB:
|
||||||
fIsSlidingTab = true;
|
_NextState(new (std::nothrow) SlideTabState(*this, where));
|
||||||
fLastMousePosition = where;
|
|
||||||
STRACE_CLICK(("===> CLICK_SLIDE_TAB\n"));
|
STRACE_CLICK(("===> CLICK_SLIDE_TAB\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLICK_MOVE_TO_BACK:
|
||||||
|
fDesktop->SendWindowBehind(fWindow);
|
||||||
|
STRACE_CLICK(("===> CLICK_MOVE_TO_BACK\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decorator != NULL) {
|
// If we have a state now, it surely wants all further mouse events.
|
||||||
// redraw decorator
|
if (fState != NULL)
|
||||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
|
||||||
fWindow->GetBorderRegion(visibleBorder);
|
|
||||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
|
||||||
|
|
||||||
DrawingEngine* engine = decorator->GetDrawingEngine();
|
|
||||||
engine->LockParallelAccess();
|
|
||||||
engine->ConstrainClippingRegion(visibleBorder);
|
|
||||||
|
|
||||||
if (fIsZooming)
|
|
||||||
decorator->SetZoom(true);
|
|
||||||
else if (fIsClosing)
|
|
||||||
decorator->SetClose(true);
|
|
||||||
else if (fIsMinimizing)
|
|
||||||
decorator->SetMinimize(true);
|
|
||||||
|
|
||||||
engine->UnlockParallelAccess();
|
|
||||||
|
|
||||||
fWindow->RegionPool()->Recycle(visibleBorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == CLICK_MOVE_TO_BACK) {
|
|
||||||
if (!fIsDragging || fWindow != fDesktop->BackWindow())
|
|
||||||
fDesktop->SendWindowBehind(fWindow);
|
|
||||||
else
|
|
||||||
fDesktop->ActivateWindow(fWindow);
|
|
||||||
} else {
|
|
||||||
fDesktop->SetMouseEventWindow(fWindow);
|
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 (action == CLICK_DRAG || action == CLICK_RESIZE)
|
|
||||||
fActivateOnMouseUp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fIsDragging && clickCount == 2)
|
|
||||||
fMinimizeCheckOnMouseUp = true;
|
|
||||||
|
|
||||||
fMouseMoveDistance = 0.0f;
|
|
||||||
fLastMoveTime = system_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,207 +689,16 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
|||||||
void
|
void
|
||||||
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
|
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
|
||||||
{
|
{
|
||||||
Decorator* decorator = fWindow->Decorator();
|
if (fState != NULL)
|
||||||
|
fState->MouseUp(message, where);
|
||||||
int32 buttons = message->FindInt32("buttons");
|
|
||||||
|
|
||||||
if (decorator != NULL) {
|
|
||||||
// redraw decorator
|
|
||||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
|
||||||
fWindow->GetBorderRegion(visibleBorder);
|
|
||||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
|
||||||
|
|
||||||
DrawingEngine* engine = decorator->GetDrawingEngine();
|
|
||||||
engine->LockParallelAccess();
|
|
||||||
engine->ConstrainClippingRegion(visibleBorder);
|
|
||||||
|
|
||||||
if (fIsZooming) {
|
|
||||||
fIsZooming = false;
|
|
||||||
decorator->SetZoom(false);
|
|
||||||
if (_RegionFor(message) == REGION_ZOOM_BUTTON)
|
|
||||||
fWindow->ServerWindow()->NotifyZoom();
|
|
||||||
}
|
|
||||||
if (fIsClosing) {
|
|
||||||
fIsClosing = false;
|
|
||||||
decorator->SetClose(false);
|
|
||||||
if (_RegionFor(message) == REGION_CLOSE_BUTTON)
|
|
||||||
fWindow->ServerWindow()->NotifyQuitRequested();
|
|
||||||
}
|
|
||||||
if (fIsMinimizing) {
|
|
||||||
fIsMinimizing = false;
|
|
||||||
decorator->SetMinimize(false);
|
|
||||||
if (_RegionFor(message) == REGION_MINIMIZE_BUTTON)
|
|
||||||
fWindow->ServerWindow()->NotifyMinimize(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
engine->UnlockParallelAccess();
|
|
||||||
|
|
||||||
fWindow->RegionPool()->Recycle(visibleBorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the primary mouse button is released, stop
|
|
||||||
// dragging/resizing/sliding
|
|
||||||
if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0) {
|
|
||||||
if (fMinimizeCheckOnMouseUp) {
|
|
||||||
// If the modifiers haven't changed in the meantime and not too
|
|
||||||
// much time has elapsed, we're supposed to minimize the window.
|
|
||||||
fMinimizeCheckOnMouseUp = false;
|
|
||||||
if (message->FindInt32("modifiers") == fLastModifiers
|
|
||||||
&& (fWindow->Flags() & B_NOT_MINIMIZABLE) == 0
|
|
||||||
&& system_time() - fLastMoveTime < kWindowActivationTimeout) {
|
|
||||||
fWindow->ServerWindow()->NotifyMinimize(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fIsDragging = false;
|
|
||||||
fIsResizing = false;
|
|
||||||
fIsSlidingTab = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DefaultWindowBehaviour::MouseMoved(BMessage *message, BPoint where, bool isFake)
|
DefaultWindowBehaviour::MouseMoved(BMessage *message, BPoint where, bool isFake)
|
||||||
{
|
{
|
||||||
Decorator* decorator = fWindow->Decorator();
|
if (fState != NULL)
|
||||||
|
fState->MouseMoved(message, where, isFake);
|
||||||
#if 0
|
|
||||||
if (decorator != NULL && fWindow->TopView() != NULL) {
|
|
||||||
DrawingEngine* engine = decorator->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 || fMinimizeCheckOnMouseUp) {
|
|
||||||
if (now - fLastMoveTime >= kWindowActivationTimeout) {
|
|
||||||
// This click is too long already for window activation/
|
|
||||||
// minimizing.
|
|
||||||
fActivateOnMouseUp = false;
|
|
||||||
fMinimizeCheckOnMouseUp = false;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
fLastMoveTime = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decorator != NULL) {
|
|
||||||
BRegion* visibleBorder = fWindow->RegionPool()->GetRegion();
|
|
||||||
fWindow->GetBorderRegion(visibleBorder);
|
|
||||||
visibleBorder->IntersectWith(&fWindow->VisibleRegion());
|
|
||||||
|
|
||||||
DrawingEngine* engine = decorator->GetDrawingEngine();
|
|
||||||
engine->LockParallelAccess();
|
|
||||||
engine->ConstrainClippingRegion(visibleBorder);
|
|
||||||
|
|
||||||
Region hitRegion = _RegionFor(message);
|
|
||||||
|
|
||||||
if (fIsZooming)
|
|
||||||
decorator->SetZoom(hitRegion == REGION_ZOOM_BUTTON);
|
|
||||||
else if (fIsClosing)
|
|
||||||
decorator->SetClose(hitRegion == REGION_CLOSE_BUTTON);
|
|
||||||
else if (fIsMinimizing)
|
|
||||||
decorator->SetMinimize(hitRegion == REGION_MINIMIZE_BUTTON);
|
|
||||||
|
|
||||||
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 || fMinimizeCheckOnMouseUp) {
|
|
||||||
fMouseMoveDistance += delta.x * delta.x + delta.y * delta.y;
|
|
||||||
if (fMouseMoveDistance > 16.0f) {
|
|
||||||
fActivateOnMouseUp = false;
|
|
||||||
fMinimizeCheckOnMouseUp = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -542,70 +761,13 @@ DefaultWindowBehaviour::_RegionFor(const BMessage* message) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DefaultWindowBehaviour::_AlterDeltaForSnap(BPoint& delta, bigtime_t now)
|
DefaultWindowBehaviour::_NextState(State* state)
|
||||||
{
|
{
|
||||||
// Alter the delta (which is a proposed offset used while dragging a
|
State* oldState = fState;
|
||||||
// window) so that the frame of the window 'snaps' to the edges of the
|
fState = state;
|
||||||
// screen.
|
|
||||||
|
|
||||||
const bigtime_t kSnappingDuration = 1500000LL;
|
if (fState != NULL)
|
||||||
const bigtime_t kSnappingPause = 3000000LL;
|
fState->EnterState(oldState);
|
||||||
const float kSnapDistance = 8.0f;
|
|
||||||
|
|
||||||
if (now - fLastSnapTime > kSnappingDuration
|
delete oldState;
|
||||||
&& 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();
|
|
||||||
|
|
||||||
Decorator* decorator = fWindow->Decorator();
|
|
||||||
if (decorator) {
|
|
||||||
frame = decorator->GetFootprint().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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,27 +48,31 @@ private:
|
|||||||
REGION_RESIZE_CORNER
|
REGION_RESIZE_CORNER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct State;
|
||||||
|
struct MouseTrackingState;
|
||||||
|
struct DragState;
|
||||||
|
struct ResizeState;
|
||||||
|
struct SlideTabState;
|
||||||
|
struct DecoratorButtonState;
|
||||||
|
|
||||||
|
// to keep gcc 2 happy
|
||||||
|
friend struct State;
|
||||||
|
friend struct MouseTrackingState;
|
||||||
|
friend struct DragState;
|
||||||
|
friend struct ResizeState;
|
||||||
|
friend struct SlideTabState;
|
||||||
|
friend struct DecoratorButtonState;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _IsWindowModifier(int32 modifiers) const;
|
bool _IsWindowModifier(int32 modifiers) const;
|
||||||
Region _RegionFor(const BMessage* message) const;
|
Region _RegionFor(const BMessage* message) const;
|
||||||
void _AlterDeltaForSnap(BPoint& delta,
|
|
||||||
bigtime_t now);
|
void _NextState(State* state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Window* fWindow;
|
Window* fWindow;
|
||||||
Desktop* fDesktop;
|
Desktop* fDesktop;
|
||||||
|
State* fState;
|
||||||
bool fIsClosing : 1;
|
|
||||||
bool fIsMinimizing : 1;
|
|
||||||
bool fIsZooming : 1;
|
|
||||||
bool fIsSlidingTab : 1;
|
|
||||||
bool fActivateOnMouseUp : 1;
|
|
||||||
bool fMinimizeCheckOnMouseUp : 1;
|
|
||||||
|
|
||||||
BPoint fLastMousePosition;
|
|
||||||
float fMouseMoveDistance;
|
|
||||||
bigtime_t fLastMoveTime;
|
|
||||||
bigtime_t fLastSnapTime;
|
|
||||||
int32 fLastModifiers;
|
int32 fLastModifiers;
|
||||||
int32 fResetClickCount;
|
int32 fResetClickCount;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user