[gthumb] filter grid: specify the image task when adding a filter
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] filter grid: specify the image task when adding a filter
- Date: Sun, 25 Jan 2015 12:05:47 +0000 (UTC)
commit a6563720f5000f6db60c1badd6ef6307df2e2d83
Author: Paolo Bacchilega <paobac src gnome org>
Date: Wed Jan 7 12:42:55 2015 +0100
filter grid: specify the image task when adding a filter
to simplify the code
.../file_tools/gth-file-tool-adjust-contrast.c | 29 ++-
extensions/file_tools/gth-file-tool-grayscale.c | 29 ++-
gthumb/gth-filter-grid.c | 260 ++++++++++++++------
gthumb/gth-filter-grid.h | 18 +-
4 files changed, 233 insertions(+), 103 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-adjust-contrast.c
b/extensions/file_tools/gth-file-tool-adjust-contrast.c
index 4f2a855..95ab6b4 100644
--- a/extensions/file_tools/gth-file-tool-adjust-contrast.c
+++ b/extensions/file_tools/gth-file-tool-adjust-contrast.c
@@ -525,9 +525,21 @@ gth_file_tool_adjust_contrast_get_options (GthFileTool *base)
gtk_widget_show (options);
filter_grid = gth_filter_grid_new ();
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_STRETCH_0_5, NULL, _("Stretch"),
_("Stretch the histogram trimming the 0.5%"));
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_EQUALIZE_SQUARE_ROOT, NULL,
_("Equalize"), _("Equalize the histogram using the square root function"));
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_EQUALIZE_LINEAR, NULL,
_("Uniform"), _("Equalize the histogram using the linear function"));
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_STRETCH_0_5,
+ get_image_task_for_method (METHOD_STRETCH_0_5),
+ _("Stretch"),
+ _("Stretch the histogram trimming the 0.5%"));
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_EQUALIZE_SQUARE_ROOT,
+ get_image_task_for_method (METHOD_EQUALIZE_SQUARE_ROOT),
+ _("Equalize"),
+ _("Equalize the histogram using the square root function"));
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_EQUALIZE_LINEAR,
+ get_image_task_for_method (METHOD_EQUALIZE_LINEAR),
+ _("Uniform"),
+ _("Equalize the histogram using the linear function"));
g_signal_connect (filter_grid,
"activated",
@@ -541,16 +553,7 @@ gth_file_tool_adjust_contrast_get_options (GthFileTool *base)
gth_preview_tool_set_image (GTH_PREVIEW_TOOL (self->priv->preview_tool), self->priv->preview);
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->preview_tool);
gth_filter_grid_activate (GTH_FILTER_GRID (filter_grid), METHOD_STRETCH_0_5);
-
- gth_filter_grid_generate_previews (GTH_FILTER_GRID (filter_grid),
- source,
- METHOD_STRETCH_0_5,
- get_image_task_for_method (METHOD_STRETCH_0_5),
- METHOD_EQUALIZE_SQUARE_ROOT,
- get_image_task_for_method (METHOD_EQUALIZE_SQUARE_ROOT),
- METHOD_EQUALIZE_LINEAR,
- get_image_task_for_method (METHOD_EQUALIZE_LINEAR),
- GTH_FILTER_GRID_NO_FILTER);
+ gth_filter_grid_generate_previews (GTH_FILTER_GRID (filter_grid), source);
return options;
}
diff --git a/extensions/file_tools/gth-file-tool-grayscale.c b/extensions/file_tools/gth-file-tool-grayscale.c
index afe7a77..7083636 100644
--- a/extensions/file_tools/gth-file-tool-grayscale.c
+++ b/extensions/file_tools/gth-file-tool-grayscale.c
@@ -364,9 +364,21 @@ gth_file_tool_grayscale_get_options (GthFileTool *base)
gtk_widget_show (options);
filter_grid = gth_filter_grid_new ();
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_BRIGHTNESS, NULL, _("_Brightness"),
NULL);
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_SATURATION, NULL, _("_Saturation"),
NULL);
- gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid), METHOD_AVARAGE, NULL, _("_Average"), NULL);
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_BRIGHTNESS,
+ get_image_task_for_method (METHOD_BRIGHTNESS),
+ _("_Brightness"),
+ NULL);
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_SATURATION,
+ get_image_task_for_method (METHOD_SATURATION),
+ _("_Saturation"),
+ NULL);
+ gth_filter_grid_add_filter (GTH_FILTER_GRID (filter_grid),
+ METHOD_AVARAGE,
+ get_image_task_for_method (METHOD_AVARAGE),
+ _("_Average"),
+ NULL);
g_signal_connect (filter_grid,
"activated",
@@ -380,16 +392,7 @@ gth_file_tool_grayscale_get_options (GthFileTool *base)
gth_preview_tool_set_image (GTH_PREVIEW_TOOL (self->priv->preview_tool), self->priv->preview);
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->preview_tool);
gth_filter_grid_activate (GTH_FILTER_GRID (filter_grid), METHOD_BRIGHTNESS);
-
- gth_filter_grid_generate_previews (GTH_FILTER_GRID (filter_grid),
- source,
- METHOD_BRIGHTNESS,
- get_image_task_for_method (METHOD_BRIGHTNESS),
- METHOD_SATURATION,
- get_image_task_for_method (METHOD_SATURATION),
- METHOD_AVARAGE,
- get_image_task_for_method (METHOD_AVARAGE),
- GTH_FILTER_GRID_NO_FILTER);
+ gth_filter_grid_generate_previews (GTH_FILTER_GRID (filter_grid), source);
return options;
}
diff --git a/gthumb/gth-filter-grid.c b/gthumb/gth-filter-grid.c
index fb2efd9..9795753 100644
--- a/gthumb/gth-filter-grid.c
+++ b/gthumb/gth-filter-grid.c
@@ -67,15 +67,36 @@ typedef struct {
} GeneratePreviewData;
+typedef struct {
+ GtkWidget *cell;
+ GtkWidget *button;
+ GtkWidget *preview;
+ GtkWidget *label;
+ GthTask *task;
+} CellData;
+
+
+static void
+cell_data_free (CellData *cell_data)
+{
+ if (cell_data == NULL)
+ return;
+
+ _g_object_unref (cell_data->task);
+ g_free (cell_data);
+}
+
+
struct _GthFilterGridPrivate {
GtkWidget *grid;
int n_columns;
int current_column;
int current_row;
- GHashTable *buttons;
- GHashTable *previews;
+ GList *filter_ids;
+ GHashTable *cell_data;
GtkWidget *active_button;
GeneratePreviewData *gp_data;
+ int next_filter_id;
};
@@ -89,11 +110,15 @@ static void
_gth_filter_grid_set_n_columns (GthFilterGrid *self,
int n_columns)
{
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
+
self->priv->grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (self->priv->grid), COLUMN_SPACING);
gtk_grid_set_row_spacing (GTK_GRID (self->priv->grid), ROW_SPACING);
gtk_widget_show (self->priv->grid);
- gtk_container_add (GTK_CONTAINER (self), self->priv->grid);
+ gtk_box_pack_start (GTK_BOX (self), self->priv->grid, TRUE, FALSE, 0);
+ gtk_widget_set_margin_top (self->priv->grid, COLUMN_SPACING);
+ gtk_widget_set_margin_bottom (self->priv->grid, COLUMN_SPACING);
self->priv->n_columns = n_columns;
self->priv->current_column = 0;
@@ -155,8 +180,8 @@ gth_filter_grid_finalize (GObject *obj)
generate_preview_data_cancel (self->priv->gp_data);
self->priv->gp_data = NULL;
}
- g_hash_table_destroy (self->priv->previews);
- g_hash_table_destroy (self->priv->buttons);
+ g_hash_table_destroy (self->priv->cell_data);
+ g_list_free (self->priv->filter_ids);
G_OBJECT_CLASS (gth_filter_grid_parent_class)->finalize (obj);
}
@@ -206,10 +231,11 @@ gth_filter_grid_init (GthFilterGrid *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILTER_GRID, GthFilterGridPrivate);
self->priv->n_columns = DEFAULT_N_COLUMNS;
- self->priv->previews = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
- self->priv->buttons = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+ self->priv->filter_ids = NULL;
+ self->priv->cell_data = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, cell_data_free);
self->priv->active_button = NULL;
self->priv->gp_data = NULL;
+ self->priv->next_filter_id = 0;
}
@@ -249,31 +275,58 @@ button_toggled_cb (GtkWidget *toggle_button,
}
-static GtkWidget *
-_gth_filter_grid_cell_new (GthFilterGrid *self,
- int filter_id,
+static void
+_gth_filter_grid_append_cell (GthFilterGrid *self,
+ GtkWidget *cell)
+{
+ gtk_grid_attach (GTK_GRID (self->priv->grid),
+ cell,
+ self->priv->current_column,
+ self->priv->current_row,
+ 1,
+ 1);
+
+ self->priv->current_column++;
+ if (self->priv->current_column >= self->priv->n_columns) {
+ self->priv->current_column = 0;
+ self->priv->current_row++;
+ }
+}
+
+
+static CellData *
+_gth_filter_grid_add_filter (GthFilterGrid *self,
+ int *filter_id_p,
cairo_surface_t *preview,
const char *label_text,
const char *tooltip)
{
+ CellData *cell_data;
+ int filter_id;
GtkWidget *cell;
GtkWidget *button;
GtkWidget *image;
GtkWidget *label;
GtkWidget *button_content;
- cell = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ cell_data = g_new0 (CellData, 1);
+
+ if (*filter_id_p == GTH_FILTER_GRID_NEW_FILTER_ID)
+ *filter_id_p = self->priv->next_filter_id++;
+ filter_id = *filter_id_p;
+
+ cell_data->cell = cell = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- button = gtk_toggle_button_new ();
+ cell_data->button = button = gtk_toggle_button_new ();
g_object_set_data_full (G_OBJECT (button), FILTER_ID_KEY, GINT_TO_POINTER (filter_id), NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (button), "filter-preview");
gtk_widget_set_tooltip_text (button, tooltip);
g_signal_connect (button, "toggled", G_CALLBACK (button_toggled_cb), self);
- image = gtk_image_new_from_surface (preview);
+ cell_data->preview = image = gtk_image_new_from_surface (preview);
gtk_widget_set_size_request (image, PREVIEW_SIZE, PREVIEW_SIZE);
- label = gtk_label_new_with_mnemonic (label_text);
+ cell_data->label = label = gtk_label_new_with_mnemonic (label_text);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
button_content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
@@ -283,36 +336,39 @@ _gth_filter_grid_cell_new (GthFilterGrid *self,
gtk_container_add (GTK_CONTAINER (button), button_content);
gtk_box_pack_start (GTK_BOX (cell), button, FALSE, FALSE, 0);
gtk_widget_show_all (cell);
+ _gth_filter_grid_append_cell (self, cell);
- g_hash_table_insert (self->priv->previews, GINT_TO_POINTER (filter_id), image);
- g_hash_table_insert (self->priv->buttons, GINT_TO_POINTER (filter_id), button);
+ self->priv->filter_ids = g_list_append (self->priv->filter_ids, GINT_TO_POINTER (filter_id));
+ g_hash_table_insert (self->priv->cell_data, GINT_TO_POINTER (filter_id), cell_data);
- return cell;
+ return cell_data;
}
void
gth_filter_grid_add_filter (GthFilterGrid *self,
- int filter_id,
- cairo_surface_t *preview,
+ int filter_id,
+ GthTask *task,
const char *label,
const char *tooltip)
{
- GtkWidget *cell;
+ CellData *cell_data;
- cell = _gth_filter_grid_cell_new (self, filter_id, preview, label, tooltip);
- gtk_grid_attach (GTK_GRID (self->priv->grid),
- cell,
- self->priv->current_column,
- self->priv->current_row,
- 1,
- 1);
+ cell_data = _gth_filter_grid_add_filter (self, &filter_id, NULL, label, tooltip);
+ if (task != NULL)
+ cell_data->task = task;
+}
+
+
+void
+gth_filter_grid_add_filter_with_preview (GthFilterGrid *self,
+ int filter_id,
+ cairo_surface_t *preview,
+ const char *label,
+ const char *tooltip)
+{
+ _gth_filter_grid_add_filter (self, &filter_id, preview, label, tooltip);
- self->priv->current_column++;
- if (self->priv->current_column >= self->priv->n_columns) {
- self->priv->current_column = 0;
- self->priv->current_row++;
- }
}
@@ -321,12 +377,12 @@ gth_filter_grid_set_filter_preview (GthFilterGrid *self,
int filter_id,
cairo_surface_t *preview)
{
- GtkWidget *image;
+ CellData *cell_data;
- image = g_hash_table_lookup (self->priv->previews, GINT_TO_POINTER (filter_id));
- g_return_if_fail (image != NULL);
+ cell_data = g_hash_table_lookup (self->priv->cell_data, GINT_TO_POINTER (filter_id));
+ g_return_if_fail (cell_data != NULL);
- gtk_image_set_from_surface (GTK_IMAGE (image), preview);
+ gtk_image_set_from_surface (GTK_IMAGE (cell_data->preview), preview);
}
@@ -336,10 +392,23 @@ gth_filter_grid_activate (GthFilterGrid *self,
{
GtkWidget *button;
- button = g_hash_table_lookup (self->priv->buttons, GINT_TO_POINTER (filter_id));
- g_return_if_fail (button != NULL);
+ if (filter_id == GTH_FILTER_GRID_NO_FILTER) {
+ if (self->priv->active_button != NULL)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->active_button), FALSE);
+ self->priv->active_button = NULL;
+
+ g_signal_emit (self,
+ gth_filter_grid_signals[ACTIVATED],
+ 0,
+ GTH_FILTER_GRID_NO_FILTER);
+ }
+ else {
+ CellData *cell_data;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ cell_data = g_hash_table_lookup (self->priv->cell_data, GINT_TO_POINTER (filter_id));
+ g_return_if_fail (cell_data != NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cell_data->button), TRUE);
+ }
}
@@ -396,6 +465,8 @@ image_preview_completed_cb (GthTask *task,
current_task = (PreviewTask *) data->current_task->data;
g_return_if_fail (task == current_task->image_task);
+ g_signal_handlers_disconnect_by_data (task, data);
+
if ((error != NULL) || (data->self == NULL)) {
generate_preview_data_free (data);
return;
@@ -479,52 +550,26 @@ resize_task_exec (GthAsyncTask *task,
}
-void
-gth_filter_grid_generate_previews (GthFilterGrid *self,
- cairo_surface_t *image,
- int filter_id,
- ...
- /* series of:
- int filter_id,
- GthTask *image_task,
- */)
+static void
+generate_previews (GthFilterGrid *self,
+ cairo_surface_t *image,
+ GList *tasks)
{
GeneratePreviewData *data;
- GthTask *image_task;
- va_list args;
+ GList *scan;
if (self->priv->gp_data != NULL)
generate_preview_data_cancel (self->priv->gp_data);
data = g_new (GeneratePreviewData, 1);
data->self = self;
- data->tasks = NULL;
+ data->tasks = tasks;
data->cancellable = g_cancellable_new ();;
data->original = NULL;
g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
self->priv->gp_data = data;
- /* collect the (filter, task) pairs */
-
- va_start (args, filter_id);
- image_task = va_arg (args, GthTask *);
- while ((filter_id >= 0) && (image_task != NULL)) {
- PreviewTask *task;
-
- task = g_new0 (PreviewTask, 1);
- task->filter_id = filter_id;
- task->image_task = image_task;
- data->tasks = g_list_prepend (data->tasks, task);
-
- filter_id = va_arg (args, int);
- if (filter_id < 0)
- break;
- image_task = va_arg (args, GthTask *);
- }
- va_end (args);
- data->tasks = g_list_reverse (data->tasks);
-
/* resize the original image */
data->resize_task = gth_image_task_new (_("Resizing images"),
@@ -541,3 +586,76 @@ gth_filter_grid_generate_previews (GthFilterGrid *self,
gth_task_exec (data->resize_task, data->cancellable);
}
+
+
+void
+gth_filter_grid_generate_previews (GthFilterGrid *self,
+ cairo_surface_t *image)
+{
+ GList *tasks;
+ GList *scan;
+
+ /* collect the (filter id, task) pairs */
+
+ tasks = NULL;
+ for (scan = self->priv->filter_ids; scan; scan = scan->next) {
+ int filter_id = GPOINTER_TO_INT (scan->data);
+ CellData *cell_data;
+ PreviewTask *task_data;
+
+ g_return_if_fail (filter_id >= 0);
+
+ cell_data = g_hash_table_lookup (self->priv->cell_data, GINT_TO_POINTER (filter_id));
+ g_return_if_fail (cell_data != NULL);
+
+ if (cell_data->task == NULL)
+ continue;
+
+ task_data = g_new0 (PreviewTask, 1);
+ task_data->filter_id = filter_id;
+ task_data->image_task = g_object_ref (cell_data->task);
+ tasks = g_list_prepend (tasks, task_data);
+ }
+ tasks = g_list_reverse (tasks);
+
+ generate_previews (self, image, tasks);
+}
+
+
+void
+gth_filter_grid_generate_preview (GthFilterGrid *self,
+ int filter_id,
+ cairo_surface_t *image)
+{
+ CellData *cell_data;
+ PreviewTask *task_data;
+ GList *tasks;
+
+ g_return_if_fail (filter_id >= 0);
+
+ cell_data = g_hash_table_lookup (self->priv->cell_data, GINT_TO_POINTER (filter_id));
+ g_return_if_fail (cell_data != NULL);
+
+ if (cell_data->task == NULL)
+ return;
+
+ task_data = g_new0 (PreviewTask, 1);
+ task_data->filter_id = filter_id;
+ task_data->image_task = g_object_ref (cell_data->task);
+ tasks = g_list_prepend (NULL, task_data);
+
+ generate_previews (self, image, tasks);
+}
+
+
+GthTask *
+gth_filter_grid_get_task (GthFilterGrid *self,
+ int filter_id)
+{
+ CellData *cell_data;
+
+ cell_data = g_hash_table_lookup (self->priv->cell_data, GINT_TO_POINTER (filter_id));
+ g_return_val_if_fail (cell_data != NULL, NULL);
+
+ return _g_object_ref (cell_data->task);
+}
diff --git a/gthumb/gth-filter-grid.h b/gthumb/gth-filter-grid.h
index d5621a0..b541add 100644
--- a/gthumb/gth-filter-grid.h
+++ b/gthumb/gth-filter-grid.h
@@ -24,10 +24,12 @@
#include <glib.h>
#include <gtk/gtk.h>
+#include <cairo/cairo.h>
G_BEGIN_DECLS
#define GTH_FILTER_GRID_NO_FILTER -1
+#define GTH_FILTER_GRID_NEW_FILTER_ID -2
#define GTH_TYPE_FILTER_GRID (gth_filter_grid_get_type ())
#define GTH_FILTER_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILTER_GRID, GthFilterGrid))
@@ -58,6 +60,11 @@ GType gth_filter_grid_get_type (void);
GtkWidget * gth_filter_grid_new (void);
void gth_filter_grid_add_filter (GthFilterGrid *self,
int filter_id,
+ GthTask *task,
+ const char *label,
+ const char *tooltip);
+void gth_filter_grid_add_filter_with_preview (GthFilterGrid *self,
+ int filter_id,
cairo_surface_t *preview,
const char *label,
const char *tooltip);
@@ -67,13 +74,12 @@ void gth_filter_grid_set_filter_preview (GthFilterGrid *self,
void gth_filter_grid_activate (GthFilterGrid *self,
int filter_id);
void gth_filter_grid_generate_previews (GthFilterGrid *self,
- cairo_surface_t *image,
- int filter_id,
- ...
- /* series of:
+ cairo_surface_t *image);
+void gth_filter_grid_generate_preview (GthFilterGrid *self,
int filter_id,
- GthTask *image_task,
- */);
+ cairo_surface_t *image);
+GthTask * gth_filter_grid_get_task (GthFilterGrid *self,
+ int filter_id);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]