source: trunk/Cocoa/DockCam/NJRWindowMagnetism.m @ 551

Last change on this file since 551 was 144, checked in by Nicholas Riley, 17 years ago

NJRWindowMagnetism.[hm]: Copied from HostLauncher?

File size: 3.6 KB
Line 
1//
2//  NJRWindowMagnetism.m
3//  HostLauncher
4//
5//  Created by Nicholas Riley on Sun Jun 02 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "NJRWindowMagnetism.h"
10#include <unistd.h>
11
12#define OUTSIDE_THRESHOLD -150
13#define INSIDE_THRESHOLD 35
14#define MOVE_INTERVAL 1
15
16@implementation NJRWindowMagnetism
17
18- (id)initForWindow:(NSWindow *)window;
19{
20    if ( (self = [super init]) != nil) {
21        [[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(windowMoved:)
22                                                     name: NSWindowDidMoveNotification
23                                                   object: window];
24        attractsScreenEdges = YES;
25    }
26    return self;
27}
28
29- (void)dealloc;
30{
31    [[NSNotificationCenter defaultCenter] removeObserver: self];
32    [super dealloc];
33}
34
35- (void)windowMoved:(NSNotification *)notification;
36{
37    NSWindow *window = [notification object];
38    NSPoint startPoint = [window frame].origin, endPoint = [window frame].origin;
39    float windowX = [window frame].origin.x;
40    float windowY = [window frame].origin.y;
41    float windowW = [window frame].size.width;
42    float screenX = [[window screen] visibleFrame].origin.x;
43    float screenW = [[window screen] visibleFrame].size.width;
44
45    if ([self attractsScreenEdges] && (inMotion == NO)) {
46        inMotion = YES;
47
48        if (windowY < ([[window screen] visibleFrame].origin.y + INSIDE_THRESHOLD)
49            && windowY > ([[window screen] visibleFrame].origin.y + OUTSIDE_THRESHOLD))
50            endPoint.y = [[window screen] visibleFrame].origin.y; /* Bottom of the screen */
51
52        if (windowX < ([[window screen] visibleFrame].origin.x + INSIDE_THRESHOLD)
53            && windowX > ([[window screen] visibleFrame].origin.x + OUTSIDE_THRESHOLD))
54            endPoint.x = [[window screen] visibleFrame].origin.x; /* Left hand side of the screen */
55
56        if ((windowX > (screenX + screenW - windowW - INSIDE_THRESHOLD))
57            && (windowX < (screenX + screenW - windowW - OUTSIDE_THRESHOLD)))
58            endPoint.x = (screenX + screenW - windowW); /* Right hand side of the screen */
59
60        if (!NSEqualPoints(startPoint, endPoint))
61            [self animateWindow: window motionToFrameOrigin: endPoint];
62
63        inMotion = NO;
64    }
65}
66
67- (void)animateWindow:(NSWindow *)window motionToFrameOrigin:(NSPoint)newOrigin;
68{
69    float animationSteps;
70    NSPoint originDelta, oldOrigin = [window frame].origin;
71
72    // Calculate the overall distance.
73    originDelta.x = newOrigin.x - oldOrigin.x;
74    originDelta.y = newOrigin.y - oldOrigin.y;
75
76    // Calculate the number of steps. The inner sqrt finds the distance. The outer sqrt gives us the duration based on the distance. Then we round the time for the loop below.
77    animationSteps = round(sqrt(sqrt(abs((originDelta.x * originDelta.x) + (originDelta.y * originDelta.y)))));
78
79    // Divide the distance by the number of steps to get our move originDelta.
80    originDelta.x /= animationSteps;
81    originDelta.y /= animationSteps;
82
83    // We will move by the originDelta up to the last step or fraction thereof.
84    while ( (animationSteps--) > 1.0) {
85        oldOrigin.x += originDelta.x;
86        oldOrigin.y += originDelta.y;
87
88        [window setFrameOrigin: oldOrigin];
89        usleep(MOVE_INTERVAL);
90    }
91
92    // To make sure we end up in the correct place we do the last move out of the loop and use the absolute position. That way we have no rounding errors.
93    [window setFrameOrigin: newOrigin];
94    usleep(MOVE_INTERVAL);
95}
96
97- (void)setAttractsScreenEdges:(BOOL)yn;
98{
99    attractsScreenEdges = yn;
100}
101
102- (BOOL)attractsScreenEdges;
103{
104    return attractsScreenEdges;
105}
106
107@end
Note: See TracBrowser for help on using the repository browser.