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 19 MagneticBorder::MagneticBorder() 20 : 21 fLastSnapTime(0) 22 { 23 24 } 25 26 27 bool 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 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