mirror of https://github.com/GNOME/gimp.git
libgimpbase, libgimpwidgets: add a concept of insensitive choices in GimpChoice.
This is used in the generated GUIs for GimpChoice arguments, but also for validation of property setting. New functions: * gimp_choice_set_sensitive() * gimp_string_combo_box_set_sensitivity()
This commit is contained in:
parent
cedc45d8f3
commit
d670ff9f82
|
@ -27,6 +27,7 @@ EXPORTS
|
|||
gimp_choice_list_nicks
|
||||
gimp_choice_new
|
||||
gimp_choice_new_with_values
|
||||
gimp_choice_set_sensitive
|
||||
gimp_clone_type_get_type
|
||||
gimp_color_tag_get_type
|
||||
gimp_component_type_get_type
|
||||
|
|
|
@ -33,8 +33,15 @@ typedef struct _GimpChoiceDesc
|
|||
gchar *label;
|
||||
gchar *help;
|
||||
gint id;
|
||||
gboolean sensitive;
|
||||
} GimpChoiceDesc;
|
||||
|
||||
enum
|
||||
{
|
||||
SENSITIVITY_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
struct _GimpChoice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
@ -53,11 +60,22 @@ G_DEFINE_TYPE (GimpChoice, gimp_choice, G_TYPE_OBJECT)
|
|||
|
||||
#define parent_class gimp_choice_parent_class
|
||||
|
||||
static guint gimp_choice_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
gimp_choice_class_init (GimpChoiceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gimp_choice_signals[SENSITIVITY_CHANGED] =
|
||||
g_signal_new ("sensitivity-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, /*G_STRUCT_OFFSET (GimpChoiceClass, sensitivity_changed),*/
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
object_class->finalize = gimp_choice_finalize;
|
||||
}
|
||||
|
||||
|
@ -177,6 +195,7 @@ gimp_choice_add (GimpChoice *choice,
|
|||
desc->id = id;
|
||||
desc->label = g_strdup (label);
|
||||
desc->help = help != NULL ? g_strdup (help) : NULL;
|
||||
desc->sensitive = TRUE;
|
||||
g_hash_table_insert (choice->choices, g_strdup (nick), desc);
|
||||
|
||||
duplicate = g_list_find_custom (choice->keys, nick, (GCompareFunc) g_strcmp0);
|
||||
|
@ -205,7 +224,13 @@ gboolean
|
|||
gimp_choice_is_valid (GimpChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
return (g_hash_table_lookup (choice->choices, nick) != NULL);
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CHOICE (choice), FALSE);
|
||||
g_return_val_if_fail (nick != NULL, FALSE);
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
return (desc != NULL && desc->sensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -328,6 +353,39 @@ gimp_choice_get_documentation (GimpChoice *choice,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_set_sensitive:
|
||||
* @choice: the %GimpChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Change the sensitivity of a possible @nick. Technically a non-sensitive @nick
|
||||
* means it cannot be chosen anymore (so [method@Gimp.Choice.is_valid] will
|
||||
* return %FALSE; nevertheless [method@Gimp.Choice.list_nicks] and other
|
||||
* functions to get information about a choice will still function).
|
||||
*
|
||||
* Returns: %TRUE if @nick is found, %FALSE otherwise.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_choice_set_sensitive (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
gboolean sensitive)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHOICE (choice));
|
||||
g_return_if_fail (nick != NULL);
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
g_return_if_fail (desc != NULL);
|
||||
if (desc->sensitive != sensitive)
|
||||
{
|
||||
desc->sensitive = sensitive;
|
||||
g_signal_emit (choice, gimp_choice_signals[SENSITIVITY_CHANGED], 0, nick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
|
|
|
@ -63,6 +63,10 @@ gboolean gimp_choice_get_documentation (GimpChoice *choice,
|
|||
const gchar **label,
|
||||
const gchar **help);
|
||||
|
||||
void gimp_choice_set_sensitive (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
gboolean sensitive);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
static void gimp_param_choice_class_init (GParamSpecClass *klass);
|
||||
static void gimp_param_choice_init (GParamSpec *pspec);
|
||||
static void gimp_param_choice_value_set_default (GParamSpec *pspec,
|
||||
GValue *value);
|
||||
static void gimp_param_choice_finalize (GParamSpec *pspec);
|
||||
static gboolean gimp_param_choice_validate (GParamSpec *pspec,
|
||||
GValue *value);
|
||||
|
@ -67,6 +69,7 @@ static void
|
|||
gimp_param_choice_class_init (GParamSpecClass *klass)
|
||||
{
|
||||
klass->value_type = G_TYPE_STRING;
|
||||
klass->value_set_default = gimp_param_choice_value_set_default;
|
||||
klass->finalize = gimp_param_choice_finalize;
|
||||
klass->value_validate = gimp_param_choice_validate;
|
||||
klass->values_cmp = gimp_param_choice_values_cmp;
|
||||
|
@ -81,6 +84,15 @@ gimp_param_choice_init (GParamSpec *pspec)
|
|||
choice->default_value = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_choice_value_set_default (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
GimpParamSpecChoice *cspec = GIMP_PARAM_SPEC_CHOICE (pspec);
|
||||
|
||||
g_value_set_string (value, cspec->default_value);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_choice_finalize (GParamSpec *pspec)
|
||||
{
|
||||
|
@ -99,8 +111,26 @@ gimp_param_choice_validate (GParamSpec *pspec,
|
|||
const gchar *strval = g_value_get_string (value);
|
||||
|
||||
if (! gimp_choice_is_valid (choice, strval))
|
||||
{
|
||||
if (gimp_choice_is_valid (choice, spec_choice->default_value))
|
||||
{
|
||||
g_value_set_string (value, spec_choice->default_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This might happen if the default value is set insensitive. Then we
|
||||
* should just set any valid random nick.
|
||||
*/
|
||||
GList *nicks;
|
||||
|
||||
nicks = gimp_choice_list_nicks (choice);
|
||||
for (GList *iter = nicks; iter; iter = iter->next)
|
||||
if (gimp_choice_is_valid (choice, (gchar *) iter->data))
|
||||
{
|
||||
g_value_set_string (value, (gchar *) iter->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -2543,6 +2543,11 @@ static void gimp_prop_string_combo_box_notify (GObject *config,
|
|||
GParamSpec *param_spec,
|
||||
GtkWidget *widget);
|
||||
|
||||
static gboolean
|
||||
gimp_prop_choice_combo_box_is_sensitive (const gchar *nick,
|
||||
GimpChoice *choice);
|
||||
|
||||
|
||||
/**
|
||||
* gimp_prop_string_combo_box_new:
|
||||
* @config: Object to which property is attached.
|
||||
|
@ -2624,7 +2629,6 @@ gimp_prop_choice_combo_box_new (GObject *config,
|
|||
GimpParamSpecChoice *cspec;
|
||||
GtkWidget *combo_box;
|
||||
GtkListStore *store;
|
||||
gchar *value;
|
||||
GList *values;
|
||||
GList *iter;
|
||||
|
||||
|
@ -2655,27 +2659,24 @@ gimp_prop_choice_combo_box_new (GObject *config,
|
|||
combo_box = gimp_string_combo_box_new (GTK_TREE_MODEL (store), 0, 1);
|
||||
g_object_unref (store);
|
||||
|
||||
g_object_get (config,
|
||||
property_name, &value,
|
||||
NULL);
|
||||
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box), value);
|
||||
|
||||
g_signal_connect (combo_box, "changed",
|
||||
G_CALLBACK (gimp_prop_string_combo_box_callback),
|
||||
config);
|
||||
|
||||
set_param_spec (G_OBJECT (combo_box), combo_box, param_spec);
|
||||
|
||||
connect_notify (config, property_name,
|
||||
G_CALLBACK (gimp_prop_string_combo_box_notify),
|
||||
gimp_string_combo_box_set_sensitivity (GIMP_STRING_COMBO_BOX (combo_box),
|
||||
(GimpStringSensitivityFunc) gimp_prop_choice_combo_box_is_sensitive,
|
||||
cspec->choice, NULL);
|
||||
g_signal_connect_swapped (cspec->choice, "sensitivity-changed",
|
||||
G_CALLBACK (gtk_widget_queue_draw),
|
||||
combo_box);
|
||||
|
||||
g_object_bind_property (config, property_name,
|
||||
combo_box, "value",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
gimp_widget_set_bound_property (combo_box, config, property_name);
|
||||
|
||||
gtk_widget_show (combo_box);
|
||||
|
||||
return combo_box;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_prop_string_combo_box_callback (GtkWidget *widget,
|
||||
GObject *config)
|
||||
|
@ -2723,6 +2724,13 @@ gimp_prop_string_combo_box_notify (GObject *config,
|
|||
g_free (value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_prop_choice_combo_box_is_sensitive (const gchar *nick,
|
||||
GimpChoice *choice)
|
||||
{
|
||||
return gimp_choice_is_valid (choice, nick);
|
||||
}
|
||||
|
||||
|
||||
/*************************/
|
||||
/* file chooser button */
|
||||
|
|
|
@ -56,6 +56,10 @@ struct _GimpStringComboBoxPrivate
|
|||
gint id_column;
|
||||
gint label_column;
|
||||
GtkCellRenderer *text_renderer;
|
||||
|
||||
GimpStringSensitivityFunc sensitivity_func;
|
||||
gpointer sensitivity_data;
|
||||
GDestroyNotify sensitivity_destroy;
|
||||
};
|
||||
|
||||
#define GET_PRIVATE(obj) (((GimpStringComboBox *) (obj))->priv)
|
||||
|
@ -71,6 +75,12 @@ static void gimp_string_combo_box_get_property (GObject *object,
|
|||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gimp_string_combo_box_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GimpStringComboBoxPrivate *priv);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpStringComboBox, gimp_string_combo_box,
|
||||
GTK_TYPE_COMBO_BOX)
|
||||
|
@ -153,7 +163,8 @@ gimp_string_combo_box_class_init (GimpStringComboBoxClass *klass)
|
|||
"Value",
|
||||
"Value of active item",
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
GIMP_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -176,6 +187,16 @@ gimp_string_combo_box_constructed (GObject *object)
|
|||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (object), cell,
|
||||
"text", priv->label_column,
|
||||
NULL);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (object), priv->text_renderer,
|
||||
(GtkCellLayoutDataFunc) gimp_string_combo_box_cell_data_func,
|
||||
priv, NULL);
|
||||
|
||||
/* The "changed" signal of the GtkComboBox also triggers a "value" property
|
||||
* notification.
|
||||
*/
|
||||
g_signal_connect (object, "changed",
|
||||
G_CALLBACK (g_object_notify),
|
||||
"value");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -345,6 +366,7 @@ gimp_string_combo_box_set_active (GimpStringComboBox *combo_box,
|
|||
if (gimp_string_model_lookup (model, column, id, &iter))
|
||||
{
|
||||
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
|
||||
g_object_notify (G_OBJECT (combo_box), "value");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -353,6 +375,7 @@ gimp_string_combo_box_set_active (GimpStringComboBox *combo_box,
|
|||
else
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), -1);
|
||||
g_object_notify (G_OBJECT (combo_box), "value");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -392,3 +415,74 @@ gimp_string_combo_box_get_active (GimpStringComboBox *combo_box)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_string_combo_box_set_sensitivity:
|
||||
* @combo_box: a #GimpStringComboBox
|
||||
* @func: a function that returns a boolean value, or %NULL to unset
|
||||
* @data: data to pass to @func
|
||||
* @destroy: destroy notification for @data
|
||||
*
|
||||
* Sets a function that is used to decide about the sensitivity of
|
||||
* rows in the @combo_box. Use this if you want to set certain rows
|
||||
* insensitive.
|
||||
*
|
||||
* Calling gtk_widget_queue_draw() on the @combo_box will cause the
|
||||
* sensitivity to be updated.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_string_combo_box_set_sensitivity (GimpStringComboBox *combo_box,
|
||||
GimpStringSensitivityFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GimpStringComboBoxPrivate *priv;
|
||||
|
||||
g_return_if_fail (GIMP_IS_STRING_COMBO_BOX (combo_box));
|
||||
|
||||
priv = GET_PRIVATE (combo_box);
|
||||
|
||||
if (priv->sensitivity_destroy)
|
||||
{
|
||||
GDestroyNotify d = priv->sensitivity_destroy;
|
||||
|
||||
priv->sensitivity_destroy = NULL;
|
||||
d (priv->sensitivity_data);
|
||||
}
|
||||
|
||||
priv->sensitivity_func = func;
|
||||
priv->sensitivity_data = data;
|
||||
priv->sensitivity_destroy = destroy;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (combo_box));
|
||||
}
|
||||
|
||||
|
||||
/* Private functions. */
|
||||
|
||||
static void
|
||||
gimp_string_combo_box_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GimpStringComboBoxPrivate *priv)
|
||||
{
|
||||
if (priv->sensitivity_func)
|
||||
{
|
||||
gchar *id;
|
||||
gboolean sensitive;
|
||||
|
||||
gtk_tree_model_get (tree_model, iter,
|
||||
priv->id_column, &id,
|
||||
-1);
|
||||
|
||||
sensitive = priv->sensitivity_func (id, priv->sensitivity_data);
|
||||
|
||||
g_object_set (cell,
|
||||
"sensitive", sensitive,
|
||||
NULL);
|
||||
g_free (id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,15 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
/**
|
||||
* GimpStringSensitivityFunc:
|
||||
* @id: the string value from the column @id_column as passed to [ctor@StringComboBox.new].
|
||||
* @data: (closure): the data passed in [method@StringComboBox.set_sensitivity].
|
||||
*/
|
||||
typedef gboolean (* GimpStringSensitivityFunc) (const gchar *id,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#define GIMP_TYPE_STRING_COMBO_BOX (gimp_string_combo_box_get_type ())
|
||||
#define GIMP_STRING_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_STRING_COMBO_BOX, GimpStringComboBox))
|
||||
#define GIMP_STRING_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_STRING_COMBO_BOX, GimpStringComboBoxClass))
|
||||
|
@ -72,6 +81,10 @@ gboolean gimp_string_combo_box_set_active (GimpStringComboBox *combo_box,
|
|||
const gchar *id);
|
||||
gchar * gimp_string_combo_box_get_active (GimpStringComboBox *combo_box);
|
||||
|
||||
void gimp_string_combo_box_set_sensitivity (GimpStringComboBox *combo_box,
|
||||
GimpStringSensitivityFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -472,6 +472,7 @@ EXPORTS
|
|||
gimp_string_combo_box_get_type
|
||||
gimp_string_combo_box_new
|
||||
gimp_string_combo_box_set_active
|
||||
gimp_string_combo_box_set_sensitivity
|
||||
gimp_toggle_button_update
|
||||
gimp_uint_adjustment_update
|
||||
gimp_unit_combo_box_get_active
|
||||
|
|
Loading…
Reference in New Issue