Sun, 29 Sep 2024 15:55:56 +0200
implement file dialog for gtk4
ui/gtk/headerbar.c | file | annotate | diff | comparison | revisions | |
ui/gtk/text.c | file | annotate | diff | comparison | revisions | |
ui/gtk/toolkit.c | file | annotate | diff | comparison | revisions | |
ui/gtk/window.c | file | annotate | diff | comparison | revisions |
--- a/ui/gtk/headerbar.c Sun Sep 29 15:01:14 2024 +0200 +++ b/ui/gtk/headerbar.c Sun Sep 29 15:55:56 2024 +0200 @@ -152,19 +152,28 @@ UiObject *obj, enum UiToolbarPos pos) { + + +#if GTK_MAJOR_VERSION >= 4 GtkWidget *menubutton = gtk_menu_button_new(); - if(item->args.label) { gtk_menu_button_set_label(GTK_MENU_BUTTON(menubutton), item->args.label); } if(item->args.icon) { gtk_menu_button_set_icon_name(GTK_MENU_BUTTON(menubutton), item->args.icon); } - + GMenu *menu = g_menu_new(); ui_gmenu_add_menu_items(menu, 0, &item->menu, obj); gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menubutton), G_MENU_MODEL(menu)); +#else + GtkWidget *menubutton = gtk_menu_button_new(); + + // TODO + + +#endif headerbar_add(headerbar, box, menubutton, pos); }
--- a/ui/gtk/text.c Sun Sep 29 15:01:14 2024 +0200 +++ b/ui/gtk/text.c Sun Sep 29 15:55:56 2024 +0200 @@ -701,7 +701,6 @@ } static void ui_path_textfield_destroy(GtkWidget *object, UiPathTextField *pathtf) { - free(pathtf->hbox); g_object_unref(pathtf->entry); free(pathtf); }
--- a/ui/gtk/toolkit.c Sun Sep 29 15:01:14 2024 +0200 +++ b/ui/gtk/toolkit.c Sun Sep 29 15:55:56 2024 +0200 @@ -394,7 +394,12 @@ size_t numClasses = cx_strsplit_a(cxDefaultAllocator, cx_str(style_classes), CX_STR(" "), 128, &cls); for(int i=0;i<numClasses;i++) { cxmutstr m = cx_strdup(cls[i]); +#if GTK_MAJOR_VERSION >= 4 gtk_widget_add_css_class(widget, m.ptr); +#elif GTK_MAJOR_VERSION >= 3 + GtkStyleContext *ctx = gtk_widget_get_style_context(widget); + gtk_style_context_add_class(ctx, m.ptr); +#endif free(m.ptr); } free(cls);
--- a/ui/gtk/window.c Sun Sep 29 15:01:14 2024 +0200 +++ b/ui/gtk/window.c Sun Sep 29 15:55:56 2024 +0200 @@ -259,11 +259,66 @@ } -#if GTK_MAJOR_VERSION >= 4 +#if GTK_MAJOR_VERSION >= 40 static void ui_gtkfilechooser(UiObject *obj, GtkFileChooserAction action, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { // TODO } #else + + + +static void filechooser_response(GtkDialog* self, gint response_id, UiEventData *data) { + UiEvent evt; + evt.obj = data->obj; + evt.document = evt.obj->ctx->document; + evt.window = evt.obj->window; + evt.intval = 0; + + UiFileList flist; + flist.files = NULL; + flist.nfiles = 0; + evt.eventdata = &flist; + + if(response_id == GTK_RESPONSE_ACCEPT) { +#if GTK_CHECK_VERSION(4, 0, 0) + GListModel *selection = gtk_file_chooser_get_files(GTK_FILE_CHOOSER(self)); + flist.nfiles = g_list_model_get_n_items(selection); + flist.files = calloc(flist.nfiles, sizeof(char*)); + for(int i=0;i<flist.nfiles;i++) { + GFile *file = g_list_model_get_item(selection, i); + char *path = g_file_get_path(file); + flist.files[i] = strdup(path ? path : ""); + g_object_unref(file); + } + g_object_unref(selection); +#else + GSList *selection = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(self)); + flist.nfiles = g_slist_length(selection); + flist.files = calloc(flist.nfiles, sizeof(char*)); + int i = 0; + while(selection) { + char *file = selection->data; + flist.files[i] = strdup(file); + g_free(file); + selection = selection->next; + i++; + } + g_slist_free(selection); +#endif + } + + + if(data->callback) { + data->callback(&evt, data->userdata); + } + + for(int i=0;i<flist.nfiles;i++) { + free(flist.files[i]); + } + + WINDOW_DESTROY(GTK_WIDGET(self)); +} + static void ui_gtkfilechooser(UiObject *obj, GtkFileChooserAction action, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { char *button; char *title; @@ -305,6 +360,25 @@ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); } + UiEventData *event = malloc(sizeof(UiEventData)); + event->obj = obj; + event->userdata = cbdata; + event->callback = file_selected_callback; + event->value = 0; + event->customdata = NULL; + + g_signal_connect( + dialog, + "response", + G_CALLBACK(filechooser_response), + event); + g_signal_connect( + dialog, + "destroy", + G_CALLBACK(ui_destroy_userdata), + event); + + UiEvent evt; evt.obj = obj; evt.document = evt.obj->ctx->document; @@ -316,31 +390,7 @@ flist.nfiles = 0; evt.eventdata = &flist; - int result = gtk_dialog_run(GTK_DIALOG (dialog)); - GSList *selection = NULL; - if(result == GTK_RESPONSE_ACCEPT) { - selection = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - flist.nfiles = g_slist_length(selection); - flist.files = calloc(flist.nfiles, sizeof(char*)); - int i = 0; - while(selection) { - flist.files[i] = selection->data; - selection = selection->next; - i++; - } - } - - if(file_selected_callback) { - file_selected_callback(&evt, cbdata); - } - - for(int i=0;i<flist.nfiles;i++) { - g_free(flist.files[i]); - } - free(flist.files); - g_slist_free(selection); - - gtk_widget_destroy(dialog); + gtk_widget_show(dialog); } #endif