[gthumb: 4/129] rotate tool: added ability to change the rotation center
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 4/129] rotate tool: added ability to change the rotation center
- Date: Wed, 27 Apr 2011 20:50:42 +0000 (UTC)
commit 1d2294ccc8bd7c10dd0df1ba15e052a355204881
Author: Paolo Bacchilega <paobac src gnome org>
Date: Wed Apr 13 20:12:14 2011 +0200
rotate tool: added ability to change the rotation center
the user can define the rotation center double-clicking on the image or using the controls in the tool options.
extensions/file_tools/data/ui/rotate-options.ui | 198 +++++++++++++---------
extensions/file_tools/gth-file-tool-rotate.c | 116 ++++++++++---
extensions/file_tools/gth-image-rotator.c | 116 ++++++++------
extensions/file_tools/gth-image-rotator.h | 6 +-
gthumb/gth-image-viewer.c | 4 +-
5 files changed, 280 insertions(+), 160 deletions(-)
---
diff --git a/extensions/file_tools/data/ui/rotate-options.ui b/extensions/file_tools/data/ui/rotate-options.ui
index 58735c7..fcb796b 100644
--- a/extensions/file_tools/data/ui/rotate-options.ui
+++ b/extensions/file_tools/data/ui/rotate-options.ui
@@ -81,7 +81,56 @@
</packing>
</child>
<child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox6">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBox" id="size_combobox">
+ <property name="visible">True</property>
+ <property name="model">size_liststore</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Size</property>
+ <property name="use_markup">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
@@ -90,15 +139,13 @@
<property name="top_padding">6</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkTable" id="table3">
+ <object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkHBox" id="hbox4">
+ <object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
- <property name="spacing">6</property>
+ <property name="spacing">4</property>
<child>
<object class="GtkSpinButton" id="center_x_spinbutton">
<property name="visible">True</property>
@@ -117,6 +164,33 @@
</packing>
</child>
<child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">×</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="center_y_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">center_y_adjustment</property>
+ <property name="climb_rate">1</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">if-valid</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkComboBox" id="unit_combobox">
<property name="visible">True</property>
<property name="model">unit_liststore</property>
@@ -131,28 +205,32 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">1</property>
+ <property name="position">3</property>
</packing>
</child>
</object>
<packing>
- <property name="x_options">GTK_FILL</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox5">
+ <object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
- <property name="spacing">6</property>
+ <property name="layout_style">start</property>
<child>
- <object class="GtkSpinButton" id="center_y_spinbutton">
+ <object class="GtkButton" id="center_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="width_chars">6</property>
- <property name="adjustment">center_y_adjustment</property>
- <property name="climb_rate">1</property>
- <property name="numeric">True</property>
- <property name="update_policy">if-valid</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Center</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -160,14 +238,9 @@
<property name="position">0</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
@@ -177,46 +250,7 @@
<child type="label">
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
- <property name="label" translatable="yes">Center</property>
- <property name="use_markup">True</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="frame1">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkComboBox" id="size_combobox">
- <property name="visible">True</property>
- <property name="model">size_liststore</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Size</property>
+ <property name="label" translatable="yes">Axis of rotation</property>
<property name="use_markup">True</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -250,19 +284,6 @@
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Background:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
<object class="GtkHBox" id="grid_box">
<property name="visible">True</property>
<property name="spacing">6</property>
@@ -289,24 +310,39 @@
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox3">
+ <object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Background:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">background_colorbutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
<child>
<object class="GtkColorButton" id="background_colorbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <property name="relief">none</property>
<property name="use_alpha">True</property>
+ <property name="title" translatable="yes"></property>
<property name="color">#000000000000</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
@@ -416,12 +452,12 @@
</data>
</object>
<object class="GtkAdjustment" id="center_x_adjustment">
- <property name="lower">1</property>
+ <property name="lower">-999999</property>
<property name="upper">999999</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="center_y_adjustment">
- <property name="lower">1</property>
+ <property name="lower">-999999</property>
<property name="upper">999999</property>
<property name="step_increment">1</property>
</object>
diff --git a/extensions/file_tools/gth-file-tool-rotate.c b/extensions/file_tools/gth-file-tool-rotate.c
index e923f73..49a3bc8 100644
--- a/extensions/file_tools/gth-file-tool-rotate.c
+++ b/extensions/file_tools/gth-file-tool-rotate.c
@@ -108,12 +108,51 @@ ok_button_clicked_cb (GtkButton *button,
static void
+rotator_center_changed_cb (GObject *gobject,
+ gpointer user_data)
+{
+ GthFileToolRotate *self = user_data;
+ int x, y;
+ double dx, dy;
+
+ g_signal_handlers_block_by_data (GET_WIDGET ("center_x_spinbutton"), self);
+ g_signal_handlers_block_by_data (GET_WIDGET ("center_y_spinbutton"), self);
+
+ gth_image_rotator_get_center (self->priv->rotator, &x, &y);
+ if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
+ dx = ((double) x / self->priv->pixbuf_width) * 100.0;
+ dy = ((double) y / self->priv->pixbuf_height) * 100.0;
+ }
+ else {
+ dx = x;
+ dy = y;
+ }
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")), dx);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")), dy);
+
+ g_signal_handlers_unblock_by_data (GET_WIDGET ("center_x_spinbutton"), self);
+ g_signal_handlers_unblock_by_data (GET_WIDGET ("center_y_spinbutton"), self);
+}
+
+
+static void
center_position_changed_cb (GtkSpinButton *spinbutton,
gpointer user_data)
{
- /*GthFileToolRotate *self = user_data;
+ GthFileToolRotate *self = user_data;
+ double x, y;
- FIXME */
+ g_signal_handlers_block_by_data (self->priv->rotator, user_data);
+
+ x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")));
+ y = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")));
+ if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
+ x = round ((double) self->priv->pixbuf_width * (x / 100.0));
+ y = round ((double) self->priv->pixbuf_height * (y / 100.0));
+ }
+ gth_image_rotator_set_center (self->priv->rotator, x, y);
+
+ g_signal_handlers_unblock_by_data (self->priv->rotator, user_data);
}
@@ -121,35 +160,41 @@ static void
unit_combobox_changed_cb (GtkComboBox *combobox,
gpointer user_data)
{
- /* FIXME GthFileToolRotate *self = user_data;
+ GthFileToolRotate *self = user_data;
- g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
- g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+ g_signal_handlers_block_by_data (GET_WIDGET ("center_x_spinbutton"), self);
+ g_signal_handlers_block_by_data (GET_WIDGET ("center_y_spinbutton"), self);
self->priv->unit = gtk_combo_box_get_active (combobox);
if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
double p;
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 2);
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 2);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")), 2);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")), 2);
+
+ p = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton"))) / self->priv->pixbuf_width * 100.0;
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")), p);
- p = ((double) self->priv->new_width) / self->priv->pixbuf_width * 100.0;
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), p);
- p = ((double) self->priv->new_height) / self->priv->pixbuf_height * 100.0;
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), p);
+ p = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton"))) / self->priv->pixbuf_height * 100.0;
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")), p);
}
else if (self->priv->unit == GTH_UNIT_PIXELS) {
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 0);
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), self->priv->new_width);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), self->priv->new_height);
+ double p;
+
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")), 0);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")), 0);
+
+ p = round (self->priv->pixbuf_width * (gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton"))) / 100.0));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_x_spinbutton")), p);
+
+ p = round (self->priv->pixbuf_height * (gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton"))) / 100.0));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("center_y_spinbutton")), p);
}
- g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
- g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+ g_signal_handlers_unblock_by_data (GET_WIDGET ("center_x_spinbutton"), self);
+ g_signal_handlers_unblock_by_data (GET_WIDGET ("center_y_spinbutton"), self);
- selection_width_value_changed_cb (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), self);
- */
+ center_position_changed_cb (NULL, self);
}
@@ -293,6 +338,18 @@ background_colorbutton_notify_color_cb (GObject *gobject,
}
+static void
+center_button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ GthFileToolRotate *self = user_data;
+
+ gth_image_rotator_set_center (self->priv->rotator,
+ self->priv->pixbuf_width * 0.5,
+ self->priv->pixbuf_height * 0.5);
+}
+
+
static GtkWidget *
gth_file_tool_rotate_get_options (GthFileTool *base)
{
@@ -355,13 +412,13 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
self->priv->angle_adj = gimp_scale_entry_new (GET_WIDGET ("angle_box"),
NULL,
- 0.0, -180.0, 180.0, 5.0, 10.0, 0);
+ 0.0, -180.0, 180.0, 1.0, 10.0, 2);
self->priv->small_angle_adj = gimp_scale_entry_new (GET_WIDGET ("small_angle_box"),
NULL,
0.0, -5.0, 5.0, 0.01, 0.1, 2);
self->priv->grid_adj = gimp_scale_entry_new (GET_WIDGET ("grid_box"),
NULL,
- DEFAULT_GRID, 1.0, 50.0, 1.0, 10.0, 0);
+ DEFAULT_GRID, 2.0, 50.0, 1.0, 10.0, 0);
g_signal_connect (GET_WIDGET ("ok_button"),
"clicked",
@@ -411,17 +468,22 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
"notify::color",
G_CALLBACK (background_colorbutton_notify_color_cb),
self);
-
+ g_signal_connect (GET_WIDGET ("center_button"),
+ "clicked",
+ G_CALLBACK (center_button_clicked_cb),
+ self);
self->priv->rotator = (GthImageRotator *) gth_image_rotator_new (GTH_IMAGE_VIEWER (viewer));
gth_image_rotator_set_grid (self->priv->rotator, FALSE, DEFAULT_GRID);
_gth_file_tool_rotate (self, 0.0);
+ gth_image_rotator_set_center (self->priv->rotator,
+ self->priv->pixbuf_width * 0.5,
+ self->priv->pixbuf_height * 0.5);
- /*g_signal_connect (self->priv->rotator,
- "changed",
- G_CALLBACK (rotator_changed_cb),
+ g_signal_connect (self->priv->rotator,
+ "center-changed",
+ G_CALLBACK (rotator_center_changed_cb),
self);
- */
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->rotator);
@@ -479,7 +541,7 @@ gth_file_tool_rotate_instance_init (GthFileToolRotate *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL_ROTATE, GthFileToolRotatePrivate);
self->priv->tmp_pixbuf = NULL;
- self->priv->step = 5.0;
+ self->priv->step = 0.0; /* FIXME */
self->priv->use_grid = TRUE;
gth_file_tool_construct (GTH_FILE_TOOL (self), "tool-rotate", _("Rotate..."), _("Rotate"), TRUE);
}
diff --git a/extensions/file_tools/gth-image-rotator.c b/extensions/file_tools/gth-image-rotator.c
index af1d66b..3e3fab1 100644
--- a/extensions/file_tools/gth-image-rotator.c
+++ b/extensions/file_tools/gth-image-rotator.c
@@ -27,6 +27,7 @@
enum {
CHANGED,
+ CENTER_CHANGED,
LAST_SIGNAL
};
@@ -51,10 +52,11 @@ struct _GthImageRotatorPrivate {
int original_width;
int original_height;
- cairo_surface_t *image;
- GdkRectangle image_area;
+ double preview_zoom;
+ cairo_surface_t *preview_image;
+ GdkRectangle preview_image_area;
+ GdkPoint preview_center;
GdkRectangle clip_area;
- gboolean paint_image;
cairo_matrix_t matrix;
};
@@ -79,8 +81,11 @@ _gth_image_rotator_update_tranformation_matrix (GthImageRotator *self)
int tx, ty;
double zoom;
- tx = self->priv->image_area.x + self->priv->center.x;
- ty = self->priv->image_area.y + self->priv->center.y;
+ self->priv->preview_center.x = self->priv->center.x * self->priv->preview_zoom;
+ self->priv->preview_center.y = self->priv->center.y * self->priv->preview_zoom;
+
+ tx = self->priv->preview_image_area.x + self->priv->preview_center.x;
+ ty = self->priv->preview_image_area.y + self->priv->preview_center.y;
zoom = gth_image_viewer_get_zoom (self->priv->viewer);
cairo_matrix_init_identity (&self->priv->matrix);
@@ -90,7 +95,7 @@ _gth_image_rotator_update_tranformation_matrix (GthImageRotator *self)
gth_transform_resize (&self->priv->matrix,
self->priv->resize,
- &self->priv->image_area,
+ &self->priv->preview_image_area,
&self->priv->clip_area);
}
@@ -103,20 +108,17 @@ update_image_surface (GthImageRotator *self)
int max_size;
int width;
int height;
- double zoom;
GdkPixbuf *tmp_pixbuf;
- if (self->priv->image != NULL) {
- cairo_surface_destroy (self->priv->image);
- self->priv->image = NULL;
+ if (self->priv->preview_image != NULL) {
+ cairo_surface_destroy (self->priv->preview_image);
+ self->priv->preview_image = NULL;
}
src_pixbuf = gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (self->priv->viewer));
if (src_pixbuf == NULL)
return;
- zoom = gth_image_viewer_get_zoom (self->priv->viewer);
-
self->priv->original_width = gdk_pixbuf_get_width (src_pixbuf);
self->priv->original_height = gdk_pixbuf_get_height (src_pixbuf);
width = self->priv->original_width;
@@ -127,14 +129,14 @@ update_image_surface (GthImageRotator *self)
tmp_pixbuf = _gdk_pixbuf_scale_simple_safe (src_pixbuf, width, height, GDK_INTERP_BILINEAR);
else
tmp_pixbuf = gdk_pixbuf_copy (src_pixbuf);
- self->priv->image = _cairo_image_surface_create_from_pixbuf (tmp_pixbuf);
- self->priv->image_area.width = width;
- self->priv->image_area.height = height;
- self->priv->image_area.x = MAX ((allocation.width - self->priv->image_area.width) / 2, 0);
- self->priv->image_area.y = MAX ((allocation.height - self->priv->image_area.height) / 2, 0);
- self->priv->center.x = self->priv->image_area.width * 0.5;
- self->priv->center.y = self->priv->image_area.height * 0.5;
+ self->priv->preview_zoom = (double) width / self->priv->original_width;
+
+ self->priv->preview_image = _cairo_image_surface_create_from_pixbuf (tmp_pixbuf);
+ self->priv->preview_image_area.width = width;
+ self->priv->preview_image_area.height = height;
+ self->priv->preview_image_area.x = MAX ((allocation.width - self->priv->preview_image_area.width) / 2, 0);
+ self->priv->preview_image_area.y = MAX ((allocation.height - self->priv->preview_image_area.height) / 2, 0);
_gth_image_rotator_update_tranformation_matrix (self);
@@ -166,21 +168,21 @@ gth_image_rotator_unmap (GthImageViewerTool *base)
static void
paint_image (GthImageRotator *self,
- GdkEventExpose *event,
cairo_t *cr)
{
cairo_save (cr);
+ cairo_set_matrix (cr, &self->priv->matrix);
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
- cairo_set_source_surface (cr, self->priv->image,
- self->priv->image_area.x,
- self->priv->image_area.y);
+ cairo_set_source_surface (cr, self->priv->preview_image,
+ self->priv->preview_image_area.x,
+ self->priv->preview_image_area.y);
cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_FAST);
cairo_rectangle (cr,
- self->priv->image_area.x,
- self->priv->image_area.y,
- self->priv->image_area.width,
- self->priv->image_area.height);
+ self->priv->preview_image_area.x,
+ self->priv->preview_image_area.y,
+ self->priv->preview_image_area.width,
+ self->priv->preview_image_area.height);
cairo_fill (cr);
cairo_restore (cr);
@@ -256,8 +258,8 @@ paint_center (GthImageRotator *self,
/* rotation center */
cairo_translate (cr,
- self->priv->image_area.x + self->priv->center.x + 0.5,
- self->priv->image_area.y + self->priv->center.y + 0.5);
+ self->priv->preview_image_area.x + self->priv->preview_center.x + 0.5,
+ self->priv->preview_image_area.y + self->priv->preview_center.y + 0.5);
cairo_arc (cr, 0.0, 0.0, 10.0, 0.0, 2 * M_PI);
cairo_move_to (cr, 0.0, - 10.0);
@@ -278,9 +280,8 @@ gth_image_rotator_expose (GthImageViewerTool *base,
GthImageRotator *self = GTH_IMAGE_ROTATOR (base);
GtkStyle *style;
GtkAllocation allocation;
- cairo_matrix_t matrix;
- if (self->priv->image == NULL)
+ if (self->priv->preview_image == NULL)
return;
cairo_save (cr);
@@ -317,21 +318,13 @@ gth_image_rotator_expose (GthImageViewerTool *base,
/* image */
- matrix = self->priv->matrix;
- cairo_set_matrix (cr, &matrix);
-
- if (self->priv->paint_image)
- paint_image (self, event, cr);
+ paint_image (self, cr);
/* grid */
- cairo_matrix_init_identity (&matrix);
- cairo_set_matrix (cr, &matrix);
-
if (self->priv->paint_grid)
paint_grid (self, event, cr);
-
- /* paint_center (self, event, cr); FIXME */
+ paint_center (self, event, cr);
cairo_restore (cr);
}
@@ -351,7 +344,15 @@ static gboolean
gth_image_rotator_button_press (GthImageViewerTool *base,
GdkEventButton *event)
{
- /* FIXME */
+ GthImageRotator *self = GTH_IMAGE_ROTATOR (base);
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ double x, y;
+
+ x = (event->x - self->priv->preview_image_area.x) / self->priv->preview_zoom;
+ y = (event->y - self->priv->preview_image_area.y) / self->priv->preview_zoom;
+ gth_image_rotator_set_center (self, (int) x, (int) y);
+ }
return FALSE;
}
@@ -385,8 +386,7 @@ static void
gth_image_rotator_instance_init (GthImageRotator *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_ROTATOR, GthImageRotatorPrivate);
- self->priv->image = NULL;
- self->priv->paint_image = TRUE;
+ self->priv->preview_image = NULL;
self->priv->paint_grid = FALSE;
self->priv->grid_lines = 0;
self->priv->resize = GTH_TRANSFORM_RESIZE_CLIP;
@@ -406,8 +406,8 @@ gth_image_rotator_finalize (GObject *object)
g_return_if_fail (GTH_IS_IMAGE_ROTATOR (object));
self = (GthImageRotator *) object;
- if (self->priv->image != NULL)
- cairo_surface_destroy (self->priv->image);
+ if (self->priv->preview_image != NULL)
+ cairo_surface_destroy (self->priv->preview_image);
/* Chain up */
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -433,6 +433,14 @@ gth_image_rotator_class_init (GthImageRotatorClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+ signals[CENTER_CHANGED] = g_signal_new ("center-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthImageRotatorClass, center_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
}
@@ -510,7 +518,17 @@ gth_image_rotator_set_center (GthImageRotator *self,
_gth_image_rotator_update_tranformation_matrix (self);
gtk_widget_queue_draw (GTK_WIDGET (self->priv->viewer));
- g_signal_emit (self, signals[CHANGED], 0);
+ g_signal_emit (self, signals[CENTER_CHANGED], 0);
+}
+
+
+void
+gth_image_rotator_get_center (GthImageRotator *self,
+ int *x,
+ int *y)
+{
+ *x = self->priv->center.x;
+ *y = self->priv->center.y;
}
@@ -583,8 +601,8 @@ gth_image_rotator_get_result (GthImageRotator *self)
/* compute the transformation matrix and the clip area */
- tx = self->priv->original_width * 0.5;
- ty = self->priv->original_height * 0.5;
+ tx = self->priv->center.x;
+ ty = self->priv->center.y;
cairo_matrix_init_identity (&matrix);
cairo_matrix_translate (&matrix, tx, ty);
cairo_matrix_rotate (&matrix, self->priv->angle);
diff --git a/extensions/file_tools/gth-image-rotator.h b/extensions/file_tools/gth-image-rotator.h
index 25c7a7e..223ba9a 100644
--- a/extensions/file_tools/gth-image-rotator.h
+++ b/extensions/file_tools/gth-image-rotator.h
@@ -52,7 +52,8 @@ struct _GthImageRotatorClass
/*< signals >*/
- void (* changed) (GthImageRotator *rotator);
+ void (* changed) (GthImageRotator *rotator);
+ void (* center_changed) (GthImageRotator *rotator);
};
GType gth_image_rotator_get_type (void);
@@ -60,6 +61,9 @@ GthImageViewerTool * gth_image_rotator_new (GthImageViewer *vie
void gth_image_rotator_set_center (GthImageRotator *rotator,
int x,
int y);
+void gth_image_rotator_get_center (GthImageRotator *rotator,
+ int *x,
+ int *y);
void gth_image_rotator_set_angle (GthImageRotator *rotator,
double angle);
void gth_image_rotator_set_grid (GthImageRotator *self,
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index c4717c0..662d657 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -916,14 +916,14 @@ gth_image_viewer_button_press (GtkWidget *widget,
|| (event->type == GDK_3BUTTON_PRESS))
{
self->priv->double_click = TRUE;
- return FALSE;
+ /*return FALSE;*/
}
else
self->priv->double_click = FALSE;
retval = gth_image_viewer_tool_button_press (self->priv->tool, event);
- if (self->pressed) {
+ if (self->pressed && ! self->priv->double_click) {
self->event_x_start = self->event_x_prev = event->x;
self->event_y_start = self->event_y_prev = event->y;
self->drag_x = self->drag_x_start = self->drag_x_prev = event->x + self->x_offset;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]