[gthumb] rotate image: simplified the align horizonal/vertical function
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] rotate image: simplified the align horizonal/vertical function
- Date: Tue, 17 May 2011 22:11:07 +0000 (UTC)
commit 527ea0312a0cf91854e9946ab436117760169a51
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue May 17 23:59:25 2011 +0200
rotate image: simplified the align horizonal/vertical function
extensions/file_tools/Makefile.am | 2 +
extensions/file_tools/data/ui/rotate-options.ui | 820 ++++++++++++++---------
extensions/file_tools/gth-file-tool-rotate.c | 176 ++----
extensions/file_tools/gth-image-line-tool.c | 404 +++++++++++
extensions/file_tools/gth-image-line-tool.h | 65 ++
5 files changed, 1012 insertions(+), 455 deletions(-)
---
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
index 74a619a..f2dffce 100644
--- a/extensions/file_tools/Makefile.am
+++ b/extensions/file_tools/Makefile.am
@@ -28,6 +28,7 @@ HEADER_FILES = \
gth-file-tool-save-as.h \
gth-file-tool-sharpen.h \
gth-file-tool-undo.h \
+ gth-image-line-tool.h \
gth-image-rotator.h \
preferences.h
@@ -76,6 +77,7 @@ libfile_tools_la_SOURCES = \
gth-file-tool-save-as.c \
gth-file-tool-sharpen.c \
gth-file-tool-undo.c \
+ gth-image-line-tool.c \
gth-image-rotator.c \
main.c
diff --git a/extensions/file_tools/data/ui/rotate-options.ui b/extensions/file_tools/data/ui/rotate-options.ui
index ebe6edd..3de50ba 100644
--- a/extensions/file_tools/data/ui/rotate-options.ui
+++ b/extensions/file_tools/data/ui/rotate-options.ui
@@ -1,47 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.16"/>
- <object class="GtkAlignment" id="options">
+ <requires lib="gtk+" version="2.24"/>
+ <object class="GtkNotebook" id="options_notebook">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="top_padding">6</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
<child>
- <object class="GtkVBox" id="vbox2">
+ <object class="GtkAlignment" id="rotation_options">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="top_padding">6</property>
<child>
- <object class="GtkVBox" id="vbox1">
+ <object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">12</property>
<child>
- <object class="GtkFrame" id="rotation_frame">
+ <object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
+ <property name="spacing">12</property>
<child>
- <object class="GtkAlignment" id="alignment12">
+ <object class="GtkFrame" id="rotation_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
<child>
- <object class="GtkVBox" id="vbox4">
+ <object class="GtkAlignment" id="alignment12">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">6</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
<child>
- <object class="GtkHBox" id="hbox4">
+ <object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkHBox" id="rotation_angle_hbox">
+ <object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="spacing">6</property>
<child>
- <placeholder/>
+ <object class="GtkHBox" id="rotation_angle_hbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
</object>
<packing>
@@ -50,79 +63,228 @@
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">spread</property>
+ <child>
+ <object class="GtkButton" id="align_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Align</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
</child>
+ <child type="label">
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Angle</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
</child>
- <child type="label">
- <object class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Angle</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="crop_frame">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
<child>
- <object class="GtkAlignment" id="alignment3">
+ <object class="GtkFrame" id="crop_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
<child>
- <object class="GtkVBox" id="vbox5">
+ <object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">6</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
<child>
- <object class="GtkComboBox" id="resize_combobox">
+ <object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="model">resize_liststore</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
+ <object class="GtkComboBox" id="resize_combobox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">resize_liststore</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="crop_options_table">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="crop_p1_hbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </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="crop_p2_hbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </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="crop_p1_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Point 1:</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="GtkLabel" id="crop_p2_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Point 2:</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="keep_aspect_ratio">
+ <property name="label" translatable="yes">Keep aspect ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Image size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="options_frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
<child>
- <object class="GtkTable" id="crop_options_table">
+ <object class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="n_rows">3</property>
+ <property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
- <object class="GtkHBox" id="crop_p1_hbox">
+ <object class="GtkVBox" id="crop_grid_hbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
@@ -132,238 +294,279 @@
<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="crop_p2_hbox">
+ <object class="GtkLabel" id="crop_grid_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <child>
- <placeholder/>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Grid:</property>
</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>
</packing>
</child>
<child>
- <object class="GtkLabel" id="crop_p1_label">
+ <object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Point 1:</property>
+ <property name="spacing">6</property>
+ <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="use_action_appearance">False</property>
+ <property name="title" translatable="yes">Pick a background color</property>
+ <property name="color">#000000000000</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="background_transparent_checkbutton">
+ <property name="label" translatable="yes">_Transparent</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</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>
- <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="crop_p2_label">
+ <object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Point 2:</property>
+ <property name="label" translatable="yes">_Background:</property>
+ <property name="use_underline">True</property>
</object>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
- <child>
- <object class="GtkCheckButton" id="keep_aspect_ratio">
- <property name="label" translatable="yes">Keep aspect ratio</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">2</property>
- </packing>
- </child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
+ <child type="label">
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
</object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
</child>
- <child type="label">
- <object class="GtkLabel" id="label3">
+ <child>
+ <object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Image size</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <property name="border_width">6</property>
+ <child>
+ <object class="GtkButton" id="reset_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Reset</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
</child>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">6</property>
<property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkFrame" id="align_frame">
+ <object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">center</property>
<child>
- <object class="GtkAlignment" id="alignment2">
+ <object class="GtkButton" id="apply_button">
+ <property name="label">gtk-apply</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkHButtonBox" id="hbuttonbox3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <property name="layout_style">spread</property>
- <child>
- <object class="GtkButton" id="align_h_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <child>
- <object class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Align horizontally</property>
- <attributes>
- <attribute name="size" value="8000"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="align_v_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <child>
- <object class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Align vertically</property>
- <attributes>
- <attribute name="size" value="8000"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
</child>
- <child type="label">
- <object class="GtkLabel" id="label12">
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label">gtk-cancel</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Automatic alignment</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0.47999998927116394</property>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="padding">6</property>
<property name="position">2</property>
</packing>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label">page 1</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment_options">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">6</property>
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
- <object class="GtkFrame" id="options_frame">
+ <object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
+ <property name="spacing">12</property>
<child>
- <object class="GtkAlignment" id="alignment4">
+ <object class="GtkVBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
+ <property name="border_width">5</property>
<child>
- <object class="GtkTable" id="table2">
+ <object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkVBox" id="crop_grid_hbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="crop_grid_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Grid:</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Draw a line on the image
+to set the alignment.</property>
+ <property name="wrap">True</property>
+ <property name="wrap_mode">word-char</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="rotation_frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</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="can_focus">False</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
<child>
- <object class="GtkHBox" id="hbox2">
+ <object class="GtkVBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkColorButton" id="background_colorbutton">
+ <object class="GtkRadioButton" id="alignment_parallel_radiobutton">
+ <property name="label" translatable="yes">Parallel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
+ <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
- <property name="title" translatable="yes">Pick a background color</property>
- <property name="color">#000000000000</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
@@ -372,163 +575,124 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="background_transparent_checkbutton">
- <property name="label" translatable="yes">_Transparent</property>
+ <object class="GtkRadioButton" id="alignment_perpendicular_radiobutton">
+ <property name="label" translatable="yes">Perpendicular</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
<property name="xalign">0</property>
+ <property name="active">True</property>
<property name="draw_indicator">True</property>
+ <property name="group">alignment_parallel_radiobutton</property>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</property>
<property name="fill">True</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>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="can_focus">False</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>
</object>
</child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Options</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <child>
- <object class="GtkButton" id="reset_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkLabel" id="label1">
+ <child type="label">
+ <object class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Reset</property>
+ <property name="label" translatable="yes">Alignment</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">4</property>
+ <property name="position">0</property>
</packing>
</child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">6</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkHButtonBox" id="hbuttonbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <property name="layout_style">center</property>
<child>
- <object class="GtkButton" id="apply_button">
- <property name="label">gtk-apply</property>
+ <object class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="use_stock">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
+ <property name="fill">True</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="cancel_button">
- <property name="label">gtk-cancel</property>
+ <object class="GtkHButtonBox" id="hbuttonbox4">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_stock">True</property>
- <property name="xalign">0.47999998927116394</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">center</property>
+ <child>
+ <object class="GtkButton" id="alignment_cancel_button">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0.47999998927116394</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">1</property>
+ <property name="padding">6</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">6</property>
- <property name="position">2</property>
- </packing>
</child>
</object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label">page 2</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label">page 3</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
</child>
</object>
<object class="GtkListStore" id="resize_liststore">
diff --git a/extensions/file_tools/gth-file-tool-rotate.c b/extensions/file_tools/gth-file-tool-rotate.c
index 51866c7..ddda9dc 100644
--- a/extensions/file_tools/gth-file-tool-rotate.c
+++ b/extensions/file_tools/gth-file-tool-rotate.c
@@ -26,6 +26,7 @@
#include "cairo-rotate.h"
#include "enum-types.h"
#include "gth-file-tool-rotate.h"
+#include "gth-image-line-tool.h"
#include "gth-image-rotator.h"
#include "preferences.h"
@@ -40,7 +41,6 @@ struct _GthFileToolRotatePrivate {
cairo_surface_t *image;
gboolean has_alpha;
GtkBuilder *builder;
- GtkWidget *options;
GtkWidget *crop_grid;
GtkAdjustment *rotation_angle_adj;
GtkAdjustment *crop_p1_adj;
@@ -48,12 +48,8 @@ struct _GthFileToolRotatePrivate {
gboolean crop_enabled;
double crop_p1_plus_p2;
GdkRectangle crop_region;
- GthImageSelector *selector_crop;
- GthImageSelector *selector_align;
+ GthImageViewerTool *alignment;
GthImageViewerTool *rotator;
- guint selector_align_direction;
- guint selector_align_point;
- GdkPoint align_points[2];
};
@@ -160,91 +156,67 @@ update_crop_grid (GthFileToolRotate *self)
static void
-align_begin (GthFileToolRotate *self)
+alignment_changed_cb (GthImageLineTool *line_tool,
+ GthFileToolRotate *self)
{
GtkWidget *window;
GtkWidget *viewer_page;
GtkWidget *viewer;
+ GdkPoint p1;
+ GdkPoint p2;
+ double angle;
window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (GET_WIDGET ("options_notebook")), 0);
+ gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->rotator);
- self->priv->selector_align_point = 0;
-
- gtk_widget_set_sensitive (self->priv->options, FALSE);
+ gth_image_line_tool_get_points (line_tool, &p1, &p2);
+ angle = _cairo_image_surface_rotate_get_align_angle (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("alignment_parallel_radiobutton"))), p1, p2);
+ gtk_adjustment_set_value (self->priv->rotation_angle_adj, angle);
+}
- /* FIXME
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->src_pixbuf, FALSE); */
- gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->selector_align);
+static void
+apply_changes (GthFileToolRotate *self)
+{
+ gth_image_rotator_set_angle (GTH_IMAGE_ROTATOR (self->priv->rotator), gtk_adjustment_get_value (self->priv->rotation_angle_adj));
+ update_crop_parameters (self);
+ update_crop_region (self);
}
static void
-align_end (GthFileToolRotate *self)
+alignment_cancel_button_clicked_cb (GtkButton *button,
+ GthFileToolRotate *self)
{
GtkWidget *window;
GtkWidget *viewer_page;
- double angle;
+ GtkWidget *viewer;
window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
-
- angle = _cairo_image_surface_rotate_get_align_angle (self->priv->selector_align_direction == 1,
- self->priv->align_points[0],
- self->priv->align_points[1]),
-
- self->priv->selector_align_direction = 0;
- self->priv->selector_align_point = 0;
-
- gtk_widget_set_sensitive (self->priv->options, TRUE);
-
- if (angle == gtk_adjustment_get_value (self->priv->rotation_angle_adj)) {
-
- /* We already have the pixmap ready */
-
- /* FIXME
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->rotate_pixbuf, FALSE);
- */
-
- update_crop_parameters (self);
- update_crop_region (self);
- }
- else {
- /* This triggers the rotation and the update of crop parameters */
-
- gtk_adjustment_set_value (self->priv->rotation_angle_adj, angle);
- }
+ viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (GET_WIDGET ("options_notebook")), 0);
+ gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->rotator);
}
static void
-apply_changes (GthFileToolRotate *self)
+align_button_clicked_cb (GtkButton *button,
+ GthFileToolRotate *self)
{
- /* FIXME
- cairo_color_t background_color;
- if (self->priv->background_transparent) {
- background_color.r = 0.0;
- background_color.g = 0.0;
- background_color.b = 0.0;
- background_color.a = 0.0;
- }
- else {
- GdkColor color;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
- gtk_color_button_get_color (GTK_COLOR_BUTTON (self->priv->background_colorbutton), &color);
- background_color.r = (double) color.red / 65535;
- background_color.g = (double) color.green / 65535;
- background_color.b = (double) color.blue / 65535;
- background_color.a = 1.0;
- }
- gth_image_rotator_set_background (GTH_IMAGE_ROTATOR (self->priv->rotator), &self->priv->background_color);
- */
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
- gth_image_rotator_set_angle (GTH_IMAGE_ROTATOR (self->priv->rotator), gtk_adjustment_get_value (self->priv->rotation_angle_adj));
- update_crop_parameters (self);
- update_crop_region (self);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (GET_WIDGET ("options_notebook")), 1);
+ gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->alignment);
}
@@ -257,26 +229,6 @@ reset_button_clicked_cb (GtkButton *button,
static void
-align_h_button_clicked_cb (GtkButton *button,
- GthFileToolRotate *self)
-{
- self->priv->selector_align_direction = 0;
-
- align_begin (self);
-}
-
-
-static void
-align_v_button_clicked_cb (GtkButton *button,
- GthFileToolRotate *self)
-{
- self->priv->selector_align_direction = 1;
-
- align_begin (self);
-}
-
-
-static void
apply_button_clicked_cb (GtkButton *button,
GthFileToolRotate *self)
{
@@ -386,24 +338,6 @@ background_transparent_toggled_cb (GtkToggleButton *toggle_button,
static void
-selector_selected_cb (GthImageSelector *selector,
- int x,
- int y,
- GthFileToolRotate *self)
-{
- guint i;
-
- i = self->priv->selector_align_point++;
-
- self->priv->align_points[i].x = x;
- self->priv->align_points[i].y = y;
-
- if (self->priv->selector_align_point == 2)
- align_end (self);
-}
-
-
-static void
resize_combobox_changed_cb (GtkComboBox *combo_box,
GthFileToolRotate *self)
{
@@ -441,9 +375,6 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
self->priv->builder = _gtk_builder_new_from_file ("rotate-options.ui", "file_tools");
- self->priv->options = _gtk_builder_get_widget (self->priv->builder, "options");
- gtk_widget_show (self->priv->options);
-
self->priv->rotation_angle_adj = gimp_scale_entry_new (GET_WIDGET ("rotation_angle_hbox"),
GTK_LABEL (GET_WIDGET ("rotation_angle_label")),
0.0, -90.0, 90.0, 0.1, 1.0, 1);
@@ -471,12 +402,9 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_aspect_ratio")), eel_gconf_get_boolean (PREF_ROTATE_KEEP_ASPECT_RATIO, TRUE));
- self->priv->selector_crop = (GthImageSelector *) gth_image_selector_new (GTH_IMAGE_VIEWER (viewer), GTH_SELECTOR_TYPE_REGION);
- self->priv->selector_align = (GthImageSelector *) gth_image_selector_new (GTH_IMAGE_VIEWER (viewer), GTH_SELECTOR_TYPE_POINT);
- gth_image_selector_set_mask_visible (self->priv->selector_crop, TRUE);
- gth_image_selector_set_mask_visible (self->priv->selector_align, FALSE);
+ self->priv->alignment = gth_image_line_tool_new ();
- self->priv->rotator = gth_image_rotator_new (GTH_IMAGE_VIEWER (viewer));
+ self->priv->rotator = gth_image_rotator_new ();
gth_image_rotator_set_center (GTH_IMAGE_ROTATOR (self->priv->rotator),
cairo_image_surface_get_width (self->priv->image) / 2,
cairo_image_surface_get_height (self->priv->image) / 2);
@@ -503,12 +431,8 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
gth_image_rotator_set_background (GTH_IMAGE_ROTATOR (self->priv->rotator), &background_color);
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->rotator);
- gth_image_viewer_set_zoom_enabled (GTH_IMAGE_VIEWER (viewer), FALSE);
gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (viewer_page));
- self->priv->selector_align_direction = 0;
- self->priv->selector_align_point = 0;
-
self->priv->crop_enabled = TRUE;
self->priv->crop_region.x = 0;
self->priv->crop_region.y = 0;
@@ -527,13 +451,9 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
"clicked",
G_CALLBACK (reset_button_clicked_cb),
self);
- g_signal_connect (GET_WIDGET ("align_h_button"),
+ g_signal_connect (GET_WIDGET ("align_button"),
"clicked",
- G_CALLBACK (align_h_button_clicked_cb),
- self);
- g_signal_connect (GET_WIDGET ("align_v_button"),
- "clicked",
- G_CALLBACK (align_v_button_clicked_cb),
+ G_CALLBACK (align_button_clicked_cb),
self);
g_signal_connect (G_OBJECT (self->priv->rotation_angle_adj),
"value-changed",
@@ -563,9 +483,13 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
"changed",
G_CALLBACK (crop_grid_changed_cb),
self);
- g_signal_connect (self->priv->selector_align,
- "selected",
- G_CALLBACK (selector_selected_cb),
+ g_signal_connect (self->priv->alignment,
+ "changed",
+ G_CALLBACK (alignment_changed_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("alignment_cancel_button"),
+ "clicked",
+ G_CALLBACK (alignment_cancel_button_clicked_cb),
self);
g_signal_connect (GET_WIDGET ("resize_combobox"),
"changed",
@@ -576,7 +500,7 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
update_crop_region (self);
update_crop_grid (self);
- return self->priv->options;
+ return GET_WIDGET ("options_notebook");
}
@@ -620,10 +544,8 @@ gth_file_tool_rotate_destroy_options (GthFileTool *base)
cairo_surface_destroy (self->priv->image);
self->priv->image = NULL;
_g_clear_object (&self->priv->builder);
- _g_clear_object (&self->priv->selector_crop);
- _g_clear_object (&self->priv->selector_align);
- self->priv->selector_align_direction = 0;
- self->priv->selector_align_point = 0;
+ _g_clear_object (&self->priv->rotator);
+ _g_clear_object (&self->priv->alignment);
}
diff --git a/extensions/file_tools/gth-image-line-tool.c b/extensions/file_tools/gth-image-line-tool.c
new file mode 100644
index 0000000..66442a9
--- /dev/null
+++ b/extensions/file_tools/gth-image-line-tool.c
@@ -0,0 +1,404 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <math.h>
+#include <gthumb.h>
+#include "gth-image-line-tool.h"
+
+
+#define MIN4(a,b,c,d) MIN(MIN((a),(b)),MIN((c),(d)))
+#define MAX4(a,b,c,d) MAX(MAX((a),(b)),MAX((c),(d)))
+
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+
+static guint signals[LAST_SIGNAL] = { 0 };
+static gpointer parent_class = NULL;
+
+
+struct _GthImageLineToolPrivate {
+ GthImageViewer *viewer;
+
+ /* options */
+
+ GdkPoint p1;
+ GdkPoint p2;
+
+ /* utility variables */
+
+ int original_width;
+ int original_height;
+ double preview_zoom;
+ cairo_surface_t *preview_image;
+ GdkRectangle preview_image_area;
+ GdkPoint preview_center;
+ GdkRectangle clip_area;
+ cairo_matrix_t matrix;
+ gboolean first_point_set;
+ GthFit original_fit_mode;
+ gboolean original_zoom_enabled;
+};
+
+
+static void
+gth_image_line_tool_set_viewer (GthImageViewerTool *base,
+ GthImageViewer *viewer)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ self->priv->viewer = viewer;
+ self->priv->original_fit_mode = gth_image_viewer_get_fit_mode (GTH_IMAGE_VIEWER (viewer));
+ self->priv->original_zoom_enabled = gth_image_viewer_get_zoom_enabled (GTH_IMAGE_VIEWER (viewer));
+ gth_image_viewer_set_fit_mode (GTH_IMAGE_VIEWER (viewer), GTH_FIT_SIZE_IF_LARGER);
+ gth_image_viewer_set_zoom_enabled (GTH_IMAGE_VIEWER (viewer), FALSE);
+ self->priv->first_point_set = FALSE;
+}
+
+
+static void
+gth_image_line_tool_unset_viewer (GthImageViewerTool *base,
+ GthImageViewer *viewer)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ gth_image_viewer_set_fit_mode (GTH_IMAGE_VIEWER (viewer), self->priv->original_fit_mode);
+ gth_image_viewer_set_zoom_enabled (GTH_IMAGE_VIEWER (viewer), self->priv->original_zoom_enabled);
+ self->priv->viewer = NULL;
+ self->priv->first_point_set = FALSE;
+}
+
+
+static void
+gth_image_line_tool_realize (GthImageViewerTool *base)
+{
+ /* void */
+}
+
+
+static void
+gth_image_line_tool_unrealize (GthImageViewerTool *base)
+{
+ /* void */
+}
+
+
+static void
+update_image_surface (GthImageLineTool *self)
+{
+ GtkAllocation allocation;
+ cairo_surface_t *image;
+ int max_size;
+ int width;
+ int height;
+ cairo_surface_t *preview_image;
+
+ if (self->priv->preview_image != NULL) {
+ cairo_surface_destroy (self->priv->preview_image);
+ self->priv->preview_image = NULL;
+ }
+
+ image = gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER (self->priv->viewer));
+ if (image == NULL)
+ return;
+
+ self->priv->original_width = cairo_image_surface_get_width (image);
+ self->priv->original_height = cairo_image_surface_get_height (image);
+ width = self->priv->original_width;
+ height = self->priv->original_height;
+ gtk_widget_get_allocation (GTK_WIDGET (self->priv->viewer), &allocation);
+ max_size = MAX (allocation.width, allocation.height) / G_SQRT2 + 2;
+ if (scale_keeping_ratio (&width, &height, max_size, max_size, FALSE))
+ preview_image = _cairo_image_surface_scale_to (image, width, height, CAIRO_FILTER_BILINEAR);
+ else
+ preview_image = cairo_surface_reference (image);
+
+ self->priv->preview_zoom = (double) width / self->priv->original_width;
+ self->priv->preview_image = preview_image;
+ 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.5, 0);
+ self->priv->preview_image_area.y = MAX ((allocation.height - self->priv->preview_image_area.height) / 2 - 0.5, 0);
+}
+
+
+static void
+gth_image_line_tool_size_allocate (GthImageViewerTool *base,
+ GtkAllocation *allocation)
+{
+ update_image_surface (GTH_IMAGE_LINE_TOOL (base));
+}
+
+
+static void
+gth_image_line_tool_map (GthImageViewerTool *base)
+{
+ /* void */
+}
+
+
+static void
+gth_image_line_tool_unmap (GthImageViewerTool *base)
+{
+ /* void */
+}
+
+
+static void
+paint_image (GthImageLineTool *self,
+ cairo_t *cr)
+{
+ cairo_save (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ 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->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);
+}
+
+
+static void
+gth_image_line_tool_expose (GthImageViewerTool *base,
+ GdkEventExpose *event,
+ cairo_t *cr)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ if (self->priv->preview_image == NULL)
+ return;
+
+ cairo_save (cr);
+
+ cairo_rectangle (cr,
+ event->area.x,
+ event->area.y,
+ event->area.width,
+ event->area.height);
+ cairo_clip (cr);
+
+ paint_image (self, cr);
+
+ if (self->priv->first_point_set) {
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2)
+ cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+#endif
+ cairo_set_line_width (cr, 5.0);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_translate (cr, self->priv->preview_image_area.x, self->priv->preview_image_area.y);
+ cairo_scale (cr, self->priv->preview_zoom, self->priv->preview_zoom);
+ cairo_move_to (cr, self->priv->p1.x, self->priv->p1.y);
+ cairo_line_to (cr, self->priv->p2.x, self->priv->p2.y);
+ cairo_stroke (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+
+static gboolean
+gth_image_line_tool_button_release (GthImageViewerTool *base,
+ GdkEventButton *event)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ g_signal_emit (self, signals[CHANGED], 0);
+ return FALSE;
+}
+
+
+static gboolean
+gth_image_line_tool_button_press (GthImageViewerTool *base,
+ GdkEventButton *event)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ if (event->type == GDK_BUTTON_PRESS) {
+ self->priv->p1.x = self->priv->p2.x = (event->x - self->priv->preview_image_area.x) / self->priv->preview_zoom;
+ self->priv->p1.y = self->priv->p2.y = (event->y - self->priv->preview_image_area.y) / self->priv->preview_zoom;
+ self->priv->first_point_set = TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+gth_image_line_tool_motion_notify (GthImageViewerTool *base,
+ GdkEventMotion *event)
+{
+ GthImageLineTool *self = GTH_IMAGE_LINE_TOOL (base);
+
+ if (! self->priv->first_point_set)
+ return FALSE;
+
+ self->priv->p2.x = (event->x - self->priv->preview_image_area.x) / self->priv->preview_zoom;
+ self->priv->p2.y = (event->y - self->priv->preview_image_area.y) / self->priv->preview_zoom;
+ gtk_widget_queue_draw (GTK_WIDGET (self->priv->viewer));
+
+ return FALSE;
+}
+
+
+static void
+gth_image_line_tool_image_changed (GthImageViewerTool *base)
+{
+ update_image_surface (GTH_IMAGE_LINE_TOOL (base));
+}
+
+
+static void
+gth_image_line_tool_zoom_changed (GthImageViewerTool *base)
+{
+ update_image_surface (GTH_IMAGE_LINE_TOOL (base));
+}
+
+
+static void
+gth_image_line_tool_instance_init (GthImageLineTool *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_LINE_TOOL, GthImageLineToolPrivate);
+ self->priv->preview_image = NULL;
+ self->priv->first_point_set = FALSE;
+}
+
+
+static void
+gth_image_line_tool_finalize (GObject *object)
+{
+ GthImageLineTool *self;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTH_IS_IMAGE_LINE_TOOL (object));
+
+ self = (GthImageLineTool *) object;
+ if (self->priv->preview_image != NULL)
+ cairo_surface_destroy (self->priv->preview_image);
+
+ /* Chain up */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_image_line_tool_class_init (GthImageLineToolClass *class)
+{
+ GObjectClass *gobject_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GthImageLineToolPrivate));
+
+ gobject_class = (GObjectClass*) class;
+ gobject_class->finalize = gth_image_line_tool_finalize;
+
+ signals[CHANGED] = g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthImageLineToolClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+
+static void
+gth_image_line_tool_gth_image_tool_interface_init (GthImageViewerToolIface *iface)
+{
+ iface->set_viewer = gth_image_line_tool_set_viewer;
+ iface->unset_viewer = gth_image_line_tool_unset_viewer;
+ iface->realize = gth_image_line_tool_realize;
+ iface->unrealize = gth_image_line_tool_unrealize;
+ iface->size_allocate = gth_image_line_tool_size_allocate;
+ iface->map = gth_image_line_tool_map;
+ iface->unmap = gth_image_line_tool_unmap;
+ iface->expose = gth_image_line_tool_expose;
+ iface->button_press = gth_image_line_tool_button_press;
+ iface->button_release = gth_image_line_tool_button_release;
+ iface->motion_notify = gth_image_line_tool_motion_notify;
+ iface->image_changed = gth_image_line_tool_image_changed;
+ iface->zoom_changed = gth_image_line_tool_zoom_changed;
+}
+
+
+GType
+gth_image_line_tool_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthImageLineToolClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_image_line_tool_class_init,
+ NULL,
+ NULL,
+ sizeof (GthImageLineTool),
+ 0,
+ (GInstanceInitFunc) gth_image_line_tool_instance_init
+ };
+ static const GInterfaceInfo gth_image_tool_info = {
+ (GInterfaceInitFunc) gth_image_line_tool_gth_image_tool_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GthImageLineTool",
+ &type_info,
+ 0);
+ g_type_add_interface_static (type, GTH_TYPE_IMAGE_VIEWER_TOOL, >h_image_tool_info);
+ }
+
+ return type;
+}
+
+
+GthImageViewerTool *
+gth_image_line_tool_new (void)
+{
+ return (GthImageViewerTool *) g_object_new (GTH_TYPE_IMAGE_LINE_TOOL, NULL);
+}
+
+
+void
+gth_image_line_tool_get_points (GthImageLineTool *self,
+ GdkPoint *p1,
+ GdkPoint *p2)
+{
+ *p1 = self->priv->p1;
+ *p2 = self->priv->p2;
+}
diff --git a/extensions/file_tools/gth-image-line-tool.h b/extensions/file_tools/gth-image-line-tool.h
new file mode 100644
index 0000000..4860ce8
--- /dev/null
+++ b/extensions/file_tools/gth-image-line-tool.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_IMAGE_LINE_TOOL_H
+#define GTH_IMAGE_LINE_TOOL_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_IMAGE_LINE_TOOL (gth_image_line_tool_get_type ())
+#define GTH_IMAGE_LINE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE_LINE_TOOL, GthImageLineTool))
+#define GTH_IMAGE_LINE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_IMAGE_LINE_TOOL, GthImageLineToolClass))
+#define GTH_IS_IMAGE_LINE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE_LINE_TOOL))
+#define GTH_IS_IMAGE_LINE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_IMAGE_LINE_TOOL))
+#define GTH_IMAGE_LINE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_IMAGE_LINE_TOOL, GthImageLineToolClass))
+
+typedef struct _GthImageLineTool GthImageLineTool;
+typedef struct _GthImageLineToolClass GthImageLineToolClass;
+typedef struct _GthImageLineToolPrivate GthImageLineToolPrivate;
+
+struct _GthImageLineTool
+{
+ GObject __parent;
+ GthImageLineToolPrivate *priv;
+};
+
+struct _GthImageLineToolClass
+{
+ GObjectClass __parent_class;
+
+ /*< signals >*/
+
+ void (* changed) (GthImageLineTool *rotator);
+};
+
+GType gth_image_line_tool_get_type (void);
+GthImageViewerTool * gth_image_line_tool_new (void);
+void gth_image_line_tool_get_points (GthImageLineTool *self,
+ GdkPoint *p1,
+ GdkPoint *p2);
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_LINE_TOOL_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]