summaryrefslogtreecommitdiffstats
path: root/app/widgets/gimpiconsizescale.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/widgets/gimpiconsizescale.c')
-rw-r--r--app/widgets/gimpiconsizescale.c538
1 files changed, 538 insertions, 0 deletions
diff --git a/app/widgets/gimpiconsizescale.c b/app/widgets/gimpiconsizescale.c
new file mode 100644
index 0000000..2358adf
--- /dev/null
+++ b/app/widgets/gimpiconsizescale.c
@@ -0,0 +1,538 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpiconsizescale.c
+ * Copyright (C) 2016 Jehan <jehan@girinstud.io>
+ *
+ * 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 "libgimpconfig/gimpconfig.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "widgets-types.h"
+
+#include "config/gimpguiconfig.h"
+
+#include "core/gimp.h"
+
+#include "gimpiconsizescale.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_GIMP
+};
+
+typedef struct _GimpIconSizeScalePrivate GimpIconSizeScalePrivate;
+
+struct _GimpIconSizeScalePrivate
+{
+ Gimp *gimp;
+
+ GtkWidget *scale;
+ GtkWidget *combo;
+};
+
+#define GET_PRIVATE(scale) \
+ ((GimpIconSizeScalePrivate *) gimp_icon_size_scale_get_instance_private ((GimpIconSizeScale *) (scale)))
+
+
+static void gimp_icon_size_scale_constructed (GObject *object);
+static void gimp_icon_size_scale_finalize (GObject *object);
+static void gimp_icon_size_scale_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_icon_size_scale_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+/* Signals on GimpGuiConfig properties. */
+static void gimp_icon_size_scale_icon_theme_notify (GimpGuiConfig *config,
+ GParamSpec *pspec,
+ GtkRange *scale);
+static void gimp_icon_size_scale_icon_size_notify (GimpGuiConfig *config,
+ GParamSpec *pspec,
+ GtkWidget *size_scale);
+
+/* Signals on the combo. */
+static void gimp_icon_size_scale_combo_changed (GtkComboBox *combo,
+ GimpGuiConfig *config);
+/* Signals on the GtkScale. */
+static void gimp_icon_size_scale_value_changed (GtkRange *range,
+ GimpGuiConfig *config);
+static gboolean gimp_icon_size_scale_change_value (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble value,
+ GimpGuiConfig *config);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpIconSizeScale, gimp_icon_size_scale,
+ GIMP_TYPE_FRAME)
+
+#define parent_class gimp_icon_size_scale_parent_class
+
+
+static void
+gimp_icon_size_scale_class_init (GimpIconSizeScaleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = gimp_icon_size_scale_constructed;
+ object_class->finalize = gimp_icon_size_scale_finalize;
+ object_class->set_property = gimp_icon_size_scale_set_property;
+ object_class->get_property = gimp_icon_size_scale_get_property;
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp",
+ NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gimp_icon_size_scale_init (GimpIconSizeScale *object)
+{
+ GimpIconSizeScalePrivate *private = GET_PRIVATE (object);
+ GtkWidget *box;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_frame_set_label_widget (GTK_FRAME (object), box);
+ private->combo = gimp_int_combo_box_new (_("Guess icon size from resolution"), 0,
+ _("Use icon size from the theme"), 1,
+ _("Custom icon size"), 2, NULL);
+ gtk_box_pack_start (GTK_BOX (box), private->combo, FALSE, FALSE, 0);
+ gtk_widget_show (box);
+
+ private->scale = gtk_hscale_new_with_range (0.0, 3.0, 1.0);
+ /* 'draw_value' updates round_digits. So set it first. */
+ gtk_scale_set_draw_value (GTK_SCALE (private->scale), FALSE);
+ gtk_range_set_round_digits (GTK_RANGE (private->scale), 0.0);
+ gtk_widget_set_sensitive (GTK_WIDGET (private->scale), FALSE);
+ gtk_container_add (GTK_CONTAINER (object), private->scale);
+}
+
+static void
+gimp_icon_size_scale_constructed (GObject *object)
+{
+ GimpIconSizeScalePrivate *private = GET_PRIVATE (object);
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ g_signal_connect (private->combo, "changed",
+ G_CALLBACK (gimp_icon_size_scale_combo_changed),
+ private->gimp->config);
+
+ g_signal_connect (private->gimp->config, "notify::icon-theme",
+ G_CALLBACK (gimp_icon_size_scale_icon_theme_notify),
+ private->scale);
+ gimp_icon_size_scale_icon_theme_notify (GIMP_GUI_CONFIG (private->gimp->config),
+ NULL, GTK_RANGE (private->scale));
+
+ g_signal_connect (private->scale, "change-value",
+ G_CALLBACK (gimp_icon_size_scale_change_value),
+ private->gimp->config);
+ g_signal_connect (private->scale, "value-changed",
+ G_CALLBACK (gimp_icon_size_scale_value_changed),
+ private->gimp->config);
+
+ g_signal_connect (private->gimp->config, "notify::icon-size",
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ private->scale);
+ gimp_icon_size_scale_icon_size_notify (GIMP_GUI_CONFIG (private->gimp->config),
+ NULL, private->scale);
+
+ gtk_widget_show (private->combo);
+ gtk_widget_show (private->scale);
+}
+
+static void
+gimp_icon_size_scale_finalize (GObject *object)
+{
+ GimpIconSizeScalePrivate *private = GET_PRIVATE (object);
+
+ g_signal_handlers_disconnect_by_func (private->gimp->config,
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ private->scale);
+ g_signal_handlers_disconnect_by_func (private->gimp->config,
+ G_CALLBACK (gimp_icon_size_scale_icon_theme_notify),
+ private->scale);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_icon_size_scale_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpIconSizeScalePrivate *private = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ private->gimp = g_value_get_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_icon_size_scale_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpIconSizeScalePrivate *private = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ g_value_set_object (value, private->gimp);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_icon_size_scale_icon_theme_notify (GimpGuiConfig *config,
+ GParamSpec *pspec,
+ GtkRange *scale)
+{
+ GtkIconTheme *theme = gtk_icon_theme_get_default();
+ gint *icon_sizes;
+ gchar *markup;
+ gdouble value = gtk_range_get_value (scale);
+ gboolean update_value = FALSE;
+ gboolean has_small_toolbar = FALSE;
+ gboolean has_large_toolbar = FALSE;
+ gboolean has_dnd = FALSE;
+ gboolean has_dialog = FALSE;
+ gint i;
+
+ icon_sizes = gtk_icon_theme_get_icon_sizes (theme, "gimp-tool-move");
+ for (i = 0; icon_sizes[i]; i++)
+ {
+ if (icon_sizes[i] == -1)
+ {
+ has_small_toolbar = TRUE;
+ has_large_toolbar = TRUE;
+ has_dnd = TRUE;
+ has_dialog = TRUE;
+ break;
+ }
+ else if (icon_sizes[i] > 13 && icon_sizes[i] < 19)
+ {
+ has_small_toolbar = TRUE;
+ }
+ else if (icon_sizes[i] > 21 && icon_sizes[i] < 27)
+ {
+ has_large_toolbar = TRUE;
+ }
+ else if (icon_sizes[i] > 29 && icon_sizes[i] < 35)
+ {
+ has_dnd = TRUE;
+ }
+ else if (icon_sizes[i] > 45 && icon_sizes[i] < 51)
+ {
+ has_dialog = TRUE;
+ }
+ }
+ g_free (icon_sizes);
+
+ gtk_scale_clear_marks (GTK_SCALE (scale));
+ markup = (gchar *) C_("icon-size", "Small");
+ if (! has_small_toolbar)
+ {
+ markup = g_strdup_printf ("<span strikethrough=\"true\">%s</span>",
+ markup);
+ if (value == 0.0)
+ update_value = TRUE;
+ }
+ gtk_scale_add_mark (GTK_SCALE (scale), 0.0, GTK_POS_BOTTOM,
+ markup);
+ if (! has_small_toolbar)
+ g_free (markup);
+
+ markup = (gchar *) C_("icon-size", "Medium");
+ if (! has_large_toolbar)
+ {
+ markup = g_strdup_printf ("<span strikethrough=\"true\">%s</span>",
+ markup);
+ if (value == 1.0)
+ update_value = TRUE;
+ }
+ gtk_scale_add_mark (GTK_SCALE (scale), 1.0, GTK_POS_BOTTOM,
+ markup);
+ if (! has_large_toolbar)
+ g_free (markup);
+
+ markup = (gchar *) C_("icon-size", "Large");
+ if (! has_dnd)
+ {
+ markup = g_strdup_printf ("<span strikethrough=\"true\">%s</span>",
+ markup);
+ if (value == 2.0)
+ update_value = TRUE;
+ }
+ gtk_scale_add_mark (GTK_SCALE (scale), 2.0, GTK_POS_BOTTOM,
+ markup);
+ if (! has_dnd)
+ g_free (markup);
+
+ markup = (gchar *) C_("icon-size", "Huge");
+ if (! has_dialog)
+ {
+ markup = g_strdup_printf ("<span strikethrough=\"true\">%s</span>",
+ markup);
+ if (value == 3.0)
+ update_value = TRUE;
+ }
+ gtk_scale_add_mark (GTK_SCALE (scale), 3.0, GTK_POS_BOTTOM,
+ markup);
+ if (! has_dialog)
+ g_free (markup);
+
+ if (update_value)
+ {
+ GimpIconSize size;
+
+ g_object_get (config, "icon-size", &size, NULL);
+
+ if (size == GIMP_ICON_SIZE_THEME || size == GIMP_ICON_SIZE_AUTO)
+ {
+ g_signal_handlers_block_by_func (scale,
+ G_CALLBACK (gimp_icon_size_scale_value_changed),
+ config);
+ }
+ if (has_small_toolbar)
+ gtk_range_set_value (scale, 0.0);
+ else if (has_large_toolbar)
+ gtk_range_set_value (scale, 1.0);
+ else if (has_dnd)
+ gtk_range_set_value (scale, 2.0);
+ else
+ gtk_range_set_value (scale, 3.0);
+ if (size == GIMP_ICON_SIZE_THEME || size == GIMP_ICON_SIZE_AUTO)
+ {
+ g_signal_handlers_unblock_by_func (scale,
+ G_CALLBACK (gimp_icon_size_scale_value_changed),
+ config);
+ }
+ }
+}
+
+static void
+gimp_icon_size_scale_icon_size_notify (GimpGuiConfig *config,
+ GParamSpec *pspec,
+ GtkWidget *size_scale)
+{
+ GimpIconSizeScalePrivate *private;
+ GtkWidget *frame = gtk_widget_get_parent (size_scale);
+ GtkWidget *combo;
+ GimpIconSize size;
+ gdouble value = 1.0;
+
+ private = GET_PRIVATE (frame);
+ combo = private->combo;
+
+ g_object_get (config, "icon-size", &size, NULL);
+
+ switch (size)
+ {
+ case GIMP_ICON_SIZE_SMALL:
+ value = 0.0;
+ break;
+ case GIMP_ICON_SIZE_MEDIUM:
+ value = 1.0;
+ break;
+ case GIMP_ICON_SIZE_LARGE:
+ value = 2.0;
+ break;
+ case GIMP_ICON_SIZE_HUGE:
+ value = 3.0;
+ break;
+ default: /* GIMP_ICON_SIZE_THEME */
+ break;
+ }
+ g_signal_handlers_block_by_func (combo,
+ G_CALLBACK (gimp_icon_size_scale_combo_changed),
+ config);
+ gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo),
+ (size == GIMP_ICON_SIZE_AUTO)? 0 :
+ (size == GIMP_ICON_SIZE_THEME)? 1 : 2);
+ g_signal_handlers_unblock_by_func (combo,
+ G_CALLBACK (gimp_icon_size_scale_combo_changed),
+ config);
+ gtk_widget_set_sensitive (GTK_WIDGET (size_scale),
+ size != GIMP_ICON_SIZE_THEME &&
+ size != GIMP_ICON_SIZE_AUTO);
+
+
+ if (size != GIMP_ICON_SIZE_THEME && size != GIMP_ICON_SIZE_AUTO)
+ {
+ g_signal_handlers_block_by_func (size_scale,
+ G_CALLBACK (gimp_icon_size_scale_value_changed),
+ config);
+ gtk_range_set_value (GTK_RANGE (size_scale), value);
+ g_signal_handlers_unblock_by_func (size_scale,
+ G_CALLBACK (gimp_icon_size_scale_value_changed),
+ config);
+ }
+}
+
+static void
+gimp_icon_size_scale_combo_changed (GtkComboBox *combo,
+ GimpGuiConfig *config)
+{
+ GtkWidget *frame;
+ GtkWidget *scale;
+ GimpIconSize size;
+
+ frame = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (combo)));
+ scale = gtk_bin_get_child (GTK_BIN (frame));
+
+ if (gtk_combo_box_get_active (combo) == 2)
+ {
+ gdouble value = gtk_range_get_value (GTK_RANGE (scale));
+
+ if (value < 0.5)
+ size = GIMP_ICON_SIZE_SMALL;
+ else if (value < 1.5)
+ size = GIMP_ICON_SIZE_MEDIUM;
+ else if (value < 2.5)
+ size = GIMP_ICON_SIZE_LARGE;
+ else
+ size = GIMP_ICON_SIZE_HUGE;
+ }
+ else
+ {
+ size = (gtk_combo_box_get_active (combo) == 0) ?
+ GIMP_ICON_SIZE_AUTO : GIMP_ICON_SIZE_THEME;
+ }
+ gtk_widget_set_sensitive (GTK_WIDGET (scale),
+ gtk_combo_box_get_active (combo) == 2);
+
+ g_signal_handlers_block_by_func (config,
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ scale);
+ g_object_set (G_OBJECT (config),
+ "icon-size", size,
+ NULL);
+ g_signal_handlers_unblock_by_func (config,
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ scale);
+}
+
+static void
+gimp_icon_size_scale_value_changed (GtkRange *range,
+ GimpGuiConfig *config)
+{
+ GimpIconSize size;
+ gdouble value = gtk_range_get_value (range);
+
+ if (value < 0.5)
+ size = GIMP_ICON_SIZE_SMALL;
+ else if (value < 1.5)
+ size = GIMP_ICON_SIZE_MEDIUM;
+ else if (value < 2.5)
+ size = GIMP_ICON_SIZE_LARGE;
+ else
+ size = GIMP_ICON_SIZE_HUGE;
+
+ g_signal_handlers_block_by_func (config,
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ range);
+ g_object_set (G_OBJECT (config), "icon-size", size, NULL);
+ g_signal_handlers_unblock_by_func (config,
+ G_CALLBACK (gimp_icon_size_scale_icon_size_notify),
+ range);
+}
+
+static gboolean
+gimp_icon_size_scale_change_value (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble value,
+ GimpGuiConfig *config)
+{
+ GtkIconTheme *theme = gtk_icon_theme_get_default();
+ gint *icon_sizes;
+ gboolean has_small_toolbar = FALSE;
+ gboolean has_large_toolbar = FALSE;
+ gboolean has_dnd = FALSE;
+ gboolean has_dialog = FALSE;
+ gint i;
+
+ /* We cannot check all icons. Use "gimp-tool-move" as template of
+ * available sizes. */
+ icon_sizes = gtk_icon_theme_get_icon_sizes (theme, "gimp-tool-move");
+ for (i = 0; icon_sizes[i]; i++)
+ {
+ if (icon_sizes[i] == -1)
+ {
+ has_small_toolbar = TRUE;
+ has_large_toolbar = TRUE;
+ has_dnd = TRUE;
+ has_dialog = TRUE;
+ break;
+ }
+ else if (icon_sizes[i] > 13 && icon_sizes[i] < 19)
+ has_small_toolbar = TRUE;
+ else if (icon_sizes[i] > 21 && icon_sizes[i] < 27)
+ has_large_toolbar = TRUE;
+ else if (icon_sizes[i] > 29 && icon_sizes[i] < 35)
+ has_dnd = TRUE;
+ else if (icon_sizes[i] > 45 && icon_sizes[i] < 51)
+ has_dialog = TRUE;
+ }
+ g_free (icon_sizes);
+
+ if ((value < 0.5 && ! has_small_toolbar) ||
+ (value >= 0.5 && value < 1.5 && ! has_large_toolbar) ||
+ (value >= 1.5 && value < 2.5 && ! has_dnd) ||
+ (value >= 2.5 && ! has_dialog))
+ /* Refuse the update. */
+ return TRUE;
+ else
+ /* Accept the update. */
+ return FALSE;
+}
+
+GtkWidget *
+gimp_icon_size_scale_new (Gimp *gimp)
+{
+ g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+ return g_object_new (GIMP_TYPE_ICON_SIZE_SCALE,
+ "gimp", gimp,
+ NULL);
+}