[glabels/vala] Added line object support.



commit 6bde9c0780b08b53216d71aac7df63b27cecc999
Author: Jim Evins <evins snaught com>
Date:   Mon Aug 6 23:24:54 2012 -0400

    Added line object support.

 data/ui/object_editor.ui       |  158 ++++++++++++++++++++++++++++++++++--
 glabels/Makefile.am            |    1 +
 glabels/handle.vala            |   38 +++++++++
 glabels/label_object_line.vala |  172 ++++++++++++++++++++++++++++++++++++++++
 glabels/object_editor.vala     |  132 +++++++++++++++++++++++++++++--
 glabels/ui.vala                |    7 +--
 glabels/view.vala              |   97 +++++++++++++++++------
 7 files changed, 559 insertions(+), 46 deletions(-)
---
diff --git a/data/ui/object_editor.ui b/data/ui/object_editor.ui
index 7b26603..9489c0a 100644
--- a/data/ui/object_editor.ui
+++ b/data/ui/object_editor.ui
@@ -8,12 +8,10 @@
     <property name="step_increment">0.5</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkAdjustment" id="line_spacing_adjustment">
-    <property name="lower">1</property>
-    <property name="upper">5</property>
-    <property name="value">1</property>
-    <property name="step_increment">0.10000000000000001</property>
-    <property name="page_increment">10</property>
+  <object class="GtkAdjustment" id="line_length_adjustment">
+    <property name="upper">100</property>
+    <property name="step_increment">0.01</property>
+    <property name="page_increment">1</property>
   </object>
   <object class="GtkAdjustment" id="line_width_adjustment">
     <property name="lower">0.25</property>
@@ -22,6 +20,13 @@
     <property name="step_increment">0.25</property>
     <property name="page_increment">1</property>
   </object>
+  <object class="GtkAdjustment" id="line_spacing_adjustment">
+    <property name="lower">1</property>
+    <property name="upper">5</property>
+    <property name="value">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">10</property>
+  </object>
   <object class="GtkAdjustment" id="shadow_opacity_adjustment">
     <property name="upper">100</property>
     <property name="value">1</property>
@@ -876,7 +881,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkFrame" id="frame2">
+                  <object class="GtkFrame" id="fill_frame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label_xalign">0</property>
@@ -1099,7 +1104,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkFrame" id="frame3">
+                  <object class="GtkFrame" id="rect_size_frame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label_xalign">0</property>
@@ -1268,6 +1273,136 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkFrame" id="line_size_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="alignment7">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkGrid" id="grid7">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="row_spacing">6</property>
+                            <property name="column_spacing">12</property>
+                            <child>
+                              <object class="GtkLabel" id="line_length_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Length:</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="line_angle_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Angle:</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="line_length_spin">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">â</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="adjustment">line_length_adjustment</property>
+                                <property name="climb_rate">0.0099999997764800008</property>
+                                <property name="digits">2</property>
+                                <property name="snap_to_ticks">True</property>
+                                <property name="numeric">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="line_angle_spin">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">â</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="adjustment">line_angle_adjustment</property>
+                                <property name="climb_rate">0.0099999997764800008</property>
+                                <property name="digits">2</property>
+                                <property name="snap_to_ticks">True</property>
+                                <property name="numeric">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="line_length_units_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="halign">start</property>
+                                <property name="label" translatable="yes">inches</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">2</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="line_angle_units_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="halign">start</property>
+                                <property name="label" translatable="yes">degrees</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label10">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Size&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="position">2</property>
@@ -1544,12 +1679,19 @@
       <widget name="pos_y_label"/>
       <widget name="size_w_label"/>
       <widget name="size_h_label"/>
+      <widget name="line_length_label"/>
+      <widget name="line_angle_label"/>
       <widget name="label40"/>
       <widget name="label41"/>
       <widget name="label45"/>
       <widget name="label46"/>
     </widgets>
   </object>
+  <object class="GtkAdjustment" id="line_angle_adjustment">
+    <property name="upper">360</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
   <object class="GtkSizeGroup" id="page_sizegroup">
     <property name="mode">both</property>
     <widgets>
diff --git a/glabels/Makefile.am b/glabels/Makefile.am
index 906ec55..1cf97ae 100644
--- a/glabels/Makefile.am
+++ b/glabels/Makefile.am
@@ -34,6 +34,7 @@ glabels_4_SOURCES = \
 	label_object.vala \
 	label_object_box.vala \
 	label_object_ellipse.vala \
+	label_object_line.vala \
 	label_object_shape.vala \
 	label_object_text.vala \
 	label_region.vala \
diff --git a/glabels/handle.vala b/glabels/handle.vala
index e65b421..2f0b048 100644
--- a/glabels/handle.vala
+++ b/glabels/handle.vala
@@ -239,5 +239,43 @@ namespace glabels
 	}
 
 
+	public class HandleP1 : Handle
+	{
+		public HandleP1( LabelObject owner )
+		{
+			this.owner = owner;
+		}
+
+		public override void draw( Cairo.Context cr )
+		{
+			draw_at( cr, 0, 0 );
+		}
+
+		public override void cairo_path( Cairo.Context cr )
+		{
+			cairo_path_at( cr, 0, 0 );
+		}
+	}
+
+
+	public class HandleP2 : Handle
+	{
+		public HandleP2( LabelObject owner )
+		{
+			this.owner = owner;
+		}
+
+		public override void draw( Cairo.Context cr )
+		{
+			draw_at( cr, owner.w, owner.h );
+		}
+
+		public override void cairo_path( Cairo.Context cr )
+		{
+			cairo_path_at( cr, owner.w, owner.h );
+		}
+	}
+
+
 }
 
diff --git a/glabels/label_object_line.vala b/glabels/label_object_line.vala
new file mode 100644
index 0000000..65cad48
--- /dev/null
+++ b/glabels/label_object_line.vala
@@ -0,0 +1,172 @@
+/*  label_object_line.vala
+ *
+ *  Copyright (C) 2012  Jim Evins <evins snaught com>
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels 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 gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+	public class LabelObjectLine : LabelObject
+	{
+
+		private const double SELECTION_SLOP_PIXELS = 4.0;
+
+		/**
+		 * Line width
+		 */
+		public override double line_width
+		{
+			get { return _line_width; }
+
+			set
+			{
+				if ( _line_width != value )
+				{
+					_line_width = value;
+					changed();
+				}
+			}
+		}
+		private double _line_width;
+
+
+		/**
+		 * Line color node
+		 */
+		public override ColorNode line_color_node
+		{
+			get { return _line_color_node; }
+
+			set
+			{
+				if ( _line_color_node != value )
+				{
+					_line_color_node = value;
+					changed();
+				}
+			}
+		}
+		private ColorNode _line_color_node;
+
+
+
+		public LabelObjectLine()
+		{
+			handles.append( new HandleP1( this ) );
+			handles.append( new HandleP2( this ) );
+
+			Prefs prefs = new Prefs();
+
+			_line_width              = prefs.default_line_width;
+			_line_color_node         = ColorNode.from_color( prefs.default_line_color );
+		}
+
+
+		public override bool can_line_color()
+		{
+			return true;
+		}
+
+		public override bool can_line_width()
+		{
+			return true;
+		}
+
+
+		public override LabelObject dup()
+		{
+			LabelObjectBox copy = new LabelObjectBox();
+
+			copy.set_common_properties_from_object( this );
+
+			return copy;
+		}
+
+
+		public override void draw_object( Cairo.Context cr, bool in_editor, MergeRecord? record )
+		{
+			Color line_color = line_color_node.expand( record );
+
+			if ( in_editor && line_color_node.field_flag )
+			{
+				line_color = Color.from_rgba( 0, 0, 0, 0.5 );
+			}
+
+			cr.move_to( 0, 0 );
+			cr.line_to( w, h );
+
+			/* Draw line */
+			cr.set_source_rgba( line_color.r, line_color.g, line_color.b, line_color.a );
+			cr.set_line_width( line_width );
+			cr.stroke();
+		}
+
+
+		public override void draw_shadow( Cairo.Context cr, bool in_editor, MergeRecord? record )
+		{
+			Color line_color   = line_color_node.expand( record );
+			Color shadow_color = shadow_color_node.expand( record );
+
+			if ( in_editor && line_color_node.field_flag )
+			{
+				line_color = Color.from_rgba( 0, 0, 0, 0.5 );
+			}
+
+			if ( in_editor && shadow_color_node.field_flag )
+			{
+				shadow_color = Color.black();
+			}
+
+			shadow_color.set_opacity( shadow_opacity );
+
+			cr.set_source_rgba( shadow_color.r, shadow_color.g, shadow_color.b, shadow_color.a );
+
+			if ( line_color.has_alpha() )
+			{
+				cr.move_to( 0, 0 );
+				cr.line_to( w, h );
+
+				/* Draw shadow. */
+				cr.set_line_width( line_width );
+				cr.stroke();
+			}
+		}
+
+
+		public override bool is_object_located_at( Cairo.Context cr, double x, double y )
+		{
+			cr.new_path();
+			cr.move_to( 0, 0 );
+			cr.line_to( w, h );
+
+			cr.set_line_width( line_width + 2*SELECTION_SLOP_PIXELS );
+			if ( cr.in_stroke( x, y ) )
+			{
+				return true;
+			}
+
+			return false;
+		}
+
+
+	}
+
+}
diff --git a/glabels/object_editor.vala b/glabels/object_editor.vala
index 77d0639..6445824 100644
--- a/glabels/object_editor.vala
+++ b/glabels/object_editor.vala
@@ -67,6 +67,7 @@ namespace glabels
 		private Gtk.Box          line_color_box;
 		private ColorButton      line_color_button;
 
+		private Gtk.Frame        fill_frame;
 		private Gtk.Box          fill_color_box;
 		private ColorButton      fill_color_button;
 
@@ -75,6 +76,7 @@ namespace glabels
 		private Gtk.Label        pos_x_units_label;
 		private Gtk.Label        pos_y_units_label;
 
+		private Gtk.Frame        rect_size_frame;
 		private Gtk.SpinButton   size_w_spin;
 		private Gtk.SpinButton   size_h_spin;
 		private Gtk.Label        size_w_units_label;
@@ -82,6 +84,11 @@ namespace glabels
 		private Gtk.CheckButton  size_aspect_check;
 		private Gtk.Button       size_reset_image_button;
 
+		private Gtk.Frame        line_size_frame;
+		private Gtk.SpinButton   line_length_spin;
+		private Gtk.SpinButton   line_angle_spin;
+		private Gtk.Label        line_length_units_label;
+
 		private Gtk.CheckButton  shadow_enable_check;
 		private Gtk.Grid         shadow_controls_grid;
 		private Gtk.SpinButton   shadow_x_spin;
@@ -120,6 +127,9 @@ namespace glabels
 		private ulong sigid_size_w_spin_changed;
 		private ulong sigid_size_h_spin_changed;
 
+		private ulong sigid_line_length_spin_changed;
+		private ulong sigid_line_angle_spin_changed;
+
 		private ulong sigid_shadow_enable_check_changed;
 		private ulong sigid_shadow_x_spin_changed;
 		private ulong sigid_shadow_y_spin_changed;
@@ -139,6 +149,7 @@ namespace glabels
 				                     "font_size_adjustment", "line_spacing_adjustment",
 				                     "line_width_adjustment",
 				                     "size_w_adjustment", "size_h_adjustment",
+				                     "line_length_adjustment", "line_angle_adjustment",
 				                     "pos_x_adjustment", "pos_y_adjustment",
 				                     "shadow_x_adjustment", "shadow_y_adjustment", "shadow_opacity_adjustment",
 				                     "page_sizegroup", "width_sizegroup", "label_sizegroup", "color_box_sizegroup",
@@ -241,6 +252,7 @@ namespace glabels
 
 
 			/* Fill widgets. */
+			fill_frame              = builder.get_object( "fill_frame" )              as Gtk.Frame;
 			fill_color_box          = builder.get_object( "fill_color_box" )          as Gtk.Box;
 
 			fill_color_button       = new ColorButton( _("No fill"), Color.none(), Color.black() );
@@ -260,7 +272,8 @@ namespace glabels
 			sigid_pos_y_spin_changed = pos_y_spin.value_changed.connect( on_pos_y_spin_changed );
 
 
-			/* Size widgets. */
+			/* Rectangle size widgets. */
+			rect_size_frame         = builder.get_object( "rect_size_frame" )         as Gtk.Frame;
 			size_w_spin             = builder.get_object( "size_w_spin" )             as Gtk.SpinButton;
 			size_h_spin             = builder.get_object( "size_h_spin" )             as Gtk.SpinButton;
 			size_w_units_label      = builder.get_object( "size_w_units_label" )      as Gtk.Label;
@@ -272,6 +285,16 @@ namespace glabels
 			sigid_size_h_spin_changed = size_h_spin.value_changed.connect( on_size_h_spin_changed );
 
 
+			/* Line size widgets. */
+			line_size_frame         = builder.get_object( "line_size_frame" )         as Gtk.Frame;
+			line_length_spin        = builder.get_object( "line_length_spin" )        as Gtk.SpinButton;
+			line_angle_spin         = builder.get_object( "line_angle_spin" )         as Gtk.SpinButton;
+			line_length_units_label = builder.get_object( "line_length_units_label" ) as Gtk.Label;
+
+			sigid_line_length_spin_changed = line_length_spin.value_changed.connect( on_line_length_spin_changed );
+			sigid_line_angle_spin_changed  = line_angle_spin.value_changed.connect( on_line_angle_spin_changed );
+
+
 			/* Shadow widgets. */
 			shadow_enable_check     = builder.get_object( "shadow_enable_check" )     as Gtk.CheckButton;
 			shadow_controls_grid    = builder.get_object( "shadow_controls_grid" )    as Gtk.Grid;
@@ -328,6 +351,7 @@ namespace glabels
 			pos_y_units_label.set_text( units.name );
 			size_w_units_label.set_text( units.name );
 			size_h_units_label.set_text( units.name );
+			line_length_units_label.set_text( units.name );
 			shadow_x_units_label.set_text( units.name );
 			shadow_y_units_label.set_text( units.name );
 
@@ -336,6 +360,7 @@ namespace glabels
 			pos_y_spin.set_digits( precision );
 			size_w_spin.set_digits( precision );
 			size_h_spin.set_digits( precision );
+			line_length_spin.set_digits( precision );
 			shadow_x_spin.set_digits( precision );
 			shadow_y_spin.set_digits( precision );
 
@@ -344,6 +369,7 @@ namespace glabels
 			pos_y_spin.set_increments( step_size, 10*step_size );
 			size_w_spin.set_increments( step_size, 10*step_size );
 			size_h_spin.set_increments( step_size, 10*step_size );
+			line_length_spin.set_increments( step_size, 10*step_size );
 			shadow_x_spin.set_increments( step_size, 10*step_size );
 			shadow_y_spin.set_increments( step_size, 10*step_size );
 
@@ -353,6 +379,7 @@ namespace glabels
 			load_pos_y_spin();
 			load_size_w_spin();
 			load_size_h_spin();
+			load_line_length_spin();
 			load_shadow_x_spin();
 			load_shadow_y_spin();
 		}
@@ -370,7 +397,7 @@ namespace glabels
 			{
 				object = model.label.get_1st_selected_object();
 
-				if ( object is LabelObjectText  )
+				if ( object is LabelObjectText )
 				{
 					title_image.set_from_icon_name( "glabels-text", Gtk.IconSize.LARGE_TOOLBAR );
 					title_label.set_text( "<b>%s</b>".printf( _("Text object properties") ) );
@@ -380,9 +407,10 @@ namespace glabels
 					pos_size_page_box.show_all();
 					shadow_page_box.show_all();
 
+					line_size_frame.hide();
 					size_reset_image_button.hide();
 				}
-				else if ( object is LabelObjectBox  )
+				else if ( object is LabelObjectBox )
 				{
 					title_image.set_from_icon_name( "glabels-box", Gtk.IconSize.LARGE_TOOLBAR );
 					title_label.set_text( "<b>%s</b>".printf( _("Box object properties") ) );
@@ -392,9 +420,10 @@ namespace glabels
 					pos_size_page_box.show_all();
 					shadow_page_box.show_all();
 
+					line_size_frame.hide();
 					size_reset_image_button.hide();
 				}
-				else if ( object is LabelObjectEllipse  )
+				else if ( object is LabelObjectEllipse )
 				{
 					title_image.set_from_icon_name( "glabels-ellipse", Gtk.IconSize.LARGE_TOOLBAR );
 					title_label.set_text( "<b>%s</b>".printf( _("Ellipse object properties") ) );
@@ -404,6 +433,21 @@ namespace glabels
 					pos_size_page_box.show_all();
 					shadow_page_box.show_all();
 
+					line_size_frame.hide();
+					size_reset_image_button.hide();
+				}
+				else if ( object is LabelObjectLine )
+				{
+					title_image.set_from_icon_name( "glabels-line", Gtk.IconSize.LARGE_TOOLBAR );
+					title_label.set_text( "<b>%s</b>".printf( _("Line object properties") ) );
+
+					text_page_box.hide();
+					line_fill_page_box.show_all();
+					pos_size_page_box.show_all();
+					shadow_page_box.show_all();
+
+					fill_frame.hide();
+					rect_size_frame.hide();
 					size_reset_image_button.hide();
 				}
 				else
@@ -428,6 +472,8 @@ namespace glabels
 				load_pos_y_spin();
 				load_size_w_spin();
 				load_size_h_spin();
+				load_line_length_spin();
+				load_line_angle_spin();
 				load_shadow_enable_check();
 				load_shadow_x_spin();
 				load_shadow_y_spin();
@@ -510,8 +556,16 @@ namespace glabels
 
 		private void on_object_changed()
 		{
-			load_size_w_spin();
-			load_size_h_spin();
+			if ( object is LabelObjectLine )
+			{
+				load_line_length_spin();
+				load_line_angle_spin();
+			}
+			else
+			{
+				load_size_w_spin();
+				load_size_h_spin();
+			}
 		}
 
 
@@ -1045,7 +1099,7 @@ namespace glabels
 
 		private void load_size_w_spin()
 		{
-			if ( object != null )
+			if ( (object != null) && !(object is LabelObjectLine) )
 			{
 				GLib.SignalHandler.block( (void*)size_w_spin, sigid_size_w_spin_changed );
 
@@ -1079,7 +1133,7 @@ namespace glabels
 
 		private void load_size_h_spin()
 		{
-			if ( object != null )
+			if ( (object != null) && !(object is LabelObjectLine) )
 			{
 				GLib.SignalHandler.block( (void*)size_h_spin, sigid_size_h_spin_changed );
 
@@ -1091,6 +1145,68 @@ namespace glabels
 
 
 		/******************************
+		 * line_length_spin
+		 ******************************/
+		private void on_line_length_spin_changed()
+		{
+			if ( object != null )
+			{
+				double length = line_length_spin.get_value() * units.points_per_unit;
+				double angle  = line_angle_spin.get_value() * Math.PI/180;
+
+				object.w = length * Math.cos( -angle );
+				object.h = length * Math.sin( -angle );
+			}
+		}
+
+
+		private void load_line_length_spin()
+		{
+			if ( (object != null) && object is LabelObjectLine )
+			{
+				GLib.SignalHandler.block( (void*)line_length_spin, sigid_line_length_spin_changed );
+
+				double length = Math.sqrt( object.w*object.w + object.h*object.h );
+
+				line_length_spin.set_value( length * units.units_per_point );
+
+				GLib.SignalHandler.unblock( (void*)line_length_spin, sigid_line_length_spin_changed );
+			}
+		}
+
+
+		/******************************
+		 * line_angle_spin
+		 ******************************/
+		private void on_line_angle_spin_changed()
+		{
+			if ( object != null )
+			{
+				double length = line_length_spin.get_value() * units.points_per_unit;
+				double angle  = line_angle_spin.get_value() * Math.PI/180;
+
+				object.w = length * Math.cos( angle );
+				object.h = length * Math.sin( angle );
+			}
+		}
+
+
+		private void load_line_angle_spin()
+		{
+			if ( (object != null) && object is LabelObjectLine )
+			{
+				GLib.SignalHandler.block( (void*)line_angle_spin, sigid_line_angle_spin_changed );
+
+				double angle = Math.atan2( object.h, object.w );
+
+				line_angle_spin.set_value( angle * 180/Math.PI );
+
+				GLib.SignalHandler.unblock( (void*)line_angle_spin, sigid_line_angle_spin_changed );
+			}
+		}
+
+
+		/******************************
 		 * shadow_enable_check
 		 ******************************/
 		private void on_shadow_enable_check_changed()
diff --git a/glabels/ui.vala b/glabels/ui.vala
index 3aec5f8..2b3b82e 100644
--- a/glabels/ui.vala
+++ b/glabels/ui.vala
@@ -1164,12 +1164,7 @@ namespace glabels
 
 		private void on_objects_create_line( Gtk.Action action )
 		{
-			/*
-			if (window->view != NULL) {
-				gl_view_object_create_mode (GL_VIEW(window->view),
-				                            GL_LABEL_OBJECT_LINE);
-			}
-			*/
+			window.view.create_line_mode();
 		}
 
 
diff --git a/glabels/view.vala b/glabels/view.vala
index d9515c2..d48429d 100644
--- a/glabels/view.vala
+++ b/glabels/view.vala
@@ -407,6 +407,28 @@ namespace glabels
 		}
 
 
+		public void create_line_mode()
+		{
+			Gdk.Window window = canvas.get_window();
+
+			try
+			{
+				Gdk.Pixbuf pixbuf = Gdk.Pixbuf.from_pixdata( Cursor.line_pixdata, false );
+				Gdk.Cursor cursor = new Gdk.Cursor.from_pixbuf( Gdk.Display.get_default(),
+				                                                pixbuf, CURSOR_X_HOTSPOT, CURSOR_Y_HOTSPOT );
+				window.set_cursor( cursor );
+			}
+			catch ( Error err )
+			{
+				error( "%s\n", err.message );
+			}
+
+			in_object_create_mode = true;
+			create_object_type    = CreateType.LINE;
+			state                 = State.IDLE;
+		}
+
+
 		public void create_text_mode()
 		{
 			Gdk.Window window = canvas.get_window();
@@ -884,7 +906,7 @@ namespace glabels
 						                        double.max( y, create_y0 ) - double.min( y, create_y0 ) );
 						break;
 					case CreateType.LINE: 
-						/* TODO */
+						create_object.set_size( x - create_x0, y - create_y0 );
 						break;
 					case CreateType.IMAGE:
 						/* TODO */
@@ -1006,19 +1028,19 @@ namespace glabels
 						switch ( create_object_type )
 						{
 						case CreateType.BOX:
-							create_object = new LabelObjectBox() as LabelObject;
+							create_object = new LabelObjectBox()     as LabelObject;
 							break;
 						case CreateType.ELLIPSE:
 							create_object = new LabelObjectEllipse() as LabelObject;
 							break;
 						case CreateType.LINE: 
-							/* TODO */
+							create_object = new LabelObjectLine()    as LabelObject;
 							break;
 						case CreateType.IMAGE:
 							/* TODO */
 							break;
 						case CreateType.TEXT:
-							create_object = new LabelObjectText() as LabelObject;
+							create_object = new LabelObjectText()    as LabelObject;
 							break;
 						case CreateType.BARCODE:
 							/* TODO */
@@ -1125,12 +1147,16 @@ namespace glabels
 					Gdk.Cursor cursor = new Gdk.Cursor( Gdk.CursorType.LEFT_PTR );
 					window.set_cursor( cursor );
 
-					if ( (create_object.w < 4) && (create_object.h < 4) )
+					if ( (Math.fabs(create_object.w) < 4) && (Math.fabs(create_object.h) < 4) )
 					{
 						if ( create_object is LabelObjectText )
 						{
 							create_object.set_size( 0, 0 );
 						}
+						else if ( create_object is LabelObjectLine )
+						{
+							create_object.set_size( 72, 0 );
+						}
 						else
 						{
 							create_object.set_size( 72, 72 );
@@ -1272,38 +1298,61 @@ namespace glabels
 				w = double.max( x2 - x, 0 );
 				h = y2 - y1;
 			}
-			else
+			else if ( resize_handle is HandleP1 )
 			{
-				assert_not_reached();
+				x1 = x;
+				y1 = y;
+				w  = x2 - x;
+				h  = y2 - y;
+				x0 = x0 + x1;
+				y0 = y0 + y1;
 			}
-
-			/*
-			 * Set size
-			 */
-			if ( resize_honor_aspect )
+			else if ( resize_handle is HandleP2 )
 			{
-				resize_object.set_size_honor_aspect( w, h );
+				w  = x - x1;
+				h  = y - y1;
+				x0 = x0 + x1;
+				y0 = y0 + y1;
 			}
 			else
 			{
-				resize_object.set_size( w, h );
+				assert_not_reached();
 			}
 
 			/*
-			 * Adjust origin, if needed.
+			 * Set size
 			 */
-			if ( resize_handle is HandleNorthWest )
+			if ( !(resize_handle is HandleP1) && !(resize_handle is HandleP2) )
 			{
-				x0 += x2 - resize_object.w;
-				y0 += y2 - resize_object.h;
-			}
-			else if ( (resize_handle is HandleNorth) || (resize_handle is HandleNorthEast) )
-			{
-				y0 += y2 - resize_object.h;
+				if ( resize_honor_aspect )
+				{
+					resize_object.set_size_honor_aspect( w, h );
+				}
+				else
+				{
+					resize_object.set_size( w, h );
+				}
+
+				/*
+				 * Adjust origin, if needed.
+				 */
+				if ( resize_handle is HandleNorthWest )
+				{
+					x0 += x2 - resize_object.w;
+					y0 += y2 - resize_object.h;
+				}
+				else if ( (resize_handle is HandleNorth) || (resize_handle is HandleNorthEast) )
+				{
+					y0 += y2 - resize_object.h;
+				}
+				else if ( (resize_handle is HandleWest) || (resize_handle is HandleSouthWest) )
+				{
+					x0 += x2 - resize_object.w;
+				}
 			}
-			else if ( (resize_handle is HandleWest) || (resize_handle is HandleSouthWest) )
+			else
 			{
-				x0 += x2 - resize_object.w;
+				resize_object.set_size( w, h );
 			}
 
 			/*



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