[gthumb] implemented the resize file tool



commit 2a11bf25c2854848d02588a81cf584032250d2a1
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Feb 21 13:42:42 2010 +0100

    implemented the resize file tool

 data/icons/hicolor/16x16/actions/Makefile.am      |    1 +
 data/icons/hicolor/16x16/actions/tool-resize.png  |  Bin 0 -> 576 bytes
 data/icons/hicolor/22x22/actions/Makefile.am      |    1 +
 data/icons/hicolor/22x22/actions/tool-resize.png  |  Bin 0 -> 902 bytes
 extensions/file_tools/Makefile.am                 |    2 +
 extensions/file_tools/data/ui/resize-options.ui   |  232 ++++---------
 extensions/file_tools/gth-file-tool-crop.c        |    2 +-
 extensions/file_tools/gth-file-tool-resize.c      |  384 ++++++++-------------
 extensions/file_tools/main.c                      |    2 +
 extensions/resize_images/data/ui/resize-images.ui |    2 +-
 10 files changed, 216 insertions(+), 410 deletions(-)
---
diff --git a/data/icons/hicolor/16x16/actions/Makefile.am b/data/icons/hicolor/16x16/actions/Makefile.am
index 8971c17..bb09002 100644
--- a/data/icons/hicolor/16x16/actions/Makefile.am
+++ b/data/icons/hicolor/16x16/actions/Makefile.am
@@ -18,6 +18,7 @@ icons_DATA = 			\
 	tool-invert.png		\
 	tool-mirror.png		\
 	tool-red-eye.png	\
+	tool-resize.png		\
 	tool-rotate-270.png	\
 	tool-rotate-90.png
 
diff --git a/data/icons/hicolor/16x16/actions/tool-resize.png b/data/icons/hicolor/16x16/actions/tool-resize.png
new file mode 100644
index 0000000..1abfe82
Binary files /dev/null and b/data/icons/hicolor/16x16/actions/tool-resize.png differ
diff --git a/data/icons/hicolor/22x22/actions/Makefile.am b/data/icons/hicolor/22x22/actions/Makefile.am
index 4d04d66..2d1e03a 100644
--- a/data/icons/hicolor/22x22/actions/Makefile.am
+++ b/data/icons/hicolor/22x22/actions/Makefile.am
@@ -16,6 +16,7 @@ icons_DATA = 			\
 	tool-desaturate.png	\
 	tool-enhance.png	\
 	tool-red-eye.png	\
+	tool-resize.png		\
 	zoom-fit-width.png
 
 EXTRA_DIST = $(icons_DATA)	
diff --git a/data/icons/hicolor/22x22/actions/tool-resize.png b/data/icons/hicolor/22x22/actions/tool-resize.png
new file mode 100644
index 0000000..4d200f2
Binary files /dev/null and b/data/icons/hicolor/22x22/actions/tool-resize.png differ
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
index 9ac35b5..b08b910 100644
--- a/extensions/file_tools/Makefile.am
+++ b/extensions/file_tools/Makefile.am
@@ -22,6 +22,8 @@ libfile_tools_la_SOURCES = 		\
 	gth-file-tool-negative.h	\
 	gth-file-tool-redo.c		\
 	gth-file-tool-redo.h		\
+	gth-file-tool-resize.c		\
+	gth-file-tool-resize.h		\
 	gth-file-tool-rotate-left.c	\
 	gth-file-tool-rotate-left.h	\
 	gth-file-tool-rotate-right.c	\
diff --git a/extensions/file_tools/data/ui/resize-options.ui b/extensions/file_tools/data/ui/resize-options.ui
index db5938d..155d396 100644
--- a/extensions/file_tools/data/ui/resize-options.ui
+++ b/extensions/file_tools/data/ui/resize-options.ui
@@ -28,40 +28,15 @@
                       <object class="GtkVBox" id="vbox10">
                         <property name="visible">True</property>
                         <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
                         <child>
                           <object class="GtkTable" id="table2">
                             <property name="visible">True</property>
-                            <property name="n_rows">4</property>
-                            <property name="n_columns">2</property>
+                            <property name="n_rows">2</property>
+                            <property name="n_columns">3</property>
                             <property name="column_spacing">6</property>
                             <property name="row_spacing">6</property>
                             <child>
-                              <object class="GtkLabel" id="label3">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_X:</property>
-                                <property name="use_underline">True</property>
-                              </object>
-                              <packing>
-                                <property name="x_options">GTK_FILL</property>
-                                <property name="y_options"></property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkLabel" id="label5">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Y:</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>
-                                <property name="y_options"></property>
-                              </packing>
-                            </child>
-                            <child>
                               <object class="GtkLabel" id="label4">
                                 <property name="visible">True</property>
                                 <property name="xalign">0</property>
@@ -69,8 +44,6 @@
                                 <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -83,25 +56,29 @@
                                 <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox5">
+                              <object class="GtkHBox" id="hbox7">
                                 <property name="visible">True</property>
                                 <child>
-                                  <object class="GtkSpinButton" id="resize_x_spinbutton">
+                                  <object class="GtkSpinButton" id="resize_width_spinbutton">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="invisible_char">&#x25CF;</property>
-                                    <property name="adjustment">resize_x_adjustment</property>
+                                    <property name="width_chars">6</property>
+                                    <property name="adjustment">resize_width_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">0</property>
                                   </packing>
                                 </child>
@@ -114,18 +91,22 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox6">
+                              <object class="GtkHBox" id="hbox8">
                                 <property name="visible">True</property>
                                 <child>
-                                  <object class="GtkSpinButton" id="resize_y_spinbutton">
+                                  <object class="GtkSpinButton" id="resize_height_spinbutton">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="invisible_char">&#x25CF;</property>
-                                    <property name="adjustment">resize_y_adjustment</property>
+                                    <property name="width_chars">6</property>
+                                    <property name="adjustment">resize_height_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">0</property>
                                   </packing>
                                 </child>
@@ -140,57 +121,24 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox7">
-                                <property name="visible">True</property>
-                                <child>
-                                  <object class="GtkSpinButton" id="resize_width_spinbutton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">&#x25CF;</property>
-                                    <property name="adjustment">resize_width_adjustment</property>
-                                    <property name="climb_rate">1</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">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>
-                                <property name="x_options">GTK_FILL</property>
-                                <property name="y_options">GTK_FILL</property>
-                              </packing>
+                              <placeholder/>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox8">
+                              <object class="GtkComboBox" id="unit_combobox">
                                 <property name="visible">True</property>
+                                <property name="model">unit_liststore</property>
+                                <property name="active">0</property>
                                 <child>
-                                  <object class="GtkSpinButton" id="resize_height_spinbutton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">&#x25CF;</property>
-                                    <property name="adjustment">resize_height_adjustment</property>
-                                    <property name="climb_rate">1</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
+                                  <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                                  <attributes>
+                                    <attribute name="text">1</attribute>
+                                  </attributes>
                                 </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>
+                                <property name="left_attach">2</property>
+                                <property name="right_attach">3</property>
                                 <property name="x_options">GTK_FILL</property>
-                                <property name="y_options">GTK_FILL</property>
                               </packing>
                             </child>
                           </object>
@@ -205,7 +153,7 @@
                 <child type="label">
                   <object class="GtkLabel" id="label15">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">Selection</property>
+                    <property name="label" translatable="yes">Dimensions</property>
                     <attributes>
                       <attribute name="weight" value="bold"/>
                     </attributes>
@@ -219,95 +167,48 @@
               </packing>
             </child>
             <child>
-              <object class="GtkFrame" id="frame5">
+              <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="alignment6">
+                  <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="vbox8">
+                      <object class="GtkVBox" id="vbox3">
                         <property name="visible">True</property>
                         <property name="orientation">vertical</property>
                         <property name="spacing">6</property>
                         <child>
-                          <object class="GtkHBox" id="ratio_combobox_box">
+                          <object class="GtkCheckButton" id="keep_ratio_checkbutton">
+                            <property name="label" translatable="yes">_Preserve original aspect ratio</property>
                             <property name="visible">True</property>
-                            <child>
-                              <placeholder/>
-                            </child>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
                           </object>
                           <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkHBox" id="custom_ratio_box">
-                            <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkSpinButton" id="ratio_w_spinbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="invisible_char">&#x25CF;</property>
-                                <property name="adjustment">ratio_w_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="label17">
-                                <property name="visible">True</property>
-                                <property name="label">:</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkSpinButton" id="ratio_h_spinbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="invisible_char">&#x25CF;</property>
-                                <property name="adjustment">ratio_h_adjustment</property>
-                                <property name="climb_rate">1</property>
-                                <property name="update_policy">if-valid</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkCheckButton" id="invert_ratio_checkbutton">
-                            <property name="label" translatable="yes">I_nvert aspect ratio</property>
+                          <object class="GtkCheckButton" id="high_quality_checkbutton">
+                            <property name="label" translatable="yes">High _quality</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="use_underline">True</property>
+                            <property name="active">True</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
                             <property name="fill">False</property>
-                            <property name="position">2</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
@@ -315,9 +216,9 @@
                   </object>
                 </child>
                 <child type="label">
-                  <object class="GtkLabel" id="label16">
+                  <object class="GtkLabel" id="label3">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">Aspect ratio</property>
+                    <property name="label" translatable="yes">Options</property>
                     <attributes>
                       <attribute name="weight" value="bold"/>
                     </attributes>
@@ -353,11 +254,12 @@
             <property name="layout_style">center</property>
             <child>
               <object class="GtkButton" id="resize_button">
-                <property name="label" translatable="yes">_Resize</property>
+                <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_underline">True</property>
+                <property name="use_stock">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -390,28 +292,32 @@
       </object>
     </child>
   </object>
-  <object class="GtkAdjustment" id="ratio_w_adjustment">
-    <property name="upper">99999</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkAdjustment" id="resize_x_adjustment">
-    <property name="upper">100</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkAdjustment" id="resize_y_adjustment">
-    <property name="upper">100</property>
-    <property name="step_increment">1</property>
-  </object>
   <object class="GtkAdjustment" id="resize_width_adjustment">
-    <property name="upper">100</property>
+    <property name="lower">1</property>
+    <property name="upper">999999</property>
     <property name="step_increment">1</property>
   </object>
   <object class="GtkAdjustment" id="resize_height_adjustment">
-    <property name="upper">100</property>
+    <property name="lower">1</property>
+    <property name="upper">999999</property>
     <property name="step_increment">1</property>
   </object>
-  <object class="GtkAdjustment" id="ratio_h_adjustment">
-    <property name="upper">99999</property>
-    <property name="step_increment">1</property>
+  <object class="GtkListStore" id="unit_liststore">
+    <columns>
+      <!-- column-name type -->
+      <column type="gint"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0">0</col>
+        <col id="1" translatable="yes">pixels</col>
+      </row>
+      <row>
+        <col id="0">1</col>
+        <col id="1" translatable="yes">%</col>
+      </row>
+    </data>
   </object>
 </interface>
diff --git a/extensions/file_tools/gth-file-tool-crop.c b/extensions/file_tools/gth-file-tool-crop.c
index d6318b0..93f76a1 100644
--- a/extensions/file_tools/gth-file-tool-crop.c
+++ b/extensions/file_tools/gth-file-tool-crop.c
@@ -455,7 +455,7 @@ static void
 gth_file_tool_crop_instance_init (GthFileToolCrop *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL_CROP, GthFileToolCropPrivate);
-	gth_file_tool_construct (GTH_FILE_TOOL (self), "tool-crop", _("Crop..."), _("Crop"), TRUE);
+	gth_file_tool_construct (GTH_FILE_TOOL (self), "tool-crop", _("Crop..."), _("Crop"), FALSE);
 }
 
 
diff --git a/extensions/file_tools/gth-file-tool-resize.c b/extensions/file_tools/gth-file-tool-resize.c
index 858ed6b..83420f8 100644
--- a/extensions/file_tools/gth-file-tool-resize.c
+++ b/extensions/file_tools/gth-file-tool-resize.c
@@ -21,12 +21,14 @@
  */
 
 #include <config.h>
+#include <math.h>
 #include <gthumb.h>
 #include <extensions/image_viewer/gth-image-viewer-page.h>
 #include "gth-file-tool-resize.h"
 
 
 #define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+#define HIGH_QUALITY_INTERPOLATION GDK_INTERP_HYPER
 
 
 typedef enum {
@@ -46,18 +48,17 @@ static gpointer parent_class = NULL;
 
 
 struct _GthFileToolResizePrivate {
-	GdkPixbuf        *src_pixbuf;
-	GtkBuilder       *builder;
-	int               pixbuf_width;
-	int               pixbuf_height;
-	int               screen_width;
-	int               screen_height;
-	GthImageSelector *selector;
-	GtkWidget        *ratio_combobox;
-	GtkWidget        *resize_x_spinbutton;
-	GtkWidget        *resize_y_spinbutton;
-	GtkWidget        *resize_width_spinbutton;
-	GtkWidget        *resize_height_spinbutton;
+	GdkPixbuf     *src_pixbuf;
+	GdkPixbuf     *new_pixbuf;
+	GtkBuilder    *builder;
+	int            original_width;
+	int            original_height;
+	double         original_ratio;
+	int            new_width;
+	int            new_height;
+	gboolean       keep_ratio;
+	GdkInterpType  interpolation;
+	GthUnit        unit;
 };
 
 
@@ -77,9 +78,15 @@ gth_file_tool_resize_update_sensitivity (GthFileTool *base)
 
 
 static void
-cancel_button_clicked_cb (GtkButton       *button,
+cancel_button_clicked_cb (GtkButton         *button,
 			  GthFileToolResize *self)
 {
+	GtkWidget *window;
+	GtkWidget *viewer_page;
+
+	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	gth_image_viewer_page_reset (GTH_IMAGE_VIEWER_PAGE (viewer_page));
 	gth_file_tool_hide_options (GTH_FILE_TOOL (self));
 }
 
@@ -88,220 +95,129 @@ static void
 resize_button_clicked_cb (GtkButton       *button,
 			GthFileToolResize *self)
 {
-	GdkRectangle  selection;
-	GdkPixbuf    *new_pixbuf;
+	GtkWidget *window;
+	GtkWidget *viewer_page;
 
-	gth_image_selector_get_selection (self->priv->selector, &selection);
-	if ((selection.width == 0) || (selection.height == 0))
+	if (self->priv->new_pixbuf == NULL)
 		return;
 
-	new_pixbuf = gdk_pixbuf_new_subpixbuf (self->priv->src_pixbuf,
-					       selection.x,
-					       selection.y,
-					       selection.width,
-					       selection.height);
-	if (new_pixbuf != NULL) {
-		GtkWidget *window;
-		GtkWidget *viewer_page;
-
-		window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
-		viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
-		gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf, TRUE);
-		gth_file_tool_hide_options (GTH_FILE_TOOL (self));
-
-		g_object_unref (new_pixbuf);
-	}
+	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->new_pixbuf, TRUE);
+	gth_file_tool_hide_options (GTH_FILE_TOOL (self));
 }
 
 
 static void
-selection_x_value_changed_cb (GtkSpinButton    *spin,
-			      GthFileToolResize *self)
+update_pixbuf_size (GthFileToolResize *self)
 {
-	gth_image_selector_set_selection_x (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
-}
-
+	GtkWidget *window;
+	GtkWidget *viewer_page;
 
-static void
-selection_y_value_changed_cb (GtkSpinButton    *spin,
-			      GthFileToolResize *self)
-{
-	gth_image_selector_set_selection_y (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
+	_g_object_unref (self->priv->new_pixbuf);
+	self->priv->new_pixbuf = gdk_pixbuf_scale_simple (self->priv->src_pixbuf,
+							  self->priv->new_width,
+							  self->priv->new_height,
+							  self->priv->interpolation);
+	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->new_pixbuf, FALSE);
 }
 
 
 static void
-selection_width_value_changed_cb (GtkSpinButton    *spin,
+selection_width_value_changed_cb (GtkSpinButton     *spin,
 				  GthFileToolResize *self)
 {
-	gth_image_selector_set_selection_width (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
-}
-
-
-static void
-selection_height_value_changed_cb (GtkSpinButton    *spin,
-				   GthFileToolResize *self)
-{
-	gth_image_selector_set_selection_height (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
-}
-
+	if (self->priv->unit == GTH_UNIT_PIXELS)
+		self->priv->new_width = MAX (gtk_spin_button_get_value_as_int (spin), 1);
+	else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
+		self->priv->new_width = MAX ((int) round ((gtk_spin_button_get_value (spin) / 100.0) * self->priv->original_width), 1);
+
+	if (self->priv->keep_ratio) {
+		g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+		self->priv->new_height = MAX ((int) round ((double) self->priv->new_width / self->priv->original_ratio), 1);
+		if (self->priv->unit == GTH_UNIT_PIXELS)
+			gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), self->priv->new_height);
+		else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
+			gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), ((double) self->priv->new_height) / self->priv->original_height * 100.0);
+		g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+	}
 
-static void
-set_spin_range_value (GthFileToolResize *self,
-		      GtkWidget        *spin,
-		      int               min,
-		      int               max,
-		      int               x)
-{
-	g_signal_handlers_block_by_data (G_OBJECT (spin), self);
-	gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), min, max);
-	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), x);
-	g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
+	update_pixbuf_size (self);
 }
 
 
 static void
-selector_selection_changed_cb (GthImageSelector *selector,
-			       GthFileToolResize *self)
+selection_height_value_changed_cb (GtkSpinButton     *spin,
+				   GthFileToolResize *self)
 {
-	GdkRectangle selection;
-	int          min, max;
-
-	gth_image_selector_get_selection (selector, &selection);
-
-	min = 0;
-	max = self->priv->pixbuf_width - selection.width;
-	set_spin_range_value (self, self->priv->resize_x_spinbutton, min, max, selection.x);
-
-	min = 0;
-	max = self->priv->pixbuf_height - selection.height;
-	set_spin_range_value (self, self->priv->resize_y_spinbutton, min, max, selection.y);
-
-	min = 0;
-	max = self->priv->pixbuf_width - selection.x;
-	set_spin_range_value (self, self->priv->resize_width_spinbutton, min, max, selection.width);
-
-	min = 0;
-	max = self->priv->pixbuf_height - selection.y;
-	set_spin_range_value (self, self->priv->resize_height_spinbutton, min, max, selection.height);
+	if (self->priv->unit == GTH_UNIT_PIXELS)
+		self->priv->new_height = MAX (gtk_spin_button_get_value_as_int (spin), 1);
+	else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
+		self->priv->new_height = MAX ((int) round ((gtk_spin_button_get_value (spin) / 100.0) * self->priv->original_height), 1);
+
+	if (self->priv->keep_ratio) {
+		g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+		self->priv->new_width = MAX ((int) round ((double) self->priv->new_height * self->priv->original_ratio), 1);
+		if (self->priv->unit == GTH_UNIT_PIXELS)
+			gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), self->priv->new_width);
+		else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
+			gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), ((double) self->priv->new_width) / self->priv->original_width * 100.0);
+		g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+	}
 
-	gth_image_selector_set_mask_visible (selector, (selection.width != 0 || selection.height != 0));
+	update_pixbuf_size (self);
 }
 
 
 static void
-set_spin_value (GthFileToolResize *self,
-		GtkWidget        *spin,
-		int               x)
+keep_ratio_checkbutton_toggled_cb (GtkToggleButton   *button,
+				   GthFileToolResize *self)
 {
-	g_signal_handlers_block_by_data (G_OBJECT (spin), self);
-	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), x);
-	g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
+	self->priv->keep_ratio = gtk_toggle_button_get_active (button);
 }
 
 
 static void
-ratio_combobox_changed_cb (GtkComboBox      *combobox,
-			   GthFileToolResize *self)
+high_quality_checkbutton_toggled_cb (GtkToggleButton   *button,
+				     GthFileToolResize *self)
 {
-	GtkWidget *ratio_w_spinbutton;
-	GtkWidget *ratio_h_spinbutton;
-	int        idx;
-	int        w, h;
-	gboolean   use_ratio;
-
-	ratio_w_spinbutton = GET_WIDGET ("ratio_w_spinbutton");
-	ratio_h_spinbutton = GET_WIDGET ("ratio_h_spinbutton");
-	w = h = 1;
-	use_ratio = TRUE;
-	idx = gtk_combo_box_get_active (combobox);
-
-	switch (idx) {
-	case GTH_RESIZE_RATIO_NONE:
-		use_ratio = FALSE;
-		break;
-	case GTH_RESIZE_RATIO_SQUARE:
-		w = h = 1;
-		break;
-	case GTH_RESIZE_RATIO_IMAGE:
-		w = self->priv->pixbuf_width;
-		h = self->priv->pixbuf_height;
-		break;
-	case GTH_RESIZE_RATIO_DISPLAY:
-		w = self->priv->screen_width;
-		h = self->priv->screen_height;
-		break;
-	case GTH_RESIZE_RATIO_4_3:
-		w = 4;
-		h = 3;
-		break;
-	case GTH_RESIZE_RATIO_4_6:
-		w = 4;
-		h = 6;
-		break;
-	case GTH_RESIZE_RATIO_5_7:
-		w = 5;
-		h = 7;
-		break;
-	case GTH_RESIZE_RATIO_8_10:
-		w = 8;
-		h = 10;
-		break;
-	case GTH_RESIZE_RATIO_CUSTOM:
-	default:
-		w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ratio_w_spinbutton));
-		h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ratio_h_spinbutton));
-		break;
-	}
-
-	gtk_widget_set_sensitive (GET_WIDGET ("custom_ratio_box"), idx == GTH_RESIZE_RATIO_CUSTOM);
-	gtk_widget_set_sensitive (GET_WIDGET ("invert_ratio_checkbutton"), use_ratio);
-	set_spin_value (self, ratio_w_spinbutton, w);
-	set_spin_value (self, ratio_h_spinbutton, h);
-	gth_image_selector_set_ratio (GTH_IMAGE_SELECTOR (self->priv->selector),
-				      use_ratio,
-				      (double) w / h,
-				      FALSE);
+	self->priv->interpolation = gtk_toggle_button_get_active (button) ? HIGH_QUALITY_INTERPOLATION : GDK_INTERP_NEAREST;
+	update_pixbuf_size (self);
 }
 
 
 static void
-update_ratio (GtkSpinButton    *spin,
-	      GthFileToolResize *self,
-	      gboolean          swap_x_and_y_to_start)
+unit_combobox_changed_cb (GtkComboBox       *combobox,
+			  GthFileToolResize *self)
 {
-	gboolean use_ratio;
-	int      w, h;
-	double   ratio;
+	g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+	g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
 
-	use_ratio = gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->ratio_combobox)) != GTH_RESIZE_RATIO_NONE;
-	w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_w_spinbutton")));
-	h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_h_spinbutton")));
+	self->priv->unit = gtk_combo_box_get_active (combobox);
+	if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
+		double p;
 
-	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("invert_ratio_checkbutton"))))
-		ratio = (double) h / w;
-	else
-		ratio = (double) w / h;
-	gth_image_selector_set_ratio (self->priv->selector,
-				      use_ratio,
-				      ratio,
-				      swap_x_and_y_to_start);
-}
+		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 1);
+		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 1);
 
+		p = ((double) self->priv->new_width) / self->priv->original_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->original_height * 100.0;
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_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);
+	}
 
-static void
-ratio_value_changed_cb (GtkSpinButton    *spin,
-			GthFileToolResize *self)
-{
-	update_ratio (spin, self, FALSE);
-}
-
+	g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+	g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
 
-static void
-invert_ratio_changed_cb (GtkSpinButton    *spin,
-			 GthFileToolResize *self)
-{
-	update_ratio (spin, self, TRUE);
+	update_pixbuf_size (self);
 }
 
 
@@ -313,7 +229,6 @@ gth_file_tool_resize_get_options (GthFileTool *base)
 	GtkWidget       *viewer_page;
 	GtkWidget       *viewer;
 	GtkWidget       *options;
-	char            *text;
 
 	self = (GthFileToolResize *) base;
 
@@ -331,35 +246,35 @@ gth_file_tool_resize_get_options (GthFileTool *base)
 
 	g_object_ref (self->priv->src_pixbuf);
 
-	self->priv->pixbuf_width = gdk_pixbuf_get_width (self->priv->src_pixbuf);
-	self->priv->pixbuf_height = gdk_pixbuf_get_height (self->priv->src_pixbuf);
-	_gtk_widget_get_screen_size (window, &self->priv->screen_width, &self->priv->screen_height);
-
+	self->priv->original_width = gdk_pixbuf_get_width (self->priv->src_pixbuf);
+	self->priv->original_height = gdk_pixbuf_get_height (self->priv->src_pixbuf);
+	self->priv->original_ratio = (double) self->priv->original_width / self->priv->original_height;
+	self->priv->new_pixbuf = NULL;
+	self->priv->new_width = self->priv->original_width;
+	self->priv->new_height = self->priv->original_height;
+	self->priv->keep_ratio = TRUE;
+	self->priv->interpolation = HIGH_QUALITY_INTERPOLATION;
+	self->priv->unit = GTH_UNIT_PERCENTAGE;
 	self->priv->builder = _gtk_builder_new_from_file ("resize-options.ui", "file_tools");
 
 	options = _gtk_builder_get_widget (self->priv->builder, "options");
 	gtk_widget_show (options);
-	self->priv->resize_x_spinbutton = _gtk_builder_get_widget (self->priv->builder, "resize_x_spinbutton");
-	self->priv->resize_y_spinbutton = _gtk_builder_get_widget (self->priv->builder, "resize_y_spinbutton");
-	self->priv->resize_width_spinbutton = _gtk_builder_get_widget (self->priv->builder, "resize_width_spinbutton");
-	self->priv->resize_height_spinbutton = _gtk_builder_get_widget (self->priv->builder, "resize_height_spinbutton");
-
-	self->priv->ratio_combobox = _gtk_combo_box_new_with_texts (_("None"), _("Square"), NULL);
-	text = g_strdup_printf (_("%d x %d (Image)"), self->priv->pixbuf_width, self->priv->pixbuf_height);
-	gtk_combo_box_append_text (GTK_COMBO_BOX (self->priv->ratio_combobox), text);
-	g_free (text);
-	text = g_strdup_printf (_("%d x %d (Screen)"), self->priv->screen_width, self->priv->screen_height);
-	gtk_combo_box_append_text (GTK_COMBO_BOX (self->priv->ratio_combobox), text);
-	g_free (text);
-	_gtk_combo_box_append_texts (GTK_COMBO_BOX (self->priv->ratio_combobox),
-				     _("4 x 3 (Book, DVD)"),
-				     _("4 x 6 (Postcard)"),
-				     _("5 x 7"),
-				     _("8 x 10"),
-				     _("Custom"),
-				     NULL);
-	gtk_widget_show (self->priv->ratio_combobox);
-	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("ratio_combobox_box")), self->priv->ratio_combobox, FALSE, FALSE, 0);
+
+	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->original_width);
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), self->priv->original_height);
+	}
+	else if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
+		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 1);
+		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 1);
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 100.0);
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 100.0);
+	}
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_ratio_checkbutton")), self->priv->keep_ratio);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("high_quality_checkbutton")), self->priv->interpolation != GDK_INTERP_NEAREST);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), self->priv->unit);
 
 	g_signal_connect (GET_WIDGET ("resize_button"),
 			  "clicked",
@@ -369,48 +284,27 @@ gth_file_tool_resize_get_options (GthFileTool *base)
 			  "clicked",
 			  G_CALLBACK (cancel_button_clicked_cb),
 			  self);
-	g_signal_connect (G_OBJECT (self->priv->resize_x_spinbutton),
-			  "value-changed",
-			  G_CALLBACK (selection_x_value_changed_cb),
-			  self);
-	g_signal_connect (G_OBJECT (self->priv->resize_y_spinbutton),
-			  "value-changed",
-			  G_CALLBACK (selection_y_value_changed_cb),
-			  self);
-	g_signal_connect (G_OBJECT (self->priv->resize_width_spinbutton),
+	g_signal_connect (GET_WIDGET ("resize_width_spinbutton"),
 			  "value-changed",
 			  G_CALLBACK (selection_width_value_changed_cb),
 			  self);
-	g_signal_connect (G_OBJECT (self->priv->resize_height_spinbutton),
+	g_signal_connect (GET_WIDGET ("resize_height_spinbutton"),
 			  "value-changed",
 			  G_CALLBACK (selection_height_value_changed_cb),
 			  self);
-	g_signal_connect (self->priv->ratio_combobox,
-			  "changed",
-			  G_CALLBACK (ratio_combobox_changed_cb),
-			  self);
-	g_signal_connect (GET_WIDGET ("ratio_w_spinbutton"),
-			  "value_changed",
-			  G_CALLBACK (ratio_value_changed_cb),
-			  self);
-	g_signal_connect (GET_WIDGET ("ratio_h_spinbutton"),
-			  "value_changed",
-			  G_CALLBACK (ratio_value_changed_cb),
+	g_signal_connect (GET_WIDGET ("keep_ratio_checkbutton"),
+			  "toggled",
+			  G_CALLBACK (keep_ratio_checkbutton_toggled_cb),
 			  self);
-	g_signal_connect (GET_WIDGET ("invert_ratio_checkbutton"),
+	g_signal_connect (GET_WIDGET ("high_quality_checkbutton"),
 			  "toggled",
-			  G_CALLBACK (invert_ratio_changed_cb),
+			  G_CALLBACK (high_quality_checkbutton_toggled_cb),
 			  self);
-
-	self->priv->selector = (GthImageSelector *) gth_image_selector_new (GTH_IMAGE_VIEWER (viewer), GTH_SELECTOR_TYPE_REGION);
-	g_signal_connect (self->priv->selector,
-			  "selection-changed",
-			  G_CALLBACK (selector_selection_changed_cb),
+	g_signal_connect (GET_WIDGET ("unit_combobox"),
+			  "changed",
+			  G_CALLBACK (unit_combobox_changed_cb),
 			  self);
 
-	gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->ratio_combobox), 0);
-	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->selector);
-
 	return options;
 }
 
@@ -430,13 +324,13 @@ gth_file_tool_resize_destroy_options (GthFileTool *base)
 	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
 	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), NULL);
 
+	_g_object_unref (self->priv->new_pixbuf);
 	_g_object_unref (self->priv->src_pixbuf);
 	_g_object_unref (self->priv->builder);
-	_g_object_unref (self->priv->selector);
 
+	self->priv->new_pixbuf = NULL;
 	self->priv->src_pixbuf = NULL;
 	self->priv->builder = NULL;
-	self->priv->selector = NULL;
 }
 
 
@@ -465,8 +359,8 @@ gth_file_tool_resize_finalize (GObject *object)
 
 	self = (GthFileToolResize *) object;
 
+	_g_object_unref (self->priv->new_pixbuf);
 	_g_object_unref (self->priv->src_pixbuf);
-	_g_object_unref (self->priv->selector);
 	_g_object_unref (self->priv->builder);
 
 	/* Chain up */
diff --git a/extensions/file_tools/main.c b/extensions/file_tools/main.c
index e32dd25..4444c3d 100644
--- a/extensions/file_tools/main.c
+++ b/extensions/file_tools/main.c
@@ -33,6 +33,7 @@
 #include "gth-file-tool-mirror.h"
 #include "gth-file-tool-negative.h"
 #include "gth-file-tool-redo.h"
+#include "gth-file-tool-resize.h"
 #include "gth-file-tool-rotate-left.h"
 #include "gth-file-tool-rotate-right.h"
 #include "gth-file-tool-save.h"
@@ -59,6 +60,7 @@ gthumb_extension_activate (void)
 	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_ROTATE_RIGHT);
 	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_ROTATE_LEFT);
 
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_RESIZE);
 	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_CROP);
 }
 
diff --git a/extensions/resize_images/data/ui/resize-images.ui b/extensions/resize_images/data/ui/resize-images.ui
index 6ab6c87..aaa167a 100644
--- a/extensions/resize_images/data/ui/resize-images.ui
+++ b/extensions/resize_images/data/ui/resize-images.ui
@@ -253,8 +253,8 @@
                     <child>
                       <object class="GtkFileChooserButton" id="destination_filechooserbutton">
                         <property name="visible">True</property>
-                        <property name="action">select-folder</property>
                         <property name="create_folders">False</property>
+                        <property name="action">select-folder</property>
                         <property name="title" translatable="yes">Choose destination folder</property>
                       </object>
                     </child>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]