2007-06-18 Mitz Pettel <mitz@webkit.org>
[WebKit-https.git] / WebKit / WebInspector / WebInspectorPanel.m
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "WebInspectorPanel.h"
30
31 #import <WebKit/WebView.h>
32 #import <WebKit/WebViewPrivate.h>
33 #import <WebKit/WebDashboardRegion.h>
34 #import <WebKit/DOMCore.h>
35 #import <WebKit/DOMHTML.h>
36 #import <WebKit/DOMCSS.h>
37
38 @implementation WebInspectorPanel
39 - (BOOL)canBecomeKeyWindow
40 {
41     return YES;
42 }
43
44 - (BOOL)canBecomeMainWindow
45 {
46     // prevent the inspector from confusing other panels
47     return NO;
48 }
49
50 - (void)moveWindow:(NSEvent *)event
51 {
52     NSPoint startLocation = [event locationInWindow];
53     NSPoint lastLocation = startLocation;
54     BOOL mouseUpOccurred = NO;
55
56     while (!mouseUpOccurred) {
57         // set mouseUp flag here, but process location of event before exiting from loop, leave mouseUp in queue
58         event = [self nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask) untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES];
59
60         if ([event type] == NSLeftMouseUp)
61             mouseUpOccurred = YES;
62
63         NSPoint newLocation = [event locationInWindow];
64         if (NSEqualPoints(newLocation, lastLocation))
65             continue;
66
67         NSPoint origin = [self frame].origin;
68         [self setFrameOrigin:NSMakePoint(origin.x + newLocation.x - startLocation.x, origin.y + newLocation.y - startLocation.y)];
69         lastLocation = newLocation;
70     }
71 }
72
73 - (void)resizeWindow:(NSEvent *)event
74 {
75     NSRect startFrame = [self frame];
76     NSPoint startLocation = [self convertBaseToScreen:[event locationInWindow]];
77     NSPoint lastLocation = startLocation;
78     NSSize minSize = [self minSize];
79     NSSize maxSize = [self maxSize];
80     BOOL mouseUpOccurred = NO;
81
82     while (!mouseUpOccurred) {
83         // set mouseUp flag here, but process location of event before exiting from loop, leave mouseUp in queue
84         event = [self nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask) untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES];
85
86         if ([event type] == NSLeftMouseUp)
87             mouseUpOccurred = YES;
88
89         NSPoint newLocation = [self convertBaseToScreen:[event locationInWindow]];
90         if (NSEqualPoints(newLocation, lastLocation))
91             continue;
92
93         NSRect proposedRect = startFrame;
94         proposedRect.size.width += newLocation.x - startLocation.x;;
95         proposedRect.size.height -= newLocation.y - startLocation.y;
96         proposedRect.origin.y += newLocation.y - startLocation.y;
97
98         if (proposedRect.size.width < minSize.width) {
99             proposedRect.size.width = minSize.width;
100         } else if (proposedRect.size.width > maxSize.width) {
101             proposedRect.size.width = maxSize.width;
102         }
103
104         if (proposedRect.size.height < minSize.height) {
105             proposedRect.origin.y -= minSize.height - proposedRect.size.height;
106             proposedRect.size.height = minSize.height;
107         } else if (proposedRect.size.height > maxSize.height) {
108             proposedRect.origin.y -= maxSize.height - proposedRect.size.height;
109             proposedRect.size.height = maxSize.height;
110         }
111
112         [self setFrame:proposedRect display:YES];
113         lastLocation = newLocation;
114     }
115 }
116
117 - (void)sendEvent:(NSEvent *)event
118 {
119     if (_mouseInRegion && [event type] == NSLeftMouseUp)
120         _mouseInRegion = NO;
121
122     if (([event type] == NSLeftMouseDown || [event type] == NSLeftMouseDragged) && !_mouseInRegion) {
123         NSPoint pointInView = [[[[(WebView *)[self contentView] mainFrame] frameView] documentView] convertPoint:[event locationInWindow] fromView:nil];
124         NSDictionary *regions = [(WebView *)[self contentView] _dashboardRegions];
125
126         WebDashboardRegion *region = [[regions objectForKey:@"resizeTop"] lastObject];
127         region = [[regions objectForKey:@"resize"] lastObject];
128         if (region) {
129             if (NSPointInRect(pointInView, [region dashboardRegionClip])) {
130                 // we are in a resize control region, resize the window now and eat the event
131                 [self resizeWindow:event];
132                 return;
133             }
134         }
135
136         NSArray *controlRegions = [regions objectForKey:@"control"];
137         NSEnumerator *enumerator = [controlRegions objectEnumerator];
138         while ((region = [enumerator nextObject])) {
139             if (NSPointInRect(pointInView, [region dashboardRegionClip])) {
140                 // we are in a control region, lets pass the event down
141                 _mouseInRegion = YES;
142                 [super sendEvent:event];
143                 return;
144             }
145         }
146
147         // if we are dragging and the mouse isn't in a control region move the window
148         if ([event type] == NSLeftMouseDragged) {
149             [self moveWindow:event];
150             return;
151         }
152     }
153
154     [super sendEvent:event];
155 }
156 @end