1 /*
2 * Copyright 2010-2011, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
4 *
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 * Ingo Weinhold <ingo_weinhold@gmx.de>
8 * Clemens Zeidler <haiku@clemens-zeidler.de>
9 */
10
11
12 #include "MagneticBorder.h"
13
14 #include "Decorator.h"
15 #include "Window.h"
16 #include "Screen.h"
17
18
MagneticBorder()19 MagneticBorder::MagneticBorder()
20 :
21 fLastSnapTime(0)
22 {
23
24 }
25
26
27 bool
AlterDeltaForSnap(Window * window,BPoint & delta,bigtime_t now)28 MagneticBorder::AlterDeltaForSnap(Window* window, BPoint& delta, bigtime_t now)
29 {
30 BRect frame = window->Frame();
31 Decorator* decorator = window->Decorator();
32 if (decorator)
33 frame = decorator->GetFootprint().Frame();
34
35 return AlterDeltaForSnap(window->Screen(), frame, delta, now);
36 }
37
38
39 bool
AlterDeltaForSnap(const Screen * screen,BRect & frame,BPoint & delta,bigtime_t now)40 MagneticBorder::AlterDeltaForSnap(const Screen* screen, BRect& frame,
41 BPoint& delta, bigtime_t now)
42 {
43 // Alter the delta (which is a proposed offset used while dragging a
44 // window) so that the frame of the window 'snaps' to the edges of the
45 // screen.
46
47 const bigtime_t kSnappingDuration = 1500000LL;
48 const bigtime_t kSnappingPause = 3000000LL;
49 const float kSnapDistance = 8.0f;
50
51 if (now - fLastSnapTime > kSnappingDuration
52 && now - fLastSnapTime < kSnappingPause) {
53 // Maintain a pause between snapping.
54 return false;
55 }
56
57 // TODO: Perhaps obtain the usable area (not covered by the Deskbar)?
58 BRect screenFrame = screen->Frame();
59 BRect originalFrame = frame;
60 frame.OffsetBy(delta);
61
62 float leftDist = fabs(frame.left - screenFrame.left);
63 float topDist = fabs(frame.top - screenFrame.top);
64 float rightDist = fabs(frame.right - screenFrame.right);
65 float bottomDist = fabs(frame.bottom - screenFrame.bottom);
66
67 bool snapped = false;
68 if (leftDist < kSnapDistance || rightDist < kSnapDistance) {
69 snapped = true;
70 if (leftDist < rightDist)
71 delta.x = screenFrame.left - originalFrame.left;
72 else
73 delta.x = screenFrame.right - originalFrame.right;
74 }
75
76 if (topDist < kSnapDistance || bottomDist < kSnapDistance) {
77 snapped = true;
78 if (topDist < bottomDist)
79 delta.y = screenFrame.top - originalFrame.top;
80 else
81 delta.y = screenFrame.bottom - originalFrame.bottom;
82 }
83 if (snapped && now - fLastSnapTime > kSnappingPause)
84 fLastSnapTime = now;
85
86 return snapped;
87 }
88