implement file dialog for gtk4 newapi

Sun, 29 Sep 2024 15:55:56 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 29 Sep 2024 15:55:56 +0200
branch
newapi
changeset 314
d96ba820083a
parent 313
b679cc6059ab
child 315
144c2b4683cb

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
 

mercurial