app: derive the layer-mode menu layout entirely from the info arrays

Replace the 'with-behind' and 'with-replace' properties with a
single 'context' property, and use it to select the included
layer modes, according to their context mask.

Add a dummy GIMP_LAYER_MODE_SEPARATOR value to the GimpLayerMode
enum, and use it to explicitly mark the menu separators in the
layer-mode group arrays; add separators to the layer-mode menu
accordingly.

Update the rest of the code to use 'context' instead of 'with-behind'
and 'with-replace'.  In particular, in the layers and layer options
dialogs, select the right context based on whether or not the
selected layer is a group.
This commit is contained in:
Ell 2017-02-17 05:20:53 -05:00
parent c3d2f57e28
commit e30d235ede
13 changed files with 281 additions and 368 deletions

View File

@ -152,7 +152,8 @@ fade_dialog_new (GimpImage *image,
/* the paint mode menu */
menu = gimp_prop_layer_mode_box_new (G_OBJECT (private->context),
"paint-mode", TRUE, TRUE);
"paint-mode",
GIMP_LAYER_MODE_CONTEXT_FADE);
gimp_table_attach_aligned (GTK_TABLE (table), 0, table_row++,
_("_Mode:"), 0.0, 0.5,
menu, 2, FALSE);

View File

@ -121,19 +121,20 @@ layer_options_dialog_new (GimpImage *image,
GimpLayerOptionsCallback callback,
gpointer user_data)
{
LayerOptionsDialog *private;
GtkWidget *dialog;
GtkWidget *table;
GtkListStore *space_model;
GtkWidget *combo;
GtkWidget *scale;
GtkWidget *label;
GtkAdjustment *adjustment;
GtkWidget *spinbutton;
GtkWidget *button;
gdouble xres;
gdouble yres;
gint row = 0;
LayerOptionsDialog *private;
GtkWidget *dialog;
GtkWidget *table;
GtkListStore *space_model;
GtkWidget *combo;
GtkWidget *scale;
GtkWidget *label;
GtkAdjustment *adjustment;
GtkWidget *spinbutton;
GtkWidget *button;
GimpLayerModeContext mode_context;
gdouble xres;
gdouble yres;
gint row = 0;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (layer == NULL || GIMP_IS_LAYER (layer), NULL);
@ -176,7 +177,12 @@ layer_options_dialog_new (GimpImage *image,
g_object_weak_ref (G_OBJECT (dialog),
(GWeakNotify) layer_options_dialog_free, private);
private->mode_box = gimp_layer_mode_box_new (FALSE, FALSE);
if (! layer || gimp_viewable_get_children (GIMP_VIEWABLE (layer)) == NULL)
mode_context = GIMP_LAYER_MODE_CONTEXT_LAYER;
else
mode_context = GIMP_LAYER_MODE_CONTEXT_GROUP;
private->mode_box = gimp_layer_mode_box_new (mode_context);
item_options_dialog_add_widget (dialog, _("_Mode:"), private->mode_box);
gimp_layer_mode_box_set_mode (GIMP_LAYER_MODE_BOX (private->mode_box),
private->mode);

View File

@ -1104,7 +1104,14 @@ static const GimpLayerModeInfo layer_mode_infos[] =
static const GimpLayerMode layer_mode_group_default[] =
{
GIMP_LAYER_MODE_NORMAL,
GIMP_LAYER_MODE_REPLACE,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND,
GIMP_LAYER_MODE_COLOR_ERASE,
GIMP_LAYER_MODE_ERASE,
GIMP_LAYER_MODE_ANTI_ERASE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LIGHTEN_ONLY,
GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
@ -1112,11 +1119,15 @@ static const GimpLayerMode layer_mode_group_default[] =
GIMP_LAYER_MODE_DODGE,
GIMP_LAYER_MODE_ADDITION,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DARKEN_ONLY,
GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
GIMP_LAYER_MODE_MULTIPLY,
GIMP_LAYER_MODE_BURN,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_OVERLAY,
GIMP_LAYER_MODE_SOFTLIGHT,
GIMP_LAYER_MODE_HARDLIGHT,
@ -1125,17 +1136,23 @@ static const GimpLayerMode layer_mode_group_default[] =
GIMP_LAYER_MODE_LINEAR_LIGHT,
GIMP_LAYER_MODE_HARD_MIX,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DIFFERENCE,
GIMP_LAYER_MODE_SUBTRACT,
GIMP_LAYER_MODE_GRAIN_EXTRACT,
GIMP_LAYER_MODE_GRAIN_MERGE,
GIMP_LAYER_MODE_DIVIDE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LCH_HUE,
GIMP_LAYER_MODE_LCH_CHROMA,
GIMP_LAYER_MODE_LCH_COLOR,
GIMP_LAYER_MODE_LCH_LIGHTNESS,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_EXCLUSION,
GIMP_LAYER_MODE_LINEAR_BURN
};
@ -1143,7 +1160,13 @@ static const GimpLayerMode layer_mode_group_default[] =
static const GimpLayerMode layer_mode_group_linear[] =
{
GIMP_LAYER_MODE_NORMAL_LINEAR,
GIMP_LAYER_MODE_REPLACE,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND_LINEAR,
GIMP_LAYER_MODE_ERASE,
GIMP_LAYER_MODE_ANTI_ERASE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LIGHTEN_ONLY,
GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
@ -1151,11 +1174,15 @@ static const GimpLayerMode layer_mode_group_linear[] =
GIMP_LAYER_MODE_DODGE_LINEAR,
GIMP_LAYER_MODE_ADDITION_LINEAR,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DARKEN_ONLY,
GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
GIMP_LAYER_MODE_MULTIPLY_LINEAR,
GIMP_LAYER_MODE_BURN_LINEAR,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_OVERLAY_LINEAR,
GIMP_LAYER_MODE_SOFTLIGHT_LINEAR,
GIMP_LAYER_MODE_HARDLIGHT_LINEAR,
@ -1164,12 +1191,16 @@ static const GimpLayerMode layer_mode_group_linear[] =
GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
GIMP_LAYER_MODE_HARD_MIX_LINEAR,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DIFFERENCE_LINEAR,
GIMP_LAYER_MODE_SUBTRACT_LINEAR,
GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
GIMP_LAYER_MODE_DIVIDE_LINEAR,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_EXCLUSION_LINEAR,
GIMP_LAYER_MODE_LINEAR_BURN_LINEAR
};
@ -1178,6 +1209,10 @@ static const GimpLayerMode layer_mode_group_perceptual[] =
{
GIMP_LAYER_MODE_NORMAL,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND,
GIMP_LAYER_MODE_COLOR_ERASE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LIGHTEN_ONLY,
GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
@ -1185,11 +1220,15 @@ static const GimpLayerMode layer_mode_group_perceptual[] =
GIMP_LAYER_MODE_DODGE,
GIMP_LAYER_MODE_ADDITION,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DARKEN_ONLY,
GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
GIMP_LAYER_MODE_MULTIPLY,
GIMP_LAYER_MODE_BURN,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_OVERLAY,
GIMP_LAYER_MODE_SOFTLIGHT,
GIMP_LAYER_MODE_HARDLIGHT,
@ -1198,22 +1237,30 @@ static const GimpLayerMode layer_mode_group_perceptual[] =
GIMP_LAYER_MODE_LINEAR_LIGHT,
GIMP_LAYER_MODE_HARD_MIX,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DIFFERENCE,
GIMP_LAYER_MODE_SUBTRACT,
GIMP_LAYER_MODE_GRAIN_EXTRACT,
GIMP_LAYER_MODE_GRAIN_MERGE,
GIMP_LAYER_MODE_DIVIDE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_HSV_HUE,
GIMP_LAYER_MODE_HSV_SATURATION,
GIMP_LAYER_MODE_HSV_COLOR,
GIMP_LAYER_MODE_HSV_VALUE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LCH_HUE,
GIMP_LAYER_MODE_LCH_CHROMA,
GIMP_LAYER_MODE_LCH_COLOR,
GIMP_LAYER_MODE_LCH_LIGHTNESS,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_EXCLUSION,
GIMP_LAYER_MODE_LINEAR_BURN
};
@ -1223,24 +1270,34 @@ static const GimpLayerMode layer_mode_group_legacy[] =
GIMP_LAYER_MODE_NORMAL,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
GIMP_LAYER_MODE_SCREEN_LEGACY,
GIMP_LAYER_MODE_DODGE_LEGACY,
GIMP_LAYER_MODE_ADDITION_LEGACY,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
GIMP_LAYER_MODE_MULTIPLY_LEGACY,
GIMP_LAYER_MODE_BURN_LEGACY,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
GIMP_LAYER_MODE_SUBTRACT_LEGACY,
GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
GIMP_LAYER_MODE_DIVIDE_LEGACY,
GIMP_LAYER_MODE_SEPARATOR,
GIMP_LAYER_MODE_HSV_HUE_LEGACY,
GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
GIMP_LAYER_MODE_HSV_COLOR_LEGACY,

View File

@ -140,7 +140,10 @@ typedef enum
/* Internal modes, not available to the PDB, must be kept at the end */
GIMP_LAYER_MODE_ERASE, /*< pdb-skip, desc="Erase" >*/
GIMP_LAYER_MODE_REPLACE, /*< pdb-skip, desc="Replace" >*/
GIMP_LAYER_MODE_ANTI_ERASE /*< pdb-skip, desc="Anti erase" >*/
GIMP_LAYER_MODE_ANTI_ERASE, /*< pdb-skip, desc="Anti erase" >*/
/* Layer mode menu separator */
GIMP_LAYER_MODE_SEPARATOR = -1 /*< pdb-skip, skip >*/
} GimpLayerMode;

View File

@ -114,7 +114,8 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
tool_type = tool_options->tool_info->tool_type;
/* the paint mode menu */
menu = gimp_prop_layer_mode_box_new (config, "paint-mode", TRUE, FALSE);
menu = gimp_prop_layer_mode_box_new (config, "paint-mode",
GIMP_LAYER_MODE_CONTEXT_PAINT);
gimp_layer_mode_box_set_label (GIMP_LAYER_MODE_BOX (menu), _("Mode"));
gimp_layer_mode_box_set_ellipsize (GIMP_LAYER_MODE_BOX (menu),
PANGO_ELLIPSIZE_END);

View File

@ -189,7 +189,7 @@ gimp_brush_select_constructed (GObject *object)
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
select->layer_mode_box = gimp_layer_mode_box_new (TRUE, FALSE);
select->layer_mode_box = gimp_layer_mode_box_new (GIMP_LAYER_MODE_CONTEXT_PAINT);
gtk_box_pack_start (GTK_BOX (hbox), select->layer_mode_box, TRUE, TRUE, 0);
gtk_widget_show (select->layer_mode_box);

View File

@ -48,20 +48,18 @@
enum
{
PROP_0,
PROP_LAYER_MODE,
PROP_WITH_BEHIND,
PROP_WITH_REPLACE
PROP_CONTEXT,
PROP_LAYER_MODE
};
struct _GimpLayerModeBoxPrivate
{
GimpLayerMode layer_mode;
gboolean with_behind;
gboolean with_replace;
GimpLayerModeContext context;
GimpLayerMode layer_mode;
GtkWidget *mode_combo;
GtkWidget *group_combo;
GtkWidget *mode_combo;
GtkWidget *group_combo;
};
@ -91,6 +89,14 @@ gimp_layer_mode_box_class_init (GimpLayerModeBoxClass *klass)
object_class->set_property = gimp_layer_mode_box_set_property;
object_class->get_property = gimp_layer_mode_box_get_property;
g_object_class_install_property (object_class, PROP_CONTEXT,
g_param_spec_flags ("context",
NULL, NULL,
GIMP_TYPE_LAYER_MODE_CONTEXT,
GIMP_LAYER_MODE_CONTEXT_ALL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_LAYER_MODE,
g_param_spec_enum ("layer-mode",
NULL, NULL,
@ -99,20 +105,6 @@ gimp_layer_mode_box_class_init (GimpLayerModeBoxClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_WITH_BEHIND,
g_param_spec_boolean ("with-behind",
NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_WITH_REPLACE,
g_param_spec_boolean ("with-replace",
NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (klass, sizeof (GimpLayerModeBoxPrivate));
}
@ -142,11 +134,15 @@ gimp_layer_mode_box_constructed (GObject *object)
G_OBJECT_CLASS (parent_class)->constructed (object);
box->priv->mode_combo = mode_combo =
gimp_layer_mode_combo_box_new (box->priv->with_behind,
box->priv->with_replace);
gimp_layer_mode_combo_box_new (box->priv->context);
gtk_box_pack_start (GTK_BOX (box), mode_combo, TRUE, TRUE, 0);
gtk_widget_show (mode_combo);
g_object_bind_property (object, "context",
G_OBJECT (mode_combo), "context",
G_BINDING_BIDIRECTIONAL |
G_BINDING_SYNC_CREATE);
g_object_bind_property (object, "layer-mode",
G_OBJECT (mode_combo), "layer-mode",
G_BINDING_BIDIRECTIONAL |
@ -202,18 +198,14 @@ gimp_layer_mode_box_set_property (GObject *object,
switch (prop_id)
{
case PROP_CONTEXT:
gimp_layer_mode_box_set_context (box, g_value_get_flags (value));
break;
case PROP_LAYER_MODE:
gimp_layer_mode_box_set_mode (box, g_value_get_enum (value));
break;
case PROP_WITH_BEHIND:
box->priv->with_behind = g_value_get_boolean (value);
break;
case PROP_WITH_REPLACE:
box->priv->with_replace = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -230,18 +222,14 @@ gimp_layer_mode_box_get_property (GObject *object,
switch (prop_id)
{
case PROP_CONTEXT:
g_value_set_flags (value, box->priv->context);
break;
case PROP_LAYER_MODE:
g_value_set_enum (value, box->priv->layer_mode);
break;
case PROP_WITH_BEHIND:
g_value_set_boolean (value, box->priv->with_behind);
break;
case PROP_WITH_REPLACE:
g_value_set_boolean (value, box->priv->with_replace);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -256,15 +244,36 @@ gimp_layer_mode_box_get_property (GObject *object,
* Return value: a new #GimpLayerModeBox.
**/
GtkWidget *
gimp_layer_mode_box_new (gboolean with_behind,
gboolean with_replace)
gimp_layer_mode_box_new (GimpLayerModeContext context)
{
return g_object_new (GIMP_TYPE_LAYER_MODE_BOX,
"with-behind", with_behind,
"with-replace", with_replace,
"context", context,
NULL);
}
void
gimp_layer_mode_box_set_context (GimpLayerModeBox *box,
GimpLayerModeContext context)
{
g_return_if_fail (GIMP_IS_LAYER_MODE_BOX (box));
if (context != box->priv->context)
{
box->priv->context = context;
g_object_notify (G_OBJECT (box), "context");
}
}
GimpLayerModeContext
gimp_layer_mode_box_get_context (GimpLayerModeBox *box)
{
g_return_val_if_fail (GIMP_IS_LAYER_MODE_BOX (box),
GIMP_LAYER_MODE_CONTEXT_ALL);
return box->priv->context;
}
void
gimp_layer_mode_box_set_mode (GimpLayerModeBox *box,
GimpLayerMode mode)

View File

@ -46,19 +46,22 @@ struct _GimpLayerModeBoxClass
};
GType gimp_layer_mode_box_get_type (void) G_GNUC_CONST;
GType gimp_layer_mode_box_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_layer_mode_box_new (gboolean with_behind,
gboolean with_replace);
GtkWidget * gimp_layer_mode_box_new (GimpLayerModeContext context);
void gimp_layer_mode_box_set_mode (GimpLayerModeBox *box,
GimpLayerMode mode);
GimpLayerMode gimp_layer_mode_box_get_mode (GimpLayerModeBox *box);
void gimp_layer_mode_box_set_context (GimpLayerModeBox *box,
GimpLayerModeContext context);
GimpLayerModeContext gimp_layer_mode_box_get_context (GimpLayerModeBox *box);
void gimp_layer_mode_box_set_label (GimpLayerModeBox *box,
const gchar *label);
void gimp_layer_mode_box_set_ellipsize (GimpLayerModeBox *box,
PangoEllipsizeMode mode);
void gimp_layer_mode_box_set_mode (GimpLayerModeBox *box,
GimpLayerMode mode);
GimpLayerMode gimp_layer_mode_box_get_mode (GimpLayerModeBox *box);
void gimp_layer_mode_box_set_label (GimpLayerModeBox *box,
const gchar *label);
void gimp_layer_mode_box_set_ellipsize (GimpLayerModeBox *box,
PangoEllipsizeMode mode);
#endif /* __GIMP_LAYER_MODE_BOX_H__ */

View File

@ -45,19 +45,17 @@
enum
{
PROP_0,
PROP_CONTEXT,
PROP_LAYER_MODE,
PROP_GROUP,
PROP_WITH_BEHIND,
PROP_WITH_REPLACE
PROP_GROUP
};
struct _GimpLayerModeComboBoxPrivate
{
GimpLayerMode layer_mode;
GimpLayerModeGroup group;
gboolean with_behind;
gboolean with_replace;
GimpLayerModeContext context;
GimpLayerMode layer_mode;
GimpLayerModeGroup group;
};
@ -75,12 +73,6 @@ static void gimp_layer_mode_combo_box_changed (GtkComboBox
static void gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
gboolean change_mode);
static void gimp_layer_mode_combo_box_insert_value (GtkListStore *store,
gint after,
gint insert_value);
static void gimp_layer_mode_combo_box_insert_separator (GtkListStore *store,
gint after,
gint separator_value);
static gboolean gimp_layer_mode_combo_box_separator_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data);
@ -104,6 +96,14 @@ gimp_layer_mode_combo_box_class_init (GimpLayerModeComboBoxClass *klass)
combo_class->changed = gimp_layer_mode_combo_box_changed;
g_object_class_install_property (object_class, PROP_CONTEXT,
g_param_spec_flags ("context",
NULL, NULL,
GIMP_TYPE_LAYER_MODE_CONTEXT,
GIMP_LAYER_MODE_CONTEXT_ALL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_LAYER_MODE,
g_param_spec_enum ("layer-mode",
NULL, NULL,
@ -120,20 +120,6 @@ gimp_layer_mode_combo_box_class_init (GimpLayerModeComboBoxClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_WITH_BEHIND,
g_param_spec_boolean ("with-behind",
NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_WITH_REPLACE,
g_param_spec_boolean ("with-replace",
NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (klass, sizeof (GimpLayerModeComboBoxPrivate));
}
@ -146,7 +132,7 @@ gimp_layer_mode_combo_box_init (GimpLayerModeComboBox *combo)
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
gimp_layer_mode_combo_box_separator_func,
GINT_TO_POINTER (-1),
GINT_TO_POINTER (GIMP_LAYER_MODE_SEPARATOR),
NULL);
}
@ -173,6 +159,10 @@ gimp_layer_mode_combo_box_set_property (GObject *object,
switch (prop_id)
{
case PROP_CONTEXT:
gimp_layer_mode_combo_box_set_context (combo, g_value_get_flags (value));
break;
case PROP_LAYER_MODE:
gimp_layer_mode_combo_box_set_mode (combo, g_value_get_enum (value));
break;
@ -181,14 +171,6 @@ gimp_layer_mode_combo_box_set_property (GObject *object,
gimp_layer_mode_combo_box_set_group (combo, g_value_get_enum (value));
break;
case PROP_WITH_BEHIND:
combo->priv->with_behind = g_value_get_boolean (value);
break;
case PROP_WITH_REPLACE:
combo->priv->with_replace = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -205,6 +187,10 @@ gimp_layer_mode_combo_box_get_property (GObject *object,
switch (prop_id)
{
case PROP_CONTEXT:
g_value_set_flags (value, combo->priv->context);
break;
case PROP_LAYER_MODE:
g_value_set_enum (value, combo->priv->layer_mode);
break;
@ -213,14 +199,6 @@ gimp_layer_mode_combo_box_get_property (GObject *object,
g_value_set_enum (value, combo->priv->group);
break;
case PROP_WITH_BEHIND:
g_value_set_boolean (value, combo->priv->with_behind);
break;
case PROP_WITH_REPLACE:
g_value_set_boolean (value, combo->priv->with_replace);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -250,20 +228,47 @@ gimp_layer_mode_combo_box_changed (GtkComboBox *gtk_combo)
* Return value: a new #GimpLayerModeComboBox.
**/
GtkWidget *
gimp_layer_mode_combo_box_new (gboolean with_behind,
gboolean with_replace)
gimp_layer_mode_combo_box_new (GimpLayerModeContext context)
{
return g_object_new (GIMP_TYPE_LAYER_MODE_COMBO_BOX,
"with-behind", with_behind,
"with-replace", with_replace,
"context", context,
NULL);
}
void
gimp_layer_mode_combo_box_set_context (GimpLayerModeComboBox *combo,
GimpLayerModeContext context)
{
g_return_if_fail (GIMP_IS_LAYER_MODE_COMBO_BOX (combo));
if (context != combo->priv->context)
{
g_object_freeze_notify (G_OBJECT (combo));
combo->priv->context = context;
g_object_notify (G_OBJECT (combo), "context");
gimp_layer_mode_combo_box_update_model (combo, TRUE);
g_object_thaw_notify (G_OBJECT (combo));
}
}
GimpLayerModeContext
gimp_layer_mode_combo_box_get_context (GimpLayerModeComboBox *combo)
{
g_return_val_if_fail (GIMP_IS_LAYER_MODE_COMBO_BOX (combo),
GIMP_LAYER_MODE_CONTEXT_ALL);
return combo->priv->context;
}
void
gimp_layer_mode_combo_box_set_mode (GimpLayerModeComboBox *combo,
GimpLayerMode mode)
{
g_return_if_fail (GIMP_IS_LAYER_MODE_COMBO_BOX (combo));
g_return_if_fail (gimp_layer_mode_get_context (mode) & combo->priv->context);
if (mode != combo->priv->layer_mode)
{
@ -350,13 +355,26 @@ gimp_enum_store_add_value (GtkListStore *store,
g_free (stripped);
}
static void
gimp_enum_store_add_separator (GtkListStore *store)
{
GtkTreeIter iter = { 0, };
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
GIMP_INT_STORE_VALUE, GIMP_LAYER_MODE_SEPARATOR,
-1);
}
static GtkListStore *
gimp_enum_store_new_from_array (GType enum_type,
gint n_values,
const gint *values)
gimp_enum_store_new_from_array (GType enum_type,
gint n_values,
const gint *values,
GimpLayerModeContext context)
{
GtkListStore *store;
GEnumValue *value;
gboolean added_values_since_last_separator = FALSE;
gint i;
g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
@ -369,156 +387,35 @@ gimp_enum_store_new_from_array (GType enum_type,
for (i = 0; i < n_values; i++)
{
value = g_enum_get_value (GIMP_ENUM_STORE (store)->enum_class, values[i]);
if (value)
gimp_enum_store_add_value (store, value);
if (values[i] != GIMP_LAYER_MODE_SEPARATOR)
{
if (gimp_layer_mode_get_context (values[i]) & context)
{
value = g_enum_get_value (GIMP_ENUM_STORE (store)->enum_class,
values[i]);
if (value)
{
gimp_enum_store_add_value (store, value);
added_values_since_last_separator = TRUE;
}
}
}
else
{
if (added_values_since_last_separator)
{
gimp_enum_store_add_separator (store);
added_values_since_last_separator = FALSE;
}
}
}
return store;
}
static void
gimp_layer_mode_combo_box_fix_default_store (GimpLayerModeComboBox *combo,
GtkListStore *store)
{
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DISSOLVE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_ADDITION, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_BURN, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_HARD_MIX, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DIVIDE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_LCH_LIGHTNESS, -1);
if (combo->priv->with_behind)
{
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_BEHIND,
GIMP_LAYER_MODE_COLOR_ERASE);
}
if (combo->priv->with_replace)
{
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_NORMAL,
GIMP_LAYER_MODE_REPLACE);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_COLOR_ERASE,
GIMP_LAYER_MODE_ERASE);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_ERASE,
GIMP_LAYER_MODE_ANTI_ERASE);
}
}
static void
gimp_layer_mode_combo_box_fix_linear_store (GimpLayerModeComboBox *combo,
GtkListStore *store)
{
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DISSOLVE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_ADDITION_LINEAR, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_BURN_LINEAR, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_HARD_MIX_LINEAR, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DIVIDE_LINEAR, -1);
if (combo->priv->with_behind)
{
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND_LINEAR);
}
if (combo->priv->with_replace)
{
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_NORMAL_LINEAR,
GIMP_LAYER_MODE_REPLACE);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_REPLACE,
GIMP_LAYER_MODE_ERASE);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_ERASE,
GIMP_LAYER_MODE_ANTI_ERASE);
}
}
static void
gimp_layer_mode_combo_box_fix_perceptual_store (GimpLayerModeComboBox *combo,
GtkListStore *store)
{
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DISSOLVE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_ADDITION, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_BURN, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_HARD_MIX, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DIVIDE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_HSV_VALUE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_LCH_LIGHTNESS, -1);
if (combo->priv->with_behind)
{
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_DISSOLVE,
GIMP_LAYER_MODE_BEHIND);
gimp_layer_mode_combo_box_insert_value (store,
GIMP_LAYER_MODE_BEHIND,
GIMP_LAYER_MODE_COLOR_ERASE);
}
}
static void
gimp_layer_mode_combo_box_fix_legacy_store (GimpLayerModeComboBox *combo,
GtkListStore *store)
{
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DISSOLVE, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_ADDITION_LEGACY, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_BURN_LEGACY, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_HARDLIGHT_LEGACY, -1);
gimp_layer_mode_combo_box_insert_separator (store,
GIMP_LAYER_MODE_DIVIDE_LEGACY, -1);
}
static void
gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
gboolean change_mode)
@ -529,29 +426,8 @@ gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
modes = gimp_layer_mode_get_group_array (combo->priv->group, &n_modes);
store = gimp_enum_store_new_from_array (GIMP_TYPE_LAYER_MODE,
n_modes, (gint *) modes);
switch (combo->priv->group)
{
case GIMP_LAYER_MODE_GROUP_DEFAULT:
gimp_layer_mode_combo_box_fix_default_store (combo, store);
break;
case GIMP_LAYER_MODE_GROUP_LINEAR:
gimp_layer_mode_combo_box_fix_linear_store (combo, store);
break;
case GIMP_LAYER_MODE_GROUP_PERCEPTUAL:
gimp_layer_mode_combo_box_fix_perceptual_store (combo, store);
break;
case GIMP_LAYER_MODE_GROUP_LEGACY:
gimp_layer_mode_combo_box_fix_legacy_store (combo, store);
break;
default:
g_return_if_reached ();
}
n_modes, (gint *) modes,
combo->priv->context);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);
@ -577,60 +453,6 @@ gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
}
}
static void
gimp_layer_mode_combo_box_insert_value (GtkListStore *store,
gint after,
gint insert_value)
{
GtkTreeIter iter;
if (gimp_int_store_lookup_by_value (GTK_TREE_MODEL (store),
after, &iter))
{
GEnumValue *enum_value;
enum_value = g_enum_get_value (GIMP_ENUM_STORE (store)->enum_class,
insert_value);
if (enum_value)
{
GtkTreeIter value_iter;
const gchar *desc;
gtk_list_store_insert_after (GTK_LIST_STORE (store),
&value_iter, &iter);
desc = gimp_enum_value_get_desc (GIMP_ENUM_STORE (store)->enum_class,
enum_value);
gtk_list_store_set (GTK_LIST_STORE (store), &value_iter,
GIMP_INT_STORE_VALUE, enum_value->value,
GIMP_INT_STORE_LABEL, desc,
-1);
}
}
}
static void
gimp_layer_mode_combo_box_insert_separator (GtkListStore *store,
gint after,
gint separator_value)
{
GtkTreeIter iter;
if (gimp_int_store_lookup_by_value (GTK_TREE_MODEL (store),
after, &iter))
{
GtkTreeIter sep_iter;
gtk_list_store_insert_after (GTK_LIST_STORE (store),
&sep_iter, &iter);
gtk_list_store_set (GTK_LIST_STORE (store), &sep_iter,
GIMP_INT_STORE_VALUE, separator_value,
-1);
}
}
static gboolean
gimp_layer_mode_combo_box_separator_func (GtkTreeModel *model,
GtkTreeIter *iter,

View File

@ -46,18 +46,21 @@ struct _GimpLayerModeComboBoxClass
};
GType gimp_layer_mode_combo_box_get_type (void) G_GNUC_CONST;
GType gimp_layer_mode_combo_box_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_layer_mode_combo_box_new (gboolean with_behind,
gboolean with_replace);
GtkWidget * gimp_layer_mode_combo_box_new (GimpLayerModeContext context);
void gimp_layer_mode_combo_box_set_mode (GimpLayerModeComboBox *combo,
GimpLayerMode mode);
GimpLayerMode gimp_layer_mode_combo_box_get_mode (GimpLayerModeComboBox *combo);
void gimp_layer_mode_combo_box_set_context (GimpLayerModeComboBox *combo,
GimpLayerModeContext context);
GimpLayerModeContext gimp_layer_mode_combo_box_get_context (GimpLayerModeComboBox *combo);
void gimp_layer_mode_combo_box_set_group (GimpLayerModeComboBox *combo,
GimpLayerModeGroup group);
GimpLayerModeGroup gimp_layer_mode_combo_box_get_group (GimpLayerModeComboBox *combo);
void gimp_layer_mode_combo_box_set_mode (GimpLayerModeComboBox *combo,
GimpLayerMode mode);
GimpLayerMode gimp_layer_mode_combo_box_get_mode (GimpLayerModeComboBox *combo);
void gimp_layer_mode_combo_box_set_group (GimpLayerModeComboBox *combo,
GimpLayerModeGroup group);
GimpLayerModeGroup gimp_layer_mode_combo_box_get_group (GimpLayerModeComboBox *combo);
#endif /* __GIMP_LAYER_MODE_COMBO_BOX_H__ */

View File

@ -265,7 +265,7 @@ gimp_layer_tree_view_init (GimpLayerTreeView *view)
/* Paint mode menu */
view->priv->layer_mode_box = gimp_layer_mode_box_new (FALSE, FALSE);
view->priv->layer_mode_box = gimp_layer_mode_box_new (GIMP_LAYER_MODE_CONTEXT_LAYER);
gimp_layer_mode_box_set_label (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
_("Mode"));
gimp_item_tree_view_add_options (GIMP_ITEM_TREE_VIEW (view), NULL,
@ -1076,6 +1076,17 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
BLOCK (view->priv->layer_mode_box,
gimp_layer_tree_view_layer_mode_box_callback);
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)) == NULL)
{
gimp_layer_mode_box_set_context (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
GIMP_LAYER_MODE_CONTEXT_LAYER);
}
else
{
gimp_layer_mode_box_set_context (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
GIMP_LAYER_MODE_CONTEXT_GROUP);
}
gimp_layer_mode_box_set_mode (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
gimp_layer_get_mode (layer));

View File

@ -148,24 +148,22 @@ gimp_prop_expanding_frame_new (GObject *config,
/**
* gimp_prop_layer_mode_box_new:
* @config: #GimpConfig object to which property is attached.
* @property_name: Name of Enum property.
* @with_behind_mode: Whether to include "Behind" mode in the menu.
* @with_replace_modes: Whether to include the "Replace", "Erase" and
* "Anti Erase" modes in the menu.
* @config: #GimpConfig object to which property is attached.
* @property_name: Name of Enum property.
* @context: A context mask, determining the set of modes to
* include in the menu.
*
* Creates a #GimpLayerModeBox widget to display and set the specified
* Enum property, for which the enum must be #GimpLayerMode.
*
* Return value: The newly created #GimpLayerModeBox widget.
*
* Since GIMP 2.4
* Since GIMP 2.10
*/
GtkWidget *
gimp_prop_layer_mode_box_new (GObject *config,
const gchar *property_name,
gboolean with_behind_mode,
gboolean with_replace_modes)
gimp_prop_layer_mode_box_new (GObject *config,
const gchar *property_name,
GimpLayerModeContext context)
{
GParamSpec *param_spec;
GtkWidget *box;
@ -175,7 +173,7 @@ gimp_prop_layer_mode_box_new (GObject *config,
if (! param_spec)
return NULL;
box = gimp_layer_mode_box_new (with_behind_mode, with_replace_modes);
box = gimp_layer_mode_box_new (context);
g_object_bind_property (config, property_name,
G_OBJECT (box), "layer-mode",

View File

@ -35,8 +35,7 @@ GtkWidget * gimp_prop_expanding_frame_new (GObject *config,
GtkWidget * gimp_prop_layer_mode_box_new (GObject *config,
const gchar *property_name,
gboolean with_behind_mode,
gboolean with_replace_modes);
GimpLayerModeContext context);
/* GimpParamColor */