summaryrefslogtreecommitdiff
path: root/src/Fl_cocoa.mm
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2009-12-13 12:03:26 +0000
committerMatthias Melcher <fltk@matthiasm.com>2009-12-13 12:03:26 +0000
commitc8278a23449da36df4e7177c49dcc6fc74683306 (patch)
treeb5d787a107b3a37d7c8d1034928fb58c5557fa44 /src/Fl_cocoa.mm
parent64716f01e27a9c8ec28cfa9fd9e9822930a14ada (diff)
New patches appliet for Cocoa port. Fixed(?) STR 2232 workaround for X11 keyrepeat bbbbuuuuuuggggg.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6966 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_cocoa.mm')
-rw-r--r--src/Fl_cocoa.mm222
1 files changed, 126 insertions, 96 deletions
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index 809f230c8..ce7665c41 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -54,6 +54,7 @@ extern "C" {
#include <FL/Fl_Window.H>
#include <FL/Fl_Tooltip.H>
#include <FL/Fl_Sys_Menu_Bar.H>
+#include <FL/Fl_Input_.H>
#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
@@ -1268,14 +1269,9 @@ extern "C" {
- (void)windowDidMiniaturize:(NSNotification *)notif;
- (void)windowWillClose:(NSNotification *)notif;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
@end
@implementation FLDelegate
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
-{
- fl_system_menu = [NSApp mainMenu];
-}
- (void)windowDidMove:(NSNotification *)notif
{
FLWindow *nsw = (FLWindow*)[notif object];
@@ -1882,14 +1878,14 @@ void Fl_X::make(Fl_Window* w)
}
else // create a desktop window
{
- NSAutoreleasePool *localPool;
- localPool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *localPool;
+ localPool = [[NSAutoreleasePool alloc] init];
Fl_Group::current(0);
fl_open_display();
- NSInteger winlevel = NSNormalWindowLevel;
- NSUInteger winstyle;
- if(w->border()) winstyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
- else winstyle = NSBorderlessWindowMask;
+ NSInteger winlevel = NSNormalWindowLevel;
+ NSUInteger winstyle;
+ if(w->border()) winstyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
+ else winstyle = NSBorderlessWindowMask;
int xp = w->x();
int yp = w->y();
int wp = w->w();
@@ -2809,11 +2805,11 @@ static void createAppleMenu(void)
[menuItem setSubmenu:appleMenu];
mainmenu = [[NSMenu alloc] initWithTitle:@""];
[mainmenu addItem:menuItem];
- if(MACsystemVersion < 0x1060) {
+ if(MACsystemVersion < 0x1060) {
// [NSApp setAppleMenu:appleMenu];
// to avoid compiler warning raised by use of undocumented setAppleMenu :
- [NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu];
- }
+ [NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu];
+ }
[NSApp setServicesMenu:services];
[NSApp setMainMenu:mainmenu];
CFRelease(nsappname);
@@ -2821,23 +2817,19 @@ static void createAppleMenu(void)
[mainmenu release];
[appleMenu release];
[menuItem release];
+ fl_system_menu = [NSApp mainMenu];
}
@interface FLMenuItem : NSMenuItem {
- const Fl_Menu_Item *item;
}
-- (void) setFlMenuItem:(const Fl_Menu_Item*)flItem;
- (void) doCallback:(id)unused;
- (void) directCallback:(id)unused;
-- (Fl_Menu_Item*)getFlMenuItem;
@end
@implementation FLMenuItem
-- (void) setFlMenuItem:(const Fl_Menu_Item*)flItem
-{
- item = flItem;
-}
- (void) doCallback:(id)unused
{
+ int flRank = [self tag];
+ const Fl_Menu_Item *item = fl_sys_menu_bar->Fl_Menu_::menu() + flRank;
if(item) {
fl_sys_menu_bar->picked(item);
if ( item->flags & FL_MENU_TOGGLE ) {// update the menu toggle symbol
@@ -2847,62 +2839,45 @@ static void createAppleMenu(void)
}
- (void) directCallback:(id)unused
{
+ Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes];
if( item && item->callback() ) item->do_callback(NULL);
}
-- (const Fl_Menu_Item*)getFlMenuItem
-{
- return item;
-}
@end
-void *MACmainMenu(void)
-{
- return (void *)[NSApp mainMenu];
-}
-void *MACcreateMenu(const char *name)
-// to create a new top-level menu in the apple menu bar
-// returns the created menu (NSMenu*)
-{
- fl_open_display();
- NSMenu *mymenu;
- NSMenuItem *menuItem;
- CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
- mymenu = [[NSMenu alloc] initWithTitle:(NSString*)cfname];
- CFRelease(cfname);
- // Put menu into the menubar
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:mymenu];
- [[NSApp mainMenu] addItem:menuItem];
- [menuItem release];
- [mymenu setAutoenablesItems:NO];
- [mymenu release];
- return (void *)mymenu;
-}
-
-void fl_mac_set_about( const Fl_Menu_Item *flItem )
+void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut = 0)
/**
- * Mac OS: attaches an Fl_Menu_Item to the "About myprog" item of the system application menu.
- * \note Only the shortcut_, callback_ and user_data_ fields of the Fl_Menu_Item* \p flItem are used.
+ * Mac OS: attaches a callback to the "About myprog" item of the system application menu.
*
* \author Manolo Gouy
*
- * \param[in] flItem is a const Fl_Menu_Item*
+ * \param[in] cb a callback that will be called by "About myprog" menu item
+ * \param[in] user_data a pointer transmitted as 2nd argument to the callback
+ * \param[in] shortcut optional shortcut to attach to the "About myprog" menu item (e.g., FL_META+'a')
*/
{
+ NSAutoreleasePool *localPool;
+ localPool = [[NSAutoreleasePool alloc] init];
fl_open_display();
+ Fl_Menu_Item aboutItem;
+ memset(&aboutItem, 0, sizeof(Fl_Menu_Item));
+ aboutItem.callback(cb);
+ aboutItem.user_data(user_data);
+ aboutItem.shortcut(shortcut);
CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]);
[appleMenu removeItemAtIndex:0];
FLMenuItem *item = [[FLMenuItem alloc] autorelease];
[item initWithTitle:(NSString*)cfname action:@selector(directCallback:) keyEquivalent:@""];
- if(flItem->shortcut()) {
- MACMenuOrItemOperation("setKeyEquivalent", item, flItem->shortcut() & 0xff);
- MACMenuOrItemOperation("setKeyEquivalentModifierMask", item, flItem->shortcut() );
+ if(aboutItem.shortcut()) {
+ MACMenuOrItemOperation("setKeyEquivalent", item, aboutItem.shortcut() & 0xff);
+ MACMenuOrItemOperation("setKeyEquivalentModifierMask", item, aboutItem.shortcut() );
}
- [item setFlMenuItem:flItem];
+ NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)];
+ [item setRepresentedObject:pointer];
[appleMenu insertItem:item atIndex:0];
CFRelease(cfname);
[item setTarget:item];
+ [localPool release];
}
static char *remove_ampersand(const char *s)
@@ -2929,6 +2904,8 @@ void *MACMenuOrItemOperation(const char *operation, ...)
/* these operations apply to menus, submenus, or menu items
*/
{
+ NSAutoreleasePool *localPool;
+ localPool = [[NSAutoreleasePool alloc] init];
NSMenu *menu;
NSMenuItem *item;
int value;
@@ -2945,7 +2922,8 @@ void *MACMenuOrItemOperation(const char *operation, ...)
else if(strcmp(operation, "setKeyEquivalent") == 0) {//arguments: NSMenuItem*, int
item = va_arg(ap, NSMenuItem*);
value = va_arg(ap, int);
- NSString *equiv = [[NSString alloc] initWithBytes:&value length:1 encoding:NSASCIIStringEncoding];
+ char key = value;
+ NSString *equiv = [[NSString alloc] initWithBytes:&key length:1 encoding:NSASCIIStringEncoding];
[item setKeyEquivalent:equiv];
[equiv release];
}
@@ -2973,7 +2951,6 @@ void *MACMenuOrItemOperation(const char *operation, ...)
CFRelease(title);
[menu setAutoenablesItems:NO];
retval = (void *)menu;
- [menu autorelease];
}
else if(strcmp(operation, "numberOfItems") == 0) {//arguments: NSMenu *menu, int *pcount
//upon return, *pcount is set to menu's item count
@@ -2986,6 +2963,7 @@ void *MACMenuOrItemOperation(const char *operation, ...)
item = va_arg(ap, NSMenuItem*);
menu = va_arg(ap, NSMenu*);
[item setSubmenu:menu];
+ [menu release];
}
else if(strcmp(operation, "setEnabled") == 0) {//arguments: NSMenuItem*, int
item = va_arg(ap, NSMenuItem*);
@@ -3009,32 +2987,49 @@ void *MACMenuOrItemOperation(const char *operation, ...)
value = va_arg(ap, int);
[menu removeItem:[menu itemAtIndex:value]];
}
- else if(strcmp(operation, "getFlMenuItem") == 0) {//arguments: NSMenu*, int. Returns the item's Fl_Menu_Item*
- menu = va_arg(ap, NSMenu*);
- value = va_arg(ap, int);
- retval = [(FLMenuItem *)[menu itemAtIndex:value] getFlMenuItem];
- }
- else if(strcmp(operation, "addNewItem") == 0) {
- //arguments: NSMenu *menu, const Fl_Menu_Item* flItem, int *prank
+ else if(strcmp(operation, "addNewItem") == 0) {//arguments: NSMenu *menu, int flrank, int *prank
//creates a new menu item at the end of 'menu'
- //attaches the Fl_Menu_Item *flItem to it
- //upon return, puts the rank of the new item in *prank unless prank is NULL
+ //attaches the item of rank flrank (counted in Fl_Menu_) of fl_sys_menu_bar to it
+ //upon return, puts the rank (counted in NSMenu) of the new item in *prank unless prank is NULL
menu = va_arg(ap, NSMenu*);
- const Fl_Menu_Item *flItem = va_arg(ap, const Fl_Menu_Item*);
- char *name = remove_ampersand(flItem->label());
+ int flRank = va_arg(ap, int);
+ char *name = remove_ampersand( (fl_sys_menu_bar->Fl_Menu_::menu() + flRank)->label());
int *prank = va_arg(ap, int*);
CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
free(name);
FLMenuItem *item = [FLMenuItem alloc];
[item initWithTitle:(NSString*)cfname action:@selector(doCallback:) keyEquivalent:@""];
- [item setFlMenuItem:flItem];
+ [item setTag:flRank];
[menu addItem:item];
CFRelease(cfname);
[item setTarget:item];
if(prank != NULL) *prank = [menu indexOfItem:item];
[item release];
+ }
+ else if(strcmp(operation, "renameItem") == 0) {//arguments: int rank, const char *newname
+ //renames the system menu item numbered rank in fl_sys_menu_bar->menu()
+ int rank = va_arg(ap, int);
+ char *newname = remove_ampersand( va_arg(ap, const char *) );
+ int countmenus = [(NSMenu*)fl_system_menu numberOfItems];
+ bool found = NO;
+ NSMenuItem *macitem;
+ for(int i = 1; (!found) && i < countmenus; i++) {
+ NSMenuItem *item = [(NSMenu*)fl_system_menu itemAtIndex:i];
+ NSMenu *submenu = [item submenu];
+ if(submenu == nil) continue;
+ int countitems = [submenu numberOfItems];
+ for(int j = 0; j < countitems; j++) {
+ macitem = [submenu itemAtIndex:j];
+ if([macitem tag] == rank) { found = YES; break; }
+ }
+ }
+ if(found) {
+ [macitem setTitle:[[[NSString alloc] initWithUTF8String:newname] autorelease]];
+ }
+ free(newname);
}
va_end(ap);
+ [localPool release];
return retval;
}
@@ -3043,39 +3038,24 @@ void MACsetkeywindow(void *nsw)
[(NSWindow*)nsw makeKeyAndOrderFront:nil];
}
-int MACpreparedrag(void)
+static NSImage *imageFromText(const char *text, int *pwidth, int *pheight)
{
- CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[0], fl_selection_length[0]);
- if (text==NULL) return false;
- NSAutoreleasePool *localPool;
- localPool = [[NSAutoreleasePool alloc] init];
- NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil];
- [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"];
- CFRelease(text);
- Fl_Widget *w = Fl::pushed();
- Fl_Window *win = w->window();
- while(win->window()) win = win->window();
- NSView *myview = [(NSWindow*)Fl_X::i(win)->xid contentView];
- NSEvent *theEvent = [NSApp currentEvent];
-
- char *p, *q;
- int width = 0, height, w2;
+ const char *p, *q;
+ int width = 0, height, w2, ltext = strlen(text);
fl_font(FL_HELVETICA, 10);
- fl_selection_buffer[0][ fl_selection_length[0] ] = 0;
- p = fl_selection_buffer[0];
+ p = text;
int nl = 0;
while((q=strchr(p, '\n')) != NULL) {
nl++;
w2 = fl_width(p, q - p);
if(w2 > width) width = w2;
p = q + 1;
- }
- if(fl_selection_buffer[0][ fl_selection_length[0] - 1] != '\n') {
+ }
+ if(text[ ltext - 1] != '\n') {
nl++;
w2 = fl_width(p);
if(w2 > width) width = w2;
- }
+ }
height = nl * fl_height() + 3;
width += 6;
Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height);
@@ -3083,7 +3063,7 @@ int MACpreparedrag(void)
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
fl_rectf(0,0,width,height);
fl_color(FL_BLACK);
- p = fl_selection_buffer[0];
+ p = text;
int y = fl_height();
while(TRUE) {
q = strchr(p, '\n');
@@ -3091,13 +3071,63 @@ int MACpreparedrag(void)
else {
fl_draw(p, 3, y);
break;
- }
+ }
y += fl_height();
p = q + 1;
- }
+ }
+ fl_end_offscreen();
+ NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off );
+ fl_delete_offscreen( off );
+ *pwidth = width;
+ *pheight = height;
+ return image;
+}
+
+static NSImage *defaultDragImage(int *pwidth, int *pheight)
+{
+ const int width = 16, height = 16;
+ Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height);
+ fl_begin_offscreen(off);
+ CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
+ fl_rectf(0,0,width,height);
+ CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6);
+ fl_rect(0,0,width,height);
+ fl_rect(2,2,width-4,height-4);
fl_end_offscreen();
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off );
fl_delete_offscreen( off );
+ *pwidth = width;
+ *pheight = height;
+ return image;
+}
+
+int MACpreparedrag(void)
+{
+ CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[0], fl_selection_length[0]);
+ if (text==NULL) return false;
+ NSAutoreleasePool *localPool;
+ localPool = [[NSAutoreleasePool alloc] init];
+ NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+ [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil];
+ [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"];
+ CFRelease(text);
+ Fl_Widget *w = Fl::pushed();
+ Fl_Window *win = w->window();
+ if(win == NULL) { win = (Fl_Window*)w; }
+ else { while(win->window()) win = win->window(); }
+ NSView *myview = [(NSWindow*)Fl_X::i(win)->xid contentView];
+ NSEvent *theEvent = [NSApp currentEvent];
+
+ int width, height;
+ NSImage *image;
+ if( dynamic_cast<Fl_Input_*>(w) != NULL) {
+ fl_selection_buffer[0][ fl_selection_length[0] ] = 0;
+ image = imageFromText(fl_selection_buffer[0], &width, &height);
+ }
+ else {
+ image = defaultDragImage(&width, &height);
+ }
+
static NSSize offset={0,0};
NSPoint pt = [theEvent locationInWindow];
pt.x -= width/2;