#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 <ucx/utils.h>
#include <pthread.h>
#ifndef UI_GTK2
static GtkApplication *app;
#endif
static char *application_name;
static ui_callback startup_func;
static void *startup_data;
static ui_callback open_func;
void *open_data;
static ui_callback exit_func;
void *exit_data;
static ui_callback appclose_fnc;
static void *appclose_udata;
static UiObject *active_window;
static int scale_factor =
1;
void ui_init(
char *appname,
int argc,
char **argv) {
uic_init_global_context();
gtk_init(&argc, &argv);
application_name = appname;
uic_docmgr_init();
ui_toolbar_init();
ui_list_init();
ui_image_init();
uic_load_app_properties();
#ifdef UI_SUPPORTS_SCALE
scale_factor = gdk_monitor_get_scale_factor(
gdk_display_get_primary_monitor(gdk_display_get_default()));
#endif
}
char* ui_appname() {
return application_name;
}
void ui_onstartup(ui_callback f,
void *userdata) {
startup_func = f;
startup_data = userdata;
}
void ui_onopen(ui_callback f,
void *userdata) {
open_func = f;
open_data = userdata;
}
void ui_onexit(ui_callback f,
void *userdata) {
exit_func = f;
exit_data = userdata;
}
#ifndef UI_GTK2
static void app_startup(GtkApplication* app, gpointer userdata) {
if(startup_func) {
startup_func(
NULL, startup_data);
}
}
static void app_activate(GtkApplication* app, gpointer userdata) {
printf(
"activate\n");
}
#endif
void ui_main() {
#ifndef UI_GTK2
sstr_t appid = ucx_sprintf(
"ui.%s",
application_name ? application_name :
"application1");
app = gtk_application_new(
appid.ptr,
G_APPLICATION_FLAGS_NONE);
g_signal_connect (app,
"startup",
G_CALLBACK (app_startup),
NULL);
g_signal_connect (app,
"activate",
G_CALLBACK (app_activate),
NULL);
g_application_run(
G_APPLICATION (app),
0,
NULL);
g_object_unref (app);
free(appid.ptr);
#else
if(startup_func) {
startup_func(
NULL, startup_data);
}
gtk_main();
#endif
if(exit_func) {
exit_func(
NULL, exit_data);
}
uic_store_app_properties();
}
#ifndef UI_GTK2
void ui_app_quit() {
g_application_quit(
G_APPLICATION(app));
}
GtkApplication* ui_get_application() {
return app;
}
#endif
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);
}
return NULL;
}
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;
}
}
int ui_get_scalefactor() {
return scale_factor;
}
void ui_destroy_userdata(GtkWidget *object,
void *userdata) {
free(userdata);
}
void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data) {
ui_destroy_boundvar(data->obj->ctx, data->var);
free(data);
}
void ui_destroy_boundvar(UiContext *ctx, UiVar *var) {
if(var->type ==
UI_VAR_SPECIAL) {
free(var);
}
else {
uic_remove_bound_var(ctx, var);
}
}
void ui_set_active_window(UiObject *obj) {
active_window = obj;
}
UiObject *ui_get_active_window() {
return active_window;
}