From: blitz-research Date: Wed, 29 Jan 2014 02:11:14 +0000 (+1300) Subject: Tweaked cocoamaxgui so it's 10.4->10.9 friendly! X-Git-Tag: v150~1 X-Git-Url: https://jcornell.net/gitweb/gitweb.cgi?a=commitdiff_plain;h=2c4d2f2f0a93088d8aea43f9bf18d5a7be6ad9d2;p=blitzmax.git Tweaked cocoamaxgui so it's 10.4->10.9 friendly! --- diff --git a/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos_tiger.m b/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos_tiger.m new file mode 100644 index 0000000..440e131 --- /dev/null +++ b/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos_tiger.m @@ -0,0 +1,4486 @@ +// 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 brl_event_EmitEvent( BBObject *event ); +BBObject *maxgui_maxgui_HotKeyEvent( int key,int mods ); +void maxgui_maxgui_DispatchGuiEvents(); +void maxgui_cocoamaxgui_EmitCocoaOSEvent( NSEvent *event,void *handle,BBObject *gadget ); +int maxgui_cocoamaxgui_EmitCocoaMouseEvent( NSEvent *event,void *handle ); +int maxgui_cocoamaxgui_EmitCocoaKeyEvent( NSEvent *event,void *handle ); +void maxgui_cocoamaxgui_PostCocoaGuiEvent( int ev,void *handle,int data,int mods,int x,int y,BBObject *extra ); + +int maxgui_cocoamaxgui_FilterChar( void *handle,int key,int mods ); +int maxgui_cocoamaxgui_FilterKeyDown( void *handle,int key,int mods ); + +static void EmitOSEvent( NSEvent *event,void *handle ){ + maxgui_cocoamaxgui_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_EmitCocoaMouseEvent( event,handle ); +} + +static int EmitKeyEvent( NSEvent *event,void *handle ){ + return maxgui_cocoamaxgui_EmitCocoaKeyEvent( event,handle ); +} + +static void PostGuiEvent( int ev,void *handle,int data,int mods,int x,int y,BBObject *extra ){ + if (extra==0) extra=&bbNullObject; + maxgui_cocoamaxgui_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_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_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]; + [column setMinWidth:0]; + for (i=0;i-1 && i<[self numberOfRows]){ + node=[self itemAtRow:i]; + PostGuiEvent( BBEVENT_GADGETMENU,[self dataSource],(int)node,0,0,0,0 ); //[self superview] + } + return nil; +} +@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=[[NSBrowserCell 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]; + [column setMinWidth:0]; + [rootNode queueWidthUpdate]; +} +-(void)outlineViewItemDidExpand:(NSNotification *)notification{ + id node; + node=[[notification userInfo] objectForKey:@"NSObject"]; + [node queueWidthUpdate]; + PostGuiEvent( BBEVENT_GADGETOPEN,self,(int)node,0,0,0,0 ); +} +-(void)outlineViewItemDidCollapse:(NSNotification *)notification{ + id node; + node=[[notification userInfo] objectForKey:@"NSObject"]; + [column setMinWidth:0]; + [rootNode queueWidthUpdate]; + PostGuiEvent( BBEVENT_GADGETCLOSE,self,(int)node,0,0,0,0 ); +} +-(void)outlineViewSelectionDidChange:(NSNotification *)notification{ + id node; + node=[self selectedNode]; + PostGuiEvent( BBEVENT_GADGETSELECT,self,(int)node,0,0,0,0 ); +} +-(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item{ + PostGuiEvent( BBEVENT_GADGETACTION,self,(int)item,0,0,0,0 ); + return NO; +} +-(void)setColor:(NSColor*)color{ + [outline setBackgroundColor:color]; +} +-(void)setTextColor:(NSColor*)color{ + if (textstyle) {[textstyle release];textstyle=nil;} + if (color){ + textstyle=[NSDictionary 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]+1]; + [rootNode queueWidthUpdate]; + } +} +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)dcell forTableColumn:(NSTableColumn *)tableColumn item:(id)node{ + if (textstyle){ + 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)]; + } + } +} +-(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]; + + 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]; +} + +int NSActiveGadget(){ + NSWindow *window; + NSResponder *responder; + window=[NSApp keyWindow]; + if (!window) return 0; + responder=[window firstResponder]; + if (!responder) return (int)window; + if ([responder isKindOfClass:[NSTextView class]] && + [window fieldEditor:NO forObject:nil] != nil ) { + NSTextView *view=(NSTextView*)responder; + return (int)[view delegate]; + } + return (int)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:nil + timestamp:0 + windowNumber:[window windowNumber] + context:nil + eventNumber: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; +} + +int NSSelectedNode(nsgadget *gadget){ + TreeView *treeview; + + switch (gadget->internalclass){ + case GADGET_TREEVIEW: + treeview=(TreeView*)gadget->handle; + return (int)[treeview selectedNode]; + } + return -1; +} + +// 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; +}; + + +#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 retain]; + 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]; +} \ No newline at end of file diff --git a/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx b/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx index ebf62fd..4017104 100644 --- a/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx +++ b/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx @@ -1,1026 +1,1026 @@ -Strict - -Import MaxGUI.MaxGUI -Import Pub.MacOs - -Import "-framework WebKit" -Import "cocoa.macos.m" - -Extern - - Function bbSystemEmitOSEvent( nsevent:Byte Ptr,nsview:Byte Ptr,source:Object ) - - Function ScheduleEventDispatch() - - Function NSBegin() - Function NSEnd() - - Function NSGetSysColor(colorindex,r:Int Ptr,g:Int Ptr, b:Int Ptr) - Function NSColorRequester(r,g,b) - Function NSSetPointer(shape) - - Function NSCharWidth(font,charcode) - ' create - Function NSInitGadget(gadget:TNSGadget) - ' generic - Function NSActiveGadget() - Function NSFreeGadget(gadget:TNSGadget) - Function NSClientWidth(gadget:TNSGadget) - Function NSClientHeight(gadget:TNSGadget) - Function NSRethink(gadget:TNSGadget) - Function NSRedraw(gadget:TNSGadget) - Function NSActivate(gadget:TNSGadget,code) - Function NSState(gadget:TNSGadget) - Function NSShow(gadget:TNSGadget,bool) - Function NSEnable(gadget:TNSGadget,bool) - Function NSCheck(gadget:TNSGadget,bool) - Function NSSetNextView(gadget:TNSGadget,nextgadget:TNSGadget) - Function NSSetHotKey(gadget:TNSGadget,hotkey,modifier) - Function NSSetTooltip(gadget:TNSGadget,tip$) - Function NSGetTooltip$(gadget:TNSGadget) - Function NSSuperview(view:Int) - ' window - Function NSSetStatus(gadget:TNSGadget,text$,pos) - Function NSSetMinimumSize(gadget:TNSGadget,width,height) - Function NSSetMaximumSize(gadget:TNSGadget,width,height) - Function NSPopupMenu(gadget:TNSGadget,menu:TNSGadget) - ' font - Function NSRequestFont(font) - Function NSLoadFont(name$,size:Double,flags) - Function NSGetDefaultFont() - Function NSSetFont(gadget:TNSGadget,font) - Function NSFontName$(font) - Function NSFontStyle(font) - Function NSFontSize:Double(font) - ' items - Function NSClearItems(gadget:TNSGadget) - Function NSAddItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) - Function NSSetItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) - Function NSRemoveItem(gadget:TNSGadget,index) - Function NSSelectItem(gadget:TNSGadget,index,state) - Function NSSelectedItem(gadget:TNSGadget,index) - Function NSSelectedNode(gadget:TNSGadget) - ' text - Function NSSetText(gadget:TNSGadget,text$) - Function NSGetText$(gadget:TNSGadget) - Function NSReplaceText(gadget:TNSGadget,pos,length,text$,units) - Function NSAddText(gadget:TNSGadget,text$) - Function NSAreaText$(gadget:TNSGadget,pos,length,units) - Function NSAreaLen(gadget:TNSGadget,units) - Function NSLockText(gadget:TNSGadget) - Function NSUnlockText(gadget:TNSGadget) - Function NSSetTabs(gadget:TNSGadget,tabwidth) - Function NSSetMargins(gadget:TNSGadget,leftmargin) - Function NSSetColor(gadget:TNSGadget,r,g,b) - Function NSRemoveColor(gadget:TNSGadget) - Function NSSetAlpha(gadget:TNSGadget,alpha#) - Function NSSetTextColor(gadget:TNSGadget,r,g,b) - Function NSGetCursorPos(gadget:TNSGadget,units) - Function NSGetSelectionlength(gadget:TNSGadget,units) - Function NSSetStyle(gadget:TNSGadget,r,g,b,flags,pos,length,units) - Function NSSetSelection(gadget:TNSGadget,pos,length,units) - Function NSCharAt(gadget:TNSGadget,line) - Function NSLineAt(gadget:TNSGadget,index) - Function NSCharX(gadget:TGadget,char) - Function NSCharY(gadget:TGadget,char) - ' prop - Function NSSetValue(gadget:TNSGadget,value#) - ' slider - Function NSSetSlider(gadget:TNSGadget,value:Double,small:Double,big:Double) - Function NSGetSlider:Double(gadget:TNSGadget) - ' images for panels and nodes - Function NSPixmapImage(image:TPixmap) - Function NSSetImage(gadget:TNSGadget,nsimage,flags) - Function NSSetIcon(gadget:TNSGadget,nsimage) - Function NSCountKids(gadget:TNSGadget) - ' html - Function NSRun$(gadget:TNSGadget,script$) - ' misc - Function NSRelease(nsobject) - ' system - Function NSGetUserName$() - Function NSGetComputerName$() - -EndExtern - -Global GadgetMap:TMap=New TMap - -maxgui_driver=New TCocoaMaxGuiDriver - -Type TCocoaMaxGUIDriver Extends TMaxGUIDriver - - Global CocoaGuiFont:TCocoaGuiFont - - Method New() - NSBegin - atexit_ NSEnd - If Not CocoaGuiFont Then CocoaGuiFont = TCocoaGuiFont(LibraryFont(GUIFONT_SYSTEM)) - End Method - - Method UserName$() - Return NSGetUserName$() - End Method - - Method ComputerName$() - Return NSGetComputerName$() - End Method - - Method CreateGadget:TGadget(internalclass,name$,x,y,w,h,group:TGadget,style) - Local p,hotkey - If internalclass=GADGET_MENUITEM - name=name.Replace("&","") - ElseIf internalclass=GADGET_BUTTON - p=name.Find("&") - If p>-1 -' hotkey=Asc(name[p..p+1]) 'to do - convert and call SetHotKey before return - name=name[..p]+name[p+1..] - EndIf - ElseIf internalclass=GADGET_TOOLBAR - Global _toolbarcount - _toolbarcount:+1 - name="Toolbar"+_toolbarcount - EndIf - Local gadget:TNSGadget = TNSGadget.Create(internalclass,name,x,y,w,h,TNSGadget(group),style) - If internalclass<>GADGET_WINDOW And internalclass<>GADGET_MENUITEM And internalclass<>GADGET_DESKTOP - gadget.SetLayout EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED - EndIf - If group Then gadget._SetParent group - gadget.SetTextColor(0,0,0) - gadget.LinkView - Return gadget - End Method - - Function CreateFont:TGuiFont(handle,flags=FONT_NORMAL) - Local font:TGuiFont = New TCocoaGuiFont - font.handle = handle - font.name = NSFontName(handle) - font.size = NSFontSize(handle) - font.style = NSFontStyle(handle)|flags - Return font - EndFunction - - Method LoadFont:TGuiFont(name$,size,flags) - Return CreateFont(NSLoadFont(name,Double(size),flags),flags) - End Method - - Method LoadFontWithDouble:TGuiFont(name$,size:Double,flags) - Return CreateFont(NSLoadFont(name,size,flags),flags) - End Method - - Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) - If pFontType = GUIFONT_SYSTEM Then - Local tmpHandle% = NSGetDefaultFont() - If pFontSize <= 0 Then pFontSize = NSFontSize(tmpHandle) - Return LoadFontWithDouble( NSFontName(tmpHandle), pFontSize, NSFontStyle(tmpHandle)|pFontStyle ) - Else - Return Super.LibraryFont( pFontType, pFontSize, pFontStyle ) - EndIf - EndMethod - - Method LookupColor( colorindex:Int, red:Byte Var, green:Byte Var, blue:Byte Var ) - - Local r, g, b - - If NSGetSysColor( colorindex, Varptr r, Varptr g, Varptr b ) - red = r & $FF - green = g & $FF - blue = b & $FF - Return True - EndIf - - Return Super.LookupColor( colorindex, red, green, blue ) - - EndMethod - - Method RequestColor(r,g,b) - Return NSColorRequester(r,g,b) - End Method - - Method RequestFont:TGuiFont(font:TGuiFont) - Local handle - If font handle=font.handle - handle=NSRequestFont(handle) - If handle - If font And handle=font.handle Return font - Return CreateFont(handle) - EndIf - End Method - - Method SetPointer(shape) - NSSetPointer shape - End Method - - Method ActiveGadget:TGadget() - PollSystem() - Local handle = NSActiveGadget() - If handle Return GadgetFromHandle(handle) - End Method - - Method LoadIconStrip:TIconStrip(source:Object) - Return TCocoaIconStrip.Create(source) - End Method -End Type - -Function GadgetFromHandle:TNSGadget( handle ) - Return TNSGadget( GadgetMap.ValueForKey( TIntWrapper.Create(handle) ) ) -End Function - -Function EmitCocoaOSEvent( event:Byte Ptr,handle,gadget:Object = Null ) - Local owner:TGadget = TGadget(gadget) - If Not owner Then owner = GadgetFromHandle( handle ) - If owner Then - While owner.source - owner = owner.source - Wend - EndIf - bbSystemEmitOSEvent event,Byte Ptr(handle),owner -End Function - -Function EmitCocoaMouseEvent( event:Byte Ptr, handle ) - Local gadget:TNSGadget -' While handle - gadget = GadgetFromHandle( handle ) - If gadget Then - If (gadget.sensitivity & SENSITIZE_MOUSE) Then - EmitCocoaOSEvent( event, handle, gadget ) - Return 1 - EndIf - Return 0 - EndIf -' handle = NSSuperview(handle) -' Wend -End Function - -Function EmitCocoaKeyEvent( event:Byte Ptr, handle ) - Local gadget:TNSGadget - While handle - gadget = GadgetFromHandle( handle ) - If gadget Then - If (gadget.sensitivity & SENSITIZE_KEYS) Then - EmitCocoaOSEvent( event, handle, gadget ) - Return 1 - EndIf - Return 0 - EndIf - handle = NSSuperview(handle) - Wend -End Function - -Function PostCocoaGuiEvent( id,handle,data,mods,x,y,extra:Object ) - - Local gadget:TNSGadget - - DispatchGuiEvents() - - If handle Then - - gadget = GadgetFromHandle(handle) - - If gadget Then - - Select gadget.internalclass - Case GADGET_TREEVIEW - extra=GadgetFromHandle(data) - data = 0 - EndSelect - - Select id - Case EVENT_WINDOWSIZE - If gadget.width <> x Or gadget.height <> y Then - gadget.SetRect gadget.xpos,gadget.ypos,x,y - gadget.LayoutKids - Else - Return - EndIf - - Case EVENT_WINDOWMOVE - If gadget.xpos <> x Or gadget.ypos <> y Then - gadget.SetRect x,y,gadget.width,gadget.height - Else - Return - EndIf - - Case EVENT_MENUACTION - extra=TNSGadget.popupextra - TNSGadget.popupextra=Null - - Case EVENT_GADGETACTION - - Select gadget.internalclass - Case GADGET_SLIDER - Local oldValue:Int = gadget.GetProp() - If data Then - Select (gadget.style&(SLIDER_SCROLLBAR|SLIDER_TRACKBAR|SLIDER_STEPPER)) - Case SLIDER_SCROLLBAR - If data > 1 Then - data = gadget.small - ElseIf data < -1 Then - data = -gadget.small - EndIf - EndSelect - gadget.SetProp(oldValue+data) - data=gadget.GetProp() - If (data = oldValue) Then Return - Else - data=gadget.GetProp() - EndIf - Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER - If (data > -1 And data < gadget.items.length) extra=gadget.ItemExtra(data) - Case GADGET_BUTTON - Select (gadget.style&7) - Case BUTTON_CHECKBOX - If ButtonState(gadget) = CHECK_INDETERMINATE Then SetButtonState(gadget, CHECK_SELECTED ) - Case BUTTON_RADIO - If (gadget.style&BUTTON_PUSH) Then SetButtonState(gadget,CHECK_SELECTED) - gadget.ExcludeOthers() - EndSelect - data=ButtonState(gadget) - Case GADGET_TOOLBAR - If data>-1 Then - extra=gadget.ItemExtra(data) - If (gadget.ItemFlags(data)&GADGETITEM_TOGGLE) Then gadget.SelectItem(data,2) - EndIf - EndSelect - - Case EVENT_GADGETSELECT, EVENT_GADGETMENU - Select gadget.internalclass - Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER - If data>-1 Then extra=gadget.ItemExtra(data) - EndSelect - - Case EVENT_GADGETLOSTFOCUS - - QueueGuiEvent id,gadget,data,mods,x,y,extra - ScheduleEventDispatch() - Return - - EndSelect - EndIf - - EndIf - - PostGuiEvent id,gadget,data,mods,x,y,extra - -EndFunction - -Function FilterKeyDown( handle,key,mods ) - Local source:TNSGadget - If handle - source=GadgetFromHandle(handle) - EndIf - If source And source.eventfilter<>Null - Local event:TEvent=CreateEvent(EVENT_KEYDOWN,source,key,mods) - Return source.eventfilter(event,source.context) - EndIf - Return 1 -End Function - -Function FilterChar( handle,key,mods ) - Local source:TNSGadget - Select key - ' Return true if they are arrow key characters - Case 63232, 63233, 63234, 63235 - Return 1 - EndSelect - If handle - source=GadgetFromHandle(handle) - EndIf - If source And source.eventfilter<>Null 'Return source.charfilter(char,mods,source.context) - Local event:TEvent=CreateEvent(EVENT_KEYCHAR,source,key,mods) - Return source.eventfilter(event,source.context) - EndIf - Return 1 -End Function - -Type TNSGadget Extends TGadget - - Field internalclass, origclass 'internalclass: Class the Cocoa driver uses to draw the gadget, origclass: Expected class to be returned by Class() method - Field handle - Field view, textcolor 'view: NSView handle, textcolor: NSColor handle for Objective-C code - Field intFontStyle 'Copy of font.style used by cocoa.macos.m to handle underlining/strikethrough etc. that isn't included in NSFont - Field pixmap:TPixmap - Field icons:TCocoaIconStrip - Field small, big - Field canvas:TGraphics - Field font:TCocoaGuiFont - Field enabled:Int = True, forceDisable:Int = False - -' main factory command - - Function Create:TNSGadget(internalclass,text$,x,y,w,h,group:TGadget,style) - - Local gadget:TNSGadget = New TNSGadget - gadget.origclass = internalclass - gadget.internalclass = internalclass - - If Not group And internalclass<>GADGET_DESKTOP Then group = Desktop() - gadget.parent = group - - gadget.name = text - gadget.SetRect x,y,w,h 'setarea - gadget.style = style - gadget.font = TCocoaMaxGUIDriver.CocoaGUIFont - - If TNSGadget(group) Then - gadget.forceDisable = Not (TNSGadget(group).enabled And Not TNSGadget(group).forceDisable) - EndIf - - NSInitGadget gadget - - If internalclass<>GADGET_TOOLBAR 'toolbars retain name to key insertgadgetitem - gadget.name = Null - EndIf - - GadgetMap.Insert TIntWrapper.Create(gadget.handle),gadget - If gadget.view And gadget.handle <> gadget.view Then - GadgetMap.Insert TIntWrapper.Create(gadget.view),gadget - EndIf - - If internalclass=GADGET_SLIDER Then gadget.SetRange(1,10) - gadget.LockLayout() - - If (internalclass=GADGET_WINDOW) And (style&WINDOW_STATUS) Then - If (style&WINDOW_CLIENTCOORDS) Then - gadget.SetMinimumSize(25,0) - Else - gadget.SetMinimumSize(25,70) - EndIf - EndIf - - If LocalizationMode() & LOCALIZATION_OVERRIDE Then LocalizeGadget(gadget,text,"") - - gadget.SetEnabled(gadget.enabled) - - Return gadget - - End Function - - Method Class() - Return origclass - EndMethod - - Function ToView:TNSGadget(value:Object) - Local view:TNSGadget = TNSGadget(value) - If Not view Return - Select view.internalclass - Case GADGET_DESKTOP,GADGET_WINDOW,GADGET_TOOLBAR,GADGET_LABEL,GADGET_PROGBAR,GADGET_MENUITEM,GADGET_NODE - Return Null - End Select - Return view - End Function - - Method LinkView() - Local First:TNSGadget - Local prev:TNSGadget - Local i,n - - If Not parent Return - If Not ToView(Self) Return - n=parent.kids.count()-1 - If n<0 Return -' find first view in family - For i=0 Until n - First=ToView(parent.kids.ValueAtIndex(i)) - If First Exit - Next - If Not First Return -' find last view in family - For i=n-1 To 0 Step -1 - prev=ToView(parent.kids.ValueAtIndex(i)) - If prev Exit - Next - If Not prev Return - NSSetNextView(prev,Self) - NSSetNextView(Self,First) - End Method - - Method Delete() - Free() - End Method - -' generic gadget commands - - Method Query(queryid) - Select queryid - Case QUERY_NSVIEW - Return handle - Case QUERY_NSVIEW_CLIENT - Return view - End Select - End Method - - Method Free() - If handle Then - - If canvas Then canvas.close - - GadgetMap.Remove TIntWrapper.Create(handle) - If view And handle <> view Then - GadgetMap.Remove TIntWrapper.Create(view) - view = Null - EndIf - - If parent Then - parent.kids.Remove Self - End If - - NSFreeGadget Self - font = Null - - handle = Null - - EndIf - End Method - - Method Rethink() 'resize - was recursive - NSRethink( Self ) - End Method - - Method ClientWidth() - Return Max(NSClientWidth(Self),0) - End Method - - Method ClientHeight() - Return Max(NSClientHeight(Self),0) - End Method - - Method Activate(cmd) - NSActivate( Self, cmd ) - End Method - - Method State() - Local tmpState:Int = NSState(Self)&~STATE_DISABLED - If Not enabled Then tmpState:|STATE_DISABLED - Return tmpState - End Method - - Method SetShow(bool) - NSShow( Self, bool ) - End Method - - Method SetText(msg$) - If internalclass=GADGET_HTMLVIEW - Local anchor$,a - a=msg.Find("#") - If a<>-1 anchor=msg[a..];msg=msg[..a] - If msg[0..7].ToLower()<>"http://" And msg[0..7].ToLower()<>"file://" - If FileType(msg) - msg="file://"+msg - Else - msg="http://"+msg - EndIf - EndIf - msg:+anchor - msg=msg.Replace(" ","%20") - ElseIf internalclass=GADGET_MENUITEM - msg=msg.Replace("&", "") - EndIf - NSSetText Self,msg - End Method - - Method Run$(msg$) - If internalclass=GADGET_HTMLVIEW Return NSRun(Self,msg) - End Method - - Method GetText$() - Return NSGetText(Self) - End Method - - Method SetFont(pFont:TGuiFont) - If Not TCocoaGuiFont(pFont) Then pFont = TCocoaMaxGUIDriver.CocoaGuiFont - font = TCocoaGuiFont(pFont) - intFontStyle = font.style - NSSetFont( Self, font.handle ) - End Method - - Method SetColor(r,g,b) - NSSetColor Self,r,g,b - End Method - - Method RemoveColor() - NSRemoveColor Self - End Method - - Method SetAlpha(alpha#) - NSSetAlpha Self,alpha - End Method - - Method SetTextColor(r,g,b) - NSSetTextColor Self,r,g,b - End Method - - Method SetPixmap(pixmap:TPixmap,flags) - Local nsimage, x - If pixmap - Select pixmap.format - Case PF_I8,PF_BGR888 - pixmap=pixmap.Convert( PF_RGB888 ) - Case PF_A8,PF_BGRA8888 - pixmap=pixmap.Convert( PF_RGBA8888 ) - End Select - - If AlphaBitsPerPixel[ pixmap.format ] - For Local y=0 Until pixmap.height - For x=0 Until pixmap.width - Local argb=pixmap.ReadPixel( x,y ) - pixmap.WritePixel x,y,premult(argb) - Next - Next - EndIf - nsimage=NSPixmapImage(pixmap) - EndIf - NSSetImage(Self,nsimage,flags) - End Method - - Method SetTooltip(pTip$) - Select internalclass - Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE - Default;Return NSSetTooltip( Self, pTip ) - EndSelect - EndMethod - - Method GetTooltip$() - Select internalclass - Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE - Default;Return NSGetTooltip( Self ) - EndSelect - EndMethod - - Method ExcludeOthers() - For Local g:TNSGadget = EachIn parent.kids - If g<>Self And g.internalclass=GADGET_BUTTON And (g.style&7)=BUTTON_RADIO - NSCheck g,False - EndIf - Next - End Method - - Method SetSelected(bool) - NSCheck Self,bool - If internalclass=GADGET_BUTTON And (style&7)=BUTTON_RADIO And bool - ExcludeOthers - EndIf - End Method - - Method SetEnabled(enable) - Local old:Int = enabled And Not forceDisable - enabled = enable - If Class() = GADGET_WINDOW Then - NSEnable Self, enable - Else - enable = enable And Not forceDisable - NSEnable Self, enable - If (enable <> old) Then - For Local tmpGadget:TNSGadget = EachIn kids - tmpGadget.forceDisable = Not enable - If tmpGadget.Class() <> GADGET_WINDOW Then tmpGadget.SetEnabled(tmpGadget.enabled) - Next - EndIf - EndIf - End Method - - Method SetHotKey(hotkey,modifier) - NSSetHotKey Self,hotkey,modifier - End Method - -' window commands - - Field _statustext$ - - Method GetStatusText$() - Return _statustext - EndMethod - - Method SetStatusText(msg$) - Local t,m0$,m1$,m2$ - _statustext = msg - m0=msg - t=m0.find("~t");If t<>-1 m1=m0[t+1..];m0=m0[..t]; - t=m1.find("~t");If t<>-1 m2=m1[t+1..];m1=m1[..t]; - NSSetStatus Self,m0,0 - NSSetStatus Self,m1,1 - NSSetStatus Self,m2,2 - End Method - - Method GetMenu:TGadget() - Return Self - End Method - - Global popupextra:Object - - Method PopupMenu(menu:TGadget,extra:Object) - popupextra=extra - NSPopupMenu Self,TNSGadget(menu) - End Method - - Method UpdateMenu() - End Method - - Method SetMinimumSize(w,h) - NSSetMinimumSize Self,w,h - End Method - - Method SetMaximumSize(w,h) - NSSetMaximumSize Self,w,h - End Method - - Method SetIconStrip(iconstrip:TIconStrip) - icons=TCocoaIconStrip(iconstrip) - End Method - -' item handling commands - - Method ClearListItems() - NSClearItems Self - End Method - - Method InsertListItem(index,item$,tip$,icon,extra:Object) - Local image - If internalclass=GADGET_TOOLBAR - item=name+":"+index - EndIf - If icons And icon>=0 image=icons.images[icon] - NSAddItem Self,index,item,tip,image,extra - End Method - - Method SetListItem(index,item$,tip$,icon,extra:Object) - Local image - If internalclass=GADGET_TOOLBAR - item=name+":"+index - EndIf - If icons And icon>=0 image=icons.images[icon] - NSSetItem Self,index,item,tip,image,extra - End Method - - Method RemoveListItem(index) - NSRemoveItem Self,index - End Method - - Method SetListItemState(index,state) - NSSelectItem Self,index,state - End Method - - Method ListItemState(index) - Return NSSelectedItem(Self,index) - End Method - -' treeview commands - - Method RootNode:TGadget() - Return Self - End Method - - Method SetIcon(icon) - Local p:TNSGadget - p=Self - While p - If p.icons Exit - p=TNSGadget(p.parent) - Wend - If p - If icon>-1 - NSSetIcon Self,p.icons.images[icon] - Else - NSSetIcon Self,Null - EndIf - EndIf - End Method - - Method InsertNode:TGadget(index,text$,icon) - Local node:TNSGadget = Create(GADGET_NODE,text,0,0,0,0,Self,index) - node.SetIcon icon - node._SetParent Self - Return node - End Method - - Method ModifyNode(text$,icon) - NSSetText Self,text - SetIcon icon - End Method - - Method SelectedNode:TGadget() - Local index = NSSelectedNode(Self) - If (index) Return GadgetFromHandle(index) - End Method - - Method CountKids() - Return NSCountKids(Self) - End Method - -' textarea commands - - Method ReplaceText(pos,length,text$,units) -?debug - If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" -? - NSReplaceText Self,pos,length,text$,units - End Method - - Method AddText(text$) - NSAddText Self,text - End Method - - Method AreaText$(pos,length,units) -?debug - If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" -? - Return NSAreaText(Self,pos,length,units) - End Method - - Method AreaLen(units) - Return NSAreaLen(Self,units) - End Method - - Method LockText() - NSLockText Self - End Method - - Method UnlockText() - NSUnlockText Self - End Method - - Method SetTabs(tabwidth) - NSSetTabs Self,tabwidth - End Method - - Method SetMargins(leftmargin) - NSSetMargins Self,leftmargin - End Method - - Method GetCursorPos(units) - Return NSGetCursorPos(Self,units) - End Method - - Method GetSelectionLength(units) - Return NSGetSelectionLength(Self,units) - End Method - - Method SetStyle(r,g,b,flags,pos,length,units) -?debug - If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" -? - If length NSSetStyle Self,r,g,b,flags,pos,length,units - End Method - - Method SetSelection(pos,length,units) -?debug - If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" -? - NSSetSelection Self,pos,length,units - End Method - - Method CharAt(line) -?debug - If line<0 Or line>AreaLen(TEXTAREA_LINES) Throw "Parameter Out Of Range" -? - Return NSCharAt(Self,line) - End Method - - Method LineAt(index) -?debug - If index<0 Or index>AreaLen(TEXTAREA_CHARS) Throw "Parameter Out Of Range" -? - Return NSLineAt(Self,index) - End Method - - Method CharX(char) - Return NSCharX(Self,char) - EndMethod - - Method CharY(char) - Return NSCharY(Self,char) - EndMethod - -' progbar - - Method SetValue(value#) - NSSetValue Self,value - End Method - -' slider / scrollbar - - Method SetRange(_small,_big) - small=_small - big=_big - NSSetSlider Self,GetProp(),small,big - End Method - - Method SetProp(pos) - NSSetSlider Self,pos,small,big - End Method - - Method GetProp() - Local value:Double = NSGetSlider(Self) - If Not (style&(SLIDER_TRACKBAR|SLIDER_STEPPER)) - value:*(big-small) - If value>big-small value=big-small - EndIf - Return Int(value+0.5:Double) - End Method - -' canvas - - Method AttachGraphics:TGraphics( flags ) - canvas=brl.Graphics.AttachGraphics( Query(QUERY_NSVIEW_CLIENT),flags ) - End Method - - Method CanvasGraphics:TGraphics() - Return canvas - End Method - -End Type - - -Type TCocoaIconStrip Extends TIconStrip - - Field images[] - - Function IsNotBlank(pixmap:TPixmap) - Local y, h = pixmap.height - Local c = pixmap.ReadPixel(0,0) - For Local x = 0 Until h - For y = 0 Until h - If pixmap.ReadPixel(x,y)<>c Return True - Next - Next - End Function - - Function Create:TCocoaIconStrip(source:Object) - Local icons:TCocoaIconStrip - Local pixmap:TPixmap,pix:TPixmap - Local n,x,w,nsimage - pixmap=TPixmap(source) - If Not pixmap pixmap=LoadPixmap(source) - If Not pixmap Return - Select pixmap.format - Case PF_I8,PF_BGR888 - pixmap=pixmap.Convert( PF_RGB888 ) - Case PF_A8,PF_BGRA8888 - pixmap=pixmap.Convert( PF_RGBA8888 ) - End Select - - If AlphaBitsPerPixel[ pixmap.format ] - For Local y=0 Until pixmap.height - For x=0 Until pixmap.width - Local argb=pixmap.ReadPixel( x,y ) - pixmap.WritePixel x,y,premult(argb) - Next - Next - EndIf - - n=pixmap.width/pixmap.height; - If n=0 Return - icons=New TCocoaIconStrip - icons.pixmap=pixmap - icons.count=n - icons.images=New Int[n] - w=pixmap.width/n - For x=0 Until n - pix=pixmap.Window(x*w,0,w,pixmap.height) - If IsNotBlank(pix) icons.images[x]=NSPixmapImage(pix) - Next - Return icons - EndFunction - -EndType - -Type TCocoaGuiFont Extends TGuiFont - - Method Delete() - If handle Then - NSRelease(handle) - handle = 0 - EndIf - EndMethod - - Method CharWidth(char) - If handle - Return NSCharWidth(handle,char) - EndIf - Return 0 - EndMethod - -EndType - -Type TIntWrapper Final - Field value:Int - Function Create:TIntWrapper(value:Int) - Local tmpWrapper:TIntWrapper = New TIntWrapper - tmpWrapper.value = value - Return tmpWrapper - EndFunction - Method Compare( o:Object ) - Local c:TIntWrapper = TIntWrapper(o) - If c Then Return (value - c.value) - Return Super.Compare(o) - EndMethod - Method ToString$() - Return value - EndMethod -EndType - -Private - -Function premult(argb) - Local a = ((argb Shr 24) & $FF) - Return ((((argb&$ff00ff)*a)Shr 8)&$ff00ff)|((((argb&$ff00)*a)Shr 8)&$ff00)|(a Shl 24) -End Function +Strict + +Import MaxGUI.MaxGUI +Import Pub.MacOs + +Import "-framework WebKit" +Import "cocoa.macos_tiger.m" + +Extern + + Function bbSystemEmitOSEvent( nsevent:Byte Ptr,nsview:Byte Ptr,source:Object ) + + Function ScheduleEventDispatch() + + Function NSBegin() + Function NSEnd() + + Function NSGetSysColor(colorindex,r:Int Ptr,g:Int Ptr, b:Int Ptr) + Function NSColorRequester(r,g,b) + Function NSSetPointer(shape) + + Function NSCharWidth(font,charcode) + ' create + Function NSInitGadget(gadget:TNSGadget) + ' generic + Function NSActiveGadget() + Function NSFreeGadget(gadget:TNSGadget) + Function NSClientWidth(gadget:TNSGadget) + Function NSClientHeight(gadget:TNSGadget) + Function NSRethink(gadget:TNSGadget) + Function NSRedraw(gadget:TNSGadget) + Function NSActivate(gadget:TNSGadget,code) + Function NSState(gadget:TNSGadget) + Function NSShow(gadget:TNSGadget,bool) + Function NSEnable(gadget:TNSGadget,bool) + Function NSCheck(gadget:TNSGadget,bool) + Function NSSetNextView(gadget:TNSGadget,nextgadget:TNSGadget) + Function NSSetHotKey(gadget:TNSGadget,hotkey,modifier) + Function NSSetTooltip(gadget:TNSGadget,tip$) + Function NSGetTooltip$(gadget:TNSGadget) + Function NSSuperview(view:Int) + ' window + Function NSSetStatus(gadget:TNSGadget,text$,pos) + Function NSSetMinimumSize(gadget:TNSGadget,width,height) + Function NSSetMaximumSize(gadget:TNSGadget,width,height) + Function NSPopupMenu(gadget:TNSGadget,menu:TNSGadget) + ' font + Function NSRequestFont(font) + Function NSLoadFont(name$,size:Double,flags) + Function NSGetDefaultFont() + Function NSSetFont(gadget:TNSGadget,font) + Function NSFontName$(font) + Function NSFontStyle(font) + Function NSFontSize:Double(font) + ' items + Function NSClearItems(gadget:TNSGadget) + Function NSAddItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) + Function NSSetItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) + Function NSRemoveItem(gadget:TNSGadget,index) + Function NSSelectItem(gadget:TNSGadget,index,state) + Function NSSelectedItem(gadget:TNSGadget,index) + Function NSSelectedNode(gadget:TNSGadget) + ' text + Function NSSetText(gadget:TNSGadget,text$) + Function NSGetText$(gadget:TNSGadget) + Function NSReplaceText(gadget:TNSGadget,pos,length,text$,units) + Function NSAddText(gadget:TNSGadget,text$) + Function NSAreaText$(gadget:TNSGadget,pos,length,units) + Function NSAreaLen(gadget:TNSGadget,units) + Function NSLockText(gadget:TNSGadget) + Function NSUnlockText(gadget:TNSGadget) + Function NSSetTabs(gadget:TNSGadget,tabwidth) + Function NSSetMargins(gadget:TNSGadget,leftmargin) + Function NSSetColor(gadget:TNSGadget,r,g,b) + Function NSRemoveColor(gadget:TNSGadget) + Function NSSetAlpha(gadget:TNSGadget,alpha#) + Function NSSetTextColor(gadget:TNSGadget,r,g,b) + Function NSGetCursorPos(gadget:TNSGadget,units) + Function NSGetSelectionlength(gadget:TNSGadget,units) + Function NSSetStyle(gadget:TNSGadget,r,g,b,flags,pos,length,units) + Function NSSetSelection(gadget:TNSGadget,pos,length,units) + Function NSCharAt(gadget:TNSGadget,line) + Function NSLineAt(gadget:TNSGadget,index) + Function NSCharX(gadget:TGadget,char) + Function NSCharY(gadget:TGadget,char) + ' prop + Function NSSetValue(gadget:TNSGadget,value#) + ' slider + Function NSSetSlider(gadget:TNSGadget,value:Double,small:Double,big:Double) + Function NSGetSlider:Double(gadget:TNSGadget) + ' images for panels and nodes + Function NSPixmapImage(image:TPixmap) + Function NSSetImage(gadget:TNSGadget,nsimage,flags) + Function NSSetIcon(gadget:TNSGadget,nsimage) + Function NSCountKids(gadget:TNSGadget) + ' html + Function NSRun$(gadget:TNSGadget,script$) + ' misc + Function NSRelease(nsobject) + ' system + Function NSGetUserName$() + Function NSGetComputerName$() + +EndExtern + +Global GadgetMap:TMap=New TMap + +maxgui_driver=New TCocoaMaxGuiDriver + +Type TCocoaMaxGUIDriver Extends TMaxGUIDriver + + Global CocoaGuiFont:TCocoaGuiFont + + Method New() + NSBegin + atexit_ NSEnd + If Not CocoaGuiFont Then CocoaGuiFont = TCocoaGuiFont(LibraryFont(GUIFONT_SYSTEM)) + End Method + + Method UserName$() + Return NSGetUserName$() + End Method + + Method ComputerName$() + Return NSGetComputerName$() + End Method + + Method CreateGadget:TGadget(internalclass,name$,x,y,w,h,group:TGadget,style) + Local p,hotkey + If internalclass=GADGET_MENUITEM + name=name.Replace("&","") + ElseIf internalclass=GADGET_BUTTON + p=name.Find("&") + If p>-1 +' hotkey=Asc(name[p..p+1]) 'to do - convert and call SetHotKey before return + name=name[..p]+name[p+1..] + EndIf + ElseIf internalclass=GADGET_TOOLBAR + Global _toolbarcount + _toolbarcount:+1 + name="Toolbar"+_toolbarcount + EndIf + Local gadget:TNSGadget = TNSGadget.Create(internalclass,name,x,y,w,h,TNSGadget(group),style) + If internalclass<>GADGET_WINDOW And internalclass<>GADGET_MENUITEM And internalclass<>GADGET_DESKTOP + gadget.SetLayout EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED + EndIf + If group Then gadget._SetParent group + gadget.SetTextColor(0,0,0) + gadget.LinkView + Return gadget + End Method + + Function CreateFont:TGuiFont(handle,flags=FONT_NORMAL) + Local font:TGuiFont = New TCocoaGuiFont + font.handle = handle + font.name = NSFontName(handle) + font.size = NSFontSize(handle) + font.style = NSFontStyle(handle)|flags + Return font + EndFunction + + Method LoadFont:TGuiFont(name$,size,flags) + Return CreateFont(NSLoadFont(name,Double(size),flags),flags) + End Method + + Method LoadFontWithDouble:TGuiFont(name$,size:Double,flags) + Return CreateFont(NSLoadFont(name,size,flags),flags) + End Method + + Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + If pFontType = GUIFONT_SYSTEM Then + Local tmpHandle% = NSGetDefaultFont() + If pFontSize <= 0 Then pFontSize = NSFontSize(tmpHandle) + Return LoadFontWithDouble( NSFontName(tmpHandle), pFontSize, NSFontStyle(tmpHandle)|pFontStyle ) + Else + Return Super.LibraryFont( pFontType, pFontSize, pFontStyle ) + EndIf + EndMethod + + Method LookupColor( colorindex:Int, red:Byte Var, green:Byte Var, blue:Byte Var ) + + Local r, g, b + + If NSGetSysColor( colorindex, Varptr r, Varptr g, Varptr b ) + red = r & $FF + green = g & $FF + blue = b & $FF + Return True + EndIf + + Return Super.LookupColor( colorindex, red, green, blue ) + + EndMethod + + Method RequestColor(r,g,b) + Return NSColorRequester(r,g,b) + End Method + + Method RequestFont:TGuiFont(font:TGuiFont) + Local handle + If font handle=font.handle + handle=NSRequestFont(handle) + If handle + If font And handle=font.handle Return font + Return CreateFont(handle) + EndIf + End Method + + Method SetPointer(shape) + NSSetPointer shape + End Method + + Method ActiveGadget:TGadget() + PollSystem() + Local handle = NSActiveGadget() + If handle Return GadgetFromHandle(handle) + End Method + + Method LoadIconStrip:TIconStrip(source:Object) + Return TCocoaIconStrip.Create(source) + End Method +End Type + +Function GadgetFromHandle:TNSGadget( handle ) + Return TNSGadget( GadgetMap.ValueForKey( TIntWrapper.Create(handle) ) ) +End Function + +Function EmitCocoaOSEvent( event:Byte Ptr,handle,gadget:Object = Null ) + Local owner:TGadget = TGadget(gadget) + If Not owner Then owner = GadgetFromHandle( handle ) + If owner Then + While owner.source + owner = owner.source + Wend + EndIf + bbSystemEmitOSEvent event,Byte Ptr(handle),owner +End Function + +Function EmitCocoaMouseEvent( event:Byte Ptr, handle ) + Local gadget:TNSGadget +' While handle + gadget = GadgetFromHandle( handle ) + If gadget Then + If (gadget.sensitivity & SENSITIZE_MOUSE) Then + EmitCocoaOSEvent( event, handle, gadget ) + Return 1 + EndIf + Return 0 + EndIf +' handle = NSSuperview(handle) +' Wend +End Function + +Function EmitCocoaKeyEvent( event:Byte Ptr, handle ) + Local gadget:TNSGadget + While handle + gadget = GadgetFromHandle( handle ) + If gadget Then + If (gadget.sensitivity & SENSITIZE_KEYS) Then + EmitCocoaOSEvent( event, handle, gadget ) + Return 1 + EndIf + Return 0 + EndIf + handle = NSSuperview(handle) + Wend +End Function + +Function PostCocoaGuiEvent( id,handle,data,mods,x,y,extra:Object ) + + Local gadget:TNSGadget + + DispatchGuiEvents() + + If handle Then + + gadget = GadgetFromHandle(handle) + + If gadget Then + + Select gadget.internalclass + Case GADGET_TREEVIEW + extra=GadgetFromHandle(data) + data = 0 + EndSelect + + Select id + Case EVENT_WINDOWSIZE + If gadget.width <> x Or gadget.height <> y Then + gadget.SetRect gadget.xpos,gadget.ypos,x,y + gadget.LayoutKids + Else + Return + EndIf + + Case EVENT_WINDOWMOVE + If gadget.xpos <> x Or gadget.ypos <> y Then + gadget.SetRect x,y,gadget.width,gadget.height + Else + Return + EndIf + + Case EVENT_MENUACTION + extra=TNSGadget.popupextra + TNSGadget.popupextra=Null + + Case EVENT_GADGETACTION + + Select gadget.internalclass + Case GADGET_SLIDER + Local oldValue:Int = gadget.GetProp() + If data Then + Select (gadget.style&(SLIDER_SCROLLBAR|SLIDER_TRACKBAR|SLIDER_STEPPER)) + Case SLIDER_SCROLLBAR + If data > 1 Then + data = gadget.small + ElseIf data < -1 Then + data = -gadget.small + EndIf + EndSelect + gadget.SetProp(oldValue+data) + data=gadget.GetProp() + If (data = oldValue) Then Return + Else + data=gadget.GetProp() + EndIf + Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER + If (data > -1 And data < gadget.items.length) extra=gadget.ItemExtra(data) + Case GADGET_BUTTON + Select (gadget.style&7) + Case BUTTON_CHECKBOX + If ButtonState(gadget) = CHECK_INDETERMINATE Then SetButtonState(gadget, CHECK_SELECTED ) + Case BUTTON_RADIO + If (gadget.style&BUTTON_PUSH) Then SetButtonState(gadget,CHECK_SELECTED) + gadget.ExcludeOthers() + EndSelect + data=ButtonState(gadget) + Case GADGET_TOOLBAR + If data>-1 Then + extra=gadget.ItemExtra(data) + If (gadget.ItemFlags(data)&GADGETITEM_TOGGLE) Then gadget.SelectItem(data,2) + EndIf + EndSelect + + Case EVENT_GADGETSELECT, EVENT_GADGETMENU + Select gadget.internalclass + Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER + If data>-1 Then extra=gadget.ItemExtra(data) + EndSelect + + Case EVENT_GADGETLOSTFOCUS + + QueueGuiEvent id,gadget,data,mods,x,y,extra + ScheduleEventDispatch() + Return + + EndSelect + EndIf + + EndIf + + PostGuiEvent id,gadget,data,mods,x,y,extra + +EndFunction + +Function FilterKeyDown( handle,key,mods ) + Local source:TNSGadget + If handle + source=GadgetFromHandle(handle) + EndIf + If source And source.eventfilter<>Null + Local event:TEvent=CreateEvent(EVENT_KEYDOWN,source,key,mods) + Return source.eventfilter(event,source.context) + EndIf + Return 1 +End Function + +Function FilterChar( handle,key,mods ) + Local source:TNSGadget + Select key + ' Return true if they are arrow key characters + Case 63232, 63233, 63234, 63235 + Return 1 + EndSelect + If handle + source=GadgetFromHandle(handle) + EndIf + If source And source.eventfilter<>Null 'Return source.charfilter(char,mods,source.context) + Local event:TEvent=CreateEvent(EVENT_KEYCHAR,source,key,mods) + Return source.eventfilter(event,source.context) + EndIf + Return 1 +End Function + +Type TNSGadget Extends TGadget + + Field internalclass, origclass 'internalclass: Class the Cocoa driver uses to draw the gadget, origclass: Expected class to be returned by Class() method + Field handle + Field view, textcolor 'view: NSView handle, textcolor: NSColor handle for Objective-C code + Field intFontStyle 'Copy of font.style used by cocoa.macos.m to handle underlining/strikethrough etc. that isn't included in NSFont + Field pixmap:TPixmap + Field icons:TCocoaIconStrip + Field small, big + Field canvas:TGraphics + Field font:TCocoaGuiFont + Field enabled:Int = True, forceDisable:Int = False + +' main factory command + + Function Create:TNSGadget(internalclass,text$,x,y,w,h,group:TGadget,style) + + Local gadget:TNSGadget = New TNSGadget + gadget.origclass = internalclass + gadget.internalclass = internalclass + + If Not group And internalclass<>GADGET_DESKTOP Then group = Desktop() + gadget.parent = group + + gadget.name = text + gadget.SetRect x,y,w,h 'setarea + gadget.style = style + gadget.font = TCocoaMaxGUIDriver.CocoaGUIFont + + If TNSGadget(group) Then + gadget.forceDisable = Not (TNSGadget(group).enabled And Not TNSGadget(group).forceDisable) + EndIf + + NSInitGadget gadget + + If internalclass<>GADGET_TOOLBAR 'toolbars retain name to key insertgadgetitem + gadget.name = Null + EndIf + + GadgetMap.Insert TIntWrapper.Create(gadget.handle),gadget + If gadget.view And gadget.handle <> gadget.view Then + GadgetMap.Insert TIntWrapper.Create(gadget.view),gadget + EndIf + + If internalclass=GADGET_SLIDER Then gadget.SetRange(1,10) + gadget.LockLayout() + + If (internalclass=GADGET_WINDOW) And (style&WINDOW_STATUS) Then + If (style&WINDOW_CLIENTCOORDS) Then + gadget.SetMinimumSize(25,0) + Else + gadget.SetMinimumSize(25,70) + EndIf + EndIf + + If LocalizationMode() & LOCALIZATION_OVERRIDE Then LocalizeGadget(gadget,text,"") + + gadget.SetEnabled(gadget.enabled) + + Return gadget + + End Function + + Method Class() + Return origclass + EndMethod + + Function ToView:TNSGadget(value:Object) + Local view:TNSGadget = TNSGadget(value) + If Not view Return + Select view.internalclass + Case GADGET_DESKTOP,GADGET_WINDOW,GADGET_TOOLBAR,GADGET_LABEL,GADGET_PROGBAR,GADGET_MENUITEM,GADGET_NODE + Return Null + End Select + Return view + End Function + + Method LinkView() + Local First:TNSGadget + Local prev:TNSGadget + Local i,n + + If Not parent Return + If Not ToView(Self) Return + n=parent.kids.count()-1 + If n<0 Return +' find first view in family + For i=0 Until n + First=ToView(parent.kids.ValueAtIndex(i)) + If First Exit + Next + If Not First Return +' find last view in family + For i=n-1 To 0 Step -1 + prev=ToView(parent.kids.ValueAtIndex(i)) + If prev Exit + Next + If Not prev Return + NSSetNextView(prev,Self) + NSSetNextView(Self,First) + End Method + + Method Delete() + Free() + End Method + +' generic gadget commands + + Method Query(queryid) + Select queryid + Case QUERY_NSVIEW + Return handle + Case QUERY_NSVIEW_CLIENT + Return view + End Select + End Method + + Method Free() + If handle Then + + If canvas Then canvas.close + + GadgetMap.Remove TIntWrapper.Create(handle) + If view And handle <> view Then + GadgetMap.Remove TIntWrapper.Create(view) + view = Null + EndIf + + If parent Then + parent.kids.Remove Self + End If + + NSFreeGadget Self + font = Null + + handle = Null + + EndIf + End Method + + Method Rethink() 'resize - was recursive + NSRethink( Self ) + End Method + + Method ClientWidth() + Return Max(NSClientWidth(Self),0) + End Method + + Method ClientHeight() + Return Max(NSClientHeight(Self),0) + End Method + + Method Activate(cmd) + NSActivate( Self, cmd ) + End Method + + Method State() + Local tmpState:Int = NSState(Self)&~STATE_DISABLED + If Not enabled Then tmpState:|STATE_DISABLED + Return tmpState + End Method + + Method SetShow(bool) + NSShow( Self, bool ) + End Method + + Method SetText(msg$) + If internalclass=GADGET_HTMLVIEW + Local anchor$,a + a=msg.Find("#") + If a<>-1 anchor=msg[a..];msg=msg[..a] + If msg[0..7].ToLower()<>"http://" And msg[0..7].ToLower()<>"file://" + If FileType(msg) + msg="file://"+msg + Else + msg="http://"+msg + EndIf + EndIf + msg:+anchor + msg=msg.Replace(" ","%20") + ElseIf internalclass=GADGET_MENUITEM + msg=msg.Replace("&", "") + EndIf + NSSetText Self,msg + End Method + + Method Run$(msg$) + If internalclass=GADGET_HTMLVIEW Return NSRun(Self,msg) + End Method + + Method GetText$() + Return NSGetText(Self) + End Method + + Method SetFont(pFont:TGuiFont) + If Not TCocoaGuiFont(pFont) Then pFont = TCocoaMaxGUIDriver.CocoaGuiFont + font = TCocoaGuiFont(pFont) + intFontStyle = font.style + NSSetFont( Self, font.handle ) + End Method + + Method SetColor(r,g,b) + NSSetColor Self,r,g,b + End Method + + Method RemoveColor() + NSRemoveColor Self + End Method + + Method SetAlpha(alpha#) + NSSetAlpha Self,alpha + End Method + + Method SetTextColor(r,g,b) + NSSetTextColor Self,r,g,b + End Method + + Method SetPixmap(pixmap:TPixmap,flags) + Local nsimage, x + If pixmap + Select pixmap.format + Case PF_I8,PF_BGR888 + pixmap=pixmap.Convert( PF_RGB888 ) + Case PF_A8,PF_BGRA8888 + pixmap=pixmap.Convert( PF_RGBA8888 ) + End Select + + If AlphaBitsPerPixel[ pixmap.format ] + For Local y=0 Until pixmap.height + For x=0 Until pixmap.width + Local argb=pixmap.ReadPixel( x,y ) + pixmap.WritePixel x,y,premult(argb) + Next + Next + EndIf + nsimage=NSPixmapImage(pixmap) + EndIf + NSSetImage(Self,nsimage,flags) + End Method + + Method SetTooltip(pTip$) + Select internalclass + Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE + Default;Return NSSetTooltip( Self, pTip ) + EndSelect + EndMethod + + Method GetTooltip$() + Select internalclass + Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE + Default;Return NSGetTooltip( Self ) + EndSelect + EndMethod + + Method ExcludeOthers() + For Local g:TNSGadget = EachIn parent.kids + If g<>Self And g.internalclass=GADGET_BUTTON And (g.style&7)=BUTTON_RADIO + NSCheck g,False + EndIf + Next + End Method + + Method SetSelected(bool) + NSCheck Self,bool + If internalclass=GADGET_BUTTON And (style&7)=BUTTON_RADIO And bool + ExcludeOthers + EndIf + End Method + + Method SetEnabled(enable) + Local old:Int = enabled And Not forceDisable + enabled = enable + If Class() = GADGET_WINDOW Then + NSEnable Self, enable + Else + enable = enable And Not forceDisable + NSEnable Self, enable + If (enable <> old) Then + For Local tmpGadget:TNSGadget = EachIn kids + tmpGadget.forceDisable = Not enable + If tmpGadget.Class() <> GADGET_WINDOW Then tmpGadget.SetEnabled(tmpGadget.enabled) + Next + EndIf + EndIf + End Method + + Method SetHotKey(hotkey,modifier) + NSSetHotKey Self,hotkey,modifier + End Method + +' window commands + + Field _statustext$ + + Method GetStatusText$() + Return _statustext + EndMethod + + Method SetStatusText(msg$) + Local t,m0$,m1$,m2$ + _statustext = msg + m0=msg + t=m0.find("~t");If t<>-1 m1=m0[t+1..];m0=m0[..t]; + t=m1.find("~t");If t<>-1 m2=m1[t+1..];m1=m1[..t]; + NSSetStatus Self,m0,0 + NSSetStatus Self,m1,1 + NSSetStatus Self,m2,2 + End Method + + Method GetMenu:TGadget() + Return Self + End Method + + Global popupextra:Object + + Method PopupMenu(menu:TGadget,extra:Object) + popupextra=extra + NSPopupMenu Self,TNSGadget(menu) + End Method + + Method UpdateMenu() + End Method + + Method SetMinimumSize(w,h) + NSSetMinimumSize Self,w,h + End Method + + Method SetMaximumSize(w,h) + NSSetMaximumSize Self,w,h + End Method + + Method SetIconStrip(iconstrip:TIconStrip) + icons=TCocoaIconStrip(iconstrip) + End Method + +' item handling commands + + Method ClearListItems() + NSClearItems Self + End Method + + Method InsertListItem(index,item$,tip$,icon,extra:Object) + Local image + If internalclass=GADGET_TOOLBAR + item=name+":"+index + EndIf + If icons And icon>=0 image=icons.images[icon] + NSAddItem Self,index,item,tip,image,extra + End Method + + Method SetListItem(index,item$,tip$,icon,extra:Object) + Local image + If internalclass=GADGET_TOOLBAR + item=name+":"+index + EndIf + If icons And icon>=0 image=icons.images[icon] + NSSetItem Self,index,item,tip,image,extra + End Method + + Method RemoveListItem(index) + NSRemoveItem Self,index + End Method + + Method SetListItemState(index,state) + NSSelectItem Self,index,state + End Method + + Method ListItemState(index) + Return NSSelectedItem(Self,index) + End Method + +' treeview commands + + Method RootNode:TGadget() + Return Self + End Method + + Method SetIcon(icon) + Local p:TNSGadget + p=Self + While p + If p.icons Exit + p=TNSGadget(p.parent) + Wend + If p + If icon>-1 + NSSetIcon Self,p.icons.images[icon] + Else + NSSetIcon Self,Null + EndIf + EndIf + End Method + + Method InsertNode:TGadget(index,text$,icon) + Local node:TNSGadget = Create(GADGET_NODE,text,0,0,0,0,Self,index) + node.SetIcon icon + node._SetParent Self + Return node + End Method + + Method ModifyNode(text$,icon) + NSSetText Self,text + SetIcon icon + End Method + + Method SelectedNode:TGadget() + Local index = NSSelectedNode(Self) + If (index) Return GadgetFromHandle(index) + End Method + + Method CountKids() + Return NSCountKids(Self) + End Method + +' textarea commands + + Method ReplaceText(pos,length,text$,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + NSReplaceText Self,pos,length,text$,units + End Method + + Method AddText(text$) + NSAddText Self,text + End Method + + Method AreaText$(pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + Return NSAreaText(Self,pos,length,units) + End Method + + Method AreaLen(units) + Return NSAreaLen(Self,units) + End Method + + Method LockText() + NSLockText Self + End Method + + Method UnlockText() + NSUnlockText Self + End Method + + Method SetTabs(tabwidth) + NSSetTabs Self,tabwidth + End Method + + Method SetMargins(leftmargin) + NSSetMargins Self,leftmargin + End Method + + Method GetCursorPos(units) + Return NSGetCursorPos(Self,units) + End Method + + Method GetSelectionLength(units) + Return NSGetSelectionLength(Self,units) + End Method + + Method SetStyle(r,g,b,flags,pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + If length NSSetStyle Self,r,g,b,flags,pos,length,units + End Method + + Method SetSelection(pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + NSSetSelection Self,pos,length,units + End Method + + Method CharAt(line) +?debug + If line<0 Or line>AreaLen(TEXTAREA_LINES) Throw "Parameter Out Of Range" +? + Return NSCharAt(Self,line) + End Method + + Method LineAt(index) +?debug + If index<0 Or index>AreaLen(TEXTAREA_CHARS) Throw "Parameter Out Of Range" +? + Return NSLineAt(Self,index) + End Method + + Method CharX(char) + Return NSCharX(Self,char) + EndMethod + + Method CharY(char) + Return NSCharY(Self,char) + EndMethod + +' progbar + + Method SetValue(value#) + NSSetValue Self,value + End Method + +' slider / scrollbar + + Method SetRange(_small,_big) + small=_small + big=_big + NSSetSlider Self,GetProp(),small,big + End Method + + Method SetProp(pos) + NSSetSlider Self,pos,small,big + End Method + + Method GetProp() + Local value:Double = NSGetSlider(Self) + If Not (style&(SLIDER_TRACKBAR|SLIDER_STEPPER)) + value:*(big-small) + If value>big-small value=big-small + EndIf + Return Int(value+0.5:Double) + End Method + +' canvas + + Method AttachGraphics:TGraphics( flags ) + canvas=brl.Graphics.AttachGraphics( Query(QUERY_NSVIEW_CLIENT),flags ) + End Method + + Method CanvasGraphics:TGraphics() + Return canvas + End Method + +End Type + + +Type TCocoaIconStrip Extends TIconStrip + + Field images[] + + Function IsNotBlank(pixmap:TPixmap) + Local y, h = pixmap.height + Local c = pixmap.ReadPixel(0,0) + For Local x = 0 Until h + For y = 0 Until h + If pixmap.ReadPixel(x,y)<>c Return True + Next + Next + End Function + + Function Create:TCocoaIconStrip(source:Object) + Local icons:TCocoaIconStrip + Local pixmap:TPixmap,pix:TPixmap + Local n,x,w,nsimage + pixmap=TPixmap(source) + If Not pixmap pixmap=LoadPixmap(source) + If Not pixmap Return + Select pixmap.format + Case PF_I8,PF_BGR888 + pixmap=pixmap.Convert( PF_RGB888 ) + Case PF_A8,PF_BGRA8888 + pixmap=pixmap.Convert( PF_RGBA8888 ) + End Select + + If AlphaBitsPerPixel[ pixmap.format ] + For Local y=0 Until pixmap.height + For x=0 Until pixmap.width + Local argb=pixmap.ReadPixel( x,y ) + pixmap.WritePixel x,y,premult(argb) + Next + Next + EndIf + + n=pixmap.width/pixmap.height; + If n=0 Return + icons=New TCocoaIconStrip + icons.pixmap=pixmap + icons.count=n + icons.images=New Int[n] + w=pixmap.width/n + For x=0 Until n + pix=pixmap.Window(x*w,0,w,pixmap.height) + If IsNotBlank(pix) icons.images[x]=NSPixmapImage(pix) + Next + Return icons + EndFunction + +EndType + +Type TCocoaGuiFont Extends TGuiFont + + Method Delete() + If handle Then + NSRelease(handle) + handle = 0 + EndIf + EndMethod + + Method CharWidth(char) + If handle + Return NSCharWidth(handle,char) + EndIf + Return 0 + EndMethod + +EndType + +Type TIntWrapper Final + Field value:Int + Function Create:TIntWrapper(value:Int) + Local tmpWrapper:TIntWrapper = New TIntWrapper + tmpWrapper.value = value + Return tmpWrapper + EndFunction + Method Compare( o:Object ) + Local c:TIntWrapper = TIntWrapper(o) + If c Then Return (value - c.value) + Return Super.Compare(o) + EndMethod + Method ToString$() + Return value + EndMethod +EndType + +Private + +Function premult(argb) + Local a = ((argb Shr 24) & $FF) + Return ((((argb&$ff00ff)*a)Shr 8)&$ff00ff)|((((argb&$ff00)*a)Shr 8)&$ff00)|(a Shl 24) +End Function