diff --git a/app/dialogs/extensions-dialog.c b/app/dialogs/extensions-dialog.c index 8a5061a26c..cf25e32a31 100644 --- a/app/dialogs/extensions-dialog.c +++ b/app/dialogs/extensions-dialog.c @@ -32,6 +32,7 @@ #include "core/gimpextensionmanager.h" #include "core/gimpextension.h" +#include "widgets/gimpextensiondetails.h" #include "widgets/gimpextensionlist.h" #include "widgets/gimphelp-ids.h" #include "widgets/gimpprefsbox.h" @@ -52,6 +53,11 @@ static void extensions_dialog_search_icon_pressed (GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data); +static void extensions_dialog_extension_activated (GimpExtensionList *list, + GimpExtension *extension, + GtkStack *stack); +static void extensions_dialog_back_button_clicked (GtkButton *button, + GtkStack *stack); /* public function */ @@ -60,7 +66,7 @@ extensions_dialog_new (Gimp *gimp) { GtkWidget *dialog; GtkWidget *stack; - GtkWidget *prefs_box; + GtkWidget *stacked; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *list; @@ -78,20 +84,21 @@ extensions_dialog_new (Gimp *gimp) dialog); stack = gtk_stack_new (); + gtk_stack_set_transition_type (GTK_STACK (stack), + GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), stack, TRUE, TRUE, 0); gtk_widget_show (stack); /* The extension lists. */ - prefs_box = gimp_prefs_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (prefs_box), 12); - gtk_stack_add_named (GTK_STACK (stack), prefs_box, - GIMP_EXTENSION_LIST_STACK_CHILD); - gtk_stack_set_visible_child_name (GTK_STACK (stack), - GIMP_EXTENSION_LIST_STACK_CHILD); - gtk_widget_show (prefs_box); - vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + stacked = gimp_prefs_box_new (); + gtk_container_set_border_width (GTK_CONTAINER (stacked), 12); + gtk_stack_add_named (GTK_STACK (stack), stacked, + GIMP_EXTENSION_LIST_STACK_CHILD); + gtk_widget_show (stacked); + + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (stacked), "system-software-install", /*"gimp-extensions-installed",*/ _("Installed Extensions"), @@ -101,11 +108,14 @@ extensions_dialog_new (Gimp *gimp) &top_iter); list = gimp_extension_list_new (gimp->extension_manager); + g_signal_connect (list, "extension-activated", + G_CALLBACK (extensions_dialog_extension_activated), + stack); gimp_extension_list_show_user (GIMP_EXTENSION_LIST (list)); gtk_box_pack_start (GTK_BOX (vbox), list, TRUE, TRUE, 1); gtk_widget_show (list); - vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (stacked), "system-software-install", _("System Extensions"), _("System Extensions"), @@ -114,11 +124,14 @@ extensions_dialog_new (Gimp *gimp) &top_iter); list = gimp_extension_list_new (gimp->extension_manager); + g_signal_connect (list, "extension-activated", + G_CALLBACK (extensions_dialog_extension_activated), + stack); gimp_extension_list_show_system (GIMP_EXTENSION_LIST (list)); gtk_box_pack_start (GTK_BOX (vbox), list, TRUE, TRUE, 1); gtk_widget_show (list); - vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (stacked), "system-software-install", _("Install Extensions"), _("Install Extensions"), @@ -127,6 +140,9 @@ extensions_dialog_new (Gimp *gimp) &top_iter); list = gimp_extension_list_new (gimp->extension_manager); + g_signal_connect (list, "extension-activated", + G_CALLBACK (extensions_dialog_extension_activated), + stack); gimp_extension_list_show_search (GIMP_EXTENSION_LIST (list), NULL); gtk_box_pack_end (GTK_BOX (vbox), list, TRUE, TRUE, 1); gtk_widget_show (list); @@ -164,13 +180,16 @@ extensions_dialog_new (Gimp *gimp) /* The extension details. */ - /*TODO: add a widget to show extension details when activating a row. - */ + stacked = gimp_extension_details_new (); + gtk_stack_add_named (GTK_STACK (stack), stacked, + GIMP_EXTENSION_DETAILS_STACK_CHILD); + gtk_widget_show (stacked); + gtk_stack_set_visible_child_name (GTK_STACK (stack), + GIMP_EXTENSION_LIST_STACK_CHILD); return dialog; } - static void extensions_dialog_response (GtkWidget *widget, gint response_id, @@ -196,3 +215,39 @@ extensions_dialog_search_icon_pressed (GtkEntry *entry, { extensions_dialog_search_activate (entry, user_data); } + +static void +extensions_dialog_extension_activated (GimpExtensionList *list, + GimpExtension *extension, + GtkStack *stack) +{ + GtkWidget *dialog = gtk_widget_get_toplevel (GTK_WIDGET (stack)); + GtkWidget *header_bar; + GtkWidget *widget; + + /* Add a back button to the header bar. */ + header_bar = gtk_window_get_titlebar (GTK_WINDOW (dialog)); + widget = gtk_button_new_from_icon_name ("go-previous", GTK_ICON_SIZE_SMALL_TOOLBAR); + g_signal_connect (widget, "clicked", + G_CALLBACK (extensions_dialog_back_button_clicked), + stack); + gtk_widget_show (widget); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), widget); + + /* Show the details of the extension. */ + widget = gtk_stack_get_child_by_name (stack, GIMP_EXTENSION_DETAILS_STACK_CHILD); + gimp_extension_details_set (GIMP_EXTENSION_DETAILS (widget), + extension); + + gtk_stack_set_visible_child_name (stack, + GIMP_EXTENSION_DETAILS_STACK_CHILD); +} + +static void +extensions_dialog_back_button_clicked (GtkButton *button, + GtkStack *stack) +{ + gtk_stack_set_visible_child_name (stack, + GIMP_EXTENSION_LIST_STACK_CHILD); + gtk_widget_destroy (GTK_WIDGET (button)); +} diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index 8c85fbd81c..999d70156e 100644 --- a/app/widgets/Makefile.am +++ b/app/widgets/Makefile.am @@ -199,6 +199,8 @@ libappwidgets_a_sources = \ gimperrordialog.h \ gimpexportdialog.c \ gimpexportdialog.h \ + gimpextensiondetails.c \ + gimpextensiondetails.h \ gimpextensionlist.c \ gimpextensionlist.h \ gimpfgbgeditor.c \ diff --git a/app/widgets/gimpextensiondetails.c b/app/widgets/gimpextensiondetails.c new file mode 100644 index 0000000000..6c2bebe04b --- /dev/null +++ b/app/widgets/gimpextensiondetails.c @@ -0,0 +1,84 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpextensiondetails.c + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimpextension.h" +#include "core/gimpextensionmanager.h" + +#include "gimpextensiondetails.h" + +#include "gimp-intl.h" + +struct _GimpExtensionDetailsPrivate +{ + GimpExtension *extension; +}; + +G_DEFINE_TYPE (GimpExtensionDetails, gimp_extension_details, GTK_TYPE_FRAME) + +#define parent_class gimp_extension_details_parent_class + + +static void +gimp_extension_details_class_init (GimpExtensionDetailsClass *klass) +{ + g_type_class_add_private (klass, sizeof (GimpExtensionDetailsPrivate)); +} + +static void +gimp_extension_details_init (GimpExtensionDetails *details) +{ + gtk_frame_set_label_align (GTK_FRAME (details), 0.5, 1.0); + details->p = G_TYPE_INSTANCE_GET_PRIVATE (details, + GIMP_TYPE_EXTENSION_DETAILS, + GimpExtensionDetailsPrivate); +} + +GtkWidget * +gimp_extension_details_new (void) +{ + return g_object_new (GIMP_TYPE_EXTENSION_DETAILS, NULL); +} + +void +gimp_extension_details_set (GimpExtensionDetails *details, + GimpExtension *extension) +{ + g_return_if_fail (GIMP_IS_EXTENSION (extension)); + + if (details->p->extension) + g_object_unref (details->p->extension); + details->p->extension = g_object_ref (extension); + + gtk_container_foreach (GTK_CONTAINER (details), + (GtkCallback) gtk_widget_destroy, + NULL); + + gtk_frame_set_label (GTK_FRAME (details), + extension ? gimp_extension_get_name (extension) : NULL); +} diff --git a/app/widgets/gimpextensiondetails.h b/app/widgets/gimpextensiondetails.h new file mode 100644 index 0000000000..6ccf61728c --- /dev/null +++ b/app/widgets/gimpextensiondetails.h @@ -0,0 +1,57 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpextensiondetails.h + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_EXTENSION_DETAILS_H__ +#define __GIMP_EXTENSION_DETAILS_H__ + + +#define GIMP_TYPE_EXTENSION_DETAILS (gimp_extension_details_get_type ()) +#define GIMP_EXTENSION_DETAILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_EXTENSION_DETAILS, GimpExtensionDetails)) +#define GIMP_EXTENSION_DETAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_EXTENSION_DETAILS, GimpExtensionDetailsClass)) +#define GIMP_IS_EXTENSION_DETAILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_EXTENSION_DETAILS)) +#define GIMP_IS_EXTENSION_DETAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_EXTENSION_DETAILS)) +#define GIMP_EXTENSION_DETAILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_EXTENSION_DETAILS, GimpExtensionDetailsClass)) + + +typedef struct _GimpExtensionDetailsClass GimpExtensionDetailsClass; +typedef struct _GimpExtensionDetailsPrivate GimpExtensionDetailsPrivate; + +struct _GimpExtensionDetails +{ + GtkFrame parent_instance; + + GimpExtensionDetailsPrivate *p; +}; + +struct _GimpExtensionDetailsClass +{ + GtkFrameClass parent_class; +}; + + +GType gimp_extension_details_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_extension_details_new (void); + +void gimp_extension_details_set (GimpExtensionDetails *details, + GimpExtension *extension); + +#endif /* __GIMP_EXTENSION_DETAILS_H__ */ + diff --git a/app/widgets/gimpextensionlist.c b/app/widgets/gimpextensionlist.c index 040e1601df..65f6d4c853 100644 --- a/app/widgets/gimpextensionlist.c +++ b/app/widgets/gimpextensionlist.c @@ -29,28 +29,49 @@ #include "core/gimpextension.h" #include "core/gimpextensionmanager.h" +#include "core/gimpmarshal.h" #include "gimpextensionlist.h" #include "gimp-intl.h" +enum +{ + EXTENSION_ACTIVATED, + LAST_SIGNAL +}; + struct _GimpExtensionListPrivate { GimpExtensionManager *manager; }; -static void gimp_extension_list_set (GimpExtensionList *list, - const GList *extensions, - gboolean is_system); +static void gimp_extension_list_set (GimpExtensionList *list, + const GList *extensions, + gboolean is_system); +static void gimp_extension_row_activated (GtkListBox *box, + GtkListBoxRow *row, + gpointer user_data); G_DEFINE_TYPE (GimpExtensionList, gimp_extension_list, GTK_TYPE_LIST_BOX) #define parent_class gimp_extension_list_parent_class +static guint signals[LAST_SIGNAL] = { 0, }; static void gimp_extension_list_class_init (GimpExtensionListClass *klass) { + signals[EXTENSION_ACTIVATED] = + g_signal_new ("extension-activated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpExtensionListClass, extension_activated), + NULL, NULL, + gimp_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GIMP_TYPE_OBJECT); + g_type_class_add_private (klass, sizeof (GimpExtensionListPrivate)); } @@ -59,6 +80,8 @@ gimp_extension_list_init (GimpExtensionList *list) { gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_SINGLE); + gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (list), + FALSE); list->p = G_TYPE_INSTANCE_GET_PRIVATE (list, GIMP_TYPE_EXTENSION_LIST, GimpExtensionListPrivate); @@ -121,6 +144,8 @@ gimp_extension_list_set (GimpExtensionList *list, frame = gtk_frame_new (gimp_extension_get_name (extension)); gtk_container_add (GTK_CONTAINER (list), frame); + g_object_set_data (G_OBJECT (gtk_widget_get_parent (frame)), + "extension", extension); gtk_widget_show (frame); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); @@ -150,4 +175,19 @@ gimp_extension_list_set (GimpExtensionList *list, gtk_box_pack_end (GTK_BOX (hbox), onoff, FALSE, FALSE, 1); gtk_widget_show (onoff); } + gtk_container_foreach (GTK_CONTAINER (list), + (GtkCallback) gtk_list_box_row_set_activatable, + GUINT_TO_POINTER (TRUE)); + g_signal_connect (list, "row-activated", + G_CALLBACK (gimp_extension_row_activated), NULL); +} + +static void +gimp_extension_row_activated (GtkListBox *box, + GtkListBoxRow *row, + gpointer user_data) +{ + g_signal_emit (box, signals[EXTENSION_ACTIVATED], 0, + g_object_get_data (G_OBJECT (row), + "extension")); } diff --git a/app/widgets/gimpextensionlist.h b/app/widgets/gimpextensionlist.h index 02fe265197..418409df73 100644 --- a/app/widgets/gimpextensionlist.h +++ b/app/widgets/gimpextensionlist.h @@ -43,6 +43,9 @@ struct _GimpExtensionList struct _GimpExtensionListClass { GtkListBoxClass parent_class; + + void (* extension_activated) (GimpExtensionList *list, + GimpExtension *extension); }; diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index a07803c219..572bf5fe05 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -185,6 +185,7 @@ typedef struct _GimpDeviceEditor GimpDeviceEditor; typedef struct _GimpDeviceInfoEditor GimpDeviceInfoEditor; typedef struct _GimpDial GimpDial; typedef struct _GimpDynamicsOutputEditor GimpDynamicsOutputEditor; +typedef struct _GimpExtensionDetails GimpExtensionDetails; typedef struct _GimpExtensionList GimpExtensionList; typedef struct _GimpFgBgEditor GimpFgBgEditor; typedef struct _GimpFgBgView GimpFgBgView;