* Make the magnetic border code more accessible by moving the code into a separate class and use it in a new protected WindowBehaviour method.
* Simplify the algorithm a bit, no functional changes are intended. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42377 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -210,8 +210,7 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
|
||||
bool activateOnMouseUp, bool minimizeCheckOnMouseUp)
|
||||
:
|
||||
MouseTrackingState(behavior, where, activateOnMouseUp,
|
||||
minimizeCheckOnMouseUp),
|
||||
fLastSnapTime(0)
|
||||
minimizeCheckOnMouseUp)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -235,7 +234,7 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
|
||||
if (!(fWindow->Flags() & B_NOT_MOVABLE)) {
|
||||
BPoint oldLeftTop = fWindow->Frame().LeftTop();
|
||||
|
||||
_AlterDeltaForSnap(delta, now);
|
||||
fBehavior.AlterDeltaForSnap(fWindow, delta, now);
|
||||
fDesktop->MoveWindowBy(fWindow, delta.x, delta.y);
|
||||
|
||||
// constrain delta to true change in position
|
||||
@@ -243,78 +242,6 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
|
||||
} 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -965,6 +892,14 @@ DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DefaultWindowBehaviour::AlterDeltaForSnap(Window* window, BPoint& delta,
|
||||
bigtime_t now)
|
||||
{
|
||||
return fMagneticBorder.AlterDeltaForSnap(window, delta, now);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DefaultWindowBehaviour::_IsWindowModifier(int32 modifiers) const
|
||||
{
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
|
||||
#include "WindowBehaviour.h"
|
||||
|
||||
#include "ServerCursor.h"
|
||||
#include "Decorator.h"
|
||||
#include "MagneticBorder.h"
|
||||
#include "ServerCursor.h"
|
||||
|
||||
|
||||
class Desktop;
|
||||
@@ -39,6 +40,9 @@ public:
|
||||
|
||||
virtual void ModifiersChanged(int32 modifiers);
|
||||
|
||||
protected:
|
||||
virtual bool AlterDeltaForSnap(Window* window, BPoint& delta,
|
||||
bigtime_t now);
|
||||
private:
|
||||
enum Action {
|
||||
ACTION_NONE,
|
||||
@@ -104,6 +108,8 @@ protected:
|
||||
Desktop* fDesktop;
|
||||
State* fState;
|
||||
int32 fLastModifiers;
|
||||
|
||||
MagneticBorder fMagneticBorder;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ Server app_server :
|
||||
InputManager.cpp
|
||||
IntPoint.cpp
|
||||
IntRect.cpp
|
||||
MagneticBorder.cpp
|
||||
MessageLooper.cpp
|
||||
MultiLocker.cpp
|
||||
OffscreenServerWindow.cpp
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
* Ingo Weinhold <[email protected]>
|
||||
* Clemens Zeidler <[email protected]>
|
||||
*/
|
||||
|
||||
|
||||
#include "MagneticBorder.h"
|
||||
|
||||
#include "Decorator.h"
|
||||
#include "Window.h"
|
||||
#include "Screen.h"
|
||||
|
||||
|
||||
MagneticBorder::MagneticBorder()
|
||||
:
|
||||
fLastSnapTime(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MagneticBorder::AlterDeltaForSnap(Window* window, BPoint& delta, bigtime_t now)
|
||||
{
|
||||
BRect frame = window->Frame();
|
||||
Decorator* decorator = window->Decorator();
|
||||
if (decorator)
|
||||
frame = decorator->GetFootprint().Frame();
|
||||
|
||||
return AlterDeltaForSnap(window->Screen(), frame, delta, now);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MagneticBorder::AlterDeltaForSnap(const Screen* screen, BRect& frame,
|
||||
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 false;
|
||||
}
|
||||
|
||||
// TODO: Perhaps obtain the usable area (not covered by the Deskbar)?
|
||||
BRect screenFrame = screen->Frame();
|
||||
BRect originalFrame = frame;
|
||||
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)
|
||||
delta.x = screenFrame.left - originalFrame.left;
|
||||
else
|
||||
delta.x = screenFrame.right - originalFrame.right;
|
||||
}
|
||||
|
||||
if (topDist < kSnapDistance || bottomDist < kSnapDistance) {
|
||||
snapped = true;
|
||||
if (topDist < bottomDist)
|
||||
delta.y = screenFrame.top - originalFrame.top;
|
||||
else
|
||||
delta.y = screenFrame.bottom - originalFrame.bottom;
|
||||
}
|
||||
if (snapped && now - fLastSnapTime > kSnappingPause)
|
||||
fLastSnapTime = now;
|
||||
|
||||
return snapped;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler <[email protected]>
|
||||
*/
|
||||
#ifndef MAGNETIC_BORDRER_H
|
||||
#define MAGNETIC_BORDRER_H
|
||||
|
||||
|
||||
#include <Point.h>
|
||||
#include <Screen.h>
|
||||
|
||||
|
||||
class Screen;
|
||||
class Window;
|
||||
|
||||
|
||||
class MagneticBorder {
|
||||
public:
|
||||
MagneticBorder();
|
||||
|
||||
bool AlterDeltaForSnap(Window* window, BPoint& delta,
|
||||
bigtime_t now);
|
||||
bool AlterDeltaForSnap(const Screen* screen,
|
||||
BRect& frame, BPoint& delta, bigtime_t now);
|
||||
|
||||
private:
|
||||
bigtime_t fLastSnapTime;
|
||||
};
|
||||
|
||||
|
||||
#endif // MAGNETIC_BORDRER_H
|
||||
@@ -29,6 +29,13 @@ WindowBehaviour::ModifiersChanged(int32 modifiers)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowBehaviour::AlterDeltaForSnap(Window* window, BPoint& delta, bigtime_t now)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*! \fn WindowBehaviour::MouseDown()
|
||||
\brief Handles a mouse-down message for the window.
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
class BMessage;
|
||||
class ClickTarget;
|
||||
class Window;
|
||||
|
||||
|
||||
class WindowBehaviour {
|
||||
@@ -35,6 +36,13 @@ public:
|
||||
bool IsDragging() const { return fIsDragging; }
|
||||
bool IsResizing() const { return fIsResizing; }
|
||||
|
||||
protected:
|
||||
/*! The window is going to be moved by delta. This hook should be used to
|
||||
implement the magnetic screen border, i.e. alter the delta accordantly.
|
||||
\return true if delta has been modified. */
|
||||
virtual bool AlterDeltaForSnap(Window* window, BPoint& delta,
|
||||
bigtime_t now);
|
||||
|
||||
protected:
|
||||
bool fIsResizing : 1;
|
||||
bool fIsDragging : 1;
|
||||
|
||||
Reference in New Issue
Block a user