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 NSLog(@"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];
199 [fillerView release]; fillerView = nil;
203 - (unsigned int)splitView:(RBSplitView*)sender dividerForPoint:(NSPoint)point
204 inSubview:(RBSplitSubview*)subview
206 MMPlugInViewController *controller = [(MMPlugInView *)subview controller];
207 MMPlugInViewHeader *header = [controller headerView];
209 if ([header mouse:[header convertPoint:point fromView:sender]
210 inRect:[header dragRect]])
211 return [subview position] - 1;
216 - (NSRect)splitView:(RBSplitView*)sender cursorRect:(NSRect)rect
217 forDivider:(unsigned int)theDivider
220 if (theDivider != 0) return NSZeroRect;
224 MMPlugInView *view = (MMPlugInView *)[sender subviewAtPosition:i];
227 MMPlugInViewHeader *header = [[view controller] headerView];
228 NSRect rect = [header dragRect];
229 rect = [sender convertRect:rect fromView:header];
230 [sender addCursorRect:rect
231 cursor:[RBSplitView cursor:RBSVHorizontalCursor]];
238 - (void)clearDragInfo
241 MMPlugInView *save = dropView;
243 [[save controller] dropViewChanged];
247 // point should be in the window's coordinate system
248 - (void)updateDragInfo:(id<NSDraggingInfo>)info
251 [self clearDragInfo];
253 if (!([info draggingSourceOperationMask] & NSDragOperationPrivate)) return;
255 if (![[info draggingSource] isKindOfClass:[MMPlugInViewController class]]) return;
257 // for now has to be THIS container. in the future, it will be ok for any
258 // container associated with the same vim instance
259 if ([[info draggingSource] container] != self) return;
261 // XXX for now we just use the view that the mouse is currently over, and
262 // always insert "above" that view. In the future, we might want to try to
263 // find the divider that the mouse is closest to and have the dropView be
264 // the view below that divider.
266 NSPoint point = [info draggingLocation];
270 MMPlugInView *subview = (MMPlugInView *)[self subviewAtPosition:i];
273 if ([subview mouse:[subview convertPoint:point fromView:nil]
274 inRect:[subview bounds]]) {
280 if ([[info draggingSource] plugInSubview] == dropView)
283 if (dropView) [[dropView controller] dropViewChanged];
286 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
288 [self updateDragInfo:sender];
291 return NSDragOperationPrivate;
293 return NSDragOperationNone;
296 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
298 [self updateDragInfo:sender];
301 return NSDragOperationPrivate;
303 return NSDragOperationNone;
306 - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
308 [self updateDragInfo:sender];
309 return dropView != nil;
312 - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
314 MMPlugInViewController *source = [sender draggingSource];
315 [source moveToContainer:self before:dropView];
316 [self clearDragInfo];
320 - (void)draggingExited:(id<NSDraggingInfo>)sender
322 [self clearDragInfo];
326 - (MMPlugInView *)dropView {