* 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:
Clemens Zeidler
2011-07-04 21:04:55 +00:00
parent d012351656
commit b91ddd8116
7 changed files with 154 additions and 76 deletions
+10 -75
View File
@@ -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
{
+7 -1
View File
@@ -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;
};
+1
View File
@@ -39,6 +39,7 @@ Server app_server :
InputManager.cpp
IntPoint.cpp
IntRect.cpp
MagneticBorder.cpp
MessageLooper.cpp
MultiLocker.cpp
OffscreenServerWindow.cpp
+87
View File
@@ -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;
}
+34
View File
@@ -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
+7
View File
@@ -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.
+8
View File
@@ -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;