source: trunk/Cocoa/F-Script Anywhere/Source/FSAViewAssociationController.m @ 224

Last change on this file since 224 was 224, checked in by rchin, 14 years ago

Object For Target... button now works as it should.

File size: 8.9 KB
Line 
1//
2//  FSAViewAssociationController.m
3//  F-Script Anywhere
4//
5//  Created by Nicholas Riley on Wed Jul 17 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9/*
10
11 F-Script Anywhere is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 F-Script Anywhere is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with F-Script Anywhere; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25*/
26
27#import "FSAViewAssociationController.h"
28#import "FSAController.h"
29#import "FSAWindowManager.h"
30#import "FSAnywhere.h"
31#import <FScript/FSInterpreter.h>
32#import <FScript/System.h>
33
34@implementation FSAViewAssociationController
35
36- (id)initWithFSAController:(FSAController *)fsa;
37{
38    self = [super init];
39
40    if (self != nil) {
41        NSImage *bullseyeImage = [[NSImage alloc] initByReferencingFile: [[NSBundle bundleForClass: [self class]] pathForResource: @"Bullseye menu cursor" ofType: @"tiff"]];
42        NSString *label = [fsa interpreterLabel];
43       
44        interpreter = [[[fsa interpreterView] interpreter] retain];
45        system = [fsa system];
46        [[self window] setResizeIncrements: NSMakeSize(1, 12)];
47        if (label != nil) [[self window] setTitle: [NSString stringWithFormat: @"%@: %@", [[self window] title], label]];
48        bullseyeCursor = [[NSCursor alloc] initWithImage: bullseyeImage hotSpot: NSMakePoint(6, 7)];
49    }
50    return self;
51}
52
53- (void)dealloc;
54{
55    [viewHierarchyMenu release];
56    [selectedElement release];
57    [interpreter release];
58    [bullseyeCursor release];
59    [[NSNotificationCenter defaultCenter] removeObserver: self];
60    [super dealloc];
61}
62
63- (void)stopCapturingVoluntarily:(BOOL)voluntary;
64{
65    FSALog(@"stopping capture");
66    [[NSNotificationCenter defaultCenter] removeObserver: self name: NSMenuWillSendActionNotification object: nil];
67    if (voluntary) {
68        FSALog(@"voluntary!");
69        [[self window] makeKeyAndOrderFront: self];
70        [bullseyeCursor pop];
71    }
72}
73
74- (void)_addElement:(id)element withLabel:(NSString *)label toSubmenuForItem:(id<NSMenuItem>)item;
75{
76    NSMenu *submenu = [item submenu];
77    id<NSMenuItem> subItem;
78    if (submenu == nil) {
79        id superElement = [item representedObject];
80        submenu = [[NSMenu alloc] initWithTitle: @""];
81        subItem = [submenu addItemWithTitle: NSStringFromClass([superElement class])
82                                     action: @selector(elementSelected:)
83                              keyEquivalent: @""];
84        [subItem setTarget: self];
85        [subItem setRepresentedObject: superElement];
86        [item setSubmenu: submenu];
87        [submenu release];
88    }
89    [submenu addItem: [NSMenuItem separatorItem]];
90    [submenu addItemWithTitle: label action: nil keyEquivalent: @""];
91    subItem = [submenu addItemWithTitle: [@"  "
92                stringByAppendingString: NSStringFromClass([element class])]
93                                           action: @selector(elementSelected:)
94                                    keyEquivalent: @""];
95    [subItem setTarget: self];
96    [subItem setRepresentedObject: element];
97}
98
99- (void)_addValueForSelector:(SEL)sel withLabel:(NSString *)label toSubmenuForItem:(id<NSMenuItem>)item;
100{
101    id obj = [item representedObject];
102    if ([obj respondsToSelector: sel]) {
103        id value = [obj performSelector: sel];
104        if (value == nil) return;
105        [self _addElement: value withLabel: label toSubmenuForItem: item];
106    }
107}
108
109- (void)_addElementToMenu:(id)element;
110{
111    id<NSMenuItem> item;
112    if (element == nil) return;
113    item = [viewHierarchyMenu addItemWithTitle: [@"  "
114                stringByAppendingString: NSStringFromClass([element class])]
115                                        action: @selector(elementSelected:)
116                                 keyEquivalent: @""];
117    [item setTarget: self];
118    [item setRepresentedObject: element];
119    [self _addValueForSelector: @selector(windowController) withLabel: @"Window Controller" toSubmenuForItem: item];
120    [self _addValueForSelector: @selector(delegate) withLabel: @"Delegate" toSubmenuForItem: item];
121    [self _addValueForSelector: @selector(dataSource) withLabel: @"Data Source" toSubmenuForItem: item];
122    [self _addValueForSelector: @selector(target) withLabel: @"Target" toSubmenuForItem: item];
123    [self _addValueForSelector: @selector(cell) withLabel: @"Cell" toSubmenuForItem: item];
124}
125
126- (void)captureOneView;
127{
128    NSEvent *event;
129    NSView *view, *superView = nil, *contentView;
130    NSWindow *eventWindow;
131    static unsigned captureCount = 0;
132    unsigned capture = captureCount++;
133   
134    FSALog(@"%4u>capturing one", capture);
135    [bullseyeCursor push];
136captureElement:
137    [bullseyeCursor set];
138    FSALog(@"%4u waiting for event...", capture);
139    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(menuWillSendAction:) name: NSMenuWillSendActionNotification object: nil];
140    event = [NSApp nextEventMatchingMask: NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask | NSKeyUpMask | NSAppKitDefinedMask
141                               untilDate: [NSDate distantFuture]
142                                  inMode: NSEventTrackingRunLoopMode
143                                 dequeue: YES];
144    FSALog(@"%4u got %@", capture, event);
145    [[NSNotificationCenter defaultCenter] removeObserver: self name: NSMenuWillSendActionNotification object: nil];
146    if ([event type] == NSAppKitDefined) {
147        if ([event subtype] == NSApplicationDeactivatedEventType) {
148            [NSApp discardEventsMatchingMask: NSAnyEventMask beforeEvent: event];
149            [self stopCapturingVoluntarily: NO];
150            [NSApp sendEvent: event];
151            return;
152        }
153        goto captureElement;
154    }
155    if ([event type] == NSKeyUp) {
156        [NSApp discardEventsMatchingMask: NSAnyEventMask & ~NSKeyUpMask beforeEvent: event];
157        FSALog(@"%4u<stop capture [key up]", capture);
158        [self stopCapturingVoluntarily: YES];
159        return;
160    }
161    [viewHierarchyMenu release]; viewHierarchyMenu = nil;
162    viewHierarchyMenu = [[NSMenu alloc] initWithTitle: @""];
163    NS_DURING
164        eventWindow = [event window];
165        contentView = [eventWindow contentView];
166        view = [[contentView superview] hitTest: [event locationInWindow]];
167        if (view == nil) {
168            [self captureOneView];
169            NS_VOIDRETURN;
170        }
171        [viewHierarchyMenu addItemWithTitle: @"View" action: nil keyEquivalent: @""];
172        [self _addElementToMenu: view];
173        superView = view;
174        do {
175            superView = [superView superview];
176            if (superView == nil) break;
177            [self _addElementToMenu: superView];
178        } while (superView != contentView);
179        [viewHierarchyMenu addItem: [NSMenuItem separatorItem]];
180        [viewHierarchyMenu addItemWithTitle: @"Window" action: nil keyEquivalent: @""];
181        [self _addElementToMenu: eventWindow];
182    NS_HANDLER
183        [self alertWithString:[NSString stringWithFormat: @"Çan exception occurred: %@È", localException]];
184    NS_ENDHANDLER
185    [NSMenu popUpContextMenu: viewHierarchyMenu withEvent: event forView: view];
186    [self stopCapturingVoluntarily: YES];
187//    if ([captureButton state] == NSOnState) goto captureElement;
188    FSALog(@"%4u<stop capture [fell through to end]", capture);
189}
190
191- (IBAction)captureView:(id)sender
192{
193    [selectedElement release]; selectedElement = nil;
194    [self captureOneView];
195}
196
197- (void)setSelectedElement:(id)element;
198{
199    FSALog(@"element selected: %@", element);
200    NS_DURING
201        [selectedElement release];
202        selectedElement = [element retain];
203        [[self window] orderFront: self];
204    NS_HANDLER
205        [self alertWithString:[NSString stringWithFormat: @"Çan exception occurred: %@È", localException]];
206    NS_ENDHANDLER
207    [viewHierarchyMenu release]; viewHierarchyMenu = nil;
208}
209
210- (void)elementSelected:(NSMenuItem *)sender;
211{
212    [self setSelectedElement: [sender representedObject]];
213    [system browse: selectedElement];
214//    [self captureOneView];
215}
216
217- (void)menuWillSendAction:(NSNotification *)notification;
218{
219    NSMenuItem *item = [[notification userInfo] objectForKey: @"MenuItem"];
220    [self setSelectedElement: item];
221    [NSApp discardEventsMatchingMask: NSAnyEventMask beforeEvent: [NSApp currentEvent]];
222    // we're already capturing, don't do it again
223}
224
225- (IBAction)viewInObjectBrowser:(id)sender;
226{
227    FSALog(@"system: %@", system);
228    [system browse: selectedElement];
229}
230
231- (void)alertWithString:(NSString *)alertString
232{
233    [NSAlert alertWithMessageText:alertString
234                    defaultButton:nil
235                  alternateButton:nil
236                      otherButton:nil
237        informativeTextWithFormat:nil];
238}
239
240@end
Note: See TracBrowser for help on using the repository browser.