comparison gtk4/dw.c @ 2267:7ac85e938b71

GTK4: Don't try to link webkit on GTK4... it doesn't support it yet. Also fix various issues with fonts, signals and implement dialogs.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 31 Jan 2021 02:54:40 +0000
parents bb0690c04413
children fefeb5b4e512
comparison
equal deleted inserted replaced
2266:bb0690c04413 2267:7ac85e938b71
121 static gint _delete_event(GtkWidget *widget, gpointer data); 121 static gint _delete_event(GtkWidget *widget, gpointer data);
122 static gint _key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); 122 static gint _key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data);
123 static gint _generic_event(GtkWidget *widget, gpointer data); 123 static gint _generic_event(GtkWidget *widget, gpointer data);
124 static gint _configure_event(GtkWidget *widget, GdkEvent *event, gpointer data); 124 static gint _configure_event(GtkWidget *widget, GdkEvent *event, gpointer data);
125 static gint _activate_event(GtkWidget *widget, gpointer data); 125 static gint _activate_event(GtkWidget *widget, gpointer data);
126 static gint _container_enter_event(GtkWidget *widget, GdkEvent *event, gpointer data); 126 static gint _container_enter_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data);
127 static gint _combobox_select_event(GtkWidget *widget, gpointer data); 127 static gint _combobox_select_event(GtkWidget *widget, gpointer data);
128 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data); 128 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data);
129 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data); 129 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data);
130 static gint _tree_context_event(GtkWidget *widget, GdkEvent *event, gpointer data); 130 static gint _tree_context_event(GtkWidget *widget, GdkEvent *event, gpointer data);
131 static gint _value_changed_event(GtkWidget *widget, gpointer user_data); 131 static gint _value_changed_event(GtkWidget *widget, gpointer user_data);
794 retval = treeexpandfunc(work.window, (HTREEITEM)iter, work.data); 794 retval = treeexpandfunc(work.window, (HTREEITEM)iter, work.data);
795 } 795 }
796 return retval; 796 return retval;
797 } 797 }
798 798
799 static gint _container_enter_event(GtkWidget *widget, GdkEvent *event, gpointer data) 799 static gint _container_enter_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data)
800 { 800 {
801 SignalHandler work = _get_signal_handler(data); 801 SignalHandler work = _get_signal_handler(data);
802 int retval = FALSE; 802 int retval = FALSE;
803 803
804 if(work.window) 804 if(work.window && GTK_IS_WIDGET(work.window))
805 { 805 {
806 GtkWidget *widget = work.window;
807
806 /* Handle both key and button events together */ 808 /* Handle both key and button events together */
807 if(retval /* TODO: Fix this... 809 if(/* TODO: Fix this...(event->type == GDK_2BUTTON_PRESS && buttonevent->button == 1) || */
808 (event->type == GDK_2BUTTON_PRESS && buttonevent->button == 1) || 810 keyval == VK_RETURN)
809 (event->type == GDK_KEY_PRESS && keyevent->keyval == VK_RETURN)*/)
810 { 811 {
811 int (*contextfunc)(HWND, char *, void *, void *) = work.func; 812 int (*contextfunc)(HWND, char *, void *, void *) = work.func;
812 char *text = NULL; 813 char *text = NULL;
813 void *data = NULL; 814 void *data = NULL;
814 815
945 } 946 }
946 } 947 }
947 return FALSE; 948 return FALSE;
948 } 949 }
949 950
950 static gint _default_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer data) 951 static gint _default_key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data)
951 { 952 {
952 GtkWidget *next = (GtkWidget *)data; 953 GtkWidget *next = (GtkWidget *)data;
953 954
954 if(next) 955 if(next)
955 { 956 {
956 if(0 /* TODO: Fix this: event->keyval == GDK_KEY_Return*/) 957 if(keyval == GDK_KEY_Return)
957 { 958 {
958 if(GTK_IS_BUTTON(next)) 959 if(GTK_IS_BUTTON(next))
959 g_signal_emit_by_name(G_OBJECT(next), "clicked"); 960 g_signal_emit_by_name(G_OBJECT(next), "clicked");
960 else 961 else
961 gtk_widget_grab_focus(next); 962 gtk_widget_grab_focus(next);
962 } 963 }
963 } 964 }
964 return FALSE; 965 return FALSE;
966 }
967
968 static void _dw_dialog_response(GtkDialog *dialog, int response_id, gpointer data)
969 {
970 DWDialog *dwdialog = (DWDialog *)data;
971
972 if(dwdialog)
973 dw_dialog_dismiss(dwdialog, DW_INT_TO_POINTER(response_id));
965 } 974 }
966 975
967 static GdkPixbuf *_dw_pixbuf_from_resource(unsigned int rid) 976 static GdkPixbuf *_dw_pixbuf_from_resource(unsigned int rid)
968 { 977 {
969 char resource_path[201] = {0}; 978 char resource_path[201] = {0};
1217 if(dialog->method) 1226 if(dialog->method)
1218 g_main_loop_quit(_DWMainLoop); 1227 g_main_loop_quit(_DWMainLoop);
1219 else 1228 else
1220 dw_event_post(dialog->eve); 1229 dw_event_post(dialog->eve);
1221 dialog->done = TRUE; 1230 dialog->done = TRUE;
1222 return 0; 1231 return DW_ERROR_NONE;
1223 } 1232 }
1224 1233
1225 /* 1234 /*
1226 * Accepts a dialog struct waits for dw_dialog_dismiss() to be 1235 * Accepts a dialog struct waits for dw_dialog_dismiss() to be
1227 * called by a signal handler with the given dialog struct. 1236 * called by a signal handler with the given dialog struct.
1233 void *tmp; 1242 void *tmp;
1234 1243
1235 if(!dialog) 1244 if(!dialog)
1236 return NULL; 1245 return NULL;
1237 1246
1238 if(pthread_self() == _dw_thread) 1247 if(_dw_thread == (pthread_t)-1 || pthread_self() == _dw_thread)
1239 { 1248 {
1240 dialog->method = TRUE; 1249 dialog->method = TRUE;
1241 g_main_loop_run(_DWMainLoop); 1250 g_main_loop_run(_DWMainLoop);
1242 } 1251 }
1243 else 1252 else
1311 GTK_DIALOG_MODAL, gtkicon, gtkbuttons, "%s", title); 1320 GTK_DIALOG_MODAL, gtkicon, gtkbuttons, "%s", title);
1312 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", outbuf); 1321 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", outbuf);
1313 if(flags & DW_MB_YESNOCANCEL) 1322 if(flags & DW_MB_YESNOCANCEL)
1314 gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL); 1323 gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL);
1315 gtk_widget_show(GTK_WIDGET(dialog)); 1324 gtk_widget_show(GTK_WIDGET(dialog));
1316 /* TODO: Implement signal handlers so this will return */ 1325 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp);
1317 response = DW_POINTER_TO_INT(dw_dialog_wait(tmp)); 1326 response = DW_POINTER_TO_INT(dw_dialog_wait(tmp));
1318 if(GTK_IS_WINDOW(dialog)) 1327 if(GTK_IS_WINDOW(dialog))
1319 gtk_window_destroy(GTK_WINDOW(dialog)); 1328 gtk_window_destroy(GTK_WINDOW(dialog));
1320 switch(response) 1329 switch(response)
1321 { 1330 {
1688 gtk_font_chooser_set_font(fd, font); 1697 gtk_font_chooser_set_font(fd, font);
1689 free(font); 1698 free(font);
1690 } 1699 }
1691 1700
1692 gtk_widget_show(GTK_WIDGET(fd)); 1701 gtk_widget_show(GTK_WIDGET(fd));
1693 1702 g_signal_connect(G_OBJECT(fd), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp);
1694 /* TODO: Connect signal handlers so this actually returns */ 1703
1695 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_OK) 1704 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_OK)
1696 { 1705 {
1697 char *fontname = gtk_font_chooser_get_font(fd); 1706 char *fontname = gtk_font_chooser_get_font(fd);
1698 if(fontname && (retfont = strdup(fontname))) 1707 if(fontname && (retfont = strdup(fontname)))
1699 { 1708 {
1751 GtkWidget *tmp = gtk_frame_get_label_widget(GTK_FRAME(handle)); 1760 GtkWidget *tmp = gtk_frame_get_label_widget(GTK_FRAME(handle));
1752 if(tmp) 1761 if(tmp)
1753 handle2 = tmp; 1762 handle2 = tmp;
1754 } 1763 }
1755 1764
1756 pcontext = gtk_widget_get_pango_context( handle2 ); 1765 pcontext = gtk_widget_get_pango_context(handle2);
1757 if ( pcontext ) 1766 if(pcontext)
1758 { 1767 {
1759 pfont = pango_context_get_font_description( pcontext ); 1768 pfont = pango_context_get_font_description(pcontext);
1760 if ( pfont ) 1769 if(pfont)
1761 { 1770 {
1762 int len, x; 1771 int len, x;
1763 1772
1764 font = pango_font_description_to_string( pfont ); 1773 font = pango_font_description_to_string( pfont );
1765 retfont = strdup(font); 1774 retfont = strdup(font);
1783 */ 1792 */
1784 font[x] = 0; 1793 font[x] = 0;
1785 snprintf(retfont, len+1, "%d.%s", size, font); 1794 snprintf(retfont, len+1, "%d.%s", size, font);
1786 } 1795 }
1787 } 1796 }
1788 g_free( font ); 1797 g_free(font);
1789 } 1798 }
1790 } 1799 }
1791 return retfont; 1800 return retfont;
1792 } 1801 }
1793 1802
5424 cd = (GtkColorChooser *)gtk_color_chooser_dialog_new("Choose color", NULL); 5433 cd = (GtkColorChooser *)gtk_color_chooser_dialog_new("Choose color", NULL);
5425 gtk_color_chooser_set_use_alpha(cd, FALSE); 5434 gtk_color_chooser_set_use_alpha(cd, FALSE);
5426 gtk_color_chooser_set_rgba(cd, &color); 5435 gtk_color_chooser_set_rgba(cd, &color);
5427 5436
5428 gtk_widget_show(GTK_WIDGET(cd)); 5437 gtk_widget_show(GTK_WIDGET(cd));
5438 g_signal_connect(G_OBJECT(cd), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp);
5429 5439
5430 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_OK) 5440 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_OK)
5431 { 5441 {
5432 gtk_color_chooser_get_rgba(cd, &color); 5442 gtk_color_chooser_get_rgba(cd, &color);
5433 retcolor = DW_RGB((int)(color.red * 255), (int)(color.green * 255), (int)(color.blue * 255)); 5443 retcolor = DW_RGB((int)(color.red * 255), (int)(color.green * 255), (int)(color.blue * 255));
5892 } 5902 }
5893 5903
5894 font = pango_font_description_from_string(fontname ? fontname : "monospace 10"); 5904 font = pango_font_description_from_string(fontname ? fontname : "monospace 10");
5895 if(font) 5905 if(font)
5896 { 5906 {
5897 PangoContext *context = pango_context_new(); 5907 PangoContext *context = gtk_widget_get_pango_context(pixmap ? pixmap->handle : handle);
5898 5908
5899 if(context) 5909 if(context)
5900 { 5910 {
5901 PangoLayout *layout = pango_layout_new(context); 5911 PangoLayout *layout = pango_layout_new(context);
5902 5912
7242 /* Set the expand attribute on the widgets now instead of the container */ 7252 /* Set the expand attribute on the widgets now instead of the container */
7243 gtk_widget_set_vexpand(item, vsize); 7253 gtk_widget_set_vexpand(item, vsize);
7244 gtk_widget_set_valign(item, vsize ? GTK_ALIGN_FILL : GTK_ALIGN_START); 7254 gtk_widget_set_valign(item, vsize ? GTK_ALIGN_FILL : GTK_ALIGN_START);
7245 gtk_widget_set_hexpand(item, hsize); 7255 gtk_widget_set_hexpand(item, hsize);
7246 gtk_widget_set_halign(item, hsize ? GTK_ALIGN_FILL : GTK_ALIGN_START); 7256 gtk_widget_set_halign(item, hsize ? GTK_ALIGN_FILL : GTK_ALIGN_START);
7247 /* Use the margin property as padding */ 7257 /* TODO: Use the margin property as padding
7248 g_object_set(G_OBJECT(item), "margin", pad, NULL); 7258 g_object_set(G_OBJECT(item), "margin", pad, NULL);*/
7249 /* Add to the grid using insert... 7259 /* Add to the grid using insert...
7250 * rows for vertical boxes and columns for horizontal. 7260 * rows for vertical boxes and columns for horizontal.
7251 */ 7261 */
7252 if(boxtype == DW_VERT) 7262 if(boxtype == DW_VERT)
7253 { 7263 {
8674 * window: Window (widget) to look for the ENTER press. 8684 * window: Window (widget) to look for the ENTER press.
8675 * next: Window (widget) to move to next (or click) 8685 * next: Window (widget) to move to next (or click)
8676 */ 8686 */
8677 void dw_window_click_default(HWND window, HWND next) 8687 void dw_window_click_default(HWND window, HWND next)
8678 { 8688 {
8679 if(!window) 8689 if(window && next && GTK_IS_WIDGET(window) && GTK_IS_WIDGET(next))
8680 return; 8690 {
8681 8691 GtkEventController *controller = gtk_event_controller_key_new();
8682 g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(_default_key_press_event), next); 8692 gtk_widget_add_controller(GTK_WIDGET(window), controller);
8693 g_signal_connect(G_OBJECT(controller), "key-pressed", G_CALLBACK(_default_key_press_event), next);
8694 }
8683 } 8695 }
8684 8696
8685 8697
8686 /* 8698 /*
8687 * Creates a new system notification if possible. 8699 * Creates a new system notification if possible.
8874 8886
8875 g_object_unref(G_OBJECT(path)); 8887 g_object_unref(G_OBJECT(path));
8876 } 8888 }
8877 } 8889 }
8878 8890
8879 /* TODO: Connect signal handlers so this actually returns */ 8891 gtk_widget_show(GTK_WIDGET(filew));
8892 g_signal_connect(G_OBJECT(filew), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp);
8893
8880 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_ACCEPT) 8894 if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_ACCEPT)
8881 { 8895 {
8882 GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(filew)); 8896 GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(filew));
8883 filename = g_file_get_path(file); 8897 filename = g_file_get_path(file);
8884 g_object_unref(G_OBJECT(file)); 8898 g_object_unref(G_OBJECT(file));
9543 thisfunc = _findsigfunc(thisname); 9557 thisfunc = _findsigfunc(thisname);
9544 } 9558 }
9545 #endif 9559 #endif
9546 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) 9560 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0)
9547 { 9561 {
9562 //GtkGesture *gesture = gtk_gesture_click_new();
9548 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc); 9563 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc);
9549 params[0] = GINT_TO_POINTER(sigid); 9564 params[0] = GINT_TO_POINTER(sigid);
9550 params[2] = (void *)thiswindow; 9565 params[2] = (void *)thiswindow;
9551 cid = g_signal_connect_data(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); 9566 cid = g_signal_connect_data(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
9552 _set_signal_handler_id(thiswindow, sigid, cid); 9567 _set_signal_handler_id(thiswindow, sigid, cid);
9578 { 9593 {
9579 thisname = "row-expanded"; 9594 thisname = "row-expanded";
9580 } 9595 }
9581 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0) 9596 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0)
9582 { 9597 {
9598 GtkEventController *controller = gtk_event_controller_key_new();
9583 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event, discfunc); 9599 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event, discfunc);
9584 params[0] = GINT_TO_POINTER(sigid); 9600 params[0] = GINT_TO_POINTER(sigid);
9585 params[2] = (void *)thiswindow; 9601 params[2] = (void *)thiswindow;
9586 cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0); 9602 gtk_widget_add_controller(GTK_WIDGET(thiswindow), controller);
9603 cid = g_signal_connect_data(G_OBJECT(controller), "key-pressed", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0);
9587 _set_signal_handler_id(thiswindow, sigid, cid); 9604 _set_signal_handler_id(thiswindow, sigid, cid);
9588 9605
9589 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS); 9606 params = calloc(sizeof(void *), _DW_INTERNAL_CALLBACK_PARAMS);
9590 9607
9591 thisname = "button_press_event"; 9608 thisname = "button_press_event";