/* * Copyright 2010-2011, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * Stephan Aßmus * Ingo Weinhold * Clemens Zeidler */ #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; }