1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
3 * VIM - Vi IMproved by Bram Moolenaar
4 * MacVim GUI port by Bjorn Winckler
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
14 * Essentially just a title bar for a plugin view. Handles drawing the
15 * drag-and-drop line where a new plugin view will be inserted.
19 * This contains a single view added by a plugin.
21 * MMPlugInViewContainer
23 * This contains multiple MMPlugInViews. It handles the drag and drop aspects
24 * of the views, as well.
30 #ifdef MM_ENABLE_PLUGINS
33 #import "CTGradient.h"
35 NSString *MMPlugInViewPboardType = @"MMPlugInViewPboardType";
37 @implementation MMPlugInViewHeader
39 - (void)mouseDown:(NSEvent *)theEvent
41 // Make image from view
44 NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc]
45 initWithFocusedViewRect: [view bounds]] autorelease];
48 NSImage *image = [[[NSImage alloc] initWithSize: [view bounds].size]
50 [image addRepresentation:bitmap];
52 NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
54 [pboard declareTypes:[NSArray arrayWithObject:MMPlugInViewPboardType]
57 NSPoint pt = [view convertPoint:[view bounds].origin
58 toView:[controller plugInSubview]];
59 [[controller plugInSubview] dragImage:image
61 offset:NSMakeSize(0, 0)
68 - (void)drawRect:(NSRect)rect
71 startColor = [NSColor colorWithCalibratedRed:.600
76 NSColor *endColor = [NSColor colorWithCalibratedRed:.800
81 CTGradient *grad = [CTGradient gradientWithBeginningColor:startColor
82 endingColor:endColor];
83 [grad fillRect:[self bounds] angle:90];
85 MMPlugInView *dropView = [[controller container] dropView];
87 if (dropView == [controller plugInSubview]) {
88 NSRect insertionRect = NSMakeRect(0,[self bounds].size.height - 2,
89 [self bounds].size.width, 2);
90 [[NSColor redColor] set];
91 NSRectFill(insertionRect);
102 return NSMakeRect(0, [self bounds].size.height - 6, [self bounds].size.width, 6);
107 @implementation MMPlugInView
109 - (MMPlugInViewController *)controller
116 @implementation MMPlugInViewController
118 - (id)initWithView:(NSView *)view title:(NSString *)title
120 if ((self = [super init]) == nil) return nil;
122 if (![NSBundle loadNibNamed:@"PlugInView" owner:self])
123 ASLogErr(@"Error loading PlugIn nib");
125 [titleField setStringValue:title];
127 [plugInSubview setMinDimension:50
128 andMaxDimension:0.0];
130 [view setFrame:[contentView bounds]];
131 [contentView addSubview:view];
136 - (RBSplitSubview *)plugInSubview
138 return plugInSubview;
141 - (void)moveToContainer:(MMPlugInViewContainer *)container
143 if ([plugInSubview splitView]) {
144 [plugInSubview removeFromSuperview];
146 [container addSubview:plugInSubview];
149 - (void)moveToContainer:(MMPlugInViewContainer *)container before:(MMPlugInView *)lowerView
151 if ([plugInSubview splitView]) {
152 [plugInSubview removeFromSuperview];
154 [container addSubview:plugInSubview positioned:NSWindowBelow relativeTo:lowerView];
157 - (MMPlugInViewHeader *)headerView
162 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
165 return NSDragOperationPrivate;
167 return NSDragOperationNone;
170 - (void)dropViewChanged {
171 [headerView setNeedsDisplay:YES];
174 - (MMPlugInViewContainer *)container {
175 return (MMPlugInViewContainer *)[plugInSubview splitView];
179 @implementation MMPlugInViewContainer
181 - (id)initWithFrame:(NSRect)frame
183 if ((self = [super initWithFrame:frame]) == nil) return nil;
185 [self registerForDraggedTypes:
186 [NSArray arrayWithObjects:MMPlugInViewPboardType, nil]];
188 [self setVertical:NO];
189 [self setDelegate:self];
191 fillerView = [[RBSplitSubview alloc] initWithFrame:NSMakeRect(0,0,0,0)];
192 [fillerView setHidden:YES];
201 [fillerView release]; fillerView = nil;
205 - (unsigned int)splitView:(RBSplitView*)sender dividerForPoint:(NSPoint)point
206 inSubview:(RBSplitSubview*)subview
208 MMPlugInViewController *controller = [(MMPlugInView *)subview controller];
209 MMPlugInViewHeader *header = [controller headerView];
211 if ([header mouse:[header convertPoint:point fromView:sender]
212 inRect:[header dragRect]])
213 return [subview position] - 1;
218 - (NSRect)splitView:(RBSplitView*)sender cursorRect:(NSRect)rect
219 forDivider:(unsigned int)theDivider
222 if (theDivider != 0) return NSZeroRect;
226 MMPlugInView *view = (MMPlugInView *)[sender subviewAtPosition:i];
229 MMPlugInViewHeader *header = [[view controller] headerView];
230 NSRect rect = [header dragRect];
231 rect = [sender convertRect:rect fromView:header];
232 [sender addCursorRect:rect
233 cursor:[RBSplitView cursor:RBSVHorizontalCursor]];
240 - (void)clearDragInfo
243 MMPlugInView *save = dropView;
245 [[save controller] dropViewChanged];
249 // point should be in the window's coordinate system
250 - (void)updateDragInfo:(id<NSDraggingInfo>)info
253 [self clearDragInfo];
255 if (!([info draggingSourceOperationMask] & NSDragOperationPrivate)) return;
257 if (![[info draggingSource] isKindOfClass:[MMPlugInViewController class]]) return;
259 // for now has to be THIS container. in the future, it will be ok for any
260 // container associated with the same vim instance
261 if ([[info draggingSource] container] != self) return;
263 // XXX for now we just use the view that the mouse is currently over, and
264 // always insert "above" that view. In the future, we might want to try to
265 // find the divider that the mouse is closest to and have the dropView be
266 // the view below that divider.
268 NSPoint point = [info draggingLocation];
272 MMPlugInView *subview = (MMPlugInView *)[self subviewAtPosition:i];
275 if ([subview mouse:[subview convertPoint:point fromView:nil]
276 inRect:[subview bounds]]) {
282 if ([[info draggingSource] plugInSubview] == dropView)
285 if (dropView) [[dropView controller] dropViewChanged];
288 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
290 [self updateDragInfo:sender];
293 return NSDragOperationPrivate;
295 return NSDragOperationNone;
298 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
300 [self updateDragInfo:sender];
303 return NSDragOperationPrivate;
305 return NSDragOperationNone;
308 - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
310 [self updateDragInfo:sender];
311 return dropView != nil;
314 - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
316 MMPlugInViewController *source = [sender draggingSource];
317 [source moveToContainer:self before:dropView];
318 [self clearDragInfo];
322 - (void)draggingExited:(id<NSDraggingInfo>)sender
324 [self clearDragInfo];
328 - (MMPlugInView *)dropView {