static gboolean _lib_plugin_header_button_press(GtkWidget *w, GdkEventButton *e, gpointer user_data) { if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS) return TRUE; dt_lib_module_t *module = (dt_lib_module_t *)user_data; if(e->button == 1) { /* bail out if module is static */ if(!module->expandable(module)) return FALSE; // make gtk scroll to the module once it updated its allocation size uint32_t container = module->container(module); if(dt_conf_get_bool("lighttable/ui/scroll_to_module")) { if(container == DT_UI_CONTAINER_PANEL_LEFT_CENTER) darktable.gui->scroll_to[0] = module->expander; else if(container == DT_UI_CONTAINER_PANEL_RIGHT_CENTER) darktable.gui->scroll_to[1] = module->expander; } /* handle shiftclick on expander, hide all except this */ if(!dt_conf_get_bool("lighttable/ui/single_module") != !(e->state & GDK_SHIFT_MASK)) { GList *it = g_list_first(darktable.lib->plugins); const dt_view_t *v = dt_view_manager_get_current_view(darktable.view_manager); gboolean all_other_closed = TRUE; while(it) { dt_lib_module_t *m = (dt_lib_module_t *)it->data; if(m != module && container == m->container(module) && m->expandable(module) && (m->views(module) & v->view(v))) { all_other_closed = all_other_closed && !dtgtk_expander_get_expanded(DTGTK_EXPANDER(m->expander)); dt_lib_gui_set_expanded(m, FALSE); } it = g_list_next(it); } if(all_other_closed) dt_lib_gui_set_expanded(module, !dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander))); else dt_lib_gui_set_expanded(module, TRUE); } else { /* else just toggle */ dt_lib_gui_set_expanded(module, !dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander))); } return TRUE; } else if(e->button == 2) { /* show preset popup if any preset for module */ return TRUE; } return FALSE; }
void dt_lib_gui_set_expanded(dt_lib_module_t *module, gboolean expanded) { if(!module->expander) return; dtgtk_expander_set_expanded(DTGTK_EXPANDER(module->expander), expanded); /* update expander arrow state */ GtkWidget *icon; GtkWidget *header = dtgtk_expander_get_header(DTGTK_EXPANDER(module->expander)); gint flags = CPF_DIRECTION_DOWN; int c = module->container(module); GList *header_childs = gtk_container_get_children(GTK_CONTAINER(header)); if((c == DT_UI_CONTAINER_PANEL_LEFT_TOP) || (c == DT_UI_CONTAINER_PANEL_LEFT_CENTER) || (c == DT_UI_CONTAINER_PANEL_LEFT_BOTTOM)) { icon = g_list_nth_data(header_childs, 0); if(!expanded) flags = CPF_DIRECTION_RIGHT; } else { icon = g_list_last(header_childs)->data; if(!expanded) flags = CPF_DIRECTION_LEFT; } g_list_free(header_childs); dtgtk_icon_set_paint(icon, dtgtk_cairo_paint_solid_arrow, flags); /* show / hide plugin widget */ if(expanded) { /* register to receive draw events */ darktable.lib->gui_module = module; /* focus the current module */ for(int k = 0; k < DT_UI_CONTAINER_SIZE; k++) dt_ui_container_focus_widget(darktable.gui->ui, k, GTK_WIDGET(module->expander)); } else { if(darktable.lib->gui_module == module) { darktable.lib->gui_module = NULL; dt_control_queue_redraw(); } } /* store expanded state of module */ char var[1024]; const dt_view_t *current_view = dt_view_manager_get_current_view(darktable.view_manager); snprintf(var, sizeof(var), "plugins/%s/%s/expanded", current_view->module_name, module->plugin_name); dt_conf_set_bool(var, expanded); }
static gboolean _lib_plugin_header_button_press(GtkWidget *w, GdkEventButton *e, gpointer user_data) { dt_lib_module_t *module = (dt_lib_module_t *)user_data; if(e->button == 1) { /* bail out if module is static */ if(!module->expandable()) return FALSE; /* handle shiftclick on expander, hide all except this */ if(!dt_conf_get_bool("lighttable/ui/single_module") != !(e->state & GDK_SHIFT_MASK)) { GList *it = g_list_first(darktable.lib->plugins); uint32_t container = module->container(); dt_view_t *v = darktable.view_manager->view + darktable.view_manager->current_view; gboolean all_other_closed = TRUE; while(it) { dt_lib_module_t *m = (dt_lib_module_t *)it->data; if(m != module && container == m->container() && m->expandable() && (m->views() & v->view(v))) { all_other_closed = all_other_closed && !dtgtk_expander_get_expanded(DTGTK_EXPANDER(m->expander)); dt_lib_gui_set_expanded(m, FALSE); } it = g_list_next(it); } if(all_other_closed) dt_lib_gui_set_expanded(module, !dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander))); else dt_lib_gui_set_expanded(module, TRUE); } else { /* else just toggle */ dt_lib_gui_set_expanded(module, !dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander))); } return TRUE; } else if(e->button == 2) { /* show preset popup if any preset for module */ return TRUE; } return FALSE; }
static void popup_callback(GtkButton *button, dt_lib_module_t *module) { static dt_lib_module_info_t mi; int size = 0; g_strlcpy(mi.plugin_name, module->plugin_name, sizeof(mi.plugin_name)); mi.version = module->version(module); mi.module = module; void *params = module->get_params(module, &size); // make sure that we have enough space for params if(params && (size <= sizeof(mi.params))) { memcpy(mi.params, params, size); mi.params_size = size; free(params); } else { mi.params_size = 0; fprintf(stderr, "something went wrong: ¶ms=%p, size=%i\n", ¶ms, size); } dt_lib_presets_popup_menu_show(&mi); #if GTK_CHECK_VERSION(3, 22, 0) int c = module->container(module); GdkGravity widget_gravity, menu_gravity; if((c == DT_UI_CONTAINER_PANEL_LEFT_TOP) || (c == DT_UI_CONTAINER_PANEL_LEFT_CENTER) || (c == DT_UI_CONTAINER_PANEL_LEFT_BOTTOM)) { // FIXME: these should be _EAST, but then it goes out of the sidepanel... widget_gravity = GDK_GRAVITY_SOUTH; menu_gravity = GDK_GRAVITY_NORTH; } else { widget_gravity = GDK_GRAVITY_SOUTH_WEST; menu_gravity = GDK_GRAVITY_NORTH_WEST; } gtk_menu_popup_at_widget(darktable.gui->presets_popup_menu, dtgtk_expander_get_header(DTGTK_EXPANDER(module->expander)), widget_gravity, menu_gravity, NULL); #else gtk_menu_popup(darktable.gui->presets_popup_menu, NULL, NULL, _preset_popup_posistion, button, 0, gtk_get_current_event_time()); #endif gtk_widget_show_all(GTK_WIDGET(darktable.gui->presets_popup_menu)); gtk_menu_reposition(GTK_MENU(darktable.gui->presets_popup_menu)); }
gboolean dt_lib_gui_get_expanded(dt_lib_module_t *module) { if(!module->expandable()) return true; if(!module->expander) return true; if(!module->widget) { char var[1024]; snprintf(var, sizeof(var), "plugins/lighttable/%s/expanded", module->plugin_name); return dt_conf_get_bool(var); } return dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander)); }
gboolean dt_lib_gui_get_expanded(dt_lib_module_t *module) { if(!module->expandable(module)) return true; if(!module->expander) return true; if(!module->widget) { char var[1024]; const dt_view_t *current_view = dt_view_manager_get_current_view(darktable.view_manager); snprintf(var, sizeof(var), "plugins/%s/%s/expanded", current_view->module_name, module->plugin_name); return dt_conf_get_bool(var); } return dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander)); }
void dt_lib_set_visible(dt_lib_module_t *module, gboolean visible) { char key[512]; g_snprintf(key, sizeof(key), "plugins/lighttable/%s/visible", module->plugin_name); dt_conf_set_bool(key, visible); if(module->widget) { if(module->expander) { dtgtk_expander_set_expanded(DTGTK_EXPANDER(module->expander), visible); } else { if(visible) gtk_widget_show_all(GTK_WIDGET(module->widget)); else gtk_widget_hide(GTK_WIDGET(module->widget)); } } }
GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) { /* check if module is expandable */ if(!module->expandable(module)) { module->expander = NULL; return NULL; } int bs = DT_PIXEL_APPLY_DPI(12); GtkWidget *header = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); GtkWidget *expander = dtgtk_expander_new(header, module->widget); GtkWidget *header_evb = dtgtk_expander_get_header_event_box(DTGTK_EXPANDER(expander)); GtkWidget *pluginui_frame = dtgtk_expander_get_frame(DTGTK_EXPANDER(expander)); /* setup the header box */ g_signal_connect(G_OBJECT(header_evb), "button-press-event", G_CALLBACK(_lib_plugin_header_button_press), module); /* setup plugin content frame */ gtk_frame_set_shadow_type(GTK_FRAME(pluginui_frame), GTK_SHADOW_IN); /* * initialize the header widgets */ int idx = 0; GtkWidget *hw[5] = { NULL, NULL, NULL, NULL, NULL }; /* add the expand indicator icon */ hw[idx] = dtgtk_icon_new(dtgtk_cairo_paint_solid_arrow, CPF_DIRECTION_LEFT); gtk_widget_set_size_request(GTK_WIDGET(hw[idx++]), bs, bs); /* add module label */ char label[128]; g_snprintf(label, sizeof(label), "<span size=\"larger\">%s</span>", module->name(module)); hw[idx] = gtk_label_new(""); gtk_widget_set_name(hw[idx], "panel_label"); gtk_label_set_markup(GTK_LABEL(hw[idx]), label); gtk_widget_set_tooltip_text(hw[idx], module->name(module)); gtk_label_set_ellipsize(GTK_LABEL(hw[idx++]), PANGO_ELLIPSIZE_MIDDLE); /* add reset button if module has implementation */ if(module->gui_reset) { hw[idx] = dtgtk_button_new(dtgtk_cairo_paint_reset, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); module->reset_button = GTK_WIDGET(hw[idx]); gtk_widget_set_tooltip_text(hw[idx], _("reset parameters")); g_signal_connect(G_OBJECT(hw[idx]), "clicked", G_CALLBACK(dt_lib_gui_reset_callback), module); } else hw[idx] = gtk_fixed_new(); gtk_widget_set_size_request(GTK_WIDGET(hw[idx++]), bs, bs); /* add preset button if module has implementation */ if(module->get_params) { hw[idx] = dtgtk_button_new(dtgtk_cairo_paint_presets, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); module->presets_button = GTK_WIDGET(hw[idx]); gtk_widget_set_tooltip_text(hw[idx], _("presets")); g_signal_connect(G_OBJECT(hw[idx]), "clicked", G_CALLBACK(popup_callback), module); } else hw[idx] = gtk_fixed_new(); gtk_widget_set_size_request(GTK_WIDGET(hw[idx++]), bs, bs); /* add a spacer to align buttons with iop buttons (enabled button) */ hw[idx] = gtk_fixed_new(); gtk_widget_set_size_request(GTK_WIDGET(hw[idx++]), bs, bs); /* lets order header elements depending on left/right side panel placement */ int c = module->container(module); if((c == DT_UI_CONTAINER_PANEL_LEFT_TOP) || (c == DT_UI_CONTAINER_PANEL_LEFT_CENTER) || (c == DT_UI_CONTAINER_PANEL_LEFT_BOTTOM)) { for(int i = 0; i <= 4; i++) if(hw[i]) gtk_box_pack_start(GTK_BOX(header), hw[i], i == 1 ? TRUE : FALSE, i == 1 ? TRUE : FALSE, 2); gtk_widget_set_halign(hw[1], GTK_ALIGN_START); dtgtk_icon_set_paint(hw[0], dtgtk_cairo_paint_solid_arrow, CPF_DIRECTION_RIGHT); } else { for(int i = 4; i >= 0; i--) if(hw[i]) gtk_box_pack_start(GTK_BOX(header), hw[i], i == 1 ? TRUE : FALSE, i == 1 ? TRUE : FALSE, 2); gtk_widget_set_halign(hw[1], GTK_ALIGN_END); dtgtk_icon_set_paint(hw[0], dtgtk_cairo_paint_solid_arrow, CPF_DIRECTION_LEFT); } /* add empty space around widget */ gtk_widget_set_margin_start(module->widget, DT_PIXEL_APPLY_DPI(8)); gtk_widget_set_margin_end(module->widget, DT_PIXEL_APPLY_DPI(8)); gtk_widget_set_margin_top(module->widget, DT_PIXEL_APPLY_DPI(8)); gtk_widget_set_margin_bottom(module->widget, DT_PIXEL_APPLY_DPI(8)); gtk_widget_show_all(module->widget); gtk_widget_set_name(pluginui_frame, "lib-plugin-ui"); module->expander = expander; gtk_widget_set_hexpand(module->widget, FALSE); gtk_widget_set_vexpand(module->widget, FALSE); return module->expander; }