From 092e0cc8949f0686ce014bdd2ff28832b8a30506 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Wed, 4 Jun 2008 21:17:05 +0200 Subject: [PATCH] Add support for popup menus --- src/MacVim/MMAtsuiTextView.h | 1 - src/MacVim/MMAtsuiTextView.m | 5 --- src/MacVim/MMBackend.h | 1 - src/MacVim/MMBackend.m | 24 +------------ src/MacVim/MMTextView.h | 2 -- src/MacVim/MMTextView.m | 8 ----- src/MacVim/MMVimController.m | 57 ++++++++++++++++++++--------- src/MacVim/MMWindowController.h | 1 - src/MacVim/MMWindowController.m | 27 -------------- src/MacVim/gui_macvim.m | 63 ++++++++++----------------------- 10 files changed, 60 insertions(+), 129 deletions(-) diff --git a/src/MacVim/MMAtsuiTextView.h b/src/MacVim/MMAtsuiTextView.h index 97fabcc08e..48c976a1b8 100644 --- a/src/MacVim/MMAtsuiTextView.h +++ b/src/MacVim/MMAtsuiTextView.h @@ -54,7 +54,6 @@ enum { MMMaxCellsPerChar = 2 }; // // MMTextView methods // -- (NSEvent *)lastMouseDownEvent; - (void)setShouldDrawInsertionPoint:(BOOL)on; - (void)setPreEditRow:(int)row column:(int)col; - (void)hideMarkedTextField; diff --git a/src/MacVim/MMAtsuiTextView.m b/src/MacVim/MMAtsuiTextView.m index 8ed5713e4f..2e156912dd 100644 --- a/src/MacVim/MMAtsuiTextView.m +++ b/src/MacVim/MMAtsuiTextView.m @@ -247,11 +247,6 @@ enum { -- (NSEvent *)lastMouseDownEvent -{ - return nil; -} - - (void)setShouldDrawInsertionPoint:(BOOL)on { } diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index a49cb24054..b99af3ebdb 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -85,7 +85,6 @@ saving:(int)saving; - (int)presentDialogWithType:(int)type title:(char *)title message:(char *)msg buttons:(char *)btns textField:(char *)txtfield; -- (void)showPopupMenuWithName:(char *)name atMouseLocation:(BOOL)mouse; - (void)showToolbar:(int)enable flags:(int)flags; - (void)createScrollbarWithIdentifier:(long)ident type:(int)type; - (void)destroyScrollbarWithIdentifier:(long)ident; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 6df13500e2..a22419236b 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -748,28 +748,6 @@ static NSString *MMSymlinkWarningString = return retval; } -- (void)showPopupMenuWithName:(char *)name atMouseLocation:(BOOL)mouse -{ - int len = strlen(name); - int row = -1, col = -1; - - if (len <= 0) return; - - if (!mouse && curwin) { - row = curwin->w_wrow; - col = curwin->w_wcol; - } - - NSMutableData *data = [NSMutableData data]; - - [data appendBytes:&row length:sizeof(int)]; - [data appendBytes:&col length:sizeof(int)]; - [data appendBytes:&len length:sizeof(int)]; - [data appendBytes:name length:len]; - - [self queueMessage:ShowPopupMenuMsgID data:data]; -} - - (void)showToolbar:(int)enable flags:(int)flags { NSMutableData *data = [NSMutableData data]; @@ -1507,7 +1485,7 @@ static NSString *MMSymlinkWarningString = // to make synchronous calls from MacVim to Vim in order to get state. #ifdef FEAT_RIGHTLEFT - BOOL rightLeft = curwin->w_p_rl; + BOOL rightLeft = curwin ? curwin->w_p_rl : NO; #else BOOL rightLeft = NO; #endif diff --git a/src/MacVim/MMTextView.h b/src/MacVim/MMTextView.h index 0cd686d791..c8f04c292e 100644 --- a/src/MacVim/MMTextView.h +++ b/src/MacVim/MMTextView.h @@ -13,7 +13,6 @@ @interface MMTextView : NSTextView { BOOL shouldDrawInsertionPoint; - NSEvent *lastMouseDownEvent; NSTrackingRectTag trackingRectTag; BOOL isDragging; BOOL isAutoscrolling; @@ -34,7 +33,6 @@ - (id)initWithFrame:(NSRect)frame; -- (NSEvent *)lastMouseDownEvent; - (void)setShouldDrawInsertionPoint:(BOOL)on; - (void)setPreEditRow:(int)row column:(int)col; - (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape diff --git a/src/MacVim/MMTextView.m b/src/MacVim/MMTextView.m index 912b02151d..a99b21b11a 100644 --- a/src/MacVim/MMTextView.m +++ b/src/MacVim/MMTextView.m @@ -128,15 +128,9 @@ enum { markedTextField = nil; } - [lastMouseDownEvent release]; lastMouseDownEvent = nil; [super dealloc]; } -- (NSEvent *)lastMouseDownEvent -{ - return lastMouseDownEvent; -} - - (BOOL)shouldDrawInsertionPoint { // NOTE: The insertion point is drawn manually in drawRect:. It would be @@ -820,8 +814,6 @@ enum { if (![self convertPoint:pt toRow:&row column:&col]) return; - lastMouseDownEvent = [event copy]; - int button = [event buttonNumber]; int flags = [event modifierFlags]; int count = [event clickCount]; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 53d8daf371..e27ee3ffcf 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -80,6 +80,9 @@ static NSTimeInterval MMResendInterval = 0.5; - (void)addToolbarItemWithLabel:(NSString *)label tip:(NSString *)tip icon:(NSString *)icon atIndex:(int)idx; +- (void)popupMenuWithDescriptor:(NSArray *)desc + atRow:(NSNumber *)row + column:(NSNumber *)col; - (void)connectionDidDie:(NSNotification *)notification; #if MM_RESEND_LAST_FAILURE - (void)resendTimerFired:(NSTimer *)timer; @@ -746,23 +749,10 @@ static NSTimeInterval MMResendInterval = 0.5; [actionName release]; } else if (ShowPopupMenuMsgID == msgid) { - const void *bytes = [data bytes]; - int row = *((int*)bytes); bytes += sizeof(int); - int col = *((int*)bytes); bytes += sizeof(int); - int len = *((int*)bytes); bytes += sizeof(int); - NSString *title = [[NSString alloc] - initWithBytes:(void*)bytes length:len - encoding:NSUTF8StringEncoding]; - - NSMenu *menu = [self topLevelMenuForTitle:title]; - if (menu) { - [windowController popupMenu:menu atRow:row column:col]; - } else { - NSLog(@"WARNING: Cannot popup menu with title %@; no such menu.", - title); - } - - [title release]; + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self popupMenuWithDescriptor:[attrs objectForKey:@"descriptor"] + atRow:[attrs objectForKey:@"row"] + column:[attrs objectForKey:@"column"]]; } else if (SetMouseShapeMsgID == msgid) { const void *bytes = [data bytes]; int shape = *((int*)bytes); bytes += sizeof(int); @@ -1176,6 +1166,39 @@ static NSTimeInterval MMResendInterval = 0.5; [toolbar insertItemWithItemIdentifier:label atIndex:idx]; } +- (void)popupMenuWithDescriptor:(NSArray *)desc + atRow:(NSNumber *)row + column:(NSNumber *)col +{ + NSMenu *menu = [[self menuItemForDescriptor:desc] submenu]; + if (!menu) return; + + id textView = [[windowController vimView] textView]; + NSPoint pt; + if (row && col) { + // TODO: Let textView convert (row,col) to NSPoint. + int r = [row intValue]; + int c = [col intValue]; + NSSize cellSize = [textView cellSize]; + pt = NSMakePoint((c+1)*cellSize.width, (r+1)*cellSize.height); + pt = [textView convertPoint:pt toView:nil]; + } else { + pt = [[windowController window] mouseLocationOutsideOfEventStream]; + } + + NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown + location:pt + modifierFlags:0 + timestamp:0 + windowNumber:[[windowController window] windowNumber] + context:nil + eventNumber:0 + clickCount:0 + pressure:1.0]; + + [NSMenu popUpContextMenu:menu withEvent:event forView:textView]; +} + - (void)connectionDidDie:(NSNotification *)notification { //NSLog(@"%@ %s%@", [self className], _cmd, notification); diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h index 97b18b21ab..c2fe2ec25c 100644 --- a/src/MacVim/MMWindowController.h +++ b/src/MacVim/MMWindowController.h @@ -51,7 +51,6 @@ - (void)setFont:(NSFont *)font; - (void)setWideFont:(NSFont *)font; - (void)processCommandQueueDidFinish; -- (void)popupMenu:(NSMenu *)menu atRow:(int)row column:(int)col; - (void)showTabBar:(BOOL)on; - (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode; - (void)setMouseShape:(int)shape; diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 2a78cae3d4..c1f7b26ab2 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -411,33 +411,6 @@ } } -- (void)popupMenu:(NSMenu *)menu atRow:(int)row column:(int)col -{ - if (!setupDone) return; - - NSEvent *event; - if (row >= 0 && col >= 0) { - // TODO: Let textView convert (row,col) to NSPoint. - NSSize cellSize = [[vimView textView] cellSize]; - NSPoint pt = { (col+1)*cellSize.width, (row+1)*cellSize.height }; - pt = [[vimView textView] convertPoint:pt toView:nil]; - - event = [NSEvent mouseEventWithType:NSRightMouseDown - location:pt - modifierFlags:0 - timestamp:0 - windowNumber:[[self window] windowNumber] - context:nil - eventNumber:0 - clickCount:0 - pressure:1.0]; - } else { - event = [[vimView textView] lastMouseDownEvent]; - } - - [NSMenu popUpContextMenu:menu withEvent:event forView:[vimView textView]]; -} - - (void)showTabBar:(BOOL)on { [[vimView tabBarControl] setHidden:!on]; diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index 99aa689957..17f68faa5d 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -615,6 +615,10 @@ clip_mch_set_selection(VimClipboard *cbd) // -- Menu ------------------------------------------------------------------ +/* + * A menu descriptor represents the "address" of a menu as an array of strings. + * E.g. the menu "File->Close" has descriptor { "File", "Close" }. + */ NSArray * descriptor_for_menu(vimmenu_T *menu) { @@ -656,37 +660,17 @@ menu_for_descriptor(NSArray *desc) } /* - * Add a sub menu to the menu bar. + * Add a submenu to the menu bar, toolbar, or a popup menu. */ void gui_mch_add_menu(vimmenu_T *menu, int idx) { - // HACK! If menu has no parent, then we set the parent tag to the type of - // menu it is. This will not mix up tag and type because pointers can not - // take values close to zero (and the tag is simply the value of the - // pointer). - int parent = (int)menu->parent; - if (!parent) { - parent = menu_is_popup(menu->name) ? MenuPopupType : - menu_is_toolbar(menu->name) ? MenuToolbarType : - MenuMenubarType; - } - - char_u *dname = menu->dname; -#ifdef FEAT_MBYTE - dname = CONVERT_TO_UTF8(dname); -#endif - NSArray *desc = descriptor_for_menu(menu); [[MMBackend sharedInstance] queueMessage:AddMenuMsgID properties: [NSDictionary dictionaryWithObjectsAndKeys: desc, @"descriptor", [NSNumber numberWithInt:idx], @"index", nil]]; - -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(dname); -#endif } @@ -775,19 +759,9 @@ gui_mch_menu_hidden(vimmenu_T *menu, int hidden) void gui_mch_show_popupmenu(vimmenu_T *menu) { -#if 0 - char_u *name = menu->name; -#ifdef FEAT_MBYTE - name = CONVERT_TO_UTF8(name); -#endif - - [[MMBackend sharedInstance] showPopupMenuWithName:(char*)name - atMouseLocation:YES]; - -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(name); -#endif -#endif + NSArray *desc = descriptor_for_menu(menu); + [[MMBackend sharedInstance] queueMessage:ShowPopupMenuMsgID properties: + [NSDictionary dictionaryWithObject:desc forKey:@"descriptor"]]; } @@ -797,18 +771,19 @@ gui_mch_show_popupmenu(vimmenu_T *menu) void gui_make_popup(char_u *path_name, int mouse_pos) { -#if 0 -#ifdef FEAT_MBYTE - path_name = CONVERT_TO_UTF8(path_name); -#endif + vimmenu_T *menu = gui_find_menu(path_name); + if (!(menu && menu->children)) return; - [[MMBackend sharedInstance] showPopupMenuWithName:(char*)path_name - atMouseLocation:mouse_pos]; + NSArray *desc = descriptor_for_menu(menu); + NSDictionary *p = (mouse_pos || NULL == curwin) + ? [NSDictionary dictionaryWithObject:desc forKey:@"descriptor"] + : [NSDictionary dictionaryWithObjectsAndKeys: + desc, @"descriptor", + [NSNumber numberWithInt:curwin->w_wrow], @"row", + [NSNumber numberWithInt:curwin->w_wcol], @"column", + nil]; -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(path_name); -#endif -#endif + [[MMBackend sharedInstance] queueMessage:ShowPopupMenuMsgID properties:p]; }