Sun, 16 Jun 2024 11:36:27 +0200
update toolkit
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2012 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <stdio.h> #import <stdlib.h> #import <sys/stat.h> #import <sys/types.h> #import <errno.h> #import "../common/context.h" #import "../common/document.h" #import "../common/properties.h" #import "toolkit.h" #import "window.h" #import "menu.h" #import "toolbar.h" #import "stock.h" NSAutoreleasePool *pool; static char *application_name; static ui_callback appclose_fnc; static void *appclose_udata; static ui_callback openfile_fnc; static void *openfile_udata; void ui_init(char *appname, int argc, char **argv) { pool = [[NSAutoreleasePool alloc] init]; [NSApplication sharedApplication]; [NSBundle loadNibNamed:@"MainMenu" owner:NSApp]; UiApplicationDelegate *delegate = [[UiApplicationDelegate alloc]init]; [NSApp setDelegate: delegate]; uic_docmgr_init(); ui_menu_init(); ui_toolbar_init(); ui_stock_init(); uic_load_app_properties(); } char* ui_appname() { return application_name; } void ui_exitfunc(ui_callback f, void *userdata) { appclose_fnc = f; appclose_udata = userdata; } void ui_openfilefunc(ui_callback f, void *userdata) { openfile_fnc = f; openfile_udata = userdata; } void ui_show(UiObject *obj) { uic_check_group_widgets(obj->ctx); if([obj->widget class] == [UiCocoaWindow class]) { UiCocoaWindow *window = (UiCocoaWindow*)obj->widget; [window makeKeyAndOrderFront:nil]; } else { printf("Error: ui_show: Object is not a Window!\n"); } } void ui_set_show_all(UIWIDGET widget, int value) { // TODO } void ui_set_visible(UIWIDGET widget, int visible) { // TODO } void ui_set_enabled(UIWIDGET widget, int enabled) { [(id)widget setEnabled: enabled]; } void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd) { UiThread *thread = [[UiThread alloc]initWithObject:obj]; [thread setJobFunction:tf]; [thread setJobData:td]; [thread setFinishCallback:f]; [thread setFinishData:fd]; [thread start]; } void ui_main() { [NSApp run]; [pool release]; } void ui_clipboard_set(char *str) { NSString *string = [[NSString alloc] initWithUTF8String:str]; NSPasteboard * pasteBoard = [NSPasteboard generalPasteboard]; [pasteBoard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; [pasteBoard setString:string forType:NSStringPboardType]; } char* ui_clipboard_get() { NSPasteboard * pasteBoard = [NSPasteboard generalPasteboard]; NSArray *classes = [[NSArray alloc] initWithObjects:[NSString class], nil]; NSDictionary *options = [NSDictionary dictionary]; NSArray *data = [pasteBoard readObjectsForClasses:classes options:options]; if(data != nil) { NSString *str = [data componentsJoinedByString: @""]; // copy C string size_t length = [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; const char *cstr = [str UTF8String]; char *value = malloc(length + 1); memcpy(value, cstr, length); value[length] = '\0'; return value; } else { return NULL; } } @implementation UiApplicationDelegate - (void)applicationWillTerminate:(NSNotification*)notification { printf("terminate\n"); } - (BOOL)applicationShouldHandleReopen:(NSApplication *)app hasVisibleWindows:(BOOL)visible; { if(!visible) { printf("reopen\n"); } return NO; } - (BOOL)application:(NSApplication*)application openFile:(NSString*)filename { if(openfile_fnc) { UiEvent event; event.obj = NULL; event.document = NULL; event.window = NULL; event.eventdata = (void*)[filename UTF8String]; event.intval = 0; openfile_fnc(&event, openfile_udata); } return NO; } @end @implementation EventWrapper - (EventWrapper*) initWithData: (void*)d callback:(ui_callback) f { data = d; callback = f; value = 0; return self; } - (void*) data { return data; } - (void) setData:(void*)d { data = d; } - (ui_callback) callback { return callback; } - (void) setCallback: (ui_callback)f { callback = f; } - (int) intval { return value; } - (void) setIntval:(int)i { value = i; } - (BOOL)handleEvent:(id)sender { NSWindow *activeWindow = [NSApp keyWindow]; UiEvent event; event.eventdata = NULL; if([activeWindow class] == [UiCocoaWindow class]) { event.obj = [(UiCocoaWindow*)activeWindow object]; event.window = event.obj->window; event.document = event.obj->ctx->document; event.intval = value; } if(callback) { callback(&event, data); } return true; } - (BOOL)handleStateEvent:(id)sender { NSWindow *activeWindow = [NSApp keyWindow]; int state = [sender state] ? NSOffState : NSOnState; UiEvent event; event.intval = state; event.eventdata = NULL; if([activeWindow class] == [UiCocoaWindow class]) { event.obj = [(UiCocoaWindow*)activeWindow object]; event.window = event.obj->window; event.document = event.obj->ctx->document; // if the sender is a menu item, we have to save the state for this // window UiMenuItem *wmi = [(UiCocoaWindow*)activeWindow getMenuItem: sender]; if(wmi) { // update state in window data wmi->state = state; } } else { event.window = NULL; event.document = NULL; } if(callback) { callback(&event, data); } [sender setState: state]; return true; } - (BOOL)handleToggleEvent:(id)sender { NSWindow *activeWindow = [NSApp keyWindow]; UiEvent event; event.intval = [sender state]; event.eventdata = NULL; if([activeWindow class] == [UiCocoaWindow class]) { event.obj = [(UiCocoaWindow*)activeWindow object]; event.window = event.obj->window; event.document = event.obj->ctx->document; } else { event.window = NULL; event.document = NULL; } if(callback) { callback(&event, data); } return true; } @end @implementation UiThread - (id) initWithObject:(UiObject*)object { obj = object; job_func = NULL; job_data = NULL; finish_callback = NULL; finish_data = NULL; return self; } - (void) setJobFunction:(ui_threadfunc)func { job_func = func; } - (void) setJobData:(void*)data { job_data = data; } - (void) setFinishCallback:(ui_callback)callback { finish_callback = callback; } - (void) setFinishData:(void*)data { finish_data = data; } - (void) start { [NSThread detachNewThreadSelector:@selector(runJob:) toTarget:self withObject:nil]; } - (void) runJob:(id)n { int result = job_func(job_data); if(!result) { [self performSelectorOnMainThread:@selector(finish:) withObject:nil waitUntilDone:NO]; } } - (void) finish:(id)n { UiEvent event; event.obj = obj; event.window = obj->window; event.document = obj->ctx->document; event.eventdata = NULL; event.intval = 0; finish_callback(&event, finish_data); } @end