// cocoa.macos.m // blitzmax cocoa interface // by simonarmstrong@blitzbasic.com #include #include #include a #include #include #include #include #include #include #include #define STATUSBARHEIGHT 18 // Custom Cursor Stuff const int curNoEntry = 0; const int curHelp = 1; const int curSizeAll = 2; const int curNESW = 3; const int curNWSE = 4; typedef struct { short bits[16]; short mask[16]; short hitpoint[2]; } ArrayCursor; ArrayCursor arrCursors[5] = {{{0x0000, 0x07E0, 0x1FF0, 0x3838, 0x3C0C, 0x6E0E, 0x6706, 0x6386, 0x61C6, 0x60E6, 0x7076, 0x303C, 0x1C1C, 0x0FF8, 0x07E0, 0x0000}, {0x0540, 0x0FF0, 0x3FF8, 0x3C3C, 0x7E0E, 0xFF0F, 0x6F86, 0xE7C7, 0x63E6, 0xE1F7, 0x70FE, 0x707E, 0x3C3C, 0x1FFC, 0x0FF0, 0x0540}, {0x0007, 0x0007}}, {{0x0000, 0x4078, 0x60FC, 0x71CE, 0x7986, 0x7C06, 0x7E0E, 0x7F1C, 0x7FB8, 0x7C30, 0x6C30, 0x4600, 0x0630, 0x0330, 0x0300, 0x0000}, {0xC078, 0xE0FC, 0xF1FE, 0xFBFF, 0xFFCF, 0xFF8F, 0xFF1F, 0xFFBE, 0xFFFC, 0xFE78, 0xFF78, 0xEFF8, 0xCFF8, 0x87F8, 0x07F8, 0x0300}, {0x0001, 0x0001}}, {{0x0000, 0x0080, 0x01C0, 0x03E0, 0x0080, 0x0888, 0x188C, 0x3FFE, 0x188C, 0x0888, 0x0080, 0x03E0, 0x01C0, 0x0080, 0x0000, 0x0000}, {0x0080, 0x01C0, 0x03E0, 0x07F0, 0x0BE8, 0x1DDC, 0x3FFE, 0x7FFF, 0x3FFE, 0x1DDC, 0x0BE8, 0x07F0, 0x03E0, 0x01C0, 0x0080, 0x0000}, {0x0007, 0x0008}}, {{0x0000, 0x001E, 0x000E, 0x060E, 0x0712, 0x03A0, 0x01C0, 0x00E0, 0x0170, 0x1238, 0x1C18, 0x1C00, 0x1E00, 0x0000, 0x0000, 0x0000}, {0x007F, 0x003F, 0x0E1F, 0x0F0F, 0x0F97, 0x07E3, 0x03E1, 0x21F0, 0x31F8, 0x3A7C, 0x3C3C, 0x3E1C, 0x3F00, 0x3F80, 0x0000, 0x0000}, {0x0006, 0x0009}}, {{0x0000, 0x7800, 0x7000, 0x7060, 0x48E0, 0x05C0, 0x0380, 0x0700, 0x0E80, 0x1C48, 0x1838, 0x0038, 0x0078, 0x0000, 0x0000, 0x0000}, {0xFE00, 0xFC00, 0xF870, 0xF0F0, 0xE9F0, 0xC7E0, 0x87C0, 0x0F84, 0x1F8C, 0x3E5C, 0x3C3C, 0x387C, 0x00FC, 0x01FC, 0x0000, 0x0000}, {0x0006, 0x0006}}}; // End of Cursor Stuff void* NSActiveGadget(); void brl_event_EmitEvent( BBObject *event ); BBObject *maxgui_maxgui_HotKeyEvent( int key,int mods ); void maxgui_maxgui_event_DispatchGuiEvents(); void maxgui_cocoamaxgui_cocoagui_EmitCocoaOSEvent( NSEvent *event,void *handle,BBObject *gadget ); int maxgui_cocoamaxgui_cocoagui_EmitCocoaMouseEvent( NSEvent *event,void *handle ); int maxgui_cocoamaxgui_cocoagui_EmitCocoaKeyEvent( NSEvent *event,void *handle ); #ifdef __x86_64 void maxgui_cocoamaxgui_cocoagui_PostCocoaGuiEvent( int ev,void *handle,BBInt64 data,int mods,int x,int y,BBObject *extra ); #else void maxgui_cocoamaxgui_cocoagui_PostCocoaGuiEvent( int ev,void *handle,int data,int mods,int x,int y,BBObject *extra ); #endif int maxgui_cocoamaxgui_cocoagui_FilterChar( void *handle,int key,int mods ); int maxgui_cocoamaxgui_cocoagui_FilterKeyDown( void *handle,int key,int mods ); static void EmitOSEvent( NSEvent *event,void *handle ){ //printf("EmitOSEvent\n");fflush(stdout); maxgui_cocoamaxgui_cocoagui_EmitCocoaOSEvent( event,handle,&bbNullObject ); } int HaltMouseEvents; static int EmitMouseEvent( NSEvent *event,void *handle ){ if(([event type] == NSScrollWheel) && ([event deltaY] == 0)) return 0; if(!HaltMouseEvents) return maxgui_cocoamaxgui_cocoagui_EmitCocoaMouseEvent( event,handle ); } static int EmitKeyEvent( NSEvent *event,void *handle ){ return maxgui_cocoamaxgui_cocoagui_EmitCocoaKeyEvent( event,handle ); } #ifdef __x86_64 static void PostGuiEvent( int ev,void *handle,BBInt64 data,int mods,int x,int y,BBObject *extra ){ #else static void PostGuiEvent( int ev,void *handle,int data,int mods,int x,int y,BBObject *extra ){ #endif //printf("PostGuiEvent\n");fflush(stdout); if (extra==0) extra=&bbNullObject; maxgui_cocoamaxgui_cocoagui_PostCocoaGuiEvent( ev,handle,data,mods,x,y,extra ); } static int filterKeyDownEvent( NSEvent *event,id source ){ int i,sz,res,key,mods; NSString *ch; key=bbSystemTranslateKey( [event keyCode] ); mods=bbSystemTranslateMods( [event modifierFlags] ); res=maxgui_cocoamaxgui_cocoagui_FilterKeyDown( source,key,mods ); if (res==0) return 0; ch=[event characters]; sz=[ch length]; for( i=0;i)sender; -(BOOL)performDragOperation:(id )sender; -(void)didResize; -(void)didMove; -(void)zoom; -(NSRect)localRect; -(BOOL)canBecomeKeyWindow; -(BOOL)canBecomeMainWindow; -(BOOL)becomeFirstResponder; -(void)setEnabled:(BOOL)flag; -(BOOL)isEnabled; -(void)dealloc; @end @interface ToolView:NSPanel{ id view; id label[3]; nsgadget *gadget; int enabled; int zooming; NSView *dragging; } -(id)textFirstResponder; -(id)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)backing defer:(BOOL)flag withGadget:(nsgadget*)_gadget ; -(id)clientView; -(void)setStatus:(NSString*)text align:(int)pos; -(void)sendEvent:(NSEvent*)event; -(NSDragOperation)draggingEntered:(id )sender; -(BOOL)performDragOperation:(id )sender; -(void)didResize; -(void)didMove; -(void)zoom; -(NSRect)localRect; -(BOOL)canBecomeKeyWindow; -(BOOL)canBecomeMainWindow; -(BOOL)becomeFirstResponder; -(void)setEnabled:(BOOL)flag; -(BOOL)isEnabled; -(void)dealloc; @end static CocoaApp *GlobalApp; @class HTMLView; @interface HTMLView:WebView{ int _state, _style; } -(id)initWithFrame:(NSRect)rect; -(int)loaded; -(void)setStyle:(int)style; -(void)setAddress:(NSString*)address; -(NSString*)address; @end @implementation HTMLView -(id)initWithFrame:(NSRect)rect{ self=[super initWithFrame:rect]; [self setAutoresizingMask:NSViewNotSizable]; [self setPolicyDelegate:self]; [self setFrameLoadDelegate:self]; [self setUIDelegate:self]; [self unregisterDraggedTypes]; _state=0; return self; } -(int)loaded{ return _state; } -(void)setStyle:(int)style{ _style = style; } -(NSString*)address{ WebDataSource *datasource; datasource = [[self mainFrame] provisionalDataSource]; if(datasource==nil) datasource = [[self mainFrame] dataSource]; if(datasource==nil) return [[NSString alloc] initWithString:@""]; return [[[datasource request] URL] absoluteString]; } -(void)setAddress:(NSString*)address{ NSURL *url; NSURLRequest *request; WebFrame *frame; url=[NSURL URLWithString:address]; if (url==nil) url=[NSURL fileURLWithPath:address]; if (url==nil) return; _state=1; request=[NSURLRequest requestWithURL:url]; frame=[self mainFrame]; [frame loadRequest:request]; } - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame{ int oldstate = _state; NSURLRequest *url; BBString*text; _state=0; url=[[frame dataSource]initialRequest]; text=bbStringFromCString((char*)[[[url URL] relativePath] cString]); if(oldstate) PostGuiEvent( BBEVENT_GADGETDONE,sender,0,0,0,0,(BBObject*)text ); } - (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame{ int oldstate = _state; NSURLRequest *url; BBString*text; _state=0; url=[[frame dataSource]initialRequest]; text=bbStringFromCString((char*)[[[url URL] relativePath] cString]); if(oldstate) PostGuiEvent( BBEVENT_GADGETDONE,sender,0,0,0,0,(BBObject*)text ); } - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)url frame:(WebFrame *)frame decisionListener:(id)listener{ BBString*text; int key; key=(int)[[actionInformation objectForKey:WebActionNavigationTypeKey] intValue]; switch (key){ case WebNavigationTypeOther: case WebNavigationTypeLinkClicked: if ((_state==0) && (_style & HTMLVIEW_NONAVIGATE)) { [listener ignore]; text=bbStringFromCString((char*)[[[url URL] absoluteString] cString]); PostGuiEvent( BBEVENT_GADGETACTION,sender,0,0,0,0,(BBObject*)text ); }else{ [listener use]; } default: [listener use]; } } - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems{ if(_style&HTMLVIEW_NOCONTEXTMENU) return [NSArray array]; else return defaultMenuItems; } @end //Toolbar @class Toolbar; @interface Toolbar:NSToolbar{ NSMutableDictionary *items; } -(id)initWithIdentifier:(NSString *)string; -(void)addToolbarItem:(NSToolbarItem *)item; -(NSArray *)toolbarAllowedItemIdentifiers; -(NSArray *)toolbarDefaultItemIdentifiers; @end @implementation Toolbar -(id)initWithIdentifier:(NSString *)string{ self=[super initWithIdentifier:string]; items=[[NSMutableDictionary dictionaryWithCapacity:10] retain]; return self; } -(void)addToolbarItem:(NSToolbarItem *)item{ [items setObject:item forKey:[item itemIdentifier]]; } -(NSArray *)toolbarAllowedItemIdentifiers{ return [items allValues]; } -(NSArray *)toolbarDefaultItemIdentifiers{ return [items allValues]; } @end // CocoaApp @implementation CocoaApp +(void)dispatchGuiEvents{ maxgui_maxgui_event_DispatchGuiEvents(); } +(void)delayedGadgetAction:(NSObject*)o{ // See controlTextDidChange PostGuiEvent( BBEVENT_GADGETACTION, o, [o respondsToSelector:@selector(indexOfSelectedItem)] ? [o indexOfSelectedItem] : 0, 0,0,0,0 ); } -(void)controlTextDidEndEditing:(NSNotification*)n{ PostGuiEvent( BBEVENT_GADGETLOSTFOCUS,[n object],0,0,0,0,0 ); } -(void)controlTextDidChange:(NSNotification*)n{ NSObject *o = [n object]; [CocoaApp performSelector:@selector(delayedGadgetAction:) withObject:o afterDelay:0.0]; } -(id)init{ toolbaritems=[[NSMutableDictionary dictionaryWithCapacity:10] retain]; menuitems=[[NSMutableArray arrayWithCapacity:10] retain]; return self; } -(BOOL)windowShouldClose:(id)sender{ PostGuiEvent( BBEVENT_WINDOWCLOSE,sender,0,0,0,0,0 ); return NO; } -(void)windowDidResize:(NSNotification *)aNotification{ WindowView *window; ToolView * panel; if ([[aNotification object] isKindOfClass:[WindowView class]]) { window=(WindowView*)[aNotification object]; [window didResize]; } else { panel =(ToolView*)[aNotification object]; [panel didResize]; } } -(void)windowDidMove:(NSNotification *)aNotification{ WindowView *window; ToolView * panel; if ([[aNotification object] isKindOfClass:[WindowView class]]) { window=(WindowView*)[aNotification object]; [window didMove]; } else { panel =(ToolView*)[aNotification object]; [panel didMove]; } } -(BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame{ [(WindowView*)sender zoom]; return YES; } -(void)windowDidBecomeKey:(NSNotification *)aNotification{ NSWindow *window; window=(NSWindow*)[aNotification object]; PostGuiEvent( BBEVENT_WINDOWACTIVATE,window,0,0,0,0,0 ); } -(void)menuSelect:(id)sender{ PostGuiEvent( BBEVENT_MENUACTION,sender,[sender tag],0,0,0,0 ); } -(void)iconSelect:(id)sender{ NSToolbar *toolbar; int index; toolbar=[sender toolbar]; index=[[toolbar items] indexOfObject:sender]; PostGuiEvent( BBEVENT_GADGETACTION,toolbar,index,0,0,0,0 ); } -(void)sliderSelect:(id)sender{ PostGuiEvent( BBEVENT_GADGETACTION,sender,0,0,0,0,0 ); } -(void)scrollerSelect:(id)sender{ NSScroller *scroller; int delta=0; scroller=(NSScroller *)sender; switch([scroller hitPart]){ case NSScrollerDecrementLine: delta=-1; break; case NSScrollerDecrementPage: delta=-2; break; case NSScrollerIncrementLine: delta=1; break; case NSScrollerIncrementPage: delta=2; break; } PostGuiEvent( BBEVENT_GADGETACTION,sender,delta,0,0,0,0 ); } -(void)buttonPush:(id)sender{ if([sender allowsMixedState]) [sender setAllowsMixedState:NO]; PostGuiEvent( BBEVENT_GADGETACTION,sender,0,0,0,0,0 ); } -(void)textEdit:(id)sender{ PostGuiEvent( BBEVENT_GADGETACTION,sender,0,0,0,0,0 ); } -(void)comboBoxSelectionDidChange:(NSNotification *)notification{ NSControl *o=(NSComboBox*)[notification object]; [CocoaApp performSelector:@selector(delayedGadgetAction:) withObject:o afterDelay:0.0]; } -(void)comboBoxSelectionIsChanging:(NSNotification *)notification{ } -(void)comboBoxWillPopUp:(NSNotification *)notification{ HaltMouseEvents = 1; } -(void)comboBoxWillDismiss:(NSNotification *)notification{ HaltMouseEvents = 0; } -(void)addToolbarItem:(NSToolbarItem *)item{ [toolbaritems setObject:item forKey:[item itemIdentifier]]; } -(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag{ return [toolbaritems objectForKey:itemIdentifier]; } -(NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar{ Toolbar *mytoolbar=(Toolbar*)toolbar; return [mytoolbar toolbarAllowedItemIdentifiers]; } -(NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar{ Toolbar *mytoolbar=(Toolbar*)toolbar; return [mytoolbar toolbarDefaultItemIdentifiers]; } -(BOOL)validateToolbarItem:(NSToolbarItem *)item{ return [item isEnabled]; } -(void)addMenuItem:(NSMenuItem *)item{ [menuitems addObject:item]; } -(void)removeMenuItem:(NSMenuItem *)item{ [menuitems removeObject:item]; } @end // Scroller @implementation Scroller -(id)init{ [super init]; [self setAlphaValue:.5f]; return self; } //-(void)drawKnob{} //-(void)drawParts{} //-(void)drawKnobSlotInRect:(NSRect)slotRect highlight:(BOOL)flag{} //-(void)drawArrow:(NSScrollerArrow)arrow highlight:(BOOL)flag{} //-(void)highlight:(BOOL)flag{} @end // FlippedView @implementation FlippedView -(BOOL)isFlipped{ return YES; } -(BOOL)mouseDownCanMoveWindow{ return YES; } @end // PanelView @implementation PanelView - (BOOL)acceptsFirstResponder{ return YES; } -(BOOL)becomeFirstResponder{ return [self isEnabled]; } -(void)setColor:(NSColor *)rgb{ [[self contentView] setColor:rgb]; } -(void)setAlpha:(float)al{ [[self contentView] setAlpha:al]; } -(void)setImage:(NSImage *)img withFlags:(int)flags{ [[self contentView] setImage:img withFlags:flags]; } -(void)setEnabled:(BOOL)e{ enabled=e; } -(BOOL)isEnabled{ return (enabled)?YES:NO; } -(void)setStyle:(int)s{ gadget->sensitivity |= (s & PANEL_ACTIVE) ? (SENSITIZE_MOUSE|SENSITIZE_KEYS) : 0; switch ( s & (PANEL_SUNKEN|PANEL_RAISED|PANEL_GROUP) ){ case PANEL_GROUP: [self setContentViewMargins: NSMakeSize(4.0,4.0)]; [self setBoxType:NSBoxPrimary]; [self setBorderType: NSBezelBorder]; [self setTitlePosition: NSAtTop]; break; case PANEL_RAISED: case PANEL_SUNKEN: [self setContentViewMargins: NSMakeSize(0.0,0.0)]; [self setBoxType: NSBoxOldStyle]; [self setBorderType: NSLineBorder]; [self setTitlePosition: NSNoTitle]; break; default: [self setContentViewMargins: NSMakeSize(0.0,0.0)]; [self setBorderType: NSNoBorder]; [self setTitlePosition: NSNoTitle]; } style=s; } -(void)setGadget:(nsgadget*)_gadget{ gadget=_gadget; } -(BOOL)mouseDownCanMoveWindow{ return NO; } @end //PanelViewContent @implementation PanelViewContent -(BOOL)isFlipped{ return YES; } -(BOOL)mouseDownCanMoveWindow{ return NO; } -(void)setColor:(NSColor *)rgb{ if (color){ [color release]; color=0; } if(rgb){ color=[rgb colorWithAlphaComponent:1.0]; [color retain]; } [self setNeedsDisplay:YES]; } -(void)setImage:(NSImage *)img withFlags:(int)flags{ if (img) [img retain]; if (image) [image release]; image=img; imageflags=flags; [self setNeedsDisplay:YES]; } -(void)setAlpha:(float)al{ alpha=al; if (color){ [color release]; color=[color colorWithAlphaComponent:alpha]; [color retain]; } [self setNeedsDisplay:YES]; } -(void)drawRect:(NSRect)rect{ NSRect dest = NSUnionRect(rect,[self frame]); if (color){ [color set]; if (alpha<1.0) NSRectFillUsingOperation( dest,NSCompositeSourceOver ); else NSRectFill( dest ); } if (image){ int op,x,y,w,h; float a; float m,mm; NSRect src,tile; a=alpha; op=NSCompositeSourceOver; src.origin.x=0; src.origin.y=0; src.size=[image size]; [image setFlipped:YES]; switch (imageflags&(GADGETPIXMAP_ICON-1)){ case PANELPIXMAP_TILE: tile.size=[image size]; for (y=0;ymm) m=mm; dest.origin.x+=(dest.size.width-src.size.width*m)/2; dest.origin.y+=(dest.size.height-src.size.height*m)/2; dest.size.width=src.size.width*m; dest.size.height=src.size.height*m; [image drawInRect:dest fromRect:src operation:op fraction:a]; break; case PANELPIXMAP_STRETCH: [image drawInRect:dest fromRect:src operation:op fraction:a]; break; case PANELPIXMAP_FIT2: m = dest.size.width/dest.size.height; if ((dest.size.width/src.size.width)<(dest.size.height/src.size.height)){ src.origin.x = (src.size.width-(src.size.height*m))/2; src.size.width = src.size.height*m; } else { src.origin.y = (src.size.height-(src.size.width/m))/2; src.size.height = src.size.width/m; } [image drawInRect:dest fromRect:src operation:op fraction:a]; break; } [image setFlipped:NO]; } [super drawRect:rect]; } @end // CanvasView @implementation CanvasView -(void)drawRect:(NSRect)rect{ [super drawRect:rect]; PostGuiEvent( BBEVENT_GADGETPAINT,self,0,0,0,0,0 ); } - (BOOL)acceptsFirstResponder{ return YES; } -(BOOL)becomeFirstResponder{ return [self isEnabled]; } @end // ImageString @class ImageString; @interface ImageString:NSObject{ NSString *_string; NSImage *_image; NSString *_tip; BBObject *_extra; } -(id)initWithString:(NSString *)text image:(NSImage *)image tip:(NSString *)tip extra:(BBObject*)extra; -(void)dealloc; -(id)copyWithZone:(NSZone *)zone; -(NSString*)string; -(NSImage*)image; -(NSString*)description; -(BBObject*)extra; @end @implementation ImageString -(id)initWithString:(NSString *)string image:(NSImage *)image tip:(NSString*)tip extra:(BBObject*)extra{ _string=string; _image=image; _tip=tip; _extra=extra; if (string) [string retain]; if (image) [image retain]; if (tip) [tip retain]; return self; } -(void)dealloc{ if (_string) [_string release]; if (_image) [_image release]; if (_tip) [_tip release]; [super dealloc]; } -(id)copyWithZone:(NSZone *)zone{ ImageString *copy=[[[self class] allocWithZone:zone] initWithString:_string image:_image tip:_tip extra:_extra]; return copy; } -(NSString*)string{return _string;} -(NSImage*)image{return _image;} -(NSString*)description{return _tip;} -(BBObject*)extra{return _extra;} @end // ListView @implementation ListView -(id)initWithFrame:(NSRect)rect{ [super initWithFrame:rect]; [self setBorderType:NSNoBorder]; [self setHasVerticalScroller:YES]; [self setHasHorizontalScroller:YES]; [self setAutohidesScrollers:YES]; column=[[NSTableColumn alloc] init]; cell=[[NSBrowserCell alloc] init]; [cell setLeaf:YES]; [column setDataCell:cell]; NSSize contentSize = [self contentSize]; table=[[TableView alloc] initWithFrame:NSMakeRect(0, 0,contentSize.width, contentSize.height)]; [table setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; items=[[NSMutableArray alloc] initWithCapacity:10]; [table setHeaderView:nil]; [table setDataSource:self]; [table setDelegate:self]; [self setDocumentView:table]; [table addTableColumn:column]; [table sizeLastColumnToFit]; return self; } -(id)table{ return table; } -(id)items{ return items; } -(void)removeItemAtIndex:(int)index{ ImageString *item=(ImageString*)[items objectAtIndex:index]; [items removeObjectAtIndex:index]; [item release]; [table reloadData]; [self queueWidthUpdate]; } -(void)setColor:(NSColor*)color{ [table setBackgroundColor:color]; } -(void)setEnabled:(BOOL)e{ [table setEnabled:e]; } -(BOOL)isEnabled{ return [table isEnabled]; } -(void)setTextColor:(NSColor*)color{ if (textstyle) {[textstyle release];textstyle=nil;} if (color){ textstyle=[NSDictionary dictionaryWithObjectsAndKeys:color,NSForegroundColorAttributeName,nil]; [textstyle retain]; } } -(int)numberOfRowsInTableView:(NSTableView *)aTableView{ return [items count]; } -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{ return [items objectAtIndex:rowIndex]; } -(BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(int)rowIndex{ /*new from BAH*/ PostGuiEvent( BBEVENT_GADGETACTION,self,rowIndex,0,0,0,0 ); return NO; } -(void)clear{ [table setDelegate:nil]; ImageString *item; int count,i; count=[items count]; for (i=0;i=0) item=(ImageString*)[items objectAtIndex:index]; else index=-1; if (item){ PostGuiEvent( BBEVENT_GADGETSELECT,self,index,0,0,0,[item extra]); }else{ PostGuiEvent( BBEVENT_GADGETSELECT,self,-1,0,0,0,&bbNullObject); } } -(void)tableView:(NSTableView *)table willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{ NSString *text=[[items objectAtIndex:rowIndex] string]; if (textstyle){ NSAttributedString *atext=[[[NSAttributedString alloc] initWithString:text attributes:textstyle] autorelease]; [aCell setAttributedStringValue:atext]; }else{ [aCell setStringValue:text]; } [aCell setImage:[[items objectAtIndex:rowIndex] image]]; } -(void)updateWidthForString:(ImageString *) imgstring{ NSCell* dcell; float cellWidth; dcell = [column dataCell]; [dcell setStringValue:[imgstring string]]; [dcell setImage:[imgstring image]]; cellWidth = ((NSSize)[dcell cellSize]).width; if([column minWidth] < cellWidth){ [column setMinWidth:cellWidth]; [column setWidth:cellWidth]; [table setNeedsDisplay:YES]; } } -(void)updateWidth{ int i, count; count = [items count]; for (i=0;i-1 && i<[self numberOfRows]){ node=[self itemAtRow:i]; #ifdef __x86_64 PostGuiEvent( BBEVENT_GADGETMENU,[self dataSource],(BBInt64)node,0,0,0,0 ); //[self superview] #else PostGuiEvent( BBEVENT_GADGETMENU,[self dataSource],(int)node,0,0,0,0 ); //[self superview] #endif } return nil; } @end @implementation VerticalCenterAlignedBrowserCell - (NSRect)titleRectForBounds:(NSRect)theRect { NSRect titleFrame = [super titleRectForBounds:theRect]; NSSize titleSize = [[self attributedStringValue] size]; titleFrame.origin.x = theRect.origin.x + 2; titleFrame.origin.y = theRect.origin.y - .5 + (theRect.size.height - titleSize.height) / 2.0; return titleFrame; } - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { NSRect titleRect = [self titleRectForBounds:cellFrame]; [[self attributedStringValue] drawInRect:titleRect]; } @end // TreeView @implementation TreeView -(id)initWithFrame:(NSRect)rect{ [super initWithFrame:rect]; [self setBorderType:NSNoBorder]; [self setHasVerticalScroller:YES]; [self setHasHorizontalScroller:YES]; [self setAutohidesScrollers:YES]; rootNode=[[NodeItem alloc] initWithTitle:@"root"]; [rootNode setOwner:self]; NSSize contentSize = [self contentSize]; outline=[[OutlineView alloc] initWithFrame:NSMakeRect(0, 0,contentSize.width, contentSize.height)]; [outline setHeaderView:nil]; [outline setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [outline setDataSource:self]; [outline setDelegate:self]; column=[[NSTableColumn alloc] init]; [outline addTableColumn:column]; [outline setOutlineTableColumn:column]; cell=[[VerticalCenterAlignedBrowserCell alloc] init]; [cell setLeaf:YES]; [cell setScrollable:YES]; [column setDataCell:cell]; [self setDocumentView:outline]; [outline sizeLastColumnToFit]; return self; } -(void)dealloc{ [outline autorelease]; [column autorelease]; [cell autorelease]; if (textstyle) { [textstyle release]; } [super dealloc]; } -(void)refresh{ [rootNode updateWidth]; [outline reloadData]; } -(int)outlineView:(NSOutlineView*)outlineView numberOfChildrenOfItem:(id)item{ if( !item ) item=rootNode; return [[item kids] count]; } -(id)outlineView:(NSOutlineView*)outlineView child:(int)index ofItem:(id)item{ if( !item ) item=rootNode; if (index>=[[item kids] count]) return 0; return [[item kids] objectAtIndex:index]; } -(BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item{ if( !item ) item=rootNode; return [item canExpand]; } -(id)outlineView:(NSOutlineView*)outlineView objectValueForTableColumn:(NSTableColumn*)tableColumn byItem:(id)item{ if (tableColumn==colin) return @""; if( !item ) item=rootNode; return [item value]; } -(unsigned)count{ return [rootNode count]; } -(id)rootNode{ return rootNode; } -(id)selectedNode{ int index; index=[outline selectedRow]; if (index==-1) return nil; return [outline itemAtRow:index]; } -(void)selectNode:(id)node{ int index; [node show]; [outline setDelegate:nil]; index = [outline rowForItem:node]; [outline selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO]; [outline setDelegate:self]; [outline scrollRowToVisible:index]; } -(void)expandNode:(id)node{ [outline setDelegate:nil]; [outline expandItem:node]; [outline tile]; [outline setDelegate:self]; [node queueWidthUpdate]; } -(void)collapseNode:(id)node{ [outline setDelegate:nil]; [outline collapseItem:node]; [outline tile]; [outline setDelegate:self]; [rootNode queueWidthUpdate]; } -(void)outlineViewItemDidExpand:(NSNotification *)notification{ id node; node=[[notification userInfo] objectForKey:@"NSObject"]; [node queueWidthUpdate]; #ifdef __x86_64 PostGuiEvent( BBEVENT_GADGETOPEN,self,(BBInt64)node,0,0,0,0 ); #else PostGuiEvent( BBEVENT_GADGETOPEN,self,(int)node,0,0,0,0 ); #endif } -(void)outlineViewItemDidCollapse:(NSNotification *)notification{ id node; node=[[notification userInfo] objectForKey:@"NSObject"]; [rootNode queueWidthUpdate]; #ifdef __x86_64 PostGuiEvent( BBEVENT_GADGETCLOSE,self,(BBInt64)node,0,0,0,0 ); #else PostGuiEvent( BBEVENT_GADGETCLOSE,self,(int)node,0,0,0,0 ); #endif } -(void)outlineViewSelectionDidChange:(NSNotification *)notification{ id node; node=[self selectedNode]; #ifdef __x86_64 PostGuiEvent( BBEVENT_GADGETSELECT,self,(BBInt64)node,0,0,0,0 ); #else PostGuiEvent( BBEVENT_GADGETSELECT,self,(int)node,0,0,0,0 ); #endif } -(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item{ #ifdef __x86_64 PostGuiEvent( BBEVENT_GADGETACTION,self,(BBInt64)item,0,0,0,0 ); #else PostGuiEvent( BBEVENT_GADGETACTION,self,(int)item,0,0,0,0 ); #endif return NO; } -(void)setColor:(NSColor*)color{ [outline setBackgroundColor:color]; } -(void)setTextColor:(NSColor*)color{ if (textstyle) {[textstyle release];textstyle=nil;} if (color){ textstyle=[NSMutableDictionary dictionaryWithObjectsAndKeys:color,NSForegroundColorAttributeName,nil]; [textstyle retain]; } } - (void)setFont:(NSFont*)font{ if (font) { NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; int i; NSArray *columnsArray = [outline tableColumns]; for (i= 0; i < [columnsArray count]; i++) { [[[columnsArray objectAtIndex:i] dataCell] setFont:font]; } [outline setRowHeight: [layoutManager defaultLineHeightForFont:font]+3]; [cell setFont:font]; [rootNode queueWidthUpdate]; } } - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)dcell forTableColumn:(NSTableColumn *)tableColumn item:(id)node{ if (textstyle){ [textstyle setValue:[cell font] forKey:NSFontAttributeName]; NSAttributedString *atext=[[[NSAttributedString alloc] initWithString:[node value] attributes:textstyle] autorelease]; [dcell setAttributedStringValue:atext]; } else{ [dcell setStringValue:[node value]]; } [dcell setImage:[node icon]]; } -(void)setEnabled:(BOOL)e{ [outline setEnabled:e]; } -(BOOL)isEnabled{ return [outline isEnabled]; } @end // NodeItem @implementation NodeItem -(void)dealloc{} -(id)initWithTitle:(NSString*)text{ owner=nil; parent=nil; title=text; icon=nil; [title retain]; kids=[[NSMutableArray alloc] initWithCapacity:10]; [kids retain]; return self; } -(void)updateWidth{ int i; float cellWidth; float indentationWidth; NSCell* dcell; NSArray* columnsArray; if(owner==nil) return; NSOutlineView* outline = owner->outline; NSTableColumn* tableColumn = owner->column; if(tableColumn!=nil){ dcell = [tableColumn dataCell]; [dcell setStringValue:title]; [dcell setImage:icon]; cellWidth = ((NSSize)[dcell cellSize]).width; indentationWidth = [outline levelForItem: self]; if(isnan(indentationWidth)) indentationWidth = 0; else indentationWidth=([outline indentationPerLevel]*(indentationWidth+1)); if((owner->rootNode == self) || [outline isItemExpanded:self]) for (i= 0; i < [kids count]; i++) [[kids objectAtIndex:i] updateWidth]; if([tableColumn minWidth] < (cellWidth+indentationWidth)){ [tableColumn setMinWidth:(cellWidth+indentationWidth)]; [tableColumn setWidth:(cellWidth+indentationWidth+10)]; } } } -(void)queueWidthUpdate{ [NSObject cancelPreviousPerformRequestsWithTarget: self selector:@selector(updateWidth) object:nil]; [self performSelector:@selector(updateWidth) withObject:nil afterDelay:0.0]; } -(void)setOwner:(TreeView*)treeview{ owner=treeview; } -(id)getOwner{ return owner; } -(void)show{ if (parent){ [parent show]; [owner expandNode:parent]; } } -(void)attach:(NodeItem*)parent_ atIndex:(unsigned)index_{ parent=parent_; if( parent ){ owner=parent->owner; [[parent kids] insertObject:self atIndex:index_]; [self release]; } if (owner) [owner refresh]; } -(void)remove{ if( parent ) [[parent kids] removeObject:self]; if (owner) [owner refresh]; } -(BOOL)canExpand{ return [kids count]>0; } -(NSMutableArray*)kids{ return kids; } -(NSString *)value{return title;} -(NSImage *)icon{return icon;} -(void)setTitle:(NSString*)text{ [title release]; title=text; [title retain]; if (owner){ [owner->outline reloadItem:self]; [owner->rootNode queueWidthUpdate]; } } -(void)setIcon:(NSImage*)image{ if (icon) [icon release]; icon=image; if (icon) [icon retain]; if (owner){ [owner->outline reloadItem:self]; [(icon ? self : owner->rootNode) queueWidthUpdate]; } } -(unsigned)count{ return [kids count]; } @end // TextView @implementation TextView -(id)initWithFrame:(NSRect)rect{ scroll=[[NSScrollView alloc] initWithFrame:rect]; // [scroll setVerticalScroller:[[Scroller alloc] init]]; // [scroll setHorizontalScroller:[[Scroller alloc] init]]; [scroll setHasVerticalScroller:YES]; [scroll setHasHorizontalScroller:YES]; [scroll setDrawsBackground:NO]; [scroll setRulersVisible:NO]; [scroll setBorderType:NSNoBorder]; [scroll setAutohidesScrollers:YES]; NSSize contentSize = [scroll contentSize]; self=[super initWithFrame:NSMakeRect(0, 0,contentSize.width,contentSize.height)]; [self setMinSize:NSMakeSize(contentSize.width, contentSize.height)]; [self setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; [self setVerticallyResizable:YES]; [self setHorizontallyResizable:YES]; [self setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [[self textContainer] setContainerSize:NSMakeSize(FLT_MAX,FLT_MAX)]; [[self textContainer] setWidthTracksTextView:NO]; [self setDelegate:self]; [self setUsesRuler:NO]; [scroll setDocumentView:self]; style=[[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setLineBreakMode:NSLineBreakByClipping]; styles=[NSMutableDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName]; [styles retain]; storage=[self textStorage]; [storage setDelegate:self]; lockedNest=0; [self setTabs: 4]; if ([self respondsToSelector: @selector(setDefaultParagraphStyle)]) [self setDefaultParagraphStyle: style]; if ([self respondsToSelector: @selector(setAutomaticLinkDetectionEnabled)]) [self setAutomaticLinkDetectionEnabled: NO]; if ([self respondsToSelector: @selector(setAutomaticQuoteSubstitutionEnabled)]) [self setAutomaticQuoteSubstitutionEnabled: NO]; if ([self respondsToSelector: @selector(setAutomaticSpellingCorrectionEnabled)]) [self setAutomaticSpellingCorrectionEnabled: NO]; if ([self respondsToSelector: @selector(setAutomaticTextReplacementEnabled)]) [self setAutomaticTextReplacementEnabled: NO]; if ([self respondsToSelector: @selector(setAutomaticDataDetectionEnabled)]) [self setAutomaticDataDetectionEnabled: NO]; // on OS X 10.6+, disable all TextCheckingTypes, as the above code has no effect. #ifdef __MAC_OS_X_VERSION_MAX_ALLOWED #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 [self setEnabledTextCheckingTypes:0]; #endif #endif return self; } -(void)free{ [scroll setDocumentView:nil]; [scroll release]; [style release]; [styles release]; [storage release]; } -(void)setHidden:(BOOL)flag{ [scroll setHidden:flag]; } -(id)storage{ return storage; } -(NSSize)contentSize{ return [scroll contentSize]; } -(id)getScroll{ return scroll; } -(void)setWordWrap:(BOOL)flag{ NSSize contentSize=[self contentSize]; if (flag){ [scroll setHasHorizontalScroller:NO]; [self setHorizontallyResizable:NO]; [self setAutoresizingMask:NSViewWidthSizable]; [[self textContainer] setContainerSize:NSMakeSize(contentSize.width, FLT_MAX)]; [[self textContainer] setWidthTracksTextView:YES]; [style setLineBreakMode:NSLineBreakByWordWrapping]; } else{ [scroll setHasHorizontalScroller:YES]; [self setHorizontallyResizable:YES]; [self setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; [[self textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)]; [[self textContainer] setWidthTracksTextView:NO]; [style setLineBreakMode:NSLineBreakByClipping]; } [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; } -(void)setTabs:(int)tabs{ [style setTabStops:[NSArray array]]; //Clear any TabStops [style setDefaultTabInterval: tabs]; //Set recurring TabStops remembering to convert from twips->pixels [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; } -(void)setMargins:(int)leftmargin{ [self setTextContainerInset:NSMakeSize( leftmargin, 0) ]; // [style setFirstLineHeadIndent: leftmargin*8]; // [style setHeadIndent: leftmargin*8]; // [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; } -(void)setText:(NSString*)text{ NSAttributedString *astring; astring=[[NSAttributedString alloc] initWithString:text attributes:styles]; if (lockedNest) [storage endEditing]; [storage setAttributedString:astring]; if (lockedNest) [storage beginEditing]; else [self setSelectedRange:NSMakeRange(0,0)]; } -(void)addText:(NSString*)text{ NSAttributedString *astring; astring=[[NSAttributedString alloc] initWithString:text attributes:styles]; if (lockedNest) [storage endEditing]; [storage appendAttributedString:astring]; if (lockedNest) [storage beginEditing]; } -(void)setScrollFrame:(NSRect)rect{ [scroll setFrame:rect]; } -(void)setTextColor:(NSColor*)color{ [styles setObject:color forKey:NSForegroundColorAttributeName]; [storage addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0,[storage length])]; [self setInsertionPointColor:color]; } -(void)setColor:(NSColor*)color{ if(color){ [self setBackgroundColor:color]; [self setDrawsBackground:true]; [scroll setBackgroundColor:color]; [scroll setDrawsBackground:true]; }else{ [self setDrawsBackground:false]; [scroll setDrawsBackground:false]; } } -(void)setFont:(NSFont*)font{ [styles setObject:font forKey:NSFontAttributeName]; [storage setFont:font]; [super setFont:font]; } -(NSMenu *)menuForEvent:(NSEvent *)event{ NSPoint p; int x,y; p=[event locationInWindow]; x=(int)p.x;y=(int)p.y; PostGuiEvent( BBEVENT_GADGETMENU,self,0,0,x,y,0 ); return nil; } -(void)updateDragTypeRegistration{ } -(NSArray *)acceptableDragTypes{ return nil; } -(void)textDidBeginEditing:(NSNotification*)n{ // printf( "textDidBeginEditing:%p\n",_textEditor );fflush(stdout); } -(void)textDidChange:(NSNotification*)n{ PostGuiEvent( BBEVENT_GADGETACTION,self,0,0,0,0,0 ); } -(void)textDidEndEditing:(NSNotification*)n{ // printf( "textDidEndEditing:%p\n",_textEditor );fflush(stdout); PostGuiEvent( BBEVENT_GADGETLOSTFOCUS,[n object],0,0,0,0,0 ); } -(void)textViewDidChangeSelection:(NSNotification *)aNotification{ PostGuiEvent( BBEVENT_GADGETSELECT,self,0,0,0,0,0 ); } -(void)textStorageDidProcessEditing:(NSNotification *)aNotification{ } -(void)textStorageWillProcessEditing:(NSNotification *)aNotification{ [storage removeAttribute:NSLinkAttributeName range:[storage editedRange]]; } @end // TabViewItem @class TabViewItem; @interface TabViewItem:NSTabViewItem{ NSImage *_image; } -(id)initWithIdentifier:(NSString *)text; -(void)setImage:(NSImage*)image; -(id)copyWithZone:(NSZone *)zone; -(NSImage*)image; -(NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel; -(void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect; @end @implementation TabViewItem -(id)initWithIdentifier:(NSString *)string{ self=[super initWithIdentifier:string]; _image=nil; return self; } -(void)setImage:(NSImage*)image{ _image=image; if (_image) [_image setScalesWhenResized:YES]; } -(id)copyWithZone:(NSZone *)zone{ TabViewItem *copy=[[[self class] allocWithZone:zone] initWithIdentifier:[self identifier]]; return copy; } -(NSImage*)image{ return _image; } -(NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel{ NSSize size; NSSize imageDimensions; float ratio; size=[super sizeOfLabel:shouldTruncateLabel]; if (_image) { imageDimensions = [_image size]; if (imageDimensions.height > size.height){ ratio = size.height/imageDimensions.height; imageDimensions.width*=ratio;imageDimensions.height*=ratio; [_image setSize: imageDimensions]; } size.width += imageDimensions.height; } return size; } -(void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)content{ NSSize imageDimensions; NSPoint point; if (_image){ imageDimensions = [_image size]; point = NSMakePoint(content.origin.x,content.origin.y+imageDimensions.height); [_image compositeToPoint:point operation:NSCompositeSourceOver]; content.origin.x+=imageDimensions.width;content.size.width-=imageDimensions.width; } [super drawLabel:shouldTruncateLabel inRect:content]; } @end // TabView @implementation TabView -(id)initWithFrame:(NSRect)rect{ rect.size.height+=8; self=[super initWithFrame:rect]; [super setControlSize:NSSmallControlSize]; [super setFont:[NSFont labelFontOfSize:[NSFont smallSystemFontSize]]]; client=[[FlippedView alloc] initWithFrame:[self contentRect]]; [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [client retain]; user=1; [self setDelegate:self]; return self; } -(id)clientView{ return client; } -(void)selectTabViewItemAtIndex:(int)index{ user=0; [super selectTabViewItemAtIndex:index]; user=1; } -(void)setFrame:(NSRect)rect{ rect.size.height+=8; [super setFrame:rect]; } -(BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem{ int index; [tabViewItem setView:client]; [client setFrame:[self contentRect]]; if (user){ index=[self indexOfTabViewItem:tabViewItem]; PostGuiEvent( BBEVENT_GADGETACTION,self,index,0,0,0,0); } return YES; } -(void)dealloc{ NSArray *items; int i,n; items=[self tabViewItems]; n=[items count]; for (i=0;istyle&WINDOW_STATUS){ rect.origin.x=rect.origin.y=0; rect.size.height-=STATUSBARHEIGHT; client=[[FlippedView alloc] initWithFrame:rect]; [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [view addSubview:client]; // label for window status rect.origin.y=rect.size.height+3; rect.size.height=STATUSBARHEIGHT-4; rect.size.width-=[NSScroller scrollerWidth]; for (i=0;i<3;i++){ l=[[NSText alloc] initWithFrame:rect]; [l setDrawsBackground:NO]; [l setEditable:NO]; [l setSelectable:NO]; [l setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; switch (i){ case 0:[l setAlignment:NSLeftTextAlignment];break; case 1:[l setAlignment:NSCenterTextAlignment];break; case 2:[l setAlignment:NSRightTextAlignment];break; } if (view) [view addSubview:l]; label[i]=l; } rect.origin.y-=3; rect.size.height=2; rect.size.width+=[NSScroller scrollerWidth]; box=[[NSBox alloc] initWithFrame:rect]; [box setBoxType:NSBoxSeparator]; [box setTitlePosition:NSNoTitle]; [box setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; if (view) [view addSubview:box]; // set clientview to inner view view=client; } return self; } -(id)clientView{ return view; } -(void)setStatus:(NSString*)text align:(int)pos{ if (label[pos]) [label[pos] setString:text]; } -(void)sendEvent:(NSEvent*)event{ static int lastHotKey; int key; id source; // Handling of Generic Key/Mouse Events switch( [event type] ){ case NSMouseEntered: [self disableCursorRects]; case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: if( [event type] != NSMouseEntered ){ dragging = [[self contentView] hitTest:[event locationInWindow]]; [self makeFirstResponder:dragging]; } case NSMouseMoved: case NSMouseExited: case NSScrollWheel: { NSView *hitView = [[self contentView] hitTest:[event locationInWindow]]; if (hitView) EmitMouseEvent( event, hitView ); if(![self isEnabled]) return; break; } case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: { //fire event for the dragged view if (dragging) { EmitMouseEvent( event, dragging ); dragging = nil; } else { //fire the event for the recieving view (if it exists) NSView *hitView = [[self contentView] hitTest:[event locationInWindow]]; if (hitView) EmitMouseEvent( event, hitView ); } if(![self isEnabled]) return; break; } case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: { if( dragging == nil ) dragging = [[self contentView] hitTest:[event locationInWindow]]; if( dragging ) EmitMouseEvent( event, dragging ); if(![self isEnabled]) return; break; } case NSKeyDown: case NSKeyUp: case NSFlagsChanged: { NSResponder *handle=(NSResponder*)NSActiveGadget(); if( handle && EmitKeyEvent( event, handle )) return; break; } } // End of Generic Key/Mouse Events // Gadget Filterkey Processing switch( [event type] ){ case NSKeyDown: if( key=bbSystemTranslateKey( [event keyCode] ) ){ int mods=bbSystemTranslateMods( [event modifierFlags] ); BBObject *event=maxgui_maxgui_HotKeyEvent( key,mods ); if( event!=&bbNullObject ){ lastHotKey=key; brl_event_EmitEvent( event ); return; } } source=[self textFirstResponder]; if( source && !filterKeyDownEvent( event,source ) ) return; if(![self isEnabled]) return; break; case NSKeyUp: key=bbSystemTranslateKey([event keyCode]); if( lastHotKey && (key==lastHotKey ) ){ lastHotKey=0; return; } if(![self isEnabled]) return; break; } lastHotKey=0; // End of FilterKey Processing [super sendEvent:event]; } - (NSDragOperation)draggingEntered:(id )sender{ // printf("windowview got dragenter\n");fflush(stdout); return YES; } - (BOOL)performDragOperation:(id )sender{ NSPasteboard *pboard = [sender draggingPasteboard]; if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; int numberOfFiles = [files count]; // Perform operation using the list of files // printf("windowview got drag\n");fflush(stdout); int i; for (i=0;istyle; if (style&WINDOW_CLIENTCOORDS){ rect=[self contentRectForFrameRect:rect]; if (style&WINDOW_STATUS) { rect.size.height-=STATUSBARHEIGHT; rect.origin.y+=STATUSBARHEIGHT; } } vis=[[NSScreen deepestScreen] visibleFrame]; rect.origin.x-=vis.origin.x; rect.origin.y=vis.size.height-(rect.origin.y-vis.origin.y)-rect.size.height; return rect; } -(BOOL)canBecomeKeyWindow{ return ([self isEnabled]); } -(BOOL)canBecomeMainWindow{ return ([self isEnabled] && [self isVisible] && ([self parentWindow]==nil)); } -(BOOL)becomeFirstResponder{ return ([self isEnabled] && [self isVisible]); } -(void)setEnabled:(BOOL)e{ enabled=e; if (enabled) [self makeKeyWindow]; } -(BOOL)isEnabled{ return (enabled)?YES:NO; } -(void)dealloc{ int i; id sview; if (gadget->style&WINDOW_STATUS) { for (i = 0; i < 3; i++) { if (label[i]) { [label[i] removeFromSuperview]; [label[i] release]; } } sview = [view superview]; [view removeFromSuperview]; [view release]; [sview removeFromSuperview]; [sview release]; } else { [view removeFromSuperview]; [view release]; } [super dealloc]; } @end // ToolView @implementation ToolView -(id)textFirstResponder{ id r=[self firstResponder]; //if ([r isKindOfClass:[PanelView class]]) return r; if ([r isKindOfClass:[NSTextView class]]){ id d=[r delegate]; if( [d isKindOfClass:[NSTextField class]] ) return d; } return r; } -(id)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)backing defer:(BOOL)flag withGadget:(nsgadget*)_gadget{ //withStatus:(BOOL)status{ id client; int i; NSText *l; NSBox *box; dragging = nil; self=[super initWithContentRect:rect styleMask:mask backing:backing defer:flag]; gadget=_gadget; view=[[FlippedView alloc] init]; enabled=true; [self setContentView:view]; [self setAcceptsMouseMovedEvents:YES]; [self disableCursorRects]; //Fixes NSSetPointer not sticking. if (gadget->style&WINDOW_STATUS){ //status){ //mask&NSTexturedBackgroundWindowMask) rect.origin.x=rect.origin.y=0; rect.size.height-=STATUSBARHEIGHT; client=[[FlippedView alloc] initWithFrame:rect]; [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [view addSubview:client]; // label for window status rect.origin.y=rect.size.height+3; rect.size.height=STATUSBARHEIGHT-4; rect.size.width-=[NSScroller scrollerWidth]; for (i=0;i<3;i++){ l=[[NSText alloc] initWithFrame:rect]; [l setDrawsBackground:NO]; [l setEditable:NO]; [l setSelectable:NO]; [l setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; switch (i){ case 0:[l setAlignment:NSLeftTextAlignment];break; case 1:[l setAlignment:NSCenterTextAlignment];break; case 2:[l setAlignment:NSRightTextAlignment];break; } if (view) [view addSubview:l]; label[i]=l; } rect.origin.y-=3; rect.size.height=2; rect.size.width+=[NSScroller scrollerWidth]; box=[[NSBox alloc] initWithFrame:rect]; [box setBoxType:NSBoxSeparator]; [box setTitlePosition:NSNoTitle]; [box setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; if (view) [view addSubview:box]; // set clientview to inner view view=client; } if ([self respondsToSelector: @selector(setShowsToolbarButton)]) [self setShowsToolbarButton: NO]; return self; } -(id)clientView{ return view; } -(void)setStatus:(NSString*)text align:(int)pos{ if (label[pos]) [label[pos] setString:text]; } -(void)sendEvent:(NSEvent*)event{ static int lastHotKey; int key; id source; // Handling of Generic Key/Mouse Events switch( [event type] ){ case NSMouseEntered: [self disableCursorRects]; case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: { if( [event type] != NSMouseEntered ){ dragging = [[self contentView] hitTest:[event locationInWindow]]; [self makeFirstResponder:dragging]; } } case NSMouseMoved: case NSMouseExited: case NSScrollWheel: { NSView *hitView = [[self contentView] hitTest:[event locationInWindow]]; if (hitView) EmitMouseEvent( event, hitView ); if(![self isEnabled]) return; break; } case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: { //fire event for the dragged view if (dragging) { EmitMouseEvent( event, dragging ); dragging = nil; } else { //fire the event for the recieving view (if it exists) NSView *hitView = [[self contentView] hitTest:[event locationInWindow]]; if (hitView) EmitMouseEvent( event, hitView ); } if(![self isEnabled]) return; break; } case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: { if( dragging == nil ) dragging = [[self contentView] hitTest:[event locationInWindow]]; if( dragging ) EmitMouseEvent( event, dragging ); if(![self isEnabled]) return; break; } case NSKeyDown: case NSKeyUp: case NSFlagsChanged: { NSResponder *handle=(NSResponder*)NSActiveGadget(); if( handle && EmitKeyEvent( event, handle )) return; break; } } // End of Generic Key/Mouse Events // Gadget Filterkey Processing switch( [event type] ){ case NSKeyDown: if( key=bbSystemTranslateKey( [event keyCode] ) ){ int mods=bbSystemTranslateMods( [event modifierFlags] ); BBObject *event=maxgui_maxgui_HotKeyEvent( key,mods ); if( event!=&bbNullObject ){ lastHotKey=key; brl_event_EmitEvent( event ); return; } } source=[self textFirstResponder]; if( source && !filterKeyDownEvent( event,source ) ) return; if(![self isEnabled]) return; break; case NSKeyUp: key=bbSystemTranslateKey([event keyCode]); if( lastHotKey && (key==lastHotKey ) ){ lastHotKey=0; return; } if(![self isEnabled]) return; break; } lastHotKey=0; // End of FilterKey Processing [super sendEvent:event]; } - (NSDragOperation)draggingEntered:(id )sender{ // printf("windowview got dragenter\n");fflush(stdout); return YES; } - (BOOL)performDragOperation:(id )sender{ NSPasteboard *pboard = [sender draggingPasteboard]; if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; int numberOfFiles = [files count]; // Perform operation using the list of files // printf("windowview got drag\n");fflush(stdout); int i; for (i=0;istyle; if (style&WINDOW_CLIENTCOORDS){ rect=[self contentRectForFrameRect:rect]; if (style&WINDOW_STATUS) { rect.size.height-=STATUSBARHEIGHT; rect.origin.y+=STATUSBARHEIGHT; } } vis=[[NSScreen deepestScreen] visibleFrame]; rect.origin.x=rect.origin.x-vis.origin.x; rect.origin.y=vis.size.height-(rect.origin.y-vis.origin.y)-rect.size.height; return rect; } -(BOOL)canBecomeKeyWindow{ return ([self isEnabled]); } -(BOOL)canBecomeMainWindow{ return ([self isEnabled] && [self isVisible] && ([self parentWindow]==nil)); } -(BOOL)becomeFirstResponder{ return ([self isEnabled] && [self isVisible]); } -(void)setEnabled:(BOOL)e{ enabled=e; if (enabled) [self makeKeyWindow]; } -(BOOL)isEnabled{ return (enabled)?YES:NO; } -(void)dealloc{ int i; id sview; if (gadget->style&WINDOW_STATUS) { for (i = 0; i < 3; i++) { if (label[i]) { [label[i] removeFromSuperview]; [label[i] release]; } } sview = [view superview]; [view removeFromSuperview]; [view release]; [sview removeFromSuperview]; [sview release]; } else { [view removeFromSuperview]; [view release]; } [super dealloc]; } @end // global app stuff void NSBegin(){ GlobalApp=[[CocoaApp alloc] init]; HaltMouseEvents=0; } void NSEnd(){ [GlobalApp release]; } void* NSActiveGadget(){ NSWindow *window; NSResponder *responder; window=[NSApp keyWindow]; if (!window) return 0; responder=[window firstResponder]; if (!responder) return window; if ([responder isKindOfClass:[NSTextView class]] && [window fieldEditor:NO forObject:nil] != nil ) { NSTextView *view=(NSTextView*)responder; return [view delegate]; } return responder; } void NSInitGadget(nsgadget *gadget){ NSRect rect,vis; NSString *text; NSView *view; NSWindow *window; NSButton *button; NSTextField *textfield; TextView *textarea; NSControl *combobox; Toolbar *toolbar; TabView *tabber; TreeView *treeview; HTMLView *htmlview; PanelView *panel; PanelViewContent *pnlcontent; CanvasView *canvas; ListView *listbox; NSText *label; NSBox *box; NSSlider *slider; NSScroller *scroller; NSStepper *stepper; NSProgressIndicator *progbar; NSMenu *menu; NSMenuItem *menuitem; NodeItem *node,*parent; nsgadget *group; int style,flags; NSImage *image; rect=NSMakeRect(gadget->x,gadget->y,gadget->w,gadget->h); text=NSStringFromBBString(gadget->textarg); style=gadget->style;flags=0; group=gadget->group; if (group==(nsgadget*)&bbNullObject) group=0; if (group) view=gadget->group->view; switch (gadget->internalclass){ case GADGET_DESKTOP: rect=[[NSScreen deepestScreen] frame]; gadget->x=rect.origin.x; gadget->y=rect.origin.y; gadget->w=rect.size.width; gadget->h=rect.size.height; break; case GADGET_WINDOW: vis=[[NSScreen deepestScreen] visibleFrame]; rect.origin.x+=vis.origin.x; rect.origin.y=vis.origin.y+vis.size.height-rect.origin.y-rect.size.height; if (style&WINDOW_TITLEBAR) flags|=NSTitledWindowMask|NSClosableWindowMask; if (style&WINDOW_RESIZABLE){ flags|=NSResizableWindowMask; if (!(group && (group->internalclass==GADGET_WINDOW))) flags |=NSMiniaturizableWindowMask; } if (style&WINDOW_TOOL) flags|=NSUtilityWindowMask; [NSApp activateIgnoringOtherApps:YES]; if (!(style&WINDOW_CLIENTCOORDS)){ rect=[NSWindow contentRectForFrameRect:rect styleMask:flags]; }else{ if (style&WINDOW_STATUS) { rect.origin.y-=STATUSBARHEIGHT; rect.size.height+=STATUSBARHEIGHT; } } if (!(style&WINDOW_TOOL)) { window=[[WindowView alloc] initWithContentRect:rect styleMask:flags backing:NSBackingStoreBuffered defer:YES withGadget:gadget]; } else { window=[[ToolView alloc] initWithContentRect:rect styleMask:flags backing:NSBackingStoreBuffered defer:YES withGadget:gadget]; } [window setOpaque:NO]; [window setAlphaValue:.999f]; if (style&WINDOW_HIDDEN) [window orderOut:window]; else [window makeKeyAndOrderFront:NSApp]; if (group && (group->internalclass==GADGET_WINDOW)){ NSWindow *parent; parent=(NSWindow*)group->handle; if(!(style&WINDOW_HIDDEN)) [parent addChildWindow:window ordered:NSWindowAbove]; [window setParentWindow:parent]; } if (style&WINDOW_ACCEPTFILES) [window registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; [window setTitle:text]; [window setDelegate:GlobalApp]; gadget->handle=window; gadget->view=[window clientView]; break; case GADGET_BUTTON: button=[[NSButton alloc] initWithFrame:rect]; [button setTitle:text]; [button setBezelStyle:NSRoundedBezelStyle]; switch (style&7){ case 0: // Push Button Size Hack if (gadget->h > 30) { [button setBezelStyle:NSRegularSquareBezelStyle]; } else { if (gadget->h < 24) [button setBezelStyle:NSShadowlessSquareBezelStyle]; else [button setBezelStyle:NSRoundedBezelStyle]; } break; case BUTTON_CHECKBOX: if (style&BUTTON_PUSH){ [button setBezelStyle:NSShadowlessSquareBezelStyle]; [button setButtonType:NSPushOnPushOffButton]; } else { [button setButtonType:NSSwitchButton]; } break; case BUTTON_RADIO: if (style&BUTTON_PUSH){ [button setBezelStyle:NSShadowlessSquareBezelStyle]; [button setButtonType:NSPushOnPushOffButton]; } else { [button setButtonType:NSRadioButton]; } break; case BUTTON_OK: [button setKeyEquivalent:@"\r"]; break; case BUTTON_CANCEL: [button setKeyEquivalent:@"\x1b"]; break; } [button setTarget:GlobalApp]; [button setAction:@selector(buttonPush:)]; if (view) [view addSubview:button]; gadget->handle=button; gadget->view=button; break; case GADGET_PANEL: panel=[[PanelView alloc] initWithFrame:rect]; [panel setContentViewMargins:NSMakeSize(0.0,0.0)]; pnlcontent=[[PanelViewContent alloc] initWithFrame:[[panel contentView] frame]]; [pnlcontent setAutoresizesSubviews:NO]; [panel setContentView:pnlcontent]; [panel setGadget:gadget]; [panel setStyle:style]; [panel setEnabled:true]; [panel setTitle:text]; [pnlcontent setAlpha:1.0]; if (view) [view addSubview:panel]; gadget->view=pnlcontent; gadget->handle=panel; break; case GADGET_CANVAS: canvas=[[CanvasView alloc] initWithFrame:rect]; [canvas setAutoresizesSubviews:NO]; [canvas setGadget:gadget]; if (view) [view addSubview:canvas]; [canvas setStyle:style|PANEL_ACTIVE]; [canvas setEnabled:true]; gadget->view=[canvas contentView]; gadget->handle=canvas; break; case GADGET_TEXTFIELD: if (style==TEXTFIELD_PASSWORD){ textfield=[[NSSecureTextField alloc] initWithFrame:rect]; }else{ textfield=[[NSTextField alloc] initWithFrame:rect]; } [textfield setDelegate:GlobalApp]; [textfield setEditable:YES]; [[textfield cell] setWraps:NO]; [[textfield cell] setScrollable:YES]; if (view) [view addSubview:textfield]; gadget->handle=textfield; gadget->view=textfield; break; case GADGET_TEXTAREA://http://developer.apple.com/documentation/Cocoa/Conceptual/TextUILayer/Tasks/TextInScrollView.html textarea=[[TextView alloc] initWithFrame:rect]; if (style&TEXTAREA_READONLY) [textarea setEditable:NO]; if (style&TEXTAREA_WORDWRAP) [textarea setWordWrap:YES]; if (view) [view addSubview:[textarea getScroll]]; gadget->handle=textarea; gadget->view=[textarea getScroll];// simon was here textarea; break; case GADGET_COMBOBOX: if (rect.size.height > 26) rect.size.height = 26; combobox=[[NSComboBox alloc] initWithFrame:rect]; [combobox setUsesDataSource:NO]; [combobox setCompletes:YES]; [combobox setDelegate:GlobalApp]; [combobox setEditable:(style&COMBOBOX_EDITABLE)?YES:NO]; [combobox setSelectable:YES]; if (view) [view addSubview:combobox]; gadget->handle=combobox; gadget->view=combobox; break; case GADGET_LISTBOX: listbox=[[ListView alloc] initWithFrame:rect]; if (view) [view addSubview:listbox]; gadget->handle=listbox; gadget->view=listbox; break; case GADGET_TOOLBAR: toolbar=[[Toolbar alloc] initWithIdentifier:text]; [toolbar setSizeMode:NSToolbarSizeModeSmall]; [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly]; [toolbar setDelegate:GlobalApp]; window=(WindowView*)group->handle; [window setToolbar:toolbar]; gadget->handle=toolbar; gadget->view=[window clientView]; break; case GADGET_TABBER: tabber=[[TabView alloc] initWithFrame:rect]; [tabber setAutoresizesSubviews:NO]; if (view) [view addSubview:tabber]; //[tabber hostView]]; gadget->handle=tabber; gadget->view=[tabber clientView]; break; case GADGET_TREEVIEW: treeview=[[TreeView alloc] initWithFrame:rect]; //NSOutlineView if (view) [view addSubview:treeview]; gadget->handle=treeview; gadget->view=treeview; break; case GADGET_HTMLVIEW: htmlview=[[HTMLView alloc] initWithFrame:rect]; if (view) [view addSubview:htmlview]; [htmlview setStyle: style]; gadget->handle=htmlview; gadget->view=htmlview; break; case GADGET_LABEL: /* BaH */ switch (style&3) { case LABEL_SEPARATOR: box=[[NSBox alloc] initWithFrame:rect]; [box setTitle:text]; [box setBoxType:NSBoxSeparator]; [box setTitlePosition:NSNoTitle]; [box setContentView:[[FlippedView alloc] init]]; if (view) [view addSubview:box]; gadget->handle=box; gadget->view=[box contentView]; break; default: textfield = [[NSTextField alloc] initWithFrame:rect]; [textfield setEditable:NO]; [textfield setDrawsBackground:NO]; if ((style&3)==LABEL_SUNKENFRAME) { [textfield setBezeled:YES]; [textfield setBezelStyle:NSTextFieldSquareBezel]; } else { [textfield setBezeled:NO]; if ((style&3)==LABEL_FRAME) [textfield setBordered:YES]; else [textfield setBordered:NO]; } [[textfield cell] setWraps:YES]; [[textfield cell] setScrollable:NO]; [textfield setStringValue:text]; switch (style&24){ case LABEL_LEFT:[textfield setAlignment:NSLeftTextAlignment];break; case LABEL_RIGHT:[textfield setAlignment:NSRightTextAlignment];break; case LABEL_CENTER:[textfield setAlignment:NSCenterTextAlignment];break; } if (view) [view addSubview: textfield]; gadget->handle=textfield; gadget->view=textfield; break; } break; case GADGET_SLIDER: switch (style&12){ case SLIDER_SCROLLBAR: if (rect.size.width>rect.size.height) { rect.size.height=[NSScroller scrollerWidth]; } else{ rect.size.width=[NSScroller scrollerWidth]; } scroller=[[NSScroller alloc] initWithFrame:rect]; [scroller setEnabled:YES]; [scroller setArrowsPosition:NSScrollerArrowsDefaultSetting]; [scroller setAction:@selector(scrollerSelect:)]; if (view) [view addSubview:scroller]; gadget->handle=scroller; gadget->view=scroller; break; case SLIDER_TRACKBAR: slider=[[NSSlider alloc] initWithFrame:rect]; [slider setEnabled:YES]; [slider setAction:@selector(sliderSelect:)]; if (view) [view addSubview:slider]; gadget->handle=slider; gadget->view=slider; break; case SLIDER_STEPPER: stepper=[[NSStepper alloc] initWithFrame:rect]; [stepper setEnabled:YES]; [stepper setAction:@selector(sliderSelect:)]; [stepper setValueWraps:NO]; if (view) [view addSubview:stepper]; gadget->handle=stepper; gadget->view=stepper; break; } break; case GADGET_PROGBAR: progbar=[[NSProgressIndicator alloc] initWithFrame:rect]; [progbar setStyle:NSProgressIndicatorBarStyle]; [progbar setIndeterminate:NO]; [progbar setMaxValue:1.0]; if (view) [view addSubview:progbar]; gadget->handle=progbar; gadget->view=progbar; break; case GADGET_MENUITEM: // Allows a popup-menu to be created with no text without crashing. if ([text length] || (group->internalclass == GADGET_DESKTOP)) { menuitem=[[NSMenuItem alloc] initWithTitle:text action:@selector(menuSelect:) keyEquivalent:@""]; [menuitem setTag:style]; [GlobalApp addMenuItem:menuitem]; } else{ menuitem=(NSMenuItem*)[NSMenuItem separatorItem]; } if (group){ switch (group->internalclass){ case GADGET_WINDOW: menu=[[NSMenu alloc] initWithTitle:text]; [menu setAutoenablesItems:NO]; [menu setSubmenu:menu forItem:menuitem]; [menu release]; menu=[NSApp mainMenu]; [menu addItem:menuitem]; if ([text length]){ [menuitem release]; } break; case GADGET_MENUITEM: menu=(NSMenu*)[group->handle submenu]; if (!menu){ menu=(NSMenu*)[[NSMenu alloc] initWithTitle:text]; [menu setAutoenablesItems:NO]; [group->handle setSubmenu:menu]; [menu addItem:menuitem]; [menu release]; } else { [menu addItem:menuitem]; } if ([text length]){ [menuitem release]; } break; } } gadget->handle=menuitem; break; case GADGET_NODE: if (!group) break; parent=0; switch (group->internalclass){ case GADGET_TREEVIEW: parent=[((TreeView*)group->handle) rootNode]; break; case GADGET_NODE: parent=(NodeItem*)group->handle; break; } if (!parent) break; node=[[NodeItem alloc] initWithTitle:text]; int index=style; if (index==-1) index=[parent count]; if (index>[parent count]) index=[parent count]; [node attach:parent atIndex:index]; gadget->handle=node; break; } } @class color_delegate; @interface color_delegate:NSObject{} @end @implementation color_delegate - (void)windowWillClose:(NSNotification *)aNotification{[NSApp stopModal];} @end int NSColorRequester(int r,int g,int b){ NSColorPanel *panel; NSColor *color; color_delegate *dele; dele=[[color_delegate alloc] init]; color=[NSColor colorWithCalibratedRed:r/255.0L green:g/255.0L blue:b/255.0L alpha:1.0]; panel=[NSColorPanel sharedColorPanel]; [panel setColor:color]; [panel setDelegate:dele]; [NSApp runModalForWindow:panel]; color=[panel color]; if (color){ color=[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; r=(int)((255*[color redComponent])+0.5); g=(int)((255*[color greenComponent])+0.5); b=(int)((255*[color blueComponent])+0.5); } return 0xff000000|(r<<16)|(g<<8)|b; } @class font_delegate; @interface font_delegate:NSObject{ NSFont *_font; } -(id)initWithFont:(NSFont*)font; -(void)changeFont:(id)sender; -(id)font; -(void)windowWillClose:(NSNotification *)aNotification; -(unsigned int)validModesForFontPanel:(NSFontPanel *)fontPanel; @end @implementation font_delegate -(id)initWithFont:(NSFont*)font{ _font=font; return self; } -(id)font{ return _font; } -(void)changeFont:(id)sender{ _font=[sender convertFont:_font]; return; } - (void)windowWillClose:(NSNotification *)aNotification{ [NSApp stopModal]; } -(unsigned int)validModesForFontPanel:(NSFontPanel *)fontPanel{ return NSFontPanelFaceModeMask|NSFontPanelSizeModeMask|NSFontPanelCollectionModeMask;//|NSFontPanelUnderlineEffectModeMask; } @end int NSGetSysColor( int colorindex, int* red, int* green, int* blue ){ float r, g, b; NSColor* c; NSWindow* w; switch(colorindex){ case GUICOLOR_WINDOWBG: w = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES]; c = [w backgroundColor]; [w release]; break; case GUICOLOR_GADGETBG: c = [NSColor controlBackgroundColor]; break; case GUICOLOR_GADGETFG: c = [NSColor controlTextColor]; break; case GUICOLOR_SELECTIONBG: c = [NSColor selectedTextBackgroundColor]; break; default: return 0; break; } [[c colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&r green:&g blue:&b alpha:NULL]; *red = (int)(255 * r); *green = (int)(255 * g); *blue = (int)(255 * b); return 1; } NSFont *NSRequestFont(NSFont *font){ NSFontPanel *panel; font_delegate *dele; if (!font) font=[NSFont userFontOfSize:0]; dele=[[font_delegate alloc] initWithFont:font]; panel=[NSFontPanel sharedFontPanel]; if (font) [panel setPanelFont:font isMultiple:NO]; [panel setEnabled:YES]; [panel setDelegate:dele]; [NSApp runModalForWindow:panel]; return [dele font]; } NSFont *NSLoadFont(BBString *name,double size,int flags){ NSString *text; NSFont *font; NSFontManager *manager; text=NSStringFromBBString(name); font=[NSFont fontWithName:text size:size]; if (!font) font=[NSFont systemFontOfSize:size]; if (flags){ manager=[NSFontManager sharedFontManager]; if (flags&FONT_BOLD) font=[manager convertFont:font toHaveTrait:NSBoldFontMask]; if (flags&FONT_ITALIC) font=[manager convertFont:font toHaveTrait:NSItalicFontMask]; } [font retain]; return font; } NSFont *NSGetDefaultFont(){ return [NSFont systemFontOfSize:[NSFont systemFontSize]]; } BBString *NSFontName(NSFont *font){ return bbStringFromNSString([font displayName]); } int NSFontStyle(NSFont *font){ int intBBStyleFlags; int intCocoaFontTraits; NSFontManager *manager; manager = [NSFontManager sharedFontManager]; intCocoaFontTraits = [manager traitsOfFont: font]; intBBStyleFlags = 0; if (intCocoaFontTraits & NSBoldFontMask) intBBStyleFlags|=FONT_BOLD; if (intCocoaFontTraits & NSItalicFontMask) intBBStyleFlags|=FONT_ITALIC; return intBBStyleFlags; } double NSFontSize(NSFont *font){ return (double)[font pointSize]; } void* NSSuperview(NSView* handle){ if(handle) return [handle superview]; return 0; } // generic gadget commands void NSFreeGadget(nsgadget *gadget){ nsgadget *group; NSWindow *parent; TextView *textview; FlippedView * flipped; if (gadget->textcolor){ [gadget->textcolor release]; gadget->textcolor = 0; } if (gadget->handle){ switch (gadget->internalclass){ case GADGET_WINDOW: if ([gadget->handle parentWindow]!=nil){ [[gadget->handle parentWindow] removeChildWindow:(NSWindow*)gadget->handle]; } [gadget->handle close]; break; case GADGET_NODE: [gadget->handle remove]; [gadget->handle autorelease]; break; case GADGET_MENUITEM: [GlobalApp removeMenuItem:gadget->handle]; [[gadget->handle menu] removeItem:gadget->handle]; break; case GADGET_TEXTAREA: textview=(TextView*)gadget->handle; [gadget->view removeFromSuperview]; [textview free]; [textview autorelease]; break; case GADGET_LABEL: switch (gadget->style&3) { case LABEL_SEPARATOR: flipped=(FlippedView*)gadget->view; [flipped removeFromSuperview]; [gadget->handle removeFromSuperview]; [flipped release]; break; default: [gadget->view removeFromSuperview]; break; } [gadget->handle autorelease]; break; case GADGET_TABBER: flipped=(FlippedView*)gadget->view; [flipped removeFromSuperview]; [gadget->handle removeFromSuperview]; [flipped release]; //Cocoa throws an exception if items exist when handle is autoreleased. NSClearItems(gadget); [gadget->handle autorelease]; break; case GADGET_PANEL: [gadget->handle setColor:nil]; [gadget->handle removeFromSuperview]; [gadget->handle autorelease]; break; default: [[gadget->view superview] setNeedsDisplayInRect:[gadget->view frame]]; [gadget->view removeFromSuperview]; [gadget->handle autorelease]; break; } } gadget->handle=0; } void NSEnable(nsgadget *gadget,int state){ switch (gadget->internalclass){ case GADGET_WINDOW: case GADGET_SLIDER: case GADGET_TEXTFIELD: case GADGET_MENUITEM: case GADGET_BUTTON: case GADGET_LISTBOX: case GADGET_COMBOBOX: case GADGET_TREEVIEW: case GADGET_PANEL: case GADGET_CANVAS: [gadget->handle setEnabled:state]; break; case GADGET_TEXTAREA: [gadget->handle setSelectable:state]; if (!(gadget->style&TEXTAREA_READONLY)) [gadget->handle setEditable:state]; break; } } void NSShow(nsgadget *gadget,int state){ switch (gadget->internalclass){ case GADGET_WINDOW: if (state==[gadget->handle isVisible]) return; if (state) { if((gadget->group!=&bbNullObject) && (gadget->group->internalclass==GADGET_WINDOW) && ([gadget->handle parentWindow]==nil)) [gadget->group->handle addChildWindow: gadget->handle ordered:NSWindowAbove]; [gadget->handle makeKeyAndOrderFront:NSApp]; } else { if([gadget->handle parentWindow]!=nil) [[gadget->handle parentWindow] removeChildWindow:(NSWindow*)gadget->handle]; [gadget->handle orderOut:NSApp]; } break; case GADGET_TOOLBAR: [gadget->handle setVisible:state]; break; default: [gadget->handle setHidden:!state]; } } void NSCheck(nsgadget *gadget,int state){ NSButton *button; switch (gadget->internalclass){ case GADGET_MENUITEM: [gadget->handle setState:state]; break; case GADGET_BUTTON: button=(NSButton *)gadget->handle; if(state==NSMixedState) [button setAllowsMixedState:YES]; else [button setAllowsMixedState:NO]; [button setState:state]; break; } } void NSPopupMenu(nsgadget *gadget,nsgadget *menugadget){ NSView *view; NSWindow *window; NSMenuItem *menuitem; NSEvent *event; NSPoint loc; window=(NSWindow*)gadget->handle; view=gadget->view; menuitem=(NSMenuItem*)menugadget->handle; event=[NSEvent mouseEventWithType:NSRightMouseUp location:[window convertScreenToBase:[NSEvent mouseLocation]] modifierFlags:(NSEventModifierFlags)nil timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:(NSInteger)nil clickCount:1 pressure:0]; [NSMenu popUpContextMenu:[menuitem submenu] withEvent:event forView:view]; // [event release]; } int NSState(nsgadget *gadget){ NSWindow *window; TextView *textview; NSButton *button; NSView *view; Toolbar *toolbar; HTMLView *browser; NSMenuItem *menuItem; int state; state=0; switch (gadget->internalclass){ case GADGET_TEXTAREA: textview=(TextView*)gadget->handle; if ([textview isHidden]) state|=STATE_HIDDEN; if ((!(gadget->style&TEXTAREA_READONLY)) && (![textview isEditable])) state|=STATE_DISABLED; break; case GADGET_HTMLVIEW: browser=(HTMLView*)gadget->handle; return [browser loaded]; case GADGET_WINDOW: window=(NSWindow*)gadget->handle; if ([window isMiniaturized]) state|=STATE_MINIMIZED; if ([window isZoomed]) state|=STATE_MAXIMIZED; if (![window isVisible]) state|=STATE_HIDDEN; break; case GADGET_MENUITEM: menuItem=(NSMenuItem*)gadget->handle; if ([menuItem state]==NSOnState) state|=STATE_SELECTED; if (![menuItem isEnabled]) state|=STATE_DISABLED; break; case GADGET_BUTTON: button=(NSButton *)gadget->handle; switch (gadget->style&7){ case BUTTON_RADIO: case BUTTON_CHECKBOX: if ([button state]==NSOnState) state|=STATE_SELECTED; if ([button state]==NSMixedState) state|=STATE_INDETERMINATE; } if ([button isHidden]) state|=STATE_HIDDEN; if (![button isEnabled]) state|=STATE_DISABLED; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; if ([toolbar isVisible]==NO) state|=STATE_HIDDEN; break; case GADGET_PROGBAR: view=(NSView*)gadget->handle; if ([view isHidden]) state|=STATE_HIDDEN; break; default: view=(NSView*)gadget->handle; if ([view isHidden]) state|=STATE_HIDDEN; if (![view isEnabled]) state|=STATE_DISABLED; break; } return state; } void NSSetMinimumSize(nsgadget *gadget,int width,int height){ NSWindow *window; NSRect rect; int style; window=(NSWindow*)gadget->handle; rect.origin.x=0; rect.origin.y=0; rect.size.width=width; rect.size.height=height; style=gadget->style; if (!(style&WINDOW_CLIENTCOORDS)){ rect=[window contentRectForFrameRect:rect]; rect.size.width-=rect.origin.x; rect.size.height-=rect.origin.y; }else{ if (style&WINDOW_STATUS) rect.size.height+=STATUSBARHEIGHT; } [window setContentMinSize:rect.size]; } void NSSetMaximumSize(nsgadget *gadget,int width,int height){ NSWindow *window; NSRect rect; int style; window=(NSWindow*)gadget->handle; rect.origin.x=0; rect.origin.y=0; rect.size.width=width; rect.size.height=height; style=gadget->style; if (!(style&WINDOW_CLIENTCOORDS)){ rect=[window contentRectForFrameRect:rect]; rect.size.width-=rect.origin.x; rect.size.height-=rect.origin.y; }else{ if (style&WINDOW_STATUS) rect.size.height+=STATUSBARHEIGHT; } [window setContentMaxSize:rect.size]; } void NSSetStatus(nsgadget *gadget,BBString *data,int pos){ NSString *text; WindowView *window; ToolView *toolview; text=NSStringFromBBString(data); if ((gadget->style&WINDOW_TOOL) == 0) { window=(WindowView*)gadget->handle; [window setStatus:text align:pos]; } else { toolview =(ToolView*)gadget->handle; [toolview setStatus:text align:pos]; } } int NSClientWidth(nsgadget *gadget){ NSRect frame; if (gadget->internalclass==GADGET_DESKTOP){ frame=[[NSScreen deepestScreen] visibleFrame]; return frame.size.width; } if (!gadget->view) return gadget->w; frame=[gadget->view frame]; return frame.size.width; } int NSClientHeight(nsgadget *gadget){ NSRect frame; if (gadget->internalclass==GADGET_DESKTOP){ frame=[[NSScreen deepestScreen] visibleFrame]; return frame.size.height; } if (!gadget->view) return gadget->h; frame=[gadget->view frame]; return frame.size.height; } void NSRedraw(nsgadget *gadget){ NSView *view; view=(NSView*)gadget->handle; [view display]; //Can just call the display method } void NSActivate(nsgadget *gadget,int code){ NSWindow *window; NSView *view; NSRect frame; NodeItem *node; TreeView *treeview; HTMLView *browser; TextView *textview; NSTextField *textfield; NSText *text; NSComboBox *combo; // generic commands switch (code){ case ACTIVATE_REDRAW: NSRedraw(gadget); return; } // gadget specific switch (gadget->internalclass){ case GADGET_WINDOW: window=(NSWindow*)gadget->handle; switch (code){ case ACTIVATE_FOCUS: if([window isVisible]) [window makeKeyAndOrderFront:NSApp]; break; case ACTIVATE_CUT: break; case ACTIVATE_COPY: break; case ACTIVATE_PASTE: break; case ACTIVATE_MINIMIZE: NSShow(gadget,true); [window miniaturize:window]; break; case ACTIVATE_MAXIMIZE: if ([window isMiniaturized]) [window deminiaturize:window]; if ([window isZoomed]==NO) [window performZoom:window]; NSShow(gadget,true); break; case ACTIVATE_RESTORE: if ([window isMiniaturized]) [window deminiaturize:window]; if ([window isZoomed]) [window performZoom:window]; NSShow(gadget,true); break; } break; case GADGET_TEXTFIELD: textfield=(NSTextField*)gadget->handle; window=[textfield window]; if (window) switch (code){ case ACTIVATE_FOCUS: [window makeFirstResponder:textfield]; break; case ACTIVATE_CUT: text=[[textfield window] fieldEditor:YES forObject:textfield]; [text cut:textfield]; break; case ACTIVATE_COPY: text=[[textfield window] fieldEditor:YES forObject:textfield]; [text copy:textfield]; break; case ACTIVATE_PASTE: text=[[textfield window] fieldEditor:YES forObject:textfield]; [text paste:textfield]; break; } break; case GADGET_TEXTAREA: textview=(TextView*)gadget->handle; switch (code){ case ACTIVATE_FOCUS: window=[textview window]; if (window) [window makeFirstResponder:textview]; break; case ACTIVATE_CUT: [textview cut:textview]; break; case ACTIVATE_COPY: [textview copy:textview]; break; case ACTIVATE_PASTE: [textview pasteAsPlainText:textview];//paste:textview]; break; case ACTIVATE_PRINT: [textview print:textview]; break; } break; case GADGET_NODE: node=(NodeItem*)gadget->handle; treeview=[node getOwner]; switch (code){ case ACTIVATE_SELECT: [treeview selectNode:node]; break; case ACTIVATE_EXPAND: [treeview expandNode:node]; break; case ACTIVATE_COLLAPSE: [treeview collapseNode:node]; break; } break; case GADGET_COMBOBOX: switch (code){ case ACTIVATE_FOCUS: combo=(NSComboBox*)gadget->handle; [combo selectText:nil]; break; } break; case GADGET_HTMLVIEW: browser=(HTMLView*)gadget->handle; switch(code){ case ACTIVATE_COPY: [browser copy:browser]; break; case ACTIVATE_BACK: [browser goBack:browser]; break; case ACTIVATE_FORWARD: [browser goForward:browser]; break; case ACTIVATE_PRINT: view = [[[browser mainFrame] frameView] documentView]; if (view != nil) [view print:view]; break; } default: switch (code){ case ACTIVATE_FOCUS: window=[gadget->handle window]; if (window) [window makeFirstResponder:gadget->handle]; break; } } } void NSRethink(nsgadget *gadget){ NSView *view; NSRect rect,vis; TextView *textview; TabView *tabber; NSButton *button; NSControl *combobox; int shouldhide; view=(NSView*)gadget->handle; rect=NSMakeRect(gadget->x,gadget->y,gadget->w,gadget->h); shouldhide = FALSE; switch(gadget->internalclass){ case GADGET_WINDOW: vis=[[NSScreen deepestScreen] visibleFrame]; rect.origin.x+=vis.origin.x; rect.origin.y=vis.origin.y+vis.size.height-rect.origin.y-rect.size.height; if ((gadget->style&WINDOW_CLIENTCOORDS)!=0){ if (gadget->style&WINDOW_STATUS) { rect.origin.y-=STATUSBARHEIGHT; rect.size.height+=STATUSBARHEIGHT; } rect = [(NSWindow*)view frameRectForContentRect:rect]; } if(![view isVisible]) shouldhide = TRUE; [view setFrame:rect display:YES]; if(shouldhide) [view orderOut:view]; return; case GADGET_NODE: case GADGET_MENUITEM: case GADGET_TOOLBAR: return; case GADGET_TEXTAREA: textview=(TextView*)view; [textview setScrollFrame:rect]; return; case GADGET_COMBOBOX: if (rect.size.height > 26) rect.size.height = 26; break; case GADGET_BUTTON: button=(NSButton*)view; // Push Button Size Hack if ((gadget->style&7)==0){ if (gadget->h > 30) { [button setBezelStyle:NSRegularSquareBezelStyle]; } else { if (gadget->h < 24) { [button setBezelStyle:NSShadowlessSquareBezelStyle]; } else { [button setBezelStyle:NSRoundedBezelStyle]; } } } break; case GADGET_SLIDER: switch (gadget->style&12){ case SLIDER_SCROLLBAR: if (gadget->style & SLIDER_HORIZONTAL) rect.size.height = [NSScroller scrollerWidth]; else rect.size.width = [NSScroller scrollerWidth]; break; } } [[view superview] setNeedsDisplayInRect:[view frame]]; [view setFrame:rect]; [view setNeedsDisplay:YES]; } void NSRemoveColor(nsgadget *gadget){ switch (gadget->internalclass){ case GADGET_BUTTON: if ([[gadget->handle cell] respondsToSelector:@selector(setDrawsBackground)]){ [[gadget->handle cell] setDrawsBackground:false]; } break; case GADGET_WINDOW: [gadget->handle setBackgroundColor:nil]; [gadget->handle display]; break; case GADGET_LABEL: if((gadget->style&3)==LABEL_SEPARATOR) break; case GADGET_COMBOBOX: case GADGET_TEXTFIELD: [gadget->handle setDrawsBackground:false]; break; case GADGET_LISTBOX: case GADGET_TREEVIEW: case GADGET_PANEL: case GADGET_TEXTAREA: [gadget->handle setColor:nil]; break; } } void NSSetColor(nsgadget *gadget,int r,int g,int b){ NSColor *color; color=[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0]; switch (gadget->internalclass){ case GADGET_BUTTON: if ([[gadget->handle cell] respondsToSelector:@selector(setBackgroundColor)]) [[gadget->handle cell] setBackgroundColor:color]; break; case GADGET_COMBOBOX: case GADGET_WINDOW: [gadget->handle setBackgroundColor:color]; [gadget->handle display]; break; case GADGET_LABEL: if((gadget->style&3)==LABEL_SEPARATOR) break; [gadget->handle setDrawsBackground:YES]; case GADGET_TEXTFIELD: [gadget->handle setBackgroundColor:color]; break; case GADGET_LISTBOX: case GADGET_TREEVIEW: case GADGET_PANEL: case GADGET_TEXTAREA: [gadget->handle setColor:color]; break; } } void NSSetAlpha(nsgadget *gadget,float alpha){ NSWindow *window; PanelView *panel; switch (gadget->internalclass){ case GADGET_WINDOW: window=(NSWindow*)gadget->handle; [window setAlphaValue:alpha]; break; case GADGET_PANEL: panel=(PanelView*)gadget->handle; [panel setAlpha:alpha]; break; } } BBString *NSGetUserName(){ return bbStringFromNSString(CSCopyUserName(true)); } BBString *NSGetComputerName(){ return bbStringFromNSString(CSCopyMachineName()); } BBString *NSRun(nsgadget *gadget,BBString *text){ HTMLView *htmlview; NSString *script; BBString *result; result=&bbEmptyString; switch (gadget->internalclass){ case GADGET_HTMLVIEW: htmlview=(HTMLView*)gadget->handle; script=NSStringFromBBString(text); script=[htmlview stringByEvaluatingJavaScriptFromString:script]; result=bbStringFromNSString(script); break; } return result; } void NSSetText(nsgadget *gadget,BBString *data){ NSString *text; NSMutableDictionary *textAttributes; NSMutableParagraphStyle *parastyle; NSAttributedString *attribtext; NSObject *nsobject; attribtext = nil; if(data == nil) data = &bbEmptyString; text = NSStringFromBBString(data); nsobject = (NSObject*)gadget->handle; //printf( "data->length: %d\n", data->length );fflush(stdout); switch (gadget->internalclass){ case GADGET_TEXTAREA: [nsobject setText:text]; break; case GADGET_HTMLVIEW: [nsobject setAddress:text]; break; case GADGET_LABEL: /* BaH */ switch (gadget->style&3) { case LABEL_SEPARATOR: return; default: [nsobject setStringValue:text]; return; } break; case GADGET_BUTTON: //if ([nsobject respondsToSelector:@selector(setAttributedTitle)] /*&& [nsobject respondsToSelector:@selector(font)]*/){ // Create attribute dictionary (autorelease'd) textAttributes = [NSMutableDictionary dictionary]; // Font [textAttributes setObject: [nsobject font] forKey:NSFontAttributeName]; // Paragraph style parastyle = [[NSMutableParagraphStyle alloc] init]; [parastyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]]; if(gadget->internalclass == GADGET_BUTTON){ if(((gadget->style & BUTTON_PUSH) == BUTTON_PUSH) || (((gadget->style & 7) != BUTTON_RADIO) && ((gadget->style & 7) != BUTTON_CHECKBOX))) [parastyle setAlignment:NSCenterTextAlignment]; } [textAttributes setObject: parastyle forKey:NSParagraphStyleAttributeName]; [parastyle release]; // Text color if(gadget->textcolor) [textAttributes setObject: gadget->textcolor forKey: NSForegroundColorAttributeName]; // Underline / strikethrough [textAttributes setObject: [NSNumber numberWithInt:0] forKey: NSUnderlineStyleAttributeName]; [textAttributes setObject: [NSNumber numberWithInt:0] forKey: NSStrikethroughStyleAttributeName]; if ((gadget->intFontStyle&FONT_UNDERLINE)!=0) [textAttributes setObject: [NSNumber numberWithInt:(NSUnderlineStyleSingle|NSUnderlinePatternSolid)] forKey: NSUnderlineStyleAttributeName]; if ((gadget->intFontStyle&FONT_STRIKETHROUGH)!=0) [textAttributes setObject: [NSNumber numberWithInt:(NSUnderlineStyleSingle|NSUnderlinePatternSolid)] forKey: NSStrikethroughStyleAttributeName]; // Create attibuted text attribtext = [[NSAttributedString alloc] initWithString: text attributes: textAttributes]; [nsobject setAttributedTitle:attribtext]; break; //} case GADGET_MENUITEM: [nsobject setTitle:text]; // Required otherwise root window menus aren't updated. [[nsobject submenu] setTitle:text]; break; case GADGET_PANEL: case GADGET_NODE: case GADGET_WINDOW: [nsobject setTitle:text]; break; case GADGET_COMBOBOX: if(!(gadget->style & COMBOBOX_EDITABLE)) break; case GADGET_TEXTFIELD: [nsobject setStringValue:text]; break; } } BBString *NSGetText(nsgadget *gadget){ NSObject *nsobject; BBString *result; result=&bbEmptyString; nsobject=(NSObject*)gadget->handle; switch (gadget->internalclass){ case GADGET_TEXTAREA: result=bbStringFromNSString([[nsobject storage] string]); break; case GADGET_TEXTFIELD: case GADGET_COMBOBOX: result=bbStringFromNSString([nsobject stringValue]); break; case GADGET_HTMLVIEW: result=bbStringFromNSString([nsobject address]); break; case GADGET_NODE: result=bbStringFromNSString([nsobject value]); break; case GADGET_LABEL: /* BaH */ switch (gadget->style&3) { case 0: case LABEL_FRAME: case LABEL_SUNKENFRAME: result=bbStringFromNSString([nsobject stringValue]); } break; case GADGET_PANEL: case GADGET_WINDOW: case GADGET_BUTTON: case GADGET_MENUITEM: result=bbStringFromNSString([nsobject title]); break; } return result; } int NSCharWidth(NSFont *font,int charcode){ NSSize size=[font advancementForGlyph:charcode]; return (int)size.width; } void NSSetFont(nsgadget *gadget,NSFont *font){ NSView *view; view = (NSView*)gadget->handle; switch (gadget->internalclass){ case GADGET_LABEL: if ((gadget->style&3)==LABEL_SEPARATOR) break; case GADGET_BUTTON: [view setFont:font]; NSSetText(gadget, NSGetText(gadget)); //Apply underline/strikethough formatting as attributed text in NSSetText(). break; case GADGET_LISTBOX: case GADGET_TREEVIEW: case GADGET_COMBOBOX: case GADGET_TEXTAREA: case GADGET_TEXTFIELD: case GADGET_TABBER: [view setFont:font]; break; } } BBString * NSGetTooltip(nsgadget *gadget){ BBString *result; NSView *view; result=&bbEmptyString; view=(NSView*)gadget->handle; if(view) result=bbStringFromNSString([view toolTip]); return result; } int NSSetTooltip(nsgadget *gadget,BBString *data){ NSString *text; NSView *view; view =(NSView*)gadget->handle; text=NSStringFromBBString(data); if(view){ [view setToolTip:text]; return 1; } return 0; } // gadgetitem commands void NSClearItems(nsgadget *gadget) { ListView *listbox; NSControl *combo; NSTabView *tabber; Toolbar *toolbar; NSToolbarItem *item; NSArray *items; int i,n; switch (gadget->internalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; [listbox clear]; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; [combo removeAllItems]; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; items=[tabber tabViewItems]; n=[tabber numberOfTabViewItems]; for (i=0;ihandle; items=[toolbar items]; n=[items count]; for (i=0;iinternalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; [listbox addItem:text atIndex:index withImage:image withTip:tiptext withExtra:extra]; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; [combo insertItemWithObjectValue:text atIndex:index]; // [[combo itemAtIndex:index] setImage:image]; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; tabitem=[[TabViewItem alloc] initWithIdentifier:text]; [tabitem setLabel:text]; [tabitem setImage:image]; [tabber insertTabViewItem:tabitem atIndex:index]; [tabitem release]; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; if (image==0){ int v; Gestalt( 'sysv',&v ); if( v>=0x1070 ){ [toolbar insertItemWithItemIdentifier:NSToolbarSpaceItemIdentifier atIndex:index]; }else{ [toolbar insertItemWithItemIdentifier:NSToolbarSeparatorItemIdentifier atIndex:index]; } } else{ item=[[NSToolbarItem alloc] initWithItemIdentifier:text]; [item setImage:image]; // [item setLabel:text]; [item setAction:@selector(iconSelect:)]; [item setTarget:GlobalApp]; [item setToolTip:tiptext]; [item setTag:0]; [GlobalApp addToolbarItem:item]; [toolbar addToolbarItem:item]; [toolbar insertItemWithItemIdentifier:text atIndex:index]; } break; } } NSToolbarItem *FindToolbarItem(NSToolbar *toolbar,int index){ return (NSToolbarItem*)[[toolbar items] objectAtIndex:index]; } void NSSetItem(nsgadget *gadget,int index,BBString *data,BBString *tip,NSImage *image,BBObject *extra){ NSString *text,*tiptext; NSControl *combo; NSTabView *tabber; TabViewItem *tabitem; ListView *listbox; Toolbar *toolbar; NSToolbarItem *item; text=NSStringFromBBString(data); tiptext=NSStringFromBBString(tip); switch (gadget->internalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; [listbox setItem:text atIndex:index withImage:image withTip:tiptext withExtra:extra]; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; [combo removeItemAtIndex:index]; [combo insertItemWithObjectValue:text atIndex:index]; // [[combo itemAtIndex:index] setImage:image]; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; tabitem=(TabViewItem*)[tabber tabViewItemAtIndex:index]; [tabitem setLabel:text]; [tabitem setImage:image]; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; item=FindToolbarItem(toolbar,index); if (item) { // [item setLabel:text]; [item setImage:image]; [item setToolTip:tiptext]; [item setTag:0]; } break; } } void NSRemoveItem(nsgadget *gadget,int index){ ListView *listbox; NSControl *combo; NSTabView *tabber; TabViewItem *tabitem; Toolbar *toolbar; switch (gadget->internalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; [listbox removeItemAtIndex:index]; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; [combo removeItemAtIndex:index]; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; tabitem=(TabViewItem*)[tabber tabViewItemAtIndex:index]; [tabber removeTabViewItem:tabitem]; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; [toolbar removeItemAtIndex:(int)index]; break; } } void NSSelectItem(nsgadget *gadget,int index,int state){ NSControl *combo; NSTabView *tabber; ListView *listbox; Toolbar *toolbar; NSToolbarItem *item; switch (gadget->internalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; if(state) [listbox selectItem:index]; else [listbox deselectItem:index]; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; [combo setDelegate:nil]; [combo selectItemAtIndex:index]; [combo setObjectValue:[combo objectValueOfSelectedItem]]; [combo setDelegate:GlobalApp]; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; [tabber selectTabViewItemAtIndex:index]; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; item=FindToolbarItem(toolbar,index); BOOL enable=(state&STATE_DISABLED)?false:true; [item setEnabled:enable]; int pressed=(state&STATE_SELECTED)?1:0; [item setTag:pressed]; break; } } int NSSelectedItem(nsgadget *gadget,int index){ NSComboBox *combo; NSTabView *tabber; ListView *listbox; Toolbar *toolbar; NSToolbarItem *item; int state; state=0; switch (gadget->internalclass){ case GADGET_LISTBOX: listbox=(ListView*)gadget->handle; if ([[listbox table] selectedRow]==index) state|=STATE_SELECTED; break; case GADGET_COMBOBOX: combo=(NSControl*)gadget->handle; if ([combo indexOfSelectedItem]==index) state|=STATE_SELECTED; break; case GADGET_TABBER: tabber=(NSTabView*)gadget->handle; if ([tabber indexOfTabViewItem:[tabber selectedTabViewItem]]==index) state|=STATE_SELECTED; break; case GADGET_TOOLBAR: toolbar=(Toolbar*)gadget->handle; item=FindToolbarItem(toolbar,index); if (![item isEnabled]) state|=STATE_DISABLED; if ([item tag]!=0) state|=STATE_SELECTED; break; } return state; } // treeview commands int NSCountKids(nsgadget *gadget){ TreeView *treeview; NodeItem *node; switch (gadget->internalclass){ case GADGET_TREEVIEW: treeview=(TreeView*)gadget->handle; return [treeview count]; case GADGET_NODE: node=(NodeItem*)gadget->handle; return [node count]; } return 0; } id NSSelectedNode(nsgadget *gadget){ TreeView *treeview; switch (gadget->internalclass){ case GADGET_TREEVIEW: treeview=(TreeView*)gadget->handle; return [treeview selectedNode]; } return 0; } // textarea commands int LinePos(NSString *text,int pos){ int line,i; line=0; for (i=0;i0){ if ([text characterAtIndex:pos]=='\n') line--; pos++; } return pos; } NSRange GetRange(NSTextStorage *storage,int pos,int count,int units){ NSString *text; unsigned int max; if (units==TEXTAREA_LINES){ text=[storage string]; if (count==TEXTAREA_ALL) count=[storage length]; else count=CharPos(text,pos+count); pos=CharPos(text,pos); max = [storage length]-pos; count-=pos; } else{ max = [storage length]-pos; if (count==TEXTAREA_ALL) count=max; } if (count > max) count = max; if (count<0) count=0; //NSLog(@"GetRange() pos: %d, count: %d, length: %d\n", pos, count, [storage length]); return NSMakeRange(pos,count); } void NSReplaceText(nsgadget *gadget,int pos,int count,BBString *data,int units){ NSString *text; TextView *textarea; NSRange range,snap; NSTextStorage *storage; unsigned int size; text=NSStringFromBBString(data); textarea=(TextView*)gadget->handle; if(([[textarea string] length] == 0) || ((pos == 0) && (count == TEXTAREA_ALL))){ [textarea setText:text]; } else { snap=[textarea selectedRange]; range=GetRange([textarea storage],pos,count,units); storage=[textarea storage]; [storage replaceCharactersInRange:range withString:text]; size=[storage length]; if (snap.location>size) snap.location=size; if (snap.location+snap.length>size) snap.length=size-snap.location; [textarea setSelectedRange:snap]; } } void NSAddText(nsgadget *gadget,BBString *data){ NSString *text; TextView *textarea; NSRange range; text=NSStringFromBBString(data); textarea=(TextView*)gadget->handle; [textarea addText:text]; range=GetRange([textarea textStorage],[[textarea string] length],0,0); [textarea setSelectedRange:range]; [textarea scrollRangeToVisible:range]; } BBString *NSAreaText(nsgadget *gadget,int pos,int length,int units){ TextView *textarea; NSRange range; NSAttributedString *astring; BBString *bstring; textarea=(TextView*)gadget->handle; range=GetRange([textarea storage],pos,length,units); astring=[[textarea storage] attributedSubstringFromRange:range]; bstring=bbStringFromNSString([astring string]); return bstring; } int NSAreaLen(nsgadget *gadget,int units){ TextView *textarea; NSTextStorage *storage; unsigned ulen; textarea=(TextView*)gadget->handle; storage=[textarea storage]; ulen=[storage length]; if (units==TEXTAREA_LINES) ulen=LinePos([storage string],ulen)+1; return ulen; } void NSSetSelection(nsgadget *gadget,int pos,int length,int units){ TextView *textarea; NSRange range; textarea=(TextView*)gadget->handle; range=GetRange([textarea textStorage],pos,length,units); [textarea setSelectedRange:range]; if( !textarea->lockedNest ) [textarea scrollRangeToVisible:range]; } void NSLockText(nsgadget *gadget){ TextView *textarea; textarea=(TextView*)gadget->handle; if( !textarea->lockedNest ){ textarea->lockedRange=[textarea rangeForUserTextChange]; [textarea->storage beginEditing]; } ++textarea->lockedNest; } void NSUnlockText(nsgadget *gadget){ TextView *textarea; textarea=(TextView*)gadget->handle; --textarea->lockedNest; if( !textarea->lockedNest ){ NSRange range=textarea->lockedRange; [textarea->storage endEditing]; if( range.location+range.length>[textarea->storage length] ) range=NSMakeRange( 0,0 ); [textarea setSelectedRange:range]; } } void NSSetTabs(nsgadget *gadget,int tabwidth){ TextView *textarea; textarea=(TextView*)gadget->handle; [textarea setTabs:tabwidth]; } void NSSetMargins(nsgadget *gadget,int leftmargin){ TextView *textarea; textarea=(TextView*)gadget->handle; [textarea setMargins:leftmargin]; } int NSCharAt(nsgadget *gadget,int line){ TextView *textarea; NSString *text; int n,i; textarea=(TextView*)gadget->handle; text=[[textarea storage] string]; n=[text length];i=0; while (line){ if (i==n) break; if ([text characterAtIndex:i]=='\n' ) line--; i++; } return i; } int NSLineAt(nsgadget *gadget,int pos){ TextView *textarea; textarea=(TextView*)gadget->handle; return LinePos([[textarea storage] string],pos); } int NSCharX(nsgadget *gadget,int pos){ unsigned int rectCount; NSRectArray rectArray; TextView *textarea = (TextView*)gadget->handle; NSRange range = GetRange([textarea textStorage],pos,0,TEXTAREA_CHARS); rectArray = [[textarea layoutManager] rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer: [textarea textContainer] rectCount:&rectCount]; if(rectCount > 0) return (int)(((NSRect)rectArray[0]).origin.x-([textarea visibleRect].origin.x-[textarea textContainerOrigin].x)); } int NSCharY(nsgadget *gadget,int pos){ unsigned int rectCount; NSRectArray rectArray; TextView *textarea = (TextView*)gadget->handle; NSRange range = GetRange([textarea textStorage],pos,0,TEXTAREA_CHARS); rectArray = [[textarea layoutManager] rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer: [textarea textContainer] rectCount:&rectCount]; if(rectCount > 0) return (int)(((NSRect)rectArray[0]).origin.y-([textarea visibleRect].origin.y-[textarea textContainerOrigin].y)); } int NSGetCursorPos(nsgadget *gadget,int units){ TextView *textarea; NSRange range; textarea=(TextView*)gadget->handle; range=[textarea rangeForUserTextChange]; if (range.location == NSNotFound) return 0; //KORIOLIS (avoids read-only text-area crash) if (units==TEXTAREA_LINES) return NSLineAt(gadget,range.location); return range.location; } int NSGetSelectionlength(nsgadget *gadget,int units){ TextView *textarea; NSRange range; textarea=(TextView*)gadget->handle; range=[textarea rangeForUserTextChange]; if (range.location == NSNotFound) return 0; //KORIOLIS (avoids read-only text-area crash) if (range.length == 0) return 0; if (units == TEXTAREA_LINES){ int l0=NSLineAt(gadget,range.location); int l1=NSLineAt(gadget,range.location+range.length-1); return (l1-l0+1); } return range.length; } void NSSetTextColor(nsgadget *gadget,int r,int g,int b){ if(gadget->textcolor) [gadget->textcolor release]; gadget->textcolor = [[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0] retain]; switch (gadget->internalclass){ case GADGET_LABEL: switch (gadget->style&3) { case LABEL_SEPARATOR: return; } case GADGET_TEXTFIELD: case GADGET_LISTBOX: case GADGET_TREEVIEW: case GADGET_TEXTAREA: [gadget->handle setTextColor:gadget->textcolor]; break; default: NSSetText(gadget, NSGetText(gadget)); //Attempt to reset text with NSAttributedString break; } } void NSSetStyle(nsgadget *gadget,int r,int g,int b,int flags,int pos,int length,int units) { TextView *textarea; NSRange _range; NSColor *color; int traits = 0; textarea=(TextView*)gadget->handle; _range=GetRange([textarea storage],pos,length,units); color=[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0]; [[textarea storage] removeAttribute:NSLinkAttributeName range:_range]; [[textarea storage] addAttribute:NSForegroundColorAttributeName value:color range:_range]; [[textarea storage] addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:(flags & 4)?NSUnderlineStyleSingle:NSUnderlineStyleNone] range:_range]; [[textarea storage] addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:(flags & 8)?NSUnderlineStyleSingle:NSUnderlineStyleNone] range:_range]; traits |= (flags & 1)?NSBoldFontMask:NSUnboldFontMask; traits |= (flags & 2)?NSItalicFontMask:NSUnitalicFontMask; [[textarea storage] applyFontTraits: traits range:_range]; } void NSSetValue(nsgadget *gadget,float value){ NSProgressIndicator *progbar; NSDate *date; NSValue *info; NSRunLoop *runloop; switch (gadget->internalclass){ case GADGET_PROGBAR: progbar=(NSProgressIndicator*)gadget->handle; [progbar setDoubleValue:value]; break; } } // slider / scrollbar void NSSetSlider(nsgadget *gadget,double value,double small,double big){ NSScroller *scroller; NSSlider *slider; NSStepper *stepper; NSRect frame; float size; switch (gadget->style&12){ case SLIDER_SCROLLBAR: scroller=(NSScroller*)gadget->handle; if(value > (big-small)) value = 1.0L; else if(big-small) value/=(big-small); else value = 0.0L; [scroller setKnobProportion:(small/big)]; [scroller setDoubleValue:value]; break; case SLIDER_TRACKBAR: slider=(NSSlider*)gadget->handle; [slider setMinValue:small]; [slider setMaxValue:big]; [slider setDoubleValue:value]; break; case SLIDER_STEPPER: stepper=(NSStepper*)gadget->handle; [stepper setMinValue:small]; [stepper setMaxValue:big]; [stepper setDoubleValue:value]; break; } } double NSGetSlider(nsgadget *gadget){ NSControl *control; control = (NSControl*)gadget->handle; return [control doubleValue]; } NSCursor* NSCursorCreateStock(short sIndex) { // Adapted from wxWidgets - if you believe this contravenes wxWidget's licensing // agreements, please let the BRL team know and it will be removed. int i; ArrayCursor* tmpCursor = &arrCursors[sIndex]; NSImage *tmpImage = [[NSImage alloc] initWithSize:NSMakeSize(16.0,16.0)]; NSBitmapImageRep *tmpRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL pixelsWide: 16 pixelsHigh: 16 bitsPerSample: 1 samplesPerPixel: 2 hasAlpha: YES isPlanar: YES colorSpaceName: NSCalibratedWhiteColorSpace bytesPerRow: 2 bitsPerPixel: 1]; unsigned char *planes[5]; [tmpRep getBitmapDataPlanes:planes]; for(i=0; i<16; ++i) { planes[0][2*i ] = (~tmpCursor->bits[i] & tmpCursor->mask[i]) >> 8 & 0xff; planes[1][2*i ] = tmpCursor->mask[i] >> 8 & 0xff; planes[0][2*i+1] = (~tmpCursor->bits[i] & tmpCursor->mask[i]) & 0xff; planes[1][2*i+1] = tmpCursor->mask[i] & 0xff; } [tmpImage addRepresentation:tmpRep]; NSCursor* tmpNSCursor = [[NSCursor alloc] initWithImage:tmpImage hotSpot:NSMakePoint(tmpCursor->hitpoint[1], tmpCursor->hitpoint[0])]; [tmpRep release];[tmpImage release]; return tmpNSCursor; } void NSSetPointer(int shape){ NSCursor *cursor; cursor=[NSCursor arrowCursor]; switch (shape){ // case POINTER_DEFAULT:cursor=[NSCursor ];break; case POINTER_ARROW:cursor=[NSCursor arrowCursor];break; case POINTER_IBEAM:cursor=[NSCursor IBeamCursor];break; // case POINTER_WAIT:cursor=[NSCursor ];break; case POINTER_CROSS:cursor=[NSCursor crosshairCursor];break; case POINTER_UPARROW:cursor=[NSCursor resizeUpCursor];break; case POINTER_SIZENWSE:cursor=NSCursorCreateStock(curNWSE);break; case POINTER_SIZENESW:cursor=NSCursorCreateStock(curNESW);break; case POINTER_SIZEWE:cursor=[NSCursor resizeLeftRightCursor];break; case POINTER_SIZENS:cursor=[NSCursor resizeUpDownCursor];break; case POINTER_SIZEALL:cursor=NSCursorCreateStock(curSizeAll);break; case POINTER_NO:cursor=NSCursorCreateStock(curNoEntry);break; case POINTER_HAND:cursor=[NSCursor pointingHandCursor];break; // case POINTER_APPSTARTING:cursor=[NSCursor ];break; case POINTER_HELP:cursor=NSCursorCreateStock(curHelp);break; } [cursor set]; } typedef struct bbpixmap bbpixmap; struct bbpixmap{ // BBObject void *class; // int refs; // pixmap unsigned char *pixels; int width,height,pitch,format,capacity; void *source; }; #define PF_I8 1 #define PF_A8 2 #define PF_BGR888 3 #define PF_RGB888 4 #define PF_BGRA8888 5 #define PF_RGBA8888 6 #define PF_STDFORMAT PF_RGBA8888 const static char BytesPerPixel[]={0,1,1,3,3,4,4}; const static char BitsPerPixel[]={0,8,8,24,24,32,32}; const static char RedBitsPerPixel[]={0,0,0,8,8,8,8}; const static char GreenBitsPerPixel[]={0,0,0,8,8,8,8}; const static char BlueBitsPerPixel[]={0,0,0,8,8,8,8}; const static char AlphaBitsPerPixel[]={0,0,8,0,0,8,8}; NSImage *NSPixmapImage(bbpixmap *pix){ NSImage *image; NSBitmapImageRep *bitmap; int spp,bpp,i; int bytesperrow; BOOL alpha; unsigned char * data; alpha=AlphaBitsPerPixel[pix->format]?YES:NO; spp=BytesPerPixel[pix->format]; bpp=BitsPerPixel[pix->format]; bytesperrow=pix->width*spp; bitmap=[[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:pix->width pixelsHigh:pix->height bitsPerSample:8 samplesPerPixel:spp hasAlpha:alpha isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace // bitmapFormat:NSAlphaNonpremultipliedBitmapFormat bytesPerRow:bytesperrow bitsPerPixel:bpp] autorelease]; data = [bitmap bitmapData]; for( i = 0; i < pix->height; i++) { memcpy( data + ( i * bytesperrow ), pix->pixels + ( i * pix->pitch ), bytesperrow ); } image=[[NSImage alloc] initWithSize:NSMakeSize(pix->width, pix->height)]; [image addRepresentation:bitmap]; [image autorelease]; return image; } void NSSetImage(nsgadget *gadget,NSImage *image,int flags){ PanelView *panel; NSButton *button; NSMenuItem *menu; switch (gadget->internalclass){ case GADGET_PANEL: panel=(PanelView*)gadget->handle; [panel setImage:image withFlags:flags]; break; case GADGET_BUTTON: if ((flags & GADGETPIXMAP_ICON) && (gadget->style <= BUTTON_PUSH)){ button=(NSButton *)gadget->handle; [button setImage:image]; if (flags & GADGETPIXMAP_NOTEXT) { [button setImagePosition:NSImageOnly]; } else { [button setImagePosition:NSImageLeft]; } } break; case GADGET_MENUITEM: if (flags & GADGETPIXMAP_ICON){ menu=(NSMenuItem*)gadget->handle; [menu setImage:image]; } break; } } void NSSetIcon(nsgadget *gadget,NSImage *image){ NodeItem *node; switch (gadget->internalclass){ case GADGET_NODE: node=(NodeItem*)gadget->handle; [node setIcon:image]; break; } } void NSSetNextView(nsgadget *gadget,nsgadget *nextgadget){ NSView *view,*nextview; view=(NSView*)gadget->handle; nextview=(NSView*)nextgadget->handle; [view setNextKeyView:nextview]; } static int keyToChar( int key ){ if( key>=KEY_A && key<=KEY_Z ) return key-KEY_A+'a'; if( key>=KEY_F1 && key<=KEY_F12 ) return key-KEY_F1+NSF1FunctionKey; switch( key ){ case KEY_BACKSPACE:return 8; case KEY_TAB:return 9; case KEY_ESC:return 27; case KEY_SPACE:return 32; case KEY_PAGEUP:return NSPageUpFunctionKey; case KEY_PAGEDOWN:return NSPageDownFunctionKey; case KEY_END:return NSEndFunctionKey; case KEY_HOME:return NSHomeFunctionKey; case KEY_UP:return NSUpArrowFunctionKey; case KEY_DOWN:return NSDownArrowFunctionKey; case KEY_LEFT:return NSLeftArrowFunctionKey; case KEY_RIGHT:return NSRightArrowFunctionKey; case KEY_INSERT:return NSInsertFunctionKey; case KEY_DELETE:return NSDeleteFunctionKey; case KEY_TILDE:return '~'; case KEY_MINUS:return '-'; case KEY_EQUALS:return '='; case KEY_OPENBRACKET:return '['; case KEY_CLOSEBRACKET:return ']'; case KEY_BACKSLASH:return '\\'; case KEY_SEMICOLON:return ';'; case KEY_QUOTES:return '\''; case KEY_COMMA:return ','; case KEY_PERIOD:return '.'; case KEY_SLASH:return '/'; } return 0; } void NSSetHotKey(nsgadget *gadget,int key,int modifier){ int chr; unichar uchar[1]; NSString *keyStr; int modMask; NSMenuItem *menuItem; if( gadget->internalclass!=GADGET_MENUITEM ) return; modMask=0; if( modifier & 1 ) modMask|=NSShiftKeyMask; if( modifier & 2 ) modMask|=NSControlKeyMask; if( modifier & 4 ) modMask|=NSAlternateKeyMask; if( modifier & 8 ) modMask|=NSCommandKeyMask; menuItem=(NSMenuItem*)gadget->handle; chr=keyToChar( key ); if( !chr ) { [menuItem setKeyEquivalent:@""]; [menuItem setKeyEquivalentModifierMask:0]; return; } uchar[0]=chr; keyStr=[NSString stringWithCharacters:uchar length:1]; [menuItem setKeyEquivalent:keyStr]; [menuItem setKeyEquivalentModifierMask:modMask]; }