/* * MACDRV Cocoa status item class * * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #import #include "macdrv_cocoa.h" #import "cocoa_app.h" #import "cocoa_event.h" @interface WineStatusItem : NSObject { NSStatusItem* item; WineEventQueue* queue; } @property (retain, nonatomic) NSStatusItem* item; @property (assign, nonatomic) WineEventQueue* queue; @end @implementation WineStatusItem @synthesize item, queue; - (id) initWithEventQueue:(WineEventQueue*)inQueue { self = [super init]; if (self) { NSStatusBar* statusBar = [NSStatusBar systemStatusBar]; item = [[statusBar statusItemWithLength:NSSquareStatusItemLength] retain]; [item setTarget:self]; [item setAction:@selector(clicked:)]; [item setDoubleAction:@selector(doubleClicked:)]; queue = inQueue; } return self; } - (void) dealloc { if (item) { NSStatusBar* statusBar = [NSStatusBar systemStatusBar]; [statusBar removeStatusItem:item]; [item release]; } [super dealloc]; } - (void) removeFromStatusBar { if (item) { NSStatusBar* statusBar = [NSStatusBar systemStatusBar]; [statusBar removeStatusItem:item]; self.item = nil; } } - (void) postClickedEventWithCount:(int)count { macdrv_event* event; event = macdrv_create_event(STATUS_ITEM_CLICKED, nil); event->status_item_clicked.item = (macdrv_status_item)self; event->status_item_clicked.count = count; [queue postEvent:event]; macdrv_release_event(event); } - (void) clicked:(id)sender { [self postClickedEventWithCount:1]; } - (void) doubleClicked:(id)sender { [self postClickedEventWithCount:2]; } @end /*********************************************************************** * macdrv_create_status_item * * Creates a new status item in the status bar. */ macdrv_status_item macdrv_create_status_item(macdrv_event_queue q) { WineEventQueue* queue = (WineEventQueue*)q; __block WineStatusItem* statusItem; OnMainThread(^{ statusItem = [[WineStatusItem alloc] initWithEventQueue:queue]; }); return (macdrv_status_item)statusItem; } /*********************************************************************** * macdrv_destroy_status_item * * Removes a status item previously returned by * macdrv_create_status_item() from the status bar and destroys it. */ void macdrv_destroy_status_item(macdrv_status_item s) { WineStatusItem* statusItem = (WineStatusItem*)s; OnMainThreadAsync(^{ [statusItem removeFromStatusBar]; [statusItem release]; }); } /*********************************************************************** * macdrv_set_status_item_image * * Sets the image for a status item. If cgimage is NULL, clears the * image of the status item (leaving it a blank spot on the menu bar). */ void macdrv_set_status_item_image(macdrv_status_item s, CGImageRef cgimage) { WineStatusItem* statusItem = (WineStatusItem*)s; CGImageRetain(cgimage); OnMainThreadAsync(^{ NSImage* image = nil; if (cgimage) { NSSize size; CGFloat maxSize = [[NSStatusBar systemStatusBar] thickness]; BOOL changed = FALSE; image = [[NSImage alloc] initWithCGImage:cgimage size:NSZeroSize]; CGImageRelease(cgimage); size = [image size]; while (size.width > maxSize || size.height > maxSize) { size.width /= 2.0; size.height /= 2.0; changed = TRUE; } if (changed) [image setSize:size]; } [statusItem.item setImage:image]; [image release]; }); } /*********************************************************************** * macdrv_set_status_item_tooltip * * Sets the tooltip string for a status item. If cftip is NULL, clears * the tooltip string for the status item. */ void macdrv_set_status_item_tooltip(macdrv_status_item s, CFStringRef cftip) { WineStatusItem* statusItem = (WineStatusItem*)s; NSString* tip = (NSString*)cftip; if (![tip length]) tip = nil; OnMainThreadAsync(^{ [statusItem.item setToolTip:tip]; }); }