widgets, pdb, libgimp: GimpProcedureDialog Item Widget
This patch adds a GimpItemChooser widget for use in GimpProcedureDialog Item parameter GUI creation. This will deprecate the existing GimpDrawableChooser, as it covers all the same cases plus others such as GimpPath.
This commit is contained in:
parent
bb9c3a85dc
commit
37a0e37d25
23 changed files with 2122 additions and 5 deletions
|
|
@ -419,6 +419,7 @@ gimp_pdb_dialog_new (Gimp *gimp,
|
|||
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
|
||||
g_return_val_if_fail (g_type_is_a (contents_type, GIMP_TYPE_RESOURCE) ||
|
||||
g_type_is_a (contents_type, GIMP_TYPE_DRAWABLE) ||
|
||||
g_type_is_a (contents_type, GIMP_TYPE_ITEM) ||
|
||||
g_type_is_a (contents_type, GIMP_TYPE_IMAGE), FALSE);
|
||||
g_return_val_if_fail (object == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (object), contents_type), FALSE);
|
||||
|
|
@ -453,6 +454,7 @@ gimp_pdb_dialog_set (Gimp *gimp,
|
|||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
|
||||
g_return_val_if_fail (g_type_is_a (contents_type, GIMP_TYPE_RESOURCE) ||
|
||||
contents_type == GIMP_TYPE_DRAWABLE ||
|
||||
contents_type == GIMP_TYPE_ITEM ||
|
||||
contents_type == GIMP_TYPE_IMAGE, FALSE);
|
||||
g_return_val_if_fail (callback_name != NULL, FALSE);
|
||||
g_return_val_if_fail (object == NULL || g_type_is_a (G_TYPE_FROM_INSTANCE (object), contents_type), FALSE);
|
||||
|
|
@ -480,6 +482,7 @@ gimp_pdb_dialog_close (Gimp *gimp,
|
|||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
|
||||
g_return_val_if_fail (g_type_is_a (contents_type, GIMP_TYPE_RESOURCE) ||
|
||||
contents_type == GIMP_TYPE_DRAWABLE ||
|
||||
contents_type == GIMP_TYPE_ITEM ||
|
||||
contents_type == GIMP_TYPE_IMAGE, FALSE);
|
||||
g_return_val_if_fail (callback_name != NULL, FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#include "widgets/gimphelp-ids.h"
|
||||
#include "widgets/gimpimageselect.h"
|
||||
#include "widgets/gimpimageview.h"
|
||||
#include "widgets/gimpitemselect.h"
|
||||
#include "widgets/gimpmenufactory.h"
|
||||
#include "widgets/gimppaletteselect.h"
|
||||
#include "widgets/gimppatternselect.h"
|
||||
|
|
@ -668,6 +669,11 @@ gui_pdb_dialog_new (Gimp *gimp,
|
|||
dialog_type = GIMP_TYPE_PICKABLE_SELECT;
|
||||
dialog_role = "gimp-pickable-selection";
|
||||
}
|
||||
else if (g_type_is_a (contents_type, GIMP_TYPE_ITEM))
|
||||
{
|
||||
dialog_type = GIMP_TYPE_ITEM_SELECT;
|
||||
dialog_role = "gimp-item-selection";
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
|
@ -675,10 +681,10 @@ gui_pdb_dialog_new (Gimp *gimp,
|
|||
|
||||
if (dialog_type != G_TYPE_NONE)
|
||||
{
|
||||
if (! object && ! g_type_is_a (contents_type, GIMP_TYPE_DRAWABLE))
|
||||
if (! object && ! g_type_is_a (contents_type, GIMP_TYPE_ITEM))
|
||||
object = gimp_context_get_by_type (context, contents_type);
|
||||
|
||||
if (object || g_type_is_a (contents_type, GIMP_TYPE_DRAWABLE))
|
||||
if (object || g_type_is_a (contents_type, GIMP_TYPE_ITEM))
|
||||
{
|
||||
gint n_properties = 0;
|
||||
gchar **names = NULL;
|
||||
|
|
@ -794,6 +800,10 @@ gui_pdb_dialog_set (Gimp *gimp,
|
|||
{
|
||||
klass = g_type_class_peek (GIMP_TYPE_PICKABLE_SELECT);
|
||||
}
|
||||
else if (contents_type == GIMP_TYPE_ITEM)
|
||||
{
|
||||
klass = g_type_class_peek (GIMP_TYPE_ITEM_SELECT);
|
||||
}
|
||||
|
||||
g_return_val_if_fail (klass != NULL, FALSE);
|
||||
|
||||
|
|
@ -848,6 +858,8 @@ gui_pdb_dialog_close (Gimp *gimp,
|
|||
klass = g_type_class_peek (GIMP_TYPE_PATTERN_SELECT);
|
||||
else if (contents_type == GIMP_TYPE_DRAWABLE)
|
||||
klass = g_type_class_peek (GIMP_TYPE_PICKABLE_SELECT);
|
||||
else if (contents_type == GIMP_TYPE_ITEM)
|
||||
klass = g_type_class_peek (GIMP_TYPE_ITEM_SELECT);
|
||||
|
||||
if (klass)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "internal-procs.h"
|
||||
|
||||
|
||||
/* 782 procedures registered total */
|
||||
/* 785 procedures registered total */
|
||||
|
||||
void
|
||||
internal_procs_init (GimpPDB *pdb)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include "pdb-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpdatafactory.h"
|
||||
#include "core/gimpgrouplayer.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpitem.h"
|
||||
|
|
@ -1113,6 +1115,95 @@ item_get_parasite_list_invoker (GimpProcedure *procedure,
|
|||
return return_vals;
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
items_popup_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
const gchar *popup_title;
|
||||
const gchar *item_type;
|
||||
GimpItem *initial_item;
|
||||
GBytes *parent_window;
|
||||
|
||||
callback = g_value_get_string (gimp_value_array_index (args, 0));
|
||||
popup_title = g_value_get_string (gimp_value_array_index (args, 1));
|
||||
item_type = g_value_get_string (gimp_value_array_index (args, 2));
|
||||
initial_item = g_value_get_object (gimp_value_array_index (args, 3));
|
||||
parent_window = g_value_get_boxed (gimp_value_array_index (args, 4));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_new (gimp, context, progress,
|
||||
g_type_from_name (item_type),
|
||||
parent_window, popup_title, callback,
|
||||
GIMP_OBJECT (initial_item),
|
||||
NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
items_close_popup_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
|
||||
callback = g_value_get_string (gimp_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_close (gimp, GIMP_TYPE_ITEM, callback))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
items_set_popup_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
GimpItem *item;
|
||||
|
||||
callback = g_value_get_string (gimp_value_array_index (args, 0));
|
||||
item = g_value_get_object (gimp_value_array_index (args, 1));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_set (gimp, GIMP_TYPE_ITEM, callback, GIMP_OBJECT (item), NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
void
|
||||
register_item_procs (GimpPDB *pdb)
|
||||
{
|
||||
|
|
@ -2201,4 +2292,108 @@ register_item_procs (GimpPDB *pdb)
|
|||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-items-popup
|
||||
*/
|
||||
procedure = gimp_procedure_new (items_popup_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-items-popup");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Invokes the item selection dialog.",
|
||||
"Opens a dialog letting a user choose an item .",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The callback PDB proc to call when user chooses an item",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("popup-title",
|
||||
"popup title",
|
||||
"Title of the item selection dialog",
|
||||
FALSE, FALSE, FALSE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("item-type",
|
||||
"item type",
|
||||
"The name of the GIMP_TYPE_ITEM subtype",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_item ("initial-item",
|
||||
"initial item",
|
||||
"The item to set as the initial choice",
|
||||
TRUE,
|
||||
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_boxed ("parent-window",
|
||||
"parent window",
|
||||
"An optional parent window handle for the popup to be set transient to",
|
||||
G_TYPE_BYTES,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-items-close-popup
|
||||
*/
|
||||
procedure = gimp_procedure_new (items_close_popup_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-items-close-popup");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Close the item selection dialog.",
|
||||
"Closes an open item selection dialog.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The name of the callback registered for this pop-up",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-items-set-popup
|
||||
*/
|
||||
procedure = gimp_procedure_new (items_set_popup_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-items-set-popup");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Sets the selected item in a item selection dialog.",
|
||||
"Sets the selected item in a item selection dialog.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The name of the callback registered for this pop-up",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_item ("item",
|
||||
"item",
|
||||
"The item to set as selected",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
}
|
||||
|
|
|
|||
639
app/widgets/gimpitemchooser.c
Normal file
639
app/widgets/gimpitemchooser.c
Normal file
|
|
@ -0,0 +1,639 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpitemchooser.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpchannel.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpitem.h"
|
||||
#include "core/gimplayer.h"
|
||||
#include "core/gimpviewable.h"
|
||||
|
||||
#include "path/gimppath.h"
|
||||
|
||||
#include "gimpcontainertreeview.h"
|
||||
#include "gimpcontainerview.h"
|
||||
#include "gimpitemchooser.h"
|
||||
#include "gimpviewrenderer.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ACTIVATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTEXT,
|
||||
PROP_ITEM_TYPE,
|
||||
PROP_ITEM,
|
||||
PROP_VIEW_SIZE,
|
||||
PROP_VIEW_BORDER_WIDTH
|
||||
};
|
||||
|
||||
struct _GimpItemChooserPrivate
|
||||
{
|
||||
GType item_type;
|
||||
GimpItem *item;
|
||||
GimpContext *context;
|
||||
|
||||
gint view_size;
|
||||
gint view_border_width;
|
||||
|
||||
GtkWidget *image_view;
|
||||
GtkWidget *layer_view;
|
||||
GtkWidget *channel_view;
|
||||
GtkWidget *path_view;
|
||||
GtkWidget *layer_label;
|
||||
};
|
||||
|
||||
|
||||
static void gimp_item_chooser_constructed (GObject *object);
|
||||
static void gimp_item_chooser_finalize (GObject *object);
|
||||
static void gimp_item_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_item_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gimp_item_chooser_image_changed (GimpContext *context,
|
||||
GimpImage *image,
|
||||
GimpItemChooser *chooser);
|
||||
static void gimp_item_chooser_item_activated (GimpContainerView *view,
|
||||
GimpItem *item,
|
||||
GimpItemChooser *chooser);
|
||||
static void gimp_item_chooser_items_selected (GimpContainerView *view,
|
||||
GimpItemChooser *chooser);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpItemChooser, gimp_item_chooser, GTK_TYPE_FRAME)
|
||||
|
||||
#define parent_class gimp_item_chooser_parent_class
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void
|
||||
gimp_item_chooser_class_init (GimpItemChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_item_chooser_constructed;
|
||||
object_class->finalize = gimp_item_chooser_finalize;
|
||||
object_class->get_property = gimp_item_chooser_get_property;
|
||||
object_class->set_property = gimp_item_chooser_set_property;
|
||||
|
||||
/**
|
||||
* GimpItemChooser::activate:
|
||||
* @chooser:
|
||||
*
|
||||
* Emitted when a item is activated, which is mostly forwarding when
|
||||
* "item-activated" signal is emitted from any of either the image, layer or
|
||||
* channel view. E.g. this happens when one double-click on one of the
|
||||
* items.
|
||||
*/
|
||||
signals[ACTIVATE] =
|
||||
g_signal_new ("activate",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpItemChooserClass, activate),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GIMP_TYPE_OBJECT);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_CONTEXT,
|
||||
g_param_spec_object ("context",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_CONTEXT,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ITEM_TYPE,
|
||||
g_param_spec_gtype ("item-type",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_ITEM,
|
||||
GIMP_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ITEM,
|
||||
g_param_spec_object ("item",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_ITEM,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_VIEW_SIZE,
|
||||
g_param_spec_int ("view-size",
|
||||
NULL, NULL,
|
||||
1, GIMP_VIEWABLE_MAX_PREVIEW_SIZE,
|
||||
GIMP_VIEW_SIZE_MEDIUM,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_VIEW_BORDER_WIDTH,
|
||||
g_param_spec_int ("view-border-width",
|
||||
NULL, NULL,
|
||||
0,
|
||||
GIMP_VIEW_MAX_BORDER_WIDTH,
|
||||
1,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_init (GimpItemChooser *chooser)
|
||||
{
|
||||
chooser->priv = gimp_item_chooser_get_instance_private (chooser);
|
||||
|
||||
chooser->priv->view_size = GIMP_VIEW_SIZE_SMALL;
|
||||
chooser->priv->view_border_width = 1;
|
||||
|
||||
chooser->priv->layer_view = NULL;
|
||||
chooser->priv->channel_view = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_constructed (GObject *object)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *notebook;
|
||||
GimpImage *image;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
gimp_assert (GIMP_IS_CONTEXT (chooser->priv->context));
|
||||
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (chooser), GTK_SHADOW_OUT);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
|
||||
gtk_container_add (GTK_CONTAINER (chooser), hbox);
|
||||
gtk_widget_set_visible (hbox, TRUE);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
|
||||
gtk_widget_set_visible (vbox, TRUE);
|
||||
|
||||
label = gtk_label_new (_("Images"));
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
|
||||
chooser->priv->image_view =
|
||||
gimp_container_tree_view_new (chooser->priv->context->gimp->images,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (chooser->priv->image_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), chooser->priv->image_view, TRUE, TRUE, 0);
|
||||
gtk_widget_set_visible (chooser->priv->image_view, TRUE);
|
||||
|
||||
g_signal_connect_object (chooser->priv->image_view, "item-activated",
|
||||
G_CALLBACK (gimp_item_chooser_item_activated),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->image_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
|
||||
gtk_widget_set_visible (vbox, TRUE);
|
||||
|
||||
chooser->priv->layer_label = label =
|
||||
gtk_label_new (_("Select an image in the left pane"));
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
|
||||
notebook = gtk_notebook_new ();
|
||||
gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
|
||||
gtk_widget_set_visible (notebook, TRUE);
|
||||
|
||||
if (g_type_is_a (GIMP_TYPE_LAYER, chooser->priv->item_type))
|
||||
{
|
||||
chooser->priv->layer_view =
|
||||
gimp_container_tree_view_new (NULL,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (GIMP_CONTAINER_TREE_VIEW (chooser->priv->layer_view)->view),
|
||||
TRUE);
|
||||
gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (chooser->priv->layer_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
chooser->priv->layer_view,
|
||||
gtk_label_new (_("Layers")));
|
||||
gtk_widget_set_visible (chooser->priv->layer_view, TRUE);
|
||||
|
||||
g_signal_connect_object (chooser->priv->layer_view, "item-activated",
|
||||
G_CALLBACK (gimp_item_chooser_item_activated),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->layer_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
if (g_type_is_a (GIMP_TYPE_CHANNEL, chooser->priv->item_type))
|
||||
{
|
||||
chooser->priv->channel_view =
|
||||
gimp_container_tree_view_new (NULL,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (chooser->priv->channel_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
chooser->priv->channel_view,
|
||||
gtk_label_new (_("Channels")));
|
||||
gtk_widget_set_visible (chooser->priv->channel_view, TRUE);
|
||||
|
||||
g_signal_connect_object (chooser->priv->channel_view, "item-activated",
|
||||
G_CALLBACK (gimp_item_chooser_item_activated),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->channel_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
if (g_type_is_a (GIMP_TYPE_PATH, chooser->priv->item_type))
|
||||
{
|
||||
chooser->priv->path_view =
|
||||
gimp_container_tree_view_new (NULL,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
gimp_container_box_set_size_request (GIMP_CONTAINER_BOX (chooser->priv->path_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
chooser->priv->path_view,
|
||||
gtk_label_new (_("Paths")));
|
||||
gtk_widget_set_visible (chooser->priv->path_view, TRUE);
|
||||
|
||||
g_signal_connect_object (chooser->priv->path_view, "item-activated",
|
||||
G_CALLBACK (gimp_item_chooser_item_activated),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->path_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
g_signal_connect_object (chooser->priv->context, "image-changed",
|
||||
G_CALLBACK (gimp_item_chooser_image_changed),
|
||||
G_OBJECT (chooser), 0);
|
||||
|
||||
image = gimp_context_get_image (chooser->priv->context);
|
||||
gimp_item_chooser_image_changed (chooser->priv->context, image, chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_finalize (GObject *object)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
g_clear_object (&chooser->priv->item);
|
||||
g_clear_object (&chooser->priv->context);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
chooser->priv->context = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_SIZE:
|
||||
chooser->priv->view_size = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_BORDER_WIDTH:
|
||||
chooser->priv->view_border_width = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
g_return_if_fail (g_value_get_gtype (value) == GIMP_TYPE_LAYER ||
|
||||
g_value_get_gtype (value) == GIMP_TYPE_CHANNEL ||
|
||||
g_value_get_gtype (value) == GIMP_TYPE_DRAWABLE ||
|
||||
g_value_get_gtype (value) == GIMP_TYPE_PATH ||
|
||||
g_value_get_gtype (value) == GIMP_TYPE_IMAGE ||
|
||||
g_value_get_gtype (value) == GIMP_TYPE_ITEM);
|
||||
chooser->priv->item_type = g_value_get_gtype (value);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_return_if_fail (g_value_get_object (value) == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (g_value_get_object (value)),
|
||||
chooser->priv->item_type));
|
||||
gimp_item_chooser_set_item (chooser, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, chooser->priv->context);
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
g_value_set_gtype (value, chooser->priv->item_type);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, chooser->priv->item);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_SIZE:
|
||||
g_value_set_int (value, chooser->priv->view_size);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_BORDER_WIDTH:
|
||||
g_value_set_int (value, chooser->priv->view_border_width);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gimp_item_chooser_new (GimpContext *context,
|
||||
GType item_type,
|
||||
gint view_size,
|
||||
gint view_border_width)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (view_size > 0 &&
|
||||
view_size <= GIMP_VIEWABLE_MAX_POPUP_SIZE, NULL);
|
||||
g_return_val_if_fail (view_border_width >= 0 &&
|
||||
view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH,
|
||||
NULL);
|
||||
|
||||
return g_object_new (GIMP_TYPE_ITEM_CHOOSER,
|
||||
"context", context,
|
||||
"item-type", item_type,
|
||||
"view-size", view_size,
|
||||
"view-border-width", view_border_width,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GimpItem *
|
||||
gimp_item_chooser_get_item (GimpItemChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_ITEM_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->priv->item;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_item_chooser_set_item (GimpItemChooser *chooser,
|
||||
GimpItem *item)
|
||||
{
|
||||
if (! gtk_widget_in_destruction (GTK_WIDGET (chooser)))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->image_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->layer_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
else
|
||||
g_return_if_fail (! GIMP_IS_LAYER (item));
|
||||
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->channel_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
else
|
||||
g_return_if_fail (! GIMP_IS_CHANNEL (item));
|
||||
|
||||
if (chooser->priv->path_view != NULL)
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->path_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
else
|
||||
g_return_if_fail (! GIMP_IS_PATH (item));
|
||||
|
||||
if (GIMP_IS_IMAGE (item))
|
||||
{
|
||||
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->image_view),
|
||||
GIMP_VIEWABLE (item));
|
||||
gimp_context_set_image (chooser->priv->context, GIMP_IMAGE (item));
|
||||
}
|
||||
else if (GIMP_IS_LAYER (item))
|
||||
{
|
||||
gimp_context_set_image (chooser->priv->context, gimp_item_get_image (GIMP_ITEM (item)));
|
||||
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->layer_view),
|
||||
GIMP_VIEWABLE (item));
|
||||
}
|
||||
else if (GIMP_IS_CHANNEL (item))
|
||||
{
|
||||
gimp_context_set_image (chooser->priv->context, gimp_item_get_image (GIMP_ITEM (item)));
|
||||
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->channel_view),
|
||||
GIMP_VIEWABLE (item));
|
||||
}
|
||||
else if (GIMP_IS_PATH (item))
|
||||
{
|
||||
gimp_context_set_image (chooser->priv->context, gimp_item_get_image (GIMP_ITEM (item)));
|
||||
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->path_view),
|
||||
GIMP_VIEWABLE (item));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_if_fail (item == NULL);
|
||||
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->image_view), NULL);
|
||||
gimp_context_set_image (chooser->priv->context, NULL);
|
||||
}
|
||||
g_signal_connect_object (chooser->priv->image_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
g_signal_connect_object (chooser->priv->layer_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
g_signal_connect_object (chooser->priv->channel_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
if (chooser->priv->path_view != NULL)
|
||||
g_signal_connect_object (chooser->priv->path_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
if (item != chooser->priv->item)
|
||||
{
|
||||
g_clear_object (&chooser->priv->item);
|
||||
chooser->priv->item = (item != NULL ? g_object_ref (item) : NULL);
|
||||
g_object_notify (G_OBJECT (chooser), "item");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_item_chooser_image_changed (GimpContext *context,
|
||||
GimpImage *image,
|
||||
GimpItemChooser *chooser)
|
||||
{
|
||||
GimpContainer *layers = NULL;
|
||||
GimpContainer *channels = NULL;
|
||||
GimpContainer *paths = NULL;
|
||||
|
||||
if (image)
|
||||
{
|
||||
gchar *desc;
|
||||
|
||||
layers = gimp_image_get_layers (image);
|
||||
channels = gimp_image_get_channels (image);
|
||||
paths = gimp_image_get_paths (image);
|
||||
|
||||
desc = gimp_viewable_get_description (GIMP_VIEWABLE (image), NULL);
|
||||
gtk_label_set_text (GTK_LABEL (chooser->priv->layer_label), desc);
|
||||
g_free (desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (chooser->priv->layer_label),
|
||||
_("Select an image in the left pane"));
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->image_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->layer_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (chooser->priv->layer_view),
|
||||
layers);
|
||||
g_signal_connect_object (chooser->priv->layer_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->channel_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (chooser->priv->channel_view),
|
||||
channels);
|
||||
g_signal_connect_object (chooser->priv->channel_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
if (chooser->priv->path_view != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->path_view,
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
chooser);
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (chooser->priv->path_view),
|
||||
paths);
|
||||
g_signal_connect_object (chooser->priv->path_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
g_signal_connect_object (chooser->priv->image_view, "selection-changed",
|
||||
G_CALLBACK (gimp_item_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_item_activated (GimpContainerView *view,
|
||||
GimpItem *item,
|
||||
GimpItemChooser *chooser)
|
||||
{
|
||||
g_signal_emit (chooser, signals[ACTIVATE], 0, item);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_items_selected (GimpContainerView *view,
|
||||
GimpItemChooser *chooser)
|
||||
{
|
||||
GimpItem *item = NULL;
|
||||
gint n_items;
|
||||
GList *items;
|
||||
|
||||
n_items = gimp_container_view_get_selected (view, &items);
|
||||
|
||||
g_return_if_fail (n_items <= 1);
|
||||
|
||||
if (items)
|
||||
item = items->data;
|
||||
|
||||
gimp_item_chooser_set_item (chooser, item);
|
||||
}
|
||||
61
app/widgets/gimpitemchooser.h
Normal file
61
app/widgets/gimpitemchooser.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpitemchooser.h
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define GIMP_TYPE_ITEM_CHOOSER (gimp_item_chooser_get_type ())
|
||||
#define GIMP_ITEM_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ITEM_CHOOSER, GimpItemChooser))
|
||||
#define GIMP_ITEM_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ITEM_CHOOSER, GimpItemChooserClass))
|
||||
#define GIMP_IS_ITEM_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ITEM_CHOOSER))
|
||||
#define GIMP_IS_ITEM_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ITEM_CHOOSER))
|
||||
#define GIMP_ITEM_CHOOSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ITEM_CHOOSER, GimpItemChooserClass))
|
||||
|
||||
|
||||
typedef struct _GimpItemChooserPrivate GimpItemChooserPrivate;
|
||||
typedef struct _GimpItemChooserClass GimpItemChooserClass;
|
||||
|
||||
struct _GimpItemChooser
|
||||
{
|
||||
GtkFrame parent_instance;
|
||||
|
||||
GimpItemChooserPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GimpItemChooserClass
|
||||
{
|
||||
GtkFrameClass parent_instance;
|
||||
|
||||
/* Signals. */
|
||||
|
||||
void (* activate) (GimpItemChooser *view,
|
||||
GimpItem *item);
|
||||
};
|
||||
|
||||
|
||||
GType gimp_item_chooser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget * gimp_item_chooser_new (GimpContext *context,
|
||||
GType item_type,
|
||||
gint view_size,
|
||||
gint view_border_width);
|
||||
|
||||
GimpItem * gimp_item_chooser_get_item (GimpItemChooser *chooser);
|
||||
void gimp_item_chooser_set_item (GimpItemChooser *chooser,
|
||||
GimpItem *item);
|
||||
174
app/widgets/gimpitemselect.c
Normal file
174
app/widgets/gimpitemselect.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpitemselect.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "gegl/gimp-babl-compat.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpitem.h"
|
||||
#include "core/gimpparamspecs.h"
|
||||
#include "core/gimptempbuf.h"
|
||||
|
||||
#include "pdb/gimppdb.h"
|
||||
|
||||
#include "gimpitemchooser.h"
|
||||
#include "gimpitemselect.h"
|
||||
#include "gimpcontainerbox.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static void gimp_item_select_constructed (GObject *object);
|
||||
|
||||
static GimpValueArray * gimp_item_select_run_callback (GimpPdbDialog *dialog,
|
||||
GimpObject *object,
|
||||
gboolean closing,
|
||||
GError **error);
|
||||
static GimpObject * gimp_item_select_get_object (GimpPdbDialog *dialog);
|
||||
static void gimp_item_select_set_object (GimpPdbDialog *dialog,
|
||||
GimpObject *object);
|
||||
|
||||
static void gimp_item_select_activate (GimpItemSelect *select);
|
||||
static void gimp_item_select_notify_item (GimpItemSelect *select);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpItemSelect, gimp_item_select, GIMP_TYPE_PDB_DIALOG)
|
||||
|
||||
#define parent_class gimp_item_select_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_item_select_class_init (GimpItemSelectClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpPdbDialogClass *pdb_class = GIMP_PDB_DIALOG_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_item_select_constructed;
|
||||
|
||||
pdb_class->run_callback = gimp_item_select_run_callback;
|
||||
pdb_class->get_object = gimp_item_select_get_object;
|
||||
pdb_class->set_object = gimp_item_select_set_object;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_select_init (GimpItemSelect *select)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_select_constructed (GObject *object)
|
||||
{
|
||||
GimpPdbDialog *dialog = GIMP_PDB_DIALOG (object);
|
||||
GimpItemSelect *select = GIMP_ITEM_SELECT (object);
|
||||
GtkWidget *content_area;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
select->chooser = gimp_item_chooser_new (dialog->context, dialog->select_type,
|
||||
GIMP_VIEW_SIZE_LARGE, 1);
|
||||
gimp_item_chooser_set_item (GIMP_ITEM_CHOOSER (select->chooser),
|
||||
GIMP_ITEM (dialog->initial_object));
|
||||
g_signal_connect_swapped (select->chooser, "notify::item",
|
||||
G_CALLBACK (gimp_item_select_notify_item),
|
||||
select);
|
||||
g_signal_connect_swapped (select->chooser, "activate",
|
||||
G_CALLBACK (gimp_item_select_activate),
|
||||
select);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), select->chooser, TRUE, TRUE, 0);
|
||||
gtk_widget_set_visible (select->chooser, TRUE);
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
gimp_item_select_run_callback (GimpPdbDialog *dialog,
|
||||
GimpObject *object,
|
||||
gboolean closing,
|
||||
GError **error)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (object);
|
||||
GimpValueArray *return_vals;
|
||||
|
||||
return_vals =
|
||||
gimp_pdb_execute_procedure_by_name (dialog->pdb,
|
||||
dialog->caller_context,
|
||||
NULL, error,
|
||||
dialog->callback_name,
|
||||
GIMP_TYPE_ITEM, item,
|
||||
G_TYPE_BOOLEAN, closing,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GimpObject *
|
||||
gimp_item_select_get_object (GimpPdbDialog *dialog)
|
||||
{
|
||||
GimpItemSelect *select = GIMP_ITEM_SELECT (dialog);
|
||||
|
||||
return (GimpObject *) gimp_item_chooser_get_item (GIMP_ITEM_CHOOSER (select->chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_select_set_object (GimpPdbDialog *dialog,
|
||||
GimpObject *object)
|
||||
{
|
||||
GimpItemSelect *select = GIMP_ITEM_SELECT (dialog);
|
||||
|
||||
gimp_item_chooser_set_item (GIMP_ITEM_CHOOSER (select->chooser), GIMP_ITEM (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_select_activate (GimpItemSelect *select)
|
||||
{
|
||||
gimp_pdb_dialog_run_callback ((GimpPdbDialog **) &select, TRUE);
|
||||
gtk_widget_destroy (GTK_WIDGET (select));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_select_notify_item (GimpItemSelect *select)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (select->chooser);
|
||||
|
||||
button = gtk_dialog_get_widget_for_response (GTK_DIALOG (select),
|
||||
GTK_RESPONSE_OK);
|
||||
|
||||
/* Clicking Okay when an image but not an item has been
|
||||
* selected causes the widget to "lock up" and not reappear when you
|
||||
* click on it again. For now, we'll disable the Okay button until
|
||||
* an item is selected */
|
||||
if (GIMP_IS_IMAGE (gimp_item_chooser_get_item (chooser)))
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
else
|
||||
gtk_widget_set_sensitive (button, TRUE);
|
||||
|
||||
gimp_pdb_dialog_run_callback ((GimpPdbDialog **) &select, FALSE);
|
||||
}
|
||||
48
app/widgets/gimpitemselect.h
Normal file
48
app/widgets/gimpitemselect.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpitemselect.h
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gimppdbdialog.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_ITEM_SELECT (gimp_item_select_get_type ())
|
||||
#define GIMP_ITEM_SELECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ITEM_SELECT, GimpItemSelect))
|
||||
#define GIMP_ITEM_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ITEM_SELECT, GimpItemSelectClass))
|
||||
#define GIMP_IS_ITEM_SELECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ITEM_SELECT))
|
||||
#define GIMP_IS_ITEM_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ITEM_SELECT))
|
||||
#define GIMP_ITEM_SELECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ITEM_SELECT, GimpItemSelectClass))
|
||||
|
||||
|
||||
typedef struct _GimpItemSelectClass GimpItemSelectClass;
|
||||
|
||||
struct _GimpItemSelect
|
||||
{
|
||||
GimpPdbDialog parent_instance;
|
||||
|
||||
GtkWidget *chooser;
|
||||
};
|
||||
|
||||
struct _GimpItemSelectClass
|
||||
{
|
||||
GimpPdbDialogClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gimp_item_select_get_type (void) G_GNUC_CONST;
|
||||
|
|
@ -145,6 +145,8 @@ libappwidgets_sources = [
|
|||
'gimpimagepropview.c',
|
||||
'gimpimageselect.c',
|
||||
'gimpimageview.c',
|
||||
'gimpitemchooser.c',
|
||||
'gimpitemselect.c',
|
||||
'gimpitemtreeview.c',
|
||||
'gimpitemtreeview-search.c',
|
||||
'gimplanguagecombobox.c',
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ typedef struct _GimpBrushSelect GimpBrushSelect;
|
|||
typedef struct _GimpFontSelect GimpFontSelect;
|
||||
typedef struct _GimpGradientSelect GimpGradientSelect;
|
||||
typedef struct _GimpImageSelect GimpImageSelect;
|
||||
typedef struct _GimpItemSelect GimpItemSelect;
|
||||
typedef struct _GimpPaletteSelect GimpPaletteSelect;
|
||||
typedef struct _GimpPatternSelect GimpPatternSelect;
|
||||
typedef struct _GimpPickableSelect GimpPickableSelect;
|
||||
|
|
@ -210,6 +211,7 @@ typedef struct _GimpImageCommentEditor GimpImageCommentEditor;
|
|||
typedef struct _GimpImageParasiteView GimpImageParasiteView;
|
||||
typedef struct _GimpImageProfileView GimpImageProfileView;
|
||||
typedef struct _GimpImagePropView GimpImagePropView;
|
||||
typedef struct _GimpItemChooser GimpItemChooser;
|
||||
typedef struct _GimpLanguageComboBox GimpLanguageComboBox;
|
||||
typedef struct _GimpLanguageEntry GimpLanguageEntry;
|
||||
typedef struct _GimpLanguageStore GimpLanguageStore;
|
||||
|
|
|
|||
|
|
@ -643,6 +643,9 @@ EXPORTS
|
|||
gimp_item_transform_scale
|
||||
gimp_item_transform_shear
|
||||
gimp_item_transform_translate
|
||||
gimp_items_close_popup
|
||||
gimp_items_popup
|
||||
gimp_items_set_popup
|
||||
gimp_layer_add_alpha
|
||||
gimp_layer_add_mask
|
||||
gimp_layer_color_space_get_type
|
||||
|
|
|
|||
|
|
@ -1427,3 +1427,117 @@ gimp_item_get_parasite_list (GimpItem *item)
|
|||
|
||||
return parasites;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_items_popup:
|
||||
* @callback: The callback PDB proc to call when user chooses an item.
|
||||
* @popup_title: Title of the item selection dialog.
|
||||
* @item_type: The name of the GIMP_TYPE_ITEM subtype.
|
||||
* @initial_item: (nullable): The item to set as the initial choice.
|
||||
* @parent_window: (nullable): An optional parent window handle for the popup to be set transient to.
|
||||
*
|
||||
* Invokes the item selection dialog.
|
||||
*
|
||||
* Opens a dialog letting a user choose an item .
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
gimp_items_popup (const gchar *callback,
|
||||
const gchar *popup_title,
|
||||
const gchar *item_type,
|
||||
GimpItem *initial_item,
|
||||
GBytes *parent_window)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
G_TYPE_STRING, popup_title,
|
||||
G_TYPE_STRING, item_type,
|
||||
GIMP_TYPE_ITEM, initial_item,
|
||||
G_TYPE_BYTES, parent_window,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-items-popup",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_items_close_popup:
|
||||
* @callback: The name of the callback registered for this pop-up.
|
||||
*
|
||||
* Close the item selection dialog.
|
||||
*
|
||||
* Closes an open item selection dialog.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
gimp_items_close_popup (const gchar *callback)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-items-close-popup",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_items_set_popup:
|
||||
* @callback: The name of the callback registered for this pop-up.
|
||||
* @item: The item to set as selected.
|
||||
*
|
||||
* Sets the selected item in a item selection dialog.
|
||||
*
|
||||
* Sets the selected item in a item selection dialog.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
gimp_items_set_popup (const gchar *callback,
|
||||
GimpItem *item)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
GIMP_TYPE_ITEM, item,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-items-set-popup",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ gboolean gimp_item_detach_parasite (GimpItem *item,
|
|||
GimpParasite* gimp_item_get_parasite (GimpItem *item,
|
||||
const gchar *name);
|
||||
gchar** gimp_item_get_parasite_list (GimpItem *item);
|
||||
gboolean gimp_items_popup (const gchar *callback,
|
||||
const gchar *popup_title,
|
||||
const gchar *item_type,
|
||||
GimpItem *initial_item,
|
||||
GBytes *parent_window);
|
||||
gboolean gimp_items_close_popup (const gchar *callback);
|
||||
gboolean gimp_items_set_popup (const gchar *callback,
|
||||
GimpItem *item);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
630
libgimp/gimpitemchooser.c
Normal file
630
libgimp/gimpitemchooser.c
Normal file
|
|
@ -0,0 +1,630 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpitemchooser.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "gimp.h"
|
||||
|
||||
#include "gimpuitypes.h"
|
||||
#include "gimpitemchooser.h"
|
||||
#include "gimpuimarshal.h"
|
||||
|
||||
#include "libgimp-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: gimpitemchooser
|
||||
* @title: GimpItemChooser
|
||||
* @short_description: A widget allowing to select an item.
|
||||
*
|
||||
* The chooser contains an optional label and a button which queries the core
|
||||
* process to pop up a item selection dialog.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
|
||||
#define CELL_SIZE 40
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_LABEL,
|
||||
PROP_ITEM,
|
||||
PROP_ITEM_TYPE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
struct _GimpItemChooser
|
||||
{
|
||||
GtkBox parent_instance;
|
||||
|
||||
GType item_type;
|
||||
GimpItem *item;
|
||||
gchar *title;
|
||||
gchar *label;
|
||||
gchar *callback;
|
||||
|
||||
GBytes *thumbnail;
|
||||
GimpItem *thumbnail_item;
|
||||
gint width;
|
||||
gint height;
|
||||
gint bpp;
|
||||
|
||||
GtkWidget *label_widget;
|
||||
GtkWidget *preview_frame;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *preview_title;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_item_chooser_constructed (GObject *object);
|
||||
static void gimp_item_chooser_dispose (GObject *object);
|
||||
static void gimp_item_chooser_finalize (GObject *object);
|
||||
|
||||
static void gimp_item_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_item_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gimp_item_chooser_clicked (GimpItemChooser *chooser);
|
||||
|
||||
static GimpValueArray * gimp_temp_callback_run (GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GimpItemChooser *chooser);
|
||||
static gboolean gimp_item_select_remove_after_run (const gchar *procedure_name);
|
||||
|
||||
static void gimp_item_chooser_draw (GimpItemChooser *chooser);
|
||||
static void gimp_item_chooser_get_thumbnail (GimpItemChooser *chooser,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
|
||||
static GParamSpec *item_button_props[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_FINAL_TYPE (GimpItemChooser, gimp_item_chooser, GTK_TYPE_BOX)
|
||||
|
||||
|
||||
static void
|
||||
gimp_item_chooser_class_init (GimpItemChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_item_chooser_constructed;
|
||||
object_class->dispose = gimp_item_chooser_dispose;
|
||||
object_class->finalize = gimp_item_chooser_finalize;
|
||||
object_class->set_property = gimp_item_chooser_set_property;
|
||||
object_class->get_property = gimp_item_chooser_get_property;
|
||||
|
||||
/**
|
||||
* GimpItemChooser:title:
|
||||
*
|
||||
* The title to be used for the item selection popup dialog.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
item_button_props[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"The title to be used for the item selection popup dialog",
|
||||
"Item Selection",
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* GimpItemChooser:label:
|
||||
*
|
||||
* Label text with mnemonic.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
item_button_props[PROP_LABEL] =
|
||||
g_param_spec_string ("label",
|
||||
"Label",
|
||||
"The label to be used next to the button",
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* GimpItemChooser:item:
|
||||
*
|
||||
* The currently selected item.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
item_button_props[PROP_ITEM] =
|
||||
gimp_param_spec_item ("item",
|
||||
"Item",
|
||||
"The currently selected item",
|
||||
TRUE,
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GimpItemChooser:item-type:
|
||||
*
|
||||
* Allowed item types, which must be either GIMP_TYPE_ITEM or a
|
||||
* subtype.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
item_button_props[PROP_ITEM_TYPE] =
|
||||
g_param_spec_gtype ("item-type",
|
||||
"Allowed item Type",
|
||||
"The GType of the item property",
|
||||
GIMP_TYPE_ITEM,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
GIMP_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class,
|
||||
N_PROPS, item_button_props);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_init (GimpItemChooser *chooser)
|
||||
{
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (chooser),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_set_spacing (GTK_BOX (chooser), 6);
|
||||
|
||||
chooser->thumbnail_item = NULL;
|
||||
chooser->thumbnail = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_constructed (GObject *object)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
GtkWidget *button;
|
||||
GtkWidget *box;
|
||||
gint scale_factor;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (chooser));
|
||||
|
||||
chooser->label_widget = gtk_label_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX (chooser), chooser->label_widget, FALSE, FALSE, 0);
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (chooser->label_widget), chooser->label);
|
||||
gtk_widget_set_visible (GTK_WIDGET (chooser->label_widget), TRUE);
|
||||
|
||||
button = gtk_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (chooser), button, FALSE, FALSE, 0);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (chooser->label_widget), button);
|
||||
gtk_widget_set_visible (button, TRUE);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
||||
gtk_container_add (GTK_CONTAINER (button), box);
|
||||
gtk_widget_set_visible (box, TRUE);
|
||||
|
||||
chooser->preview_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (chooser->preview_frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (box), chooser->preview_frame, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (chooser->preview_frame, TRUE);
|
||||
|
||||
chooser->preview = gimp_preview_area_new ();
|
||||
gtk_widget_set_size_request (chooser->preview, scale_factor * CELL_SIZE, scale_factor * CELL_SIZE);
|
||||
gtk_container_add (GTK_CONTAINER (chooser->preview_frame), chooser->preview);
|
||||
gtk_widget_set_visible (chooser->preview, TRUE);
|
||||
|
||||
chooser->preview_title = gtk_label_new (_("Browse..."));
|
||||
gtk_box_pack_start (GTK_BOX (box), chooser->preview_title, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (chooser->preview_title, TRUE);
|
||||
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gimp_item_chooser_clicked),
|
||||
chooser);
|
||||
|
||||
G_OBJECT_CLASS (gimp_item_chooser_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_dispose (GObject *object)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
if (chooser->callback)
|
||||
{
|
||||
gimp_items_close_popup (chooser->callback);
|
||||
|
||||
gimp_plug_in_remove_temp_procedure (gimp_get_plug_in (),
|
||||
chooser->callback);
|
||||
g_clear_pointer (&chooser->callback, g_free);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gimp_item_chooser_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_finalize (GObject *object)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
g_clear_pointer (&chooser->title, g_free);
|
||||
g_clear_pointer (&chooser->label, g_free);
|
||||
g_clear_pointer (&chooser->thumbnail, g_bytes_unref);
|
||||
|
||||
G_OBJECT_CLASS (gimp_item_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *gvalue,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
chooser->title = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
chooser->label = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_return_if_fail (g_value_get_object (gvalue) == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (g_value_get_object (gvalue)),
|
||||
chooser->item_type));
|
||||
gimp_item_chooser_set_item (chooser, g_value_get_object (gvalue));
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
chooser->item_type = g_value_get_gtype (gvalue);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpItemChooser *chooser = GIMP_ITEM_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, chooser->title);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, chooser->label);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, chooser->item);
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
g_value_set_gtype (value, chooser->item_type);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @item_type: the acceptable subtype of choosable items.
|
||||
* @item: (nullable): Initial item.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a item which must be of
|
||||
* type @item_type. @item_type of values %G_TYPE_NONE and
|
||||
* %GIMP_TYPE_ITEM are equivalent. Otherwise it must be a subtype of
|
||||
* %GIMP_TYPE_ITEM.
|
||||
*
|
||||
* When @item is %NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A [class@GimpUi.ItemChooser.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
gimp_item_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
GType item_type,
|
||||
GimpItem *item)
|
||||
{
|
||||
GtkWidget *chooser;
|
||||
|
||||
if (item_type == G_TYPE_NONE)
|
||||
item_type = GIMP_TYPE_ITEM;
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (item_type, GIMP_TYPE_ITEM), NULL);
|
||||
g_return_val_if_fail (item == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (item), item_type),
|
||||
NULL);
|
||||
|
||||
chooser = g_object_new (GIMP_TYPE_ITEM_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"item", item,
|
||||
"item-type", item_type,
|
||||
NULL);
|
||||
|
||||
return chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_chooser_get_item:
|
||||
* @chooser: A #GimpItemChooser
|
||||
*
|
||||
* Gets the currently selected item.
|
||||
*
|
||||
* Returns: (transfer none): an internal copy of the item which must not be freed.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GimpItem *
|
||||
gimp_item_chooser_get_item (GimpItemChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_ITEM_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->item;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_chooser_set_item:
|
||||
* @chooser: A #GimpItemChooser
|
||||
* @item: Item to set.
|
||||
*
|
||||
* Sets the currently selected item.
|
||||
* This will select the item in both the button and any chooser popup.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
gimp_item_chooser_set_item (GimpItemChooser *chooser,
|
||||
GimpItem *item)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_ITEM_CHOOSER (chooser));
|
||||
g_return_if_fail (item == NULL || GIMP_IS_ITEM (item));
|
||||
|
||||
chooser->item = item;
|
||||
|
||||
if (chooser->callback)
|
||||
gimp_items_set_popup (chooser->callback, chooser->item);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (chooser), item_button_props[PROP_ITEM]);
|
||||
|
||||
gimp_item_chooser_draw (chooser);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_chooser_get_label:
|
||||
* @widget: A [class@ItemChooser].
|
||||
*
|
||||
* Returns the label widget.
|
||||
*
|
||||
* Returns: (transfer none): the [class@Gtk.Widget] showing the label text.
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
gimp_item_chooser_get_label (GimpItemChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_ITEM_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->label_widget;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static GimpValueArray *
|
||||
gimp_temp_callback_run (GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GimpItemChooser *chooser)
|
||||
{
|
||||
GimpItem *item;
|
||||
gboolean closing;
|
||||
|
||||
g_object_get (config,
|
||||
"item", &item,
|
||||
"closing", &closing,
|
||||
NULL);
|
||||
|
||||
g_object_set (chooser, "item", item, NULL);
|
||||
|
||||
if (closing)
|
||||
{
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
(GSourceFunc) gimp_item_select_remove_after_run,
|
||||
g_strdup (gimp_procedure_get_name (procedure)),
|
||||
g_free);
|
||||
g_clear_pointer (&chooser->callback, g_free);
|
||||
}
|
||||
|
||||
g_clear_object (&item);
|
||||
|
||||
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_item_select_remove_after_run (const gchar *procedure_name)
|
||||
{
|
||||
gimp_plug_in_remove_temp_procedure (gimp_get_plug_in (), procedure_name);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_clicked (GimpItemChooser *chooser)
|
||||
{
|
||||
if (chooser->callback)
|
||||
{
|
||||
/* Popup already created. Calling setter raises the popup. */
|
||||
gimp_items_set_popup (chooser->callback, chooser->item);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpPlugIn *plug_in = gimp_get_plug_in ();
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (chooser));
|
||||
GBytes *handle = NULL;
|
||||
gchar *callback_name;
|
||||
GimpProcedure *callback_procedure;
|
||||
|
||||
if (GIMP_IS_DIALOG (toplevel))
|
||||
handle = gimp_dialog_get_native_handle (GIMP_DIALOG (toplevel));
|
||||
|
||||
callback_name = gimp_pdb_temp_procedure_name (gimp_get_pdb ());
|
||||
callback_procedure = gimp_procedure_new (plug_in,
|
||||
callback_name,
|
||||
GIMP_PDB_PROC_TYPE_TEMPORARY,
|
||||
(GimpRunFunc) gimp_temp_callback_run,
|
||||
g_object_ref (chooser),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
gimp_procedure_add_item_argument (callback_procedure, "item",
|
||||
"Item", "The selected item",
|
||||
TRUE, G_PARAM_READWRITE);
|
||||
gimp_procedure_add_boolean_argument (callback_procedure, "closing",
|
||||
"Closing", "If the dialog was closing",
|
||||
FALSE, G_PARAM_READWRITE);
|
||||
|
||||
gimp_plug_in_add_temp_procedure (plug_in, callback_procedure);
|
||||
g_object_unref (callback_procedure);
|
||||
g_free (callback_name);
|
||||
|
||||
if (gimp_items_popup (gimp_procedure_get_name (callback_procedure), chooser->title,
|
||||
g_type_name (chooser->item_type), chooser->item, handle))
|
||||
{
|
||||
/* Allow callbacks to be watched */
|
||||
gimp_plug_in_persistent_enable (plug_in);
|
||||
|
||||
chooser->callback = g_strdup (gimp_procedure_get_name (callback_procedure));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("%s: failed to open remote item select dialog.", G_STRFUNC);
|
||||
gimp_plug_in_remove_temp_procedure (plug_in, gimp_procedure_get_name (callback_procedure));
|
||||
return;
|
||||
}
|
||||
gimp_items_set_popup (chooser->callback, chooser->item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_draw (GimpItemChooser *chooser)
|
||||
{
|
||||
GimpPreviewArea *area = GIMP_PREVIEW_AREA (chooser->preview);
|
||||
GtkAllocation allocation;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
|
||||
gtk_widget_get_allocation (chooser->preview, &allocation);
|
||||
|
||||
gimp_item_chooser_get_thumbnail (chooser, allocation.width, allocation.height);
|
||||
|
||||
if (chooser->width < allocation.width ||
|
||||
chooser->height < allocation.height)
|
||||
{
|
||||
x = ((allocation.width - chooser->width) / 2);
|
||||
y = ((allocation.height - chooser->height) / 2);
|
||||
}
|
||||
gimp_preview_area_reset (area);
|
||||
|
||||
if (chooser->thumbnail)
|
||||
{
|
||||
GimpImageType type;
|
||||
gint rowstride;
|
||||
|
||||
rowstride = chooser->width * chooser->bpp;
|
||||
switch (chooser->bpp)
|
||||
{
|
||||
case 1:
|
||||
type = GIMP_GRAY_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
type = GIMP_GRAYA_IMAGE;
|
||||
break;
|
||||
case 3:
|
||||
type = GIMP_RGB_IMAGE;
|
||||
break;
|
||||
case 4:
|
||||
type = GIMP_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
gimp_preview_area_draw (area, x, y, chooser->width, chooser->height, type,
|
||||
g_bytes_get_data (chooser->thumbnail, NULL), rowstride);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: GimpItems like GimpPath do not have a built-in drawable,
|
||||
* but it is possible to get a preview from it. We should add a
|
||||
* standard way to generate this preview. */
|
||||
if (chooser->item)
|
||||
gtk_label_set_text (GTK_LABEL (chooser->preview_title),
|
||||
gimp_item_get_name (chooser->item));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_chooser_get_thumbnail (GimpItemChooser *chooser,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (chooser->item == chooser->thumbnail_item &&
|
||||
chooser->width == width &&
|
||||
chooser->height == height)
|
||||
/* Let's assume item contents is not changing in a single run. */
|
||||
return;
|
||||
|
||||
g_clear_pointer (&chooser->thumbnail, g_bytes_unref);
|
||||
chooser->width = chooser->height = 0;
|
||||
|
||||
chooser->thumbnail_item = chooser->item;
|
||||
if (chooser->item)
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE (chooser->item))
|
||||
{
|
||||
chooser->thumbnail =
|
||||
gimp_drawable_get_thumbnail_data (GIMP_DRAWABLE (chooser->item),
|
||||
width, height,
|
||||
&chooser->width,
|
||||
&chooser->height,
|
||||
&chooser->bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
libgimp/gimpitemchooser.h
Normal file
47
libgimp/gimpitemchooser.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpitemchooser.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
|
||||
#error "Only <libgimp/gimpui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GIMP_ITEM_CHOOSER_H__
|
||||
#define __GIMP_ITEM_CHOOSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GIMP_TYPE_ITEM_CHOOSER (gimp_item_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GimpItemChooser, gimp_item_chooser, GIMP, ITEM_CHOOSER, GtkBox)
|
||||
|
||||
|
||||
GtkWidget * gimp_item_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
GType item_type,
|
||||
GimpItem *item);
|
||||
|
||||
GimpItem * gimp_item_chooser_get_item (GimpItemChooser *chooser);
|
||||
void gimp_item_chooser_set_item (GimpItemChooser *chooser,
|
||||
GimpItem *item);
|
||||
GtkWidget * gimp_item_chooser_get_label (GimpItemChooser *widget);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_ITEM_CHOOSER_H__ */
|
||||
|
|
@ -913,6 +913,10 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
|
|||
{
|
||||
widget = gimp_prop_drawable_chooser_new (G_OBJECT (priv->config), property, NULL);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && (pspec->value_type == GIMP_TYPE_PATH))
|
||||
{
|
||||
widget = gimp_prop_item_chooser_new (G_OBJECT (priv->config), property, NULL);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_IMAGE)
|
||||
{
|
||||
widget = gimp_prop_image_chooser_new (G_OBJECT (priv->config), property, NULL);
|
||||
|
|
@ -966,6 +970,8 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
|
|||
label = gimp_resource_chooser_get_label (GIMP_RESOURCE_CHOOSER (widget));
|
||||
else if (GIMP_IS_DRAWABLE_CHOOSER (widget))
|
||||
label = gimp_drawable_chooser_get_label (GIMP_DRAWABLE_CHOOSER (widget));
|
||||
else if (GIMP_IS_ITEM_CHOOSER (widget))
|
||||
label = gimp_item_chooser_get_label (GIMP_ITEM_CHOOSER (widget));
|
||||
else if (GIMP_IS_IMAGE_CHOOSER (widget))
|
||||
label = gimp_image_chooser_get_label (GIMP_IMAGE_CHOOSER (widget));
|
||||
}
|
||||
|
|
@ -2922,6 +2928,10 @@ gimp_procedure_dialog_check_mnemonic (GimpProcedureDialog *dialog,
|
|||
{
|
||||
label = gimp_drawable_chooser_get_label (GIMP_DRAWABLE_CHOOSER (widget));
|
||||
}
|
||||
else if (GIMP_IS_ITEM_CHOOSER (widget))
|
||||
{
|
||||
label = gimp_item_chooser_get_label (GIMP_ITEM_CHOOSER (widget));
|
||||
}
|
||||
else if (GIMP_IS_IMAGE_CHOOSER (widget))
|
||||
{
|
||||
label = gimp_image_chooser_get_label (GIMP_IMAGE_CHOOSER (widget));
|
||||
|
|
|
|||
|
|
@ -206,6 +206,74 @@ gimp_prop_image_chooser_new (GObject *config,
|
|||
return prop_chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_prop_item_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Item] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.ItemChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.ItemChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
gimp_prop_item_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
GParamSpec *param_spec;
|
||||
GtkWidget *prop_chooser;
|
||||
GimpItem *initial_item = NULL;
|
||||
gchar *title = NULL;
|
||||
const gchar *label;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
|
||||
property_name);
|
||||
|
||||
g_return_val_if_fail (param_spec != NULL, NULL);
|
||||
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_OBJECT) &&
|
||||
g_type_is_a (param_spec->value_type, GIMP_TYPE_ITEM), NULL);
|
||||
|
||||
g_object_get (config,
|
||||
property_name, &initial_item,
|
||||
NULL);
|
||||
|
||||
label = g_param_spec_get_nick (param_spec);
|
||||
|
||||
if (chooser_title == NULL)
|
||||
{
|
||||
gchar *canonical;
|
||||
|
||||
canonical = gimp_utils_make_canonical_menu_label (label);
|
||||
if (g_type_is_a (param_spec->value_type, GIMP_TYPE_LAYER))
|
||||
title = g_strdup_printf (_("Choose layer: %s"), canonical);
|
||||
if (g_type_is_a (param_spec->value_type, GIMP_TYPE_CHANNEL))
|
||||
title = g_strdup_printf (_("Choose channel: %s"), canonical);
|
||||
if (g_type_is_a (param_spec->value_type, GIMP_TYPE_PATH))
|
||||
title = g_strdup_printf (_("Choose path: %s"), canonical);
|
||||
else
|
||||
title = g_strdup_printf (_("Choose item: %s"), canonical);
|
||||
g_free (canonical);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = g_strdup (chooser_title);
|
||||
}
|
||||
|
||||
prop_chooser = gimp_item_chooser_new (title, label, param_spec->value_type,
|
||||
initial_item);
|
||||
g_clear_object (&initial_item);
|
||||
g_free (title);
|
||||
|
||||
g_object_bind_property (prop_chooser, "item",
|
||||
config, property_name,
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
return prop_chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_prop_drawable_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ GtkWidget * gimp_prop_pattern_chooser_new (GObject *config,
|
|||
GtkWidget * gimp_prop_image_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * gimp_prop_item_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * gimp_prop_drawable_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ EXPORTS
|
|||
gimp_image_chooser_set_image
|
||||
gimp_image_combo_box_get_type
|
||||
gimp_image_combo_box_new
|
||||
gimp_item_chooser_get_item
|
||||
gimp_item_chooser_get_label
|
||||
gimp_item_chooser_get_type
|
||||
gimp_item_chooser_new
|
||||
gimp_item_chooser_set_item
|
||||
gimp_layer_combo_box_get_type
|
||||
gimp_layer_combo_box_new
|
||||
gimp_palette_chooser_get_type
|
||||
|
|
@ -76,6 +81,7 @@ EXPORTS
|
|||
gimp_prop_font_chooser_new
|
||||
gimp_prop_gradient_chooser_new
|
||||
gimp_prop_image_chooser_new
|
||||
gimp_prop_item_chooser_new
|
||||
gimp_prop_palette_chooser_new
|
||||
gimp_prop_pattern_chooser_new
|
||||
gimp_prop_resolution_entry_new
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <libgimp/gimpgradientchooser.h>
|
||||
#include <libgimp/gimpimagechooser.h>
|
||||
#include <libgimp/gimpimagecombobox.h>
|
||||
#include <libgimp/gimpitemchooser.h>
|
||||
#include <libgimp/gimpitemcombobox.h>
|
||||
#include <libgimp/gimppalettechooser.h>
|
||||
#include <libgimp/gimppatternchooser.h>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ typedef struct _GimpBrushChooser GimpBrushChooser;
|
|||
typedef struct _GimpFontChooser GimpFontChooser;
|
||||
typedef struct _GimpGradientChooser GimpGradientChooser;
|
||||
typedef struct _GimpImageChooser GimpImageChooser;
|
||||
typedef struct _GimpItemChooser GimpItemChooser;
|
||||
typedef struct _GimpPaletteChooser GimpPaletteChooser;
|
||||
typedef struct _GimpPatternChooser GimpPatternChooser;
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ libgimpui_sources_introspectable = [
|
|||
'gimpgradientchooser.c',
|
||||
'gimpimagechooser.c',
|
||||
'gimpimagecombobox.c',
|
||||
'gimpitemchooser.c',
|
||||
'gimpitemcombobox.c',
|
||||
'gimppalettechooser.c',
|
||||
'gimppatternchooser.c',
|
||||
|
|
@ -342,6 +343,7 @@ libgimpui_headers_introspectable = [
|
|||
'gimpgradientchooser.h',
|
||||
'gimpimagechooser.h',
|
||||
'gimpimagecombobox.h',
|
||||
'gimpitemchooser.h',
|
||||
'gimpitemcombobox.h',
|
||||
'gimppalettechooser.h',
|
||||
'gimppatternchooser.h',
|
||||
|
|
|
|||
|
|
@ -1121,7 +1121,92 @@ CODE
|
|||
);
|
||||
}
|
||||
|
||||
@headers = qw("core/gimpgrouplayer.h"
|
||||
sub items_popup {
|
||||
$blurb = 'Invokes the item selection dialog.';
|
||||
$help = 'Opens a dialog letting a user choose an item .';
|
||||
|
||||
&alxsa_pdb_misc('2025');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The callback PDB proc to call when user chooses an item ' },
|
||||
{ name => 'popup_title', type => 'string',
|
||||
desc => 'Title of the item selection dialog' },
|
||||
{ name => 'item_type', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the GIMP_TYPE_ITEM subtype' },
|
||||
{ name => 'initial_item', type => 'item ', none_ok => 1, no_validate => 1,
|
||||
desc => 'The item to set as the initial choice' },
|
||||
{ name => 'parent_window', type => 'bytes', none_ok => 1,
|
||||
desc => 'An optional parent window handle for the popup to be set transient to' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_new (gimp, context, progress,
|
||||
g_type_from_name (item_type),
|
||||
parent_window, popup_title, callback,
|
||||
GIMP_OBJECT (initial_item),
|
||||
NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub items_close_popup {
|
||||
$blurb = 'Close the item selection dialog.';
|
||||
$help = 'Closes an open item selection dialog.';
|
||||
|
||||
&alxsa_pdb_misc('2025');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the callback registered for this pop-up' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_close (gimp, GIMP_TYPE_ITEM, callback))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub items_set_popup {
|
||||
$blurb = 'Sets the selected item in a item selection dialog.';
|
||||
$help = $blurb;
|
||||
|
||||
&alxsa_pdb_misc('2025');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the callback registered for this pop-up' },
|
||||
{ name => 'item', type => 'item', no_validate => 1,
|
||||
desc => 'The item to set as selected' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gimp->no_interface ||
|
||||
! gimp_pdb_lookup_procedure (gimp->pdb, callback) ||
|
||||
! gimp_pdb_dialog_set (gimp, GIMP_TYPE_ITEM, callback, GIMP_OBJECT (item), NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
@headers = qw("core/gimp.h"
|
||||
"core/gimpdatafactory.h"
|
||||
"core/gimpgrouplayer.h"
|
||||
"core/gimplayermask.h"
|
||||
"core/gimplinklayer.h"
|
||||
"core/gimplist.h"
|
||||
|
|
@ -1159,7 +1244,10 @@ CODE
|
|||
item_get_tattoo item_set_tattoo
|
||||
item_attach_parasite item_detach_parasite
|
||||
item_get_parasite
|
||||
item_get_parasite_list);
|
||||
item_get_parasite_list
|
||||
items_popup
|
||||
items_close_popup
|
||||
items_set_popup);
|
||||
|
||||
%exports = (app => [@procs], lib => [@procs]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue