app: new GimpExtensionDetails widget.

The extension dialog will show details about an extension (long
description, screenshot, upstream URLs, etc.) with this widget.

Update the GimpExtensionList to send a "extension-activated" signal on
double click, and make the extensions dialog react on it to display the
extension details for the activated extension.

This is all still mostly a skeleton GUI, but it is starting to get into
shape.
This commit is contained in:
Jehan 2018-07-07 16:04:10 +02:00
parent 869f345ff0
commit 22099db280
7 changed files with 259 additions and 17 deletions

View File

@ -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));
}

View File

@ -199,6 +199,8 @@ libappwidgets_a_sources = \
gimperrordialog.h \
gimpexportdialog.c \
gimpexportdialog.h \
gimpextensiondetails.c \
gimpextensiondetails.h \
gimpextensionlist.c \
gimpextensionlist.h \
gimpfgbgeditor.c \

View File

@ -0,0 +1,84 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpextensiondetails.c
* Copyright (C) 2018 Jehan <jehan@gimp.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#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);
}

View File

@ -0,0 +1,57 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpextensiondetails.h
* Copyright (C) 2018 Jehan <jehan@gimp.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@ -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"));
}

View File

@ -43,6 +43,9 @@ struct _GimpExtensionList
struct _GimpExtensionListClass
{
GtkListBoxClass parent_class;
void (* extension_activated) (GimpExtensionList *list,
GimpExtension *extension);
};

View File

@ -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;