[gimp] app: allow GimpColorHistory widgets to be on 1 or 2 rows.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: allow GimpColorHistory widgets to be on 1 or 2 rows.
- Date: Wed, 13 Feb 2019 13:45:00 +0000 (UTC)
commit 1cda00d426d12841fd771c27a0a91e0f63fc81ed
Author: Jehan <jehan girinstud io>
Date: Wed Feb 13 14:36:18 2019 +0100
app: allow GimpColorHistory widgets to be on 1 or 2 rows.
Current implementation was always making 2 rows. Yet sometimes the dock
can be made wide enough to accomodate all the color icons on 1 row,
hence saving vertical space, as well as not leaving this ugly space on
the side of the widget.
Now the widget will be able to compute an optimal size. Therefore if
there is enough space to align all color icons on a single row, this
will be organized this way. Otherwise, the widget will request more
vertical space to use 2 rows, hence allow a narrower dock as well.
Basically this will adapt to how you organize your docks, depending on
whatever screen size, pixel density, etc.
app/widgets/gimpcolorhistory.c | 242 ++++++++++++++++++++++++++++++++++-------
app/widgets/gimpcolorhistory.h | 2 +
2 files changed, 204 insertions(+), 40 deletions(-)
---
diff --git a/app/widgets/gimpcolorhistory.c b/app/widgets/gimpcolorhistory.c
index eb0ce4e119..8e75570750 100644
--- a/app/widgets/gimpcolorhistory.c
+++ b/app/widgets/gimpcolorhistory.c
@@ -56,25 +56,43 @@ enum
#define DEFAULT_HISTORY_SIZE 12
#define COLOR_AREA_SIZE 20
-static void gimp_color_history_constructed (GObject *object);
-static void gimp_color_history_finalize (GObject *object);
-static void gimp_color_history_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_color_history_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gimp_color_history_color_clicked (GtkWidget *widget,
- GimpColorHistory *history);
-
-static void gimp_color_history_palette_dirty (GimpPalette *palette,
- GimpColorHistory *history);
-
-static void gimp_color_history_color_changed (GtkWidget *widget,
- gpointer data);
+/* GObject methods */
+static void gimp_color_history_constructed (GObject *object);
+static void gimp_color_history_finalize (GObject *object);
+static void gimp_color_history_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_color_history_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+/* GtkWidget methods */
+static GtkSizeRequestMode gimp_color_history_get_request_mode (GtkWidget *widget);
+static void gimp_color_history_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
+static void gimp_color_history_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+static void gimp_color_history_size_allocate (GtkWidget *widget,
+ GdkRectangle *allocation);
+
+/* Signal handlers */
+static void gimp_color_history_color_clicked (GtkWidget *widget,
+ GimpColorHistory *history);
+
+static void gimp_color_history_palette_dirty (GimpPalette *palette,
+ GimpColorHistory *history);
+
+static void gimp_color_history_color_changed (GtkWidget *widget,
+ gpointer data);
+
+/* Utils */
+static void gimp_color_history_reorganize (GimpColorHistory *history);
G_DEFINE_TYPE (GimpColorHistory, gimp_color_history, GTK_TYPE_GRID)
@@ -86,13 +104,19 @@ static guint history_signals[LAST_SIGNAL] = { 0 };
static void
gimp_color_history_class_init (GimpColorHistoryClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = gimp_color_history_constructed;
object_class->set_property = gimp_color_history_set_property;
object_class->get_property = gimp_color_history_get_property;
object_class->finalize = gimp_color_history_finalize;
+ widget_class->get_request_mode = gimp_color_history_get_request_mode;
+ widget_class->get_preferred_width_for_height = gimp_color_history_get_preferred_width_for_height;
+ widget_class->get_preferred_height_for_width = gimp_color_history_get_preferred_height_for_width;
+ widget_class->size_allocate = gimp_color_history_size_allocate;
+
history_signals[COLOR_SELECTED] =
g_signal_new ("color-selected",
G_TYPE_FROM_CLASS (klass),
@@ -126,6 +150,11 @@ static void
gimp_color_history_init (GimpColorHistory *history)
{
history->color_areas = NULL;
+ history->buttons = NULL;
+ history->n_rows = 1;
+
+ gtk_grid_set_row_spacing (GTK_GRID (history), 2);
+ gtk_grid_set_column_spacing (GTK_GRID (history), 2);
}
static void
@@ -141,8 +170,6 @@ gimp_color_history_constructed (GObject *object)
g_signal_connect_object (palette, "dirty",
G_CALLBACK (gimp_color_history_palette_dirty),
G_OBJECT (history), 0);
-
- gimp_color_history_palette_dirty (palette, history);
}
static void
@@ -152,6 +179,8 @@ gimp_color_history_finalize (GObject *object)
g_free (history->color_areas);
history->color_areas = NULL;
+ g_free (history->buttons);
+ history->buttons = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -172,15 +201,19 @@ gimp_color_history_set_property (GObject *object,
case PROP_HISTORY_SIZE:
{
- GtkWidget *button;
- gint i;
+ GimpPalette *palette;
+ GtkWidget *button;
+ GtkWidget *color_area;
+ gint i;
+
+ history->history_size = g_value_get_int (value);
/* Destroy previous color buttons. */
gtk_container_foreach (GTK_CONTAINER (history),
(GtkCallback) gtk_widget_destroy, NULL);
- history->history_size = g_value_get_int (value);
- gtk_grid_set_row_spacing (GTK_GRID (history), 2);
- gtk_grid_set_column_spacing (GTK_GRID (history), 2);
+ history->buttons = g_realloc_n (history->buttons,
+ history->history_size,
+ sizeof (GtkWidget*));
history->color_areas = g_realloc_n (history->color_areas,
history->history_size,
sizeof (GtkWidget*));
@@ -189,32 +222,35 @@ gimp_color_history_set_property (GObject *object,
GimpRGB black = { 0.0, 0.0, 0.0, 1.0 };
gint row, column;
- column = i % (history->history_size / 2);
- row = i / (history->history_size / 2);
+ column = i % (history->history_size / history->n_rows);
+ row = i / (history->history_size / history->n_rows);
button = gtk_button_new ();
- gtk_widget_set_size_request (button,
- COLOR_AREA_SIZE, COLOR_AREA_SIZE);
- gtk_grid_attach (GTK_GRID (history), button,
- column, row, 1, 1);
+ gtk_widget_set_size_request (button, COLOR_AREA_SIZE, COLOR_AREA_SIZE);
+ gtk_grid_attach (GTK_GRID (history), button, column, row, 1, 1);
gtk_widget_show (button);
- history->color_areas[i] = gimp_color_area_new (&black,
- GIMP_COLOR_AREA_SMALL_CHECKS,
- GDK_BUTTON2_MASK);
- gimp_color_area_set_color_config (GIMP_COLOR_AREA (history->color_areas[i]),
+ color_area = gimp_color_area_new (&black, GIMP_COLOR_AREA_SMALL_CHECKS,
+ GDK_BUTTON2_MASK);
+ gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area),
history->context->gimp->config->color_management);
- gtk_container_add (GTK_CONTAINER (button), history->color_areas[i]);
- gtk_widget_show (history->color_areas[i]);
+ gtk_container_add (GTK_CONTAINER (button), color_area);
+ gtk_widget_show (color_area);
g_signal_connect (button, "clicked",
G_CALLBACK (gimp_color_history_color_clicked),
history);
- g_signal_connect (history->color_areas[i], "color-changed",
+ g_signal_connect (color_area, "color-changed",
G_CALLBACK (gimp_color_history_color_changed),
GINT_TO_POINTER (i));
+
+ history->buttons[i] = button;
+ history->color_areas[i] = color_area;
}
+
+ palette = gimp_palettes_get_color_history (history->context->gimp);
+ gimp_color_history_palette_dirty (palette, history);
}
break;
@@ -248,6 +284,109 @@ gimp_color_history_get_property (GObject *object,
}
}
+static GtkSizeRequestMode
+gimp_color_history_get_request_mode (GtkWidget *widget)
+{
+ return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+}
+
+static void
+gimp_color_history_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GimpColorHistory *history = GIMP_COLOR_HISTORY (widget);
+ GtkWidget *button;
+ gint button_width = COLOR_AREA_SIZE;
+
+ button = gtk_grid_get_child_at (GTK_GRID (widget), 0, 0);
+ if (button)
+ button_width = MAX (gtk_widget_get_allocated_width (button),
+ COLOR_AREA_SIZE);
+
+ /* This is a bit of a trick. Though the height actually depends on the
+ * width, I actually just request for about half the expected width if
+ * we were to align all color buttons on one line. This way, it is
+ * possible to resize the widget smaller than it currently is, hence
+ * allowing reorganization of icons.
+ */
+ *minimum_width = button_width * (1 + history->history_size / 2);
+ *natural_width = *minimum_width;
+}
+
+static void
+gimp_color_history_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GimpColorHistory *history = GIMP_COLOR_HISTORY (widget);
+ GtkWidget *button;
+ gint button_width = COLOR_AREA_SIZE;
+ gint button_height = COLOR_AREA_SIZE;
+ gint height;
+
+ button = gtk_grid_get_child_at (GTK_GRID (widget), 0, 0);
+ if (button)
+ {
+ button_width = MAX (gtk_widget_get_allocated_width (button),
+ COLOR_AREA_SIZE);
+ button_height = MAX (gtk_widget_get_allocated_height (button),
+ COLOR_AREA_SIZE);
+ }
+
+ if (width > button_width * history->history_size + 2 * (history->history_size - 1))
+ height = button_height;
+ else
+ height = 2 * button_height + 2;
+
+ *minimum_height = height;
+ *natural_height = height;
+}
+
+static void
+gimp_color_history_size_allocate (GtkWidget *widget,
+ GdkRectangle *allocation)
+{
+ GimpColorHistory *history = GIMP_COLOR_HISTORY (widget);
+ GtkWidget *button;
+ gint button_width = COLOR_AREA_SIZE;
+ gint button_height = COLOR_AREA_SIZE;
+ gint height;
+ gint n_rows;
+
+ button = gtk_grid_get_child_at (GTK_GRID (widget), 0, 0);
+ if (button)
+ {
+ button_width = MAX (gtk_widget_get_allocated_width (button),
+ COLOR_AREA_SIZE);
+ button_height = MAX (gtk_widget_get_allocated_height (button),
+ COLOR_AREA_SIZE);
+ }
+
+ if (allocation->width > button_width * history->history_size +
+ 2 * (history->history_size - 1))
+ {
+ n_rows = 1;
+ height = button_height;
+ }
+ else
+ {
+ n_rows = 2;
+ height = 2 * button_height + 2;
+ }
+
+ if (n_rows != history->n_rows)
+ {
+ history->n_rows = n_rows;
+ gimp_color_history_reorganize (history);
+ }
+
+ allocation->height = height;
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+}
+
/* Public Functions */
@@ -329,3 +468,26 @@ gimp_color_history_color_changed (GtkWidget *widget,
gimp_palette_set_entry_color (palette, GPOINTER_TO_INT (data), &color);
}
+
+static void
+gimp_color_history_reorganize (GimpColorHistory *history)
+{
+ GtkWidget *button;
+ gint i;
+
+ g_return_if_fail (history->buttons[0] && GTK_IS_BUTTON (history->buttons[0]));
+
+ for (i = 0; i < history->history_size; i++)
+ {
+ gint row, column;
+
+ column = i % (history->history_size / history->n_rows);
+ row = i / (history->history_size / history->n_rows);
+
+ button = history->buttons[i];
+
+ g_object_ref (button);
+ gtk_container_remove (GTK_CONTAINER (history), button);
+ gtk_grid_attach (GTK_GRID (history), button, column, row, 1, 1);
+ }
+}
diff --git a/app/widgets/gimpcolorhistory.h b/app/widgets/gimpcolorhistory.h
index cc975c92dd..f0f5c65fd4 100644
--- a/app/widgets/gimpcolorhistory.h
+++ b/app/widgets/gimpcolorhistory.h
@@ -39,7 +39,9 @@ struct _GimpColorHistory
GimpContext *context;
GtkWidget **color_areas;
+ GtkWidget **buttons;
gint history_size;
+ gint n_rows;
};
struct _GimpColorHistoryClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]