Sun, 17 Jan 2016 19:19:28 +0100
improved gtk2 implementation of grid container
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2014 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. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include "toolkit.h" #include "toolbar.h" #include "model.h" #include "image.h" #include "../common/document.h" #include "../common/properties.h" #include <pthread.h> static char *application_name; static ui_callback appclose_fnc; static void *appclose_udata; static UiObject *active_window; void ui_init(char *appname, int argc, char **argv) { gtk_init(&argc, &argv); application_name = appname; uic_docmgr_init(); ui_toolbar_init(); // init custom types ui_list_init(); ui_image_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) { // OS X only } void ui_main() { gtk_main(); if(appclose_fnc) { appclose_fnc(NULL, appclose_udata); } uic_store_app_properties(); } void ui_show(UiObject *obj) { uic_check_group_widgets(obj->ctx); gtk_widget_show_all(obj->widget); } void ui_close(UiObject *obj) { gtk_widget_destroy(obj->widget); } static gboolean ui_job_finished(void *data) { UiJob *job = data; UiEvent event; event.obj = job->obj; event.window = job->obj->window; event.document = job->obj->ctx->document; event.intval = 0; event.eventdata = NULL; job->finish_callback(&event, job->finish_data); free(job); return FALSE; } static void* ui_jobthread(void *data) { UiJob *job = data; int result = job->job_func(job->job_data); if(!result) { g_idle_add(ui_job_finished, job); } } void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd) { UiJob *job = malloc(sizeof(UiJob)); job->obj = obj; job->job_func = tf; job->job_data = td; job->finish_callback = f; job->finish_data = fd; pthread_t pid; pthread_create(&pid, NULL, ui_jobthread, job); } void ui_set_enabled(UIWIDGET widget, int enabled) { gtk_widget_set_sensitive(widget, enabled); } void ui_set_show_all(UIWIDGET widget, int value) { gtk_widget_set_no_show_all(widget, !value); } void ui_set_visible(UIWIDGET widget, int visible) { if(visible) { gtk_widget_set_no_show_all(widget, FALSE); gtk_widget_show_all(widget); } else { gtk_widget_hide(widget); } } void ui_clipboard_set(char *str) { GtkClipboard *cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text(cb, str, strlen(str)); } char* ui_clipboard_get() { GtkClipboard *cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); char *str = gtk_clipboard_wait_for_text(cb); if(str) { char *copy = strdup(str); g_free(str); return copy; } else { return NULL; } } void ui_destroy_userdata(GtkWidget *object, void *userdata) { free(userdata); } void ui_set_active_window(UiObject *obj) { active_window = obj; } UiObject *ui_get_active_window() { return active_window; } /* -------------------- common widget functions -------------------- */ static gboolean widget_button_pressed( GtkWidget *widget, GdkEvent *event, gpointer userdata) { UiEventData *eventdata = userdata; UiMouseEvent me; me.x = (int)event->button.x; me.y = (int)event->button.y; int exec = 0; if(event->button.type == GDK_BUTTON_PRESS) { exec = 1; me.type = UI_PRESS; } else if(event->button.type == GDK_2BUTTON_PRESS) { exec = 1; me.type = UI_PRESS2; } if(exec) { UiEvent e; e.obj = eventdata->obj; e.window = eventdata->obj->window; e.document = eventdata->obj->ctx->document; e.eventdata = &me; e.intval = 0; eventdata->callback(&e, eventdata->userdata); } return true; } void ui_mouse_handler(UiObject *obj, UIWIDGET widget, ui_callback f, void *u) { gtk_widget_set_events(widget, GDK_BUTTON_PRESS_MASK); if(f) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; event->callback = f; event->userdata = u; g_signal_connect(G_OBJECT(widget), "button-press-event", G_CALLBACK(widget_button_pressed), event); } else { // TODO: warning } }