[gthumb/ext: 12/20] [image_print] allow to move, resize and rotate the selected image
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 12/20] [image_print] allow to move, resize and rotate the selected image
- Date: Wed, 25 Nov 2009 17:13:50 +0000 (UTC)
commit 015d1e35d45d7edf4f38ddd466ac7464114d7084
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Nov 23 19:50:07 2009 +0100
[image_print] allow to move, resize and rotate the selected image
extensions/image_print/data/ui/print-layout.ui | 383 ++++++++++-----------
extensions/image_print/gth-image-info.c | 98 ++++--
extensions/image_print/gth-image-info.h | 21 +-
extensions/image_print/gth-image-print-job.c | 343 ++++++++++++++++---
extensions/image_print/gth-load-image-info-task.c | 23 +--
5 files changed, 550 insertions(+), 318 deletions(-)
---
diff --git a/extensions/image_print/data/ui/print-layout.ui b/extensions/image_print/data/ui/print-layout.ui
index d178622..7e52816 100644
--- a/extensions/image_print/data/ui/print-layout.ui
+++ b/extensions/image_print/data/ui/print-layout.ui
@@ -9,13 +9,13 @@
</columns>
<data>
<row>
- <col id="0" translatable="yes">mm</col>
+ <col id="0" translatable="yes">pixels</col>
</row>
<row>
- <col id="0" translatable="yes">inches</col>
+ <col id="0" translatable="yes">mm</col>
</row>
<row>
- <col id="0" translatable="yes">pixels</col>
+ <col id="0" translatable="yes">inches</col>
</row>
</data>
</object>
@@ -35,22 +35,6 @@
<col id="0" translatable="yes">Custom</col>
<col id="1">1</col>
</row>
- <row>
- <col id="0" translatable="yes">Top</col>
- <col id="1">2</col>
- </row>
- <row>
- <col id="0" translatable="yes">Bottom</col>
- <col id="1">3</col>
- </row>
- <row>
- <col id="0" translatable="yes">Left</col>
- <col id="1">4</col>
- </row>
- <row>
- <col id="0" translatable="yes">Right</col>
- <col id="1">5</col>
- </row>
</data>
</object>
<object class="GtkListStore" id="size_liststore">
@@ -124,6 +108,7 @@
</child>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
@@ -223,18 +208,29 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox2">
+ <object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkLabel" id="label4">
+ <object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Image</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Image</property>
+ <property name="use_underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">0</property>
@@ -245,256 +241,199 @@
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox6">
+ <object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkTable" id="table2">
+ <object class="GtkTable" id="table1">
<property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">4</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
- <object class="GtkLabel" id="label9">
+ <object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Position:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label15">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Scale:</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="GtkComboBox" id="combobox2">
- <property name="visible">True</property>
- <property name="model">align_liststore</property>
- <property name="active">0</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext3"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
+ <property name="label" translatable="yes">Position:</property>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
</child>
<child>
- <object class="GtkHBox" id="scale_image_box2">
+ <object class="GtkHBox" id="hbox6">
<property name="visible">True</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkHScale" id="image_scale2">
+ <object class="GtkSpinButton" id="img_left_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="adjustment">scale_adjustment</property>
- <property name="digits">0</property>
- <property name="value_pos">right</property>
+ <property name="tooltip_text" translatable="yes">Left</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">left_adjustment</property>
+ <property name="climb_rate">1</property>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="label14">
+ <object class="GtkSpinButton" id="img_top_spinbutton">
<property name="visible">True</property>
- <property name="label" translatable="yes">%</property>
- <property name="justify">center</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Top</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">top_adjustment</property>
+ <property name="climb_rate">1</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="rotation_combobox">
- <property name="visible">True</property>
- <property name="model">rotation_liststore</property>
- <property name="active">0</property>
<child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
+ <object class="GtkComboBox" id="position_combobox">
+ <property name="visible">True</property>
+ <property name="model">align_liststore</property>
+ <property name="active">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
</child>
</object>
<packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="label1">
+ <object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Rotation:</property>
- <property name="use_underline">True</property>
+ <property name="label" translatable="yes">Size:</property>
</object>
<packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="top_padding">6</property>
- <property name="bottom_padding">6</property>
<child>
- <object class="GtkHSeparator" id="hseparator1">
+ <object class="GtkHBox" id="hbox11">
<property name="visible">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment3">
- <property name="visible">True</property>
- <child>
- <object class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">5</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Width:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="img_width_spinbutton3">
+ <object class="GtkSpinButton" id="img_width_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Width</property>
<property name="invisible_char">●</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">width_adjustment</property>
<property name="climb_rate">1</property>
- <property name="digits">1</property>
</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>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Height:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="expand">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkSpinButton" id="img_height_spinbutton3">
+ <object class="GtkSpinButton" id="img_height_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Height</property>
<property name="invisible_char">●</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">height_adjustment</property>
<property name="climb_rate">1</property>
- <property name="digits">1</property>
</object>
<packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="expand">False</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Left:</property>
- <property name="use_underline">True</property>
- </object>
- </child>
- <child>
- <object class="GtkSpinButton" id="img_width_spinbutton1">
+ <object class="GtkHScale" id="image_scale">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="climb_rate">1</property>
- <property name="digits">1</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Top:</property>
- <property name="use_underline">True</property>
+ <property name="adjustment">scale_adjustment</property>
+ <property name="digits">2</property>
+ <property name="value_pos">right</property>
</object>
<packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
+ <property name="position">2</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>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
<child>
- <object class="GtkSpinButton" id="img_height_spinbutton1">
+ <object class="GtkComboBox" id="rotation_combobox">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="climb_rate">1</property>
- <property name="digits">1</property>
+ <property name="model">rotation_liststore</property>
+ <property name="active">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
</object>
<packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
+ <property name="expand">False</property>
+ <property name="position">0</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Rotation:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Unit:</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
<child>
<object class="GtkComboBox" id="combobox1">
<property name="visible">True</property>
@@ -508,18 +447,21 @@
</child>
</object>
<packing>
- <property name="left_attach">4</property>
- <property name="right_attach">5</property>
+ <property name="expand">False</property>
+ <property name="position">0</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">0</property>
</packing>
</child>
</object>
@@ -669,10 +611,11 @@
</child>
</object>
<object class="GtkAdjustment" id="scale_adjustment">
- <property name="upper">100</property>
- <property name="value">100</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
+ <property name="lower">0.01</property>
+ <property name="upper">1</property>
+ <property name="value">1</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">0.10000000000000001</property>
</object>
<object class="GtkListStore" id="rotation_liststore">
<columns>
@@ -700,4 +643,24 @@
</row>
</data>
</object>
+ <object class="GtkAdjustment" id="left_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="width_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="height_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="top_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
</interface>
diff --git a/extensions/image_print/gth-image-info.c b/extensions/image_print/gth-image-info.c
index 4cd7375..22d0462 100644
--- a/extensions/image_print/gth-image-info.c
+++ b/extensions/image_print/gth-image-info.c
@@ -25,6 +25,9 @@
#include "gth-image-info.h"
+#define THUMBNAIL_SIZE 256
+
+
static void
gth_rectangle_init (GthRectangle *rect)
{
@@ -44,12 +47,16 @@ gth_image_info_new (GthFileData *file_data)
image_info->ref_count = 1;
image_info->file_data = g_object_ref (file_data);
image_info->pixbuf = NULL;
+ image_info->thumbnail_original = NULL;
image_info->thumbnail = NULL;
image_info->thumbnail_active = NULL;
- image_info->rotation = 0;
- image_info->zoom = 0.0;
+ image_info->rotation = GTH_TRANSFORM_NONE;
+ image_info->zoom = 1.0;
+ image_info->transformation.x = 0.0;
+ image_info->transformation.y = 0.0;
image_info->print_comment = FALSE;
image_info->page = -1;
+ image_info->reset = TRUE;
gth_rectangle_init (&image_info->boundary);
gth_rectangle_init (&image_info->maximized);
gth_rectangle_init (&image_info->image);
@@ -76,6 +83,7 @@ gth_image_info_unref (GthImageInfo *image_info)
_g_object_unref (image_info->file_data);
_g_object_unref (image_info->pixbuf);
+ _g_object_unref (image_info->thumbnail_original);
_g_object_unref (image_info->thumbnail);
_g_object_unref (image_info->thumbnail_active);
g_free (image_info->comment_text);
@@ -84,53 +92,79 @@ gth_image_info_unref (GthImageInfo *image_info)
void
+gth_image_info_set_pixbuf (GthImageInfo *image_info,
+ GdkPixbuf *pixbuf)
+{
+ int thumb_w;
+ int thumb_h;
+
+ g_return_if_fail (pixbuf != NULL);
+
+ _g_object_clear (&image_info->pixbuf);
+ _g_object_clear (&image_info->thumbnail_original);
+ _g_object_clear (&image_info->thumbnail);
+ _g_object_clear (&image_info->thumbnail_active);
+
+ image_info->pixbuf = g_object_ref (pixbuf);
+ thumb_w = image_info->original_width = image_info->pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+ thumb_h = image_info->original_height = image_info->pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+ if (scale_keeping_ratio (&thumb_w, &thumb_h, THUMBNAIL_SIZE, THUMBNAIL_SIZE, FALSE))
+ image_info->thumbnail_original = gdk_pixbuf_scale_simple (pixbuf,
+ thumb_w,
+ thumb_h,
+ GDK_INTERP_BILINEAR);
+ else
+ image_info->thumbnail_original = g_object_ref (image_info->pixbuf);
+
+ image_info->thumbnail = g_object_ref (image_info->thumbnail_original);
+ image_info->thumbnail_active = gdk_pixbuf_copy (image_info->thumbnail);
+ _gdk_pixbuf_colorshift (image_info->thumbnail_active, image_info->thumbnail_active, 30);
+}
+
+
+void
+gth_image_info_reset (GthImageInfo *image_info)
+{
+ image_info->reset = TRUE;
+}
+
+
+void
gth_image_info_rotate (GthImageInfo *image_info,
int angle)
{
- GdkPixbuf *tmp_pixbuf;
-
- image_info->transform = GTH_TRANSFORM_NONE;
+ angle = angle % 360;
+ image_info->rotation = GTH_TRANSFORM_NONE;
switch (angle) {
case 90:
- image_info->transform = GTH_TRANSFORM_ROTATE_90;
+ image_info->rotation = GTH_TRANSFORM_ROTATE_90;
break;
case 180:
- image_info->transform = GTH_TRANSFORM_ROTATE_180;
+ image_info->rotation = GTH_TRANSFORM_ROTATE_180;
break;
case 270:
- image_info->transform = GTH_TRANSFORM_ROTATE_270;
+ image_info->rotation = GTH_TRANSFORM_ROTATE_270;
break;
default:
break;
}
- if (image_info->transform == GTH_TRANSFORM_NONE)
- return;
+ _g_object_clear (&image_info->thumbnail);
+ if (image_info->thumbnail_original != NULL)
+ image_info->thumbnail = _gdk_pixbuf_transform (image_info->thumbnail_original, image_info->rotation);
- /* FIXME
- tmp_pixbuf = image_info->pixbuf;
- if (tmp_pixbuf != NULL) {
- image_info->pixbuf = _gdk_pixbuf_transform (tmp_pixbuf, transform);
- g_object_unref (tmp_pixbuf);
+ _g_object_clear (&image_info->thumbnail_active);
+ if (image_info->thumbnail != NULL) {
+ image_info->thumbnail_active = gdk_pixbuf_copy (image_info->thumbnail);
+ _gdk_pixbuf_colorshift (image_info->thumbnail_active, image_info->thumbnail_active, 30);
}
- */
- tmp_pixbuf = image_info->thumbnail;
- if (tmp_pixbuf != NULL) {
- image_info->thumbnail = _gdk_pixbuf_transform (tmp_pixbuf, image_info->transform);
- g_object_unref (tmp_pixbuf);
- }
-
- tmp_pixbuf = image_info->thumbnail_active;
- if (tmp_pixbuf != NULL) {
- image_info->thumbnail_active = _gdk_pixbuf_transform (tmp_pixbuf, image_info->transform);
- g_object_unref (tmp_pixbuf);
- }
-
- image_info->rotation = (image_info->rotation + angle) % 360;
if ((angle == 90) || (angle == 270)) {
- int tmp = image_info->pixbuf_width;
- image_info->pixbuf_width = image_info->pixbuf_height;
- image_info->pixbuf_height = tmp;
+ image_info->pixbuf_width = image_info->original_height;
+ image_info->pixbuf_height = image_info->original_width;
+ }
+ else {
+ image_info->pixbuf_width = image_info->original_width;
+ image_info->pixbuf_height = image_info->original_height;
}
}
diff --git a/extensions/image_print/gth-image-info.h b/extensions/image_print/gth-image-info.h
index c6b3d34..ff862e7 100644
--- a/extensions/image_print/gth-image-info.h
+++ b/extensions/image_print/gth-image-info.h
@@ -38,17 +38,21 @@ typedef struct {
typedef struct {
int ref_count;
GthFileData *file_data;
+ int original_width;
+ int original_height;
int pixbuf_width;
int pixbuf_height;
GdkPixbuf *pixbuf;
+ GdkPixbuf *thumbnail_original;
GdkPixbuf *thumbnail;
GdkPixbuf *thumbnail_active;
int page;
int row;
int col;
- int rotation;
- GthTransform transform;
+ GthTransform rotation;
double zoom;
+ GthRectangle transformation;
+ gboolean reset;
gboolean print_comment;
char *comment_text;
GthRectangle boundary;
@@ -57,11 +61,14 @@ typedef struct {
GthRectangle comment;
} GthImageInfo;
-GthImageInfo * gth_image_info_new (GthFileData *file_data);
-GthImageInfo * gth_image_info_ref (GthImageInfo *image_info);
-void gth_image_info_unref (GthImageInfo *image_info);
-void gth_image_info_rotate (GthImageInfo *image_info,
- int angle);
+GthImageInfo * gth_image_info_new (GthFileData *file_data);
+GthImageInfo * gth_image_info_ref (GthImageInfo *image_info);
+void gth_image_info_unref (GthImageInfo *image_info);
+void gth_image_info_set_pixbuf (GthImageInfo *image_info,
+ GdkPixbuf *pixbuf);
+void gth_image_info_reset (GthImageInfo *image_info);
+void gth_image_info_rotate (GthImageInfo *image_info,
+ int angle);
G_END_DECLS
diff --git a/extensions/image_print/gth-image-print-job.c b/extensions/image_print/gth-image-print-job.c
index 19ed25e..c943480 100644
--- a/extensions/image_print/gth-image-print-job.c
+++ b/extensions/image_print/gth-image-print-job.c
@@ -57,6 +57,14 @@ struct _GthImagePrintJobPrivate {
GtkWidget *caption_chooser;
GthImageInfo *selected;
+ gulong rotation_combobox_changed_event;
+ gulong scale_adjustment_value_changed_event;
+ gulong left_adjustment_value_changed_event;
+ gulong top_adjustment_value_changed_event;
+ gulong width_adjustment_value_changed_event;
+ gulong height_adjustment_value_changed_event;
+ gulong position_combobox_changed_event;
+
/* settings */
GthImageInfo **images;
@@ -125,6 +133,8 @@ gth_image_print_job_init (GthImagePrintJob *self)
self->priv->current_page = 0;
self->priv->caption_attributes = eel_gconf_get_string (PREF_IMAGE_PRINT_CAPTION, "");
self->priv->selected = NULL;
+ self->priv->requested_images_per_page = 1;
+ self->priv->auto_sizing = TRUE;
}
@@ -310,7 +320,7 @@ gth_image_print_job_update_page_layout (GthImagePrintJob *self,
font_desc = pango_font_description_from_string ("[sans serif] [normal] [10]");
pango_layout_set_font_description (pango_layout, font_desc);
- attributes_v = g_strsplit(self->priv->caption_attributes, ",", -1);
+ attributes_v = g_strsplit (self->priv->caption_attributes, ",", -1);
for (i = 0; i < self->priv->n_images; i++) {
GthImageInfo *image_info = self->priv->images[i];
double max_image_width;
@@ -323,8 +333,8 @@ gth_image_print_job_update_page_layout (GthImagePrintJob *self,
if (self->priv->selected == NULL)
self->priv->selected = image_info;
+ /* FIXME
gth_image_info_rotate (image_info, (360 - image_info->rotation) % 360);
- /*
if (((self->priv->max_image_width > self->priv->max_image_height)
&& (image_info->pixbuf_width < image_info->pixbuf_height))
|| ((self->priv->max_image_width < self->priv->max_image_height)
@@ -334,7 +344,6 @@ gth_image_print_job_update_page_layout (GthImagePrintJob *self,
}
*/
- image_info->zoom = 1.0;
image_info->boundary.x = (image_info->col - 1) * (self->priv->max_image_width + self->priv->x_padding);
image_info->boundary.y = (image_info->row - 1) * (self->priv->max_image_height + self->priv->y_padding);
image_info->boundary.width = self->priv->max_image_width;
@@ -347,6 +356,11 @@ gth_image_print_job_update_page_layout (GthImagePrintJob *self,
g_free (image_info->comment_text);
image_info->comment_text = NULL;
+ image_info->comment.x = 0.0;
+ image_info->comment.y = 0.0;
+ image_info->comment.width = 0.0;
+ image_info->comment.height = 0.0;
+
if (strcmp (self->priv->caption_attributes, "") != 0) {
gboolean comment_present = FALSE;
GString *text;
@@ -394,14 +408,23 @@ gth_image_print_job_update_page_layout (GthImagePrintJob *self,
image_info->maximized.height = (double) image_info->pixbuf_height * factor;
image_info->maximized.x = image_info->boundary.x + ((max_image_width - image_info->maximized.width) / 2);
image_info->maximized.y = image_info->boundary.y + ((max_image_height - image_info->maximized.height) / 2);
- image_info->image.x = image_info->maximized.x;
- image_info->image.y = image_info->maximized.y;
+
+ if (image_info->reset) {
+ /* calculate the transformation to center the image */
+ image_info->transformation.x = image_info->maximized.x / self->priv->max_image_width;
+ image_info->transformation.y = image_info->maximized.y / self->priv->max_image_height;
+ image_info->zoom = 1.0;
+ image_info->reset = FALSE;
+ }
+
+ image_info->image.x = self->priv->max_image_width * image_info->transformation.x;
+ image_info->image.y = self->priv->max_image_height * image_info->transformation.y;
image_info->image.width = image_info->maximized.width * image_info->zoom;
image_info->image.height = image_info->maximized.height * image_info->zoom;
if (image_info->print_comment) {
image_info->comment.x += image_info->boundary.x;
- image_info->comment.y += image_info->maximized.y + image_info->maximized.height;
+ image_info->comment.y += image_info->image.y + image_info->image.height;
}
}
@@ -442,7 +465,6 @@ gth_image_print_job_paint (GthImagePrintJob *self,
GthImageInfo *image_info = self->priv->images[i];
double scale_factor;
GdkPixbuf *fullsize_pixbuf;
- GdkPixbuf *pixbuf;
if (image_info->page != page)
continue;
@@ -509,32 +531,38 @@ gth_image_print_job_paint (GthImagePrintJob *self,
/*scale_factor = MIN (image_info->pixbuf_width / image_info->image.width, image_info->pixbuf_height / image_info->image.height);*/
if (! preview) {
- if (image_info->rotation != 0)
- fullsize_pixbuf = _gdk_pixbuf_transform (image_info->pixbuf, image_info->transform);
+ if (image_info->rotation != GTH_TRANSFORM_NONE)
+ fullsize_pixbuf = _gdk_pixbuf_transform (image_info->pixbuf, image_info->rotation);
else
fullsize_pixbuf = g_object_ref (image_info->pixbuf);
}
else
fullsize_pixbuf = g_object_ref (image_info->thumbnail);
- pixbuf = gdk_pixbuf_scale_simple (fullsize_pixbuf,
- image_info->image.width,
- image_info->image.height,
- preview ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR);
+ if ((image_info->image.width > 0) && (image_info->image.height > 0)) {
+ GdkPixbuf *pixbuf;
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr,
- pixbuf,
- x_offset + image_info->image.x,
- y_offset + image_info->image.y);
- cairo_rectangle (cr,
- x_offset + image_info->image.x,
- y_offset + image_info->image.y,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
- cairo_clip (cr);
- cairo_paint (cr);
- cairo_restore (cr);
+ pixbuf = gdk_pixbuf_scale_simple (fullsize_pixbuf,
+ image_info->image.width,
+ image_info->image.height,
+ preview ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR);
+
+ cairo_save (cr);
+ gdk_cairo_set_source_pixbuf (cr,
+ pixbuf,
+ x_offset + image_info->image.x,
+ y_offset + image_info->image.y);
+ cairo_rectangle (cr,
+ x_offset + image_info->image.x,
+ y_offset + image_info->image.y,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ g_object_unref (pixbuf);
+ }
if (image_info->print_comment) {
cairo_save (cr);
@@ -569,7 +597,6 @@ gth_image_print_job_paint (GthImagePrintJob *self,
}
g_object_unref (fullsize_pixbuf);
- g_object_unref (pixbuf);
}
pango_font_description_free (font_desc);
@@ -629,35 +656,77 @@ gth_image_print_job_paint (GthImagePrintJob *self,
}
-static void
-gth_image_print_job_update_status (GthImagePrintJob *self)
+static int
+get_combo_box_index_from_rotation (GthTransform rotation)
{
- int idx;
-
- idx = gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("ipp_combobox")));
- if (idx == N_IMAGES_PER_PAGE) {
- self->priv->auto_sizing = FALSE;
- self->priv->requested_images_per_page = 1;
- }
- else {
- self->priv->auto_sizing = TRUE;
- self->priv->requested_images_per_page = get_ipp_from_combo_box_index (idx);
+ int idx = 0;
+
+ switch (rotation) {
+ case GTH_TRANSFORM_NONE:
+ idx = 0;
+ break;
+ case GTH_TRANSFORM_ROTATE_90:
+ idx = 1;
+ break;
+ case GTH_TRANSFORM_ROTATE_180:
+ idx = 2;
+ break;
+ case GTH_TRANSFORM_ROTATE_270:
+ idx = 3;
+ break;
+ default:
+ break;
}
- gtk_widget_queue_draw (GET_WIDGET ("preview_drawingarea"));
+ return idx;
}
static void
gth_image_print_job_update_image_controls (GthImagePrintJob *self)
{
- int idx;
+ gboolean centered;
if (self->priv->selected == NULL)
return;
- idx = self->priv->selected->rotation / 90;
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("rotation_combobox")), idx);
+ g_signal_handler_block (GET_WIDGET ("rotation_combobox"), self->priv->rotation_combobox_changed_event);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("rotation_combobox")), get_combo_box_index_from_rotation (self->priv->selected->rotation));
+ g_signal_handler_unblock (GET_WIDGET ("rotation_combobox"), self->priv->rotation_combobox_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("scale_adjustment"), self->priv->scale_adjustment_value_changed_event);
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("scale_adjustment")), self->priv->selected->zoom);
+ g_signal_handler_unblock (GET_WIDGET ("scale_adjustment"), self->priv->scale_adjustment_value_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("left_adjustment"), self->priv->left_adjustment_value_changed_event);
+ gtk_adjustment_set_lower (GTK_ADJUSTMENT (GET_WIDGET ("left_adjustment")), 0.0);
+ gtk_adjustment_set_upper (GTK_ADJUSTMENT (GET_WIDGET ("left_adjustment")), self->priv->selected->boundary.width - self->priv->selected->image.width);
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("left_adjustment")), self->priv->selected->image.x);
+ g_signal_handler_unblock (GET_WIDGET ("left_adjustment"), self->priv->left_adjustment_value_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("top_adjustment"), self->priv->top_adjustment_value_changed_event);
+ gtk_adjustment_set_lower (GTK_ADJUSTMENT (GET_WIDGET ("top_adjustment")), 0.0);
+ gtk_adjustment_set_upper (GTK_ADJUSTMENT (GET_WIDGET ("top_adjustment")), self->priv->selected->boundary.height - self->priv->selected->comment.height - self->priv->selected->image.height);
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("top_adjustment")), self->priv->selected->image.y);
+ g_signal_handler_unblock (GET_WIDGET ("top_adjustment"), self->priv->top_adjustment_value_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("width_adjustment"), self->priv->width_adjustment_value_changed_event);
+ gtk_adjustment_set_lower (GTK_ADJUSTMENT (GET_WIDGET ("width_adjustment")), 0.0);
+ gtk_adjustment_set_upper (GTK_ADJUSTMENT (GET_WIDGET ("width_adjustment")), self->priv->selected->maximized.width);
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("width_adjustment")), self->priv->selected->image.width);
+ g_signal_handler_unblock (GET_WIDGET ("width_adjustment"), self->priv->width_adjustment_value_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("height_adjustment"), self->priv->height_adjustment_value_changed_event);
+ gtk_adjustment_set_lower (GTK_ADJUSTMENT (GET_WIDGET ("height_adjustment")), 0.0);
+ gtk_adjustment_set_upper (GTK_ADJUSTMENT (GET_WIDGET ("height_adjustment")), self->priv->selected->maximized.height);
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("height_adjustment")), self->priv->selected->image.height);
+ g_signal_handler_unblock (GET_WIDGET ("height_adjustment"), self->priv->height_adjustment_value_changed_event);
+
+ g_signal_handler_block (GET_WIDGET ("position_combobox"), self->priv->position_combobox_changed_event);
+ centered = (self->priv->selected->image.x == ((self->priv->selected->boundary.width - self->priv->selected->image.width) / 2.0))
+ && (self->priv->selected->image.y == ((self->priv->selected->boundary.height - self->priv->selected->comment.height - self->priv->selected->image.height) / 2.0));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("position_combobox")), centered ? 0 : 1);
+ g_signal_handler_unblock (GET_WIDGET ("position_combobox"), self->priv->position_combobox_changed_event);
}
@@ -666,7 +735,6 @@ gth_image_print_job_update_preview (GthImagePrintJob *self)
{
char *text;
- gth_image_print_job_update_status (self);
gth_image_print_job_update_layout (self,
gtk_page_setup_get_page_width (self->priv->page_setup, GTK_UNIT_MM),
gtk_page_setup_get_page_height (self->priv->page_setup, GTK_UNIT_MM),
@@ -725,6 +793,12 @@ ipp_combobox_changed_cb (GtkComboBox *widget,
gpointer user_data)
{
GthImagePrintJob *self = user_data;
+ int i;
+
+ self->priv->auto_sizing = TRUE;
+ self->priv->requested_images_per_page = get_ipp_from_combo_box_index (gtk_combo_box_get_active (widget));
+ for (i = 0; i < self->priv->n_images; i++)
+ gth_image_info_reset (self->priv->images[i]);
gth_image_print_job_update_preview (self);
}
@@ -806,6 +880,142 @@ caption_chooser_changed_cb (GthMetadataChooser *chooser,
}
+static void
+rotation_combobox_changed_cb (GtkComboBox *combo_box,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ gth_image_info_rotate (self->priv->selected, gtk_combo_box_get_active (combo_box) * 90);
+ gth_image_info_reset (self->priv->selected);
+ gth_image_print_job_update_preview (self);
+}
+
+
+static void
+gth_image_print_job_set_selected_zoom (GthImagePrintJob *self,
+ double zoom)
+{
+ self->priv->selected->zoom = CLAMP (zoom, 0.0, 1.0);
+ self->priv->selected->image.width = self->priv->selected->maximized.width * self->priv->selected->zoom;
+ self->priv->selected->image.height = self->priv->selected->maximized.height * self->priv->selected->zoom;
+
+ if (self->priv->selected->image.x + self->priv->selected->image.width > self->priv->selected->boundary.width)
+ self->priv->selected->image.x = self->priv->selected->boundary.width -self->priv->selected->image.width;
+ if (self->priv->selected->image.x + self->priv->selected->image.width > self->priv->selected->boundary.width)
+ self->priv->selected->image.width = self->priv->selected->boundary.width -self->priv->selected->image.x;
+
+ if (self->priv->selected->image.y + self->priv->selected->image.height > self->priv->selected->boundary.height - self->priv->selected->comment.height)
+ self->priv->selected->image.y = self->priv->selected->boundary.height - self->priv->selected->comment.height - self->priv->selected->image.height;
+ if (self->priv->selected->image.y + self->priv->selected->image.height > self->priv->selected->boundary.height - self->priv->selected->comment.height)
+ self->priv->selected->image.height = self->priv->selected->boundary.height - self->priv->selected->comment.height - self->priv->selected->image.y;
+
+ self->priv->selected->zoom = MIN (self->priv->selected->image.width / self->priv->selected->maximized.width, self->priv->selected->image.height / self->priv->selected->maximized.height);
+ self->priv->selected->transformation.x = self->priv->selected->image.x / self->priv->max_image_width;
+ self->priv->selected->transformation.y = self->priv->selected->image.y / self->priv->max_image_height;
+
+ gth_image_print_job_update_preview (self); /* FIXME: update only the selected image */
+}
+
+
+static void
+scale_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ gth_image_print_job_set_selected_zoom (self, gtk_adjustment_get_value (adjustment));
+}
+
+
+static void
+left_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ self->priv->selected->transformation.x = gtk_adjustment_get_value (adjustment) / self->priv->max_image_width;
+ gth_image_print_job_update_preview (self);
+}
+
+
+static void
+top_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ self->priv->selected->transformation.y = gtk_adjustment_get_value (adjustment) / self->priv->max_image_height;
+ gth_image_print_job_update_preview (self);
+}
+
+
+static void
+width_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ gth_image_print_job_set_selected_zoom (self, gtk_adjustment_get_value (adjustment) / self->priv->selected->maximized.width);
+}
+
+
+static void
+height_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ gth_image_print_job_set_selected_zoom (self, gtk_adjustment_get_value (adjustment) / self->priv->selected->maximized.height);
+}
+
+
+static void
+position_combobox_changed_cb (GtkComboBox *combo_box,
+ gpointer user_data)
+{
+ GthImagePrintJob *self = user_data;
+
+ if (self->priv->selected == NULL)
+ return;
+
+ if (gtk_combo_box_get_active (combo_box) == 0) {
+ self->priv->selected->image.x = (self->priv->selected->boundary.width - self->priv->selected->image.width) / 2.0;
+ self->priv->selected->image.y = (self->priv->selected->boundary.height - self->priv->selected->comment.height - self->priv->selected->image.height) / 2.0;
+ self->priv->selected->transformation.x = self->priv->selected->image.x / self->priv->max_image_width;
+ self->priv->selected->transformation.y = self->priv->selected->image.y / self->priv->max_image_height;
+ gth_image_print_job_update_preview (self);
+ }
+}
+
+
+static char *
+image_scale_format_value_cb (GtkScale *scale,
+ double value,
+ gpointer user_data)
+{
+ return g_strdup_printf ("%0.0f%%", value * 100.0);
+}
+
+
static GObject *
operation_create_custom_widget_cb (GtkPrintOperation *operation,
gpointer user_data)
@@ -840,6 +1050,46 @@ operation_create_custom_widget_cb (GtkPrintOperation *operation,
G_CALLBACK (caption_chooser_changed_cb),
self);
+ self->priv->rotation_combobox_changed_event =
+ g_signal_connect (GET_WIDGET ("rotation_combobox"),
+ "changed",
+ G_CALLBACK (rotation_combobox_changed_cb),
+ self);
+ self->priv->scale_adjustment_value_changed_event =
+ g_signal_connect (GET_WIDGET ("scale_adjustment"),
+ "value-changed",
+ G_CALLBACK (scale_adjustment_value_changed_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("image_scale"),
+ "format-value",
+ G_CALLBACK (image_scale_format_value_cb),
+ self);
+ self->priv->left_adjustment_value_changed_event =
+ g_signal_connect (GET_WIDGET ("left_adjustment"),
+ "value-changed",
+ G_CALLBACK (left_adjustment_value_changed_cb),
+ self);
+ self->priv->top_adjustment_value_changed_event =
+ g_signal_connect (GET_WIDGET ("top_adjustment"),
+ "value-changed",
+ G_CALLBACK (top_adjustment_value_changed_cb),
+ self);
+ self->priv->width_adjustment_value_changed_event =
+ g_signal_connect (GET_WIDGET ("width_adjustment"),
+ "value-changed",
+ G_CALLBACK (width_adjustment_value_changed_cb),
+ self);
+ self->priv->height_adjustment_value_changed_event =
+ g_signal_connect (GET_WIDGET ("height_adjustment"),
+ "value-changed",
+ G_CALLBACK (height_adjustment_value_changed_cb),
+ self);
+ self->priv->position_combobox_changed_event =
+ g_signal_connect (GET_WIDGET ("position_combobox"),
+ "changed",
+ G_CALLBACK (position_combobox_changed_cb),
+ self);
+
return gtk_builder_get_object (self->priv->builder, "print_layout");
}
@@ -849,10 +1099,7 @@ operation_custom_widget_apply_cb (GtkPrintOperation *operation,
GtkWidget *widget,
gpointer user_data)
{
- GthImagePrintJob *self = user_data;
-
- gth_image_print_job_update_status (self);
- gtk_widget_queue_draw (GET_WIDGET ("preview_drawingarea"));
+ /* FIXME */
}
diff --git a/extensions/image_print/gth-load-image-info-task.c b/extensions/image_print/gth-load-image-info-task.c
index efa1a4c..7348c21 100644
--- a/extensions/image_print/gth-load-image-info-task.c
+++ b/extensions/image_print/gth-load-image-info-task.c
@@ -23,8 +23,6 @@
#include <config.h>
#include "gth-load-image-info-task.h"
-#define THUMBNAIL_SIZE 256
-
struct _GthLoadImageInfoTaskPrivate {
GthImageInfo **images;
@@ -102,25 +100,8 @@ image_loader_ready_cb (GthImageLoader *loader,
image_info = self->priv->images[self->priv->current];
pixbuf = gth_image_loader_get_pixbuf (loader);
- if (pixbuf != NULL) {
- int thumb_w, thumb_h;
-
- image_info->pixbuf = g_object_ref (pixbuf);
- thumb_w = image_info->pixbuf_width = gdk_pixbuf_get_width (pixbuf);
- thumb_h = image_info->pixbuf_height = gdk_pixbuf_get_height (pixbuf);
- if (scale_keeping_ratio (&thumb_w, &thumb_h, THUMBNAIL_SIZE, THUMBNAIL_SIZE, FALSE))
- image_info->thumbnail = gdk_pixbuf_scale_simple (pixbuf,
- thumb_w,
- thumb_h,
- GDK_INTERP_BILINEAR);
- else
- image_info->thumbnail = g_object_ref (image_info->pixbuf);
-
- if (image_info->thumbnail != NULL) {
- image_info->thumbnail_active = gdk_pixbuf_copy (image_info->thumbnail);
- _gdk_pixbuf_colorshift (image_info->thumbnail_active, image_info->thumbnail_active, 30);
- }
- }
+ if (pixbuf != NULL)
+ gth_image_info_set_pixbuf (image_info, pixbuf);
if (strcmp (self->priv->attributes, "") != 0) {
GList *files;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]