[glom] Print Layout: Allow editing of positions and size numerically,



commit fed3abdbf23cd76bd0f9cac95ca5c74148196b54
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Aug 5 21:05:01 2011 +0200

    Print Layout: Allow editing of positions and size numerically,
    
    	* ui/developer/window_print_layout_edit.glade: Add a row of SpinButtons
    	at the bottom to show the position and dimensins of the selected item,
    	also letting the user change them by changing the numbers.
    	* glom/utility_widgets/canvas/canvas_item_movable.[h|cc]:
    	Added signal_selected().
    	* glom/utility_widgets/canvas/canvas_editable.[h|cc]:
    	Added signal_selection_changed().
    	* glom/print_layout/canvas_print_layout.[h|cc]:
    	Added get_selected_items().
    	* glom/mode_design/print_layouts/window_print_layout_edit.[h|cc]:
    	Constructor: Get the SpinButton widgets from Gtk::Builder, and set their
    	values when an item is selected. Also change the item when the values in
    	the SpinButtons change.

 ChangeLog                                          |   18 ++
 .../print_layouts/window_print_layout_edit.cc      |  166 ++++++++++++++++++++
 .../print_layouts/window_print_layout_edit.h       |   14 ++
 glom/print_layout/canvas_print_layout.cc           |   39 +++++
 glom/print_layout/canvas_print_layout.h            |   11 ++-
 glom/utility_widgets/canvas/canvas_editable.cc     |   16 ++
 glom/utility_widgets/canvas/canvas_editable.h      |   20 ++-
 glom/utility_widgets/canvas/canvas_item_movable.cc |   15 ++-
 glom/utility_widgets/canvas/canvas_item_movable.h  |   12 ++
 ui/developer/window_print_layout_edit.glade        |  115 +++++++++++++-
 10 files changed, 420 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index db323ef..faba16b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-08-06  Murray Cumming  <murrayc murrayc com>
+
+	Print Layout: Allow editing of positions and size numerically,
+
+	* ui/developer/window_print_layout_edit.glade: Add a row of SpinButtons
+	at the bottom to show the position and dimensins of the selected item,
+	also letting the user change them by changing the numbers.
+	* glom/utility_widgets/canvas/canvas_item_movable.[h|cc]:
+	Added signal_selected().
+	* glom/utility_widgets/canvas/canvas_editable.[h|cc]:
+	Added signal_selection_changed().
+	* glom/print_layout/canvas_print_layout.[h|cc]: 
+	Added get_selected_items().
+	* glom/mode_design/print_layouts/window_print_layout_edit.[h|cc]:
+	Constructor: Get the SpinButton widgets from Gtk::Builder, and set their 
+	values when an item is selected. Also change the item when the values in 
+	the SpinButtons change.
+
 2011-08-05  Murray Cumming  <murrayc murrayc com>
 
 	Print Layout: Allow the user to select items with a click.
diff --git a/glom/mode_design/print_layouts/window_print_layout_edit.cc b/glom/mode_design/print_layouts/window_print_layout_edit.cc
index 87cf6b0..8d12363 100644
--- a/glom/mode_design/print_layouts/window_print_layout_edit.cc
+++ b/glom/mode_design/print_layouts/window_print_layout_edit.cc
@@ -44,6 +44,11 @@ Window_PrintLayout_Edit::Window_PrintLayout_Edit(BaseObjectType* cobject, const
   m_label_table_name(0),
   m_button_close(0),
   m_box(0),
+  m_box_item_position(0),
+  m_spinbutton_x(0),
+  m_spinbutton_y(0),
+  m_spinbutton_width(0),
+  m_spinbutton_height(0),
   m_drag_preview_requested(false),
   m_vruler(0),
   m_hruler(0),
@@ -61,6 +66,20 @@ Window_PrintLayout_Edit::Window_PrintLayout_Edit(BaseObjectType* cobject, const
   builder->get_widget("entry_name", m_entry_name);
   builder->get_widget("entry_title", m_entry_title);
 
+  builder->get_widget("box_item_position", m_box_item_position);
+  builder->get_widget("spinbutton_x", m_spinbutton_x);
+  m_spinbutton_x->signal_value_changed().connect(
+    sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_spinbutton_x));
+  builder->get_widget("spinbutton_y", m_spinbutton_y);
+  m_spinbutton_y->signal_value_changed().connect(
+    sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_spinbutton_y));
+  builder->get_widget("spinbutton_width", m_spinbutton_width);
+  m_spinbutton_width->signal_value_changed().connect(
+    sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_spinbutton_width));
+  builder->get_widget("spinbutton_height", m_spinbutton_height);
+  m_spinbutton_height->signal_value_changed().connect(
+    sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_spinbutton_height));
+
   //The rulers are not in the glade file because they use an unusual widget 
   //that Glade wouldn't usually know about:
   m_vruler = GIMP_RULER(gimp_ruler_new(GTK_ORIENTATION_VERTICAL));
@@ -126,6 +145,10 @@ Window_PrintLayout_Edit::Window_PrintLayout_Edit(BaseObjectType* cobject, const
   setup_context_menu();
   m_canvas.signal_show_context().connect(sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_canvas_show_context_menu));
 
+  m_canvas.signal_selection_changed().connect(
+    sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_canvas_selection_changed));
+  on_canvas_selection_changed(); //Disable relevant widgets by default.
+  
   show_all_children();
 }
 
@@ -858,6 +881,12 @@ void Window_PrintLayout_Edit::on_menu_file_page_setup()
   set_ruler_sizes();
 }
 
+static void spinbutton_set_max(Gtk::SpinButton& spinbutton, double max)
+{
+  spinbutton.set_range(0, max);
+  spinbutton.set_increments(1, 10);
+}
+
 void Window_PrintLayout_Edit::set_ruler_sizes()
 {
   //Note: We should use the page size if we decide not to make the canvas bounds == page size.
@@ -871,6 +900,12 @@ void Window_PrintLayout_Edit::set_ruler_sizes()
 
   gimp_ruler_set_range(m_hruler, x1, x2, x2);
   gimp_ruler_set_range(m_vruler, y1, y2, x2);
+
+  //Set the limits for the SpinButtons too:
+  spinbutton_set_max(*m_spinbutton_x, x2);
+  spinbutton_set_max(*m_spinbutton_y, y2);
+  spinbutton_set_max(*m_spinbutton_width, x2);
+  spinbutton_set_max(*m_spinbutton_height, y2);
 }
 
 void Window_PrintLayout_Edit::on_scroll_value_changed()
@@ -902,6 +937,137 @@ bool Window_PrintLayout_Edit::on_configure_event(GdkEventConfigure* event)
   return result;
 }
 
+void Window_PrintLayout_Edit::on_canvas_selection_changed()
+{
+  Canvas_PrintLayout::type_vec_items items = m_canvas.get_selected_items();
+  
+  double x = 0;
+  double y = 0;
+  double x2 = 0;
+  double y2 = 0;
+  bool first = true;
+  for(Canvas_PrintLayout::type_vec_items::const_iterator iter = items.begin();
+    iter != items.end(); ++iter)
+  {
+    Glib::RefPtr<CanvasLayoutItem> item = *iter;
+    if(!item)
+      continue;
+
+    double item_x = 0;
+    double item_y = 0;
+    item->get_xy(item_x, item_y);
+    double item_width = 0;
+    double item_height = 0;
+    item->get_width_height(item_width, item_height);
+    const double item_x2 = item_x + item_width;
+    const double item_y2 = item_y + item_height;
+
+    if(first || item_x < x)
+      x = item_x;
+
+    if(first || item_y < y)
+      y = item_y;
+
+    if(item_x2 > x2)
+      x2 = item_x2;
+
+    if(item_y2 > y2)
+      y2 = item_y2;
+
+    first = false;
+  }
+
+  const double width = x2 - x;
+  const double height = y2 - y;
+
+  m_spinbutton_x->set_value(x);
+  m_spinbutton_y->set_value(y);
+  m_spinbutton_width->set_value(width);
+  m_spinbutton_height->set_value(height);
+
+  //Disable the spinbuttons if there are no items selected,
+  //or if there are more than 1.
+  //TODO: Let the user resize groups of items.
+  const bool enable = (items.size() == 1);
+  m_box_item_position->set_sensitive(enable);
+}
+
+void Window_PrintLayout_Edit::on_spinbutton_x()
+{
+  Canvas_PrintLayout::type_vec_items items = m_canvas.get_selected_items();
+  if(items.empty())
+    return;
+
+  Glib::RefPtr<CanvasLayoutItem> item = items[0];
+  if(!item)
+    return;
+
+  double x = 0;
+  double y = 0;
+  item->get_xy(x, y);
+
+  item->set_xy(
+    m_spinbutton_x->get_value(),
+    y);
+}
+
+void Window_PrintLayout_Edit::on_spinbutton_y()
+{
+  Canvas_PrintLayout::type_vec_items items = m_canvas.get_selected_items();
+  if(items.empty())
+    return;
+
+  Glib::RefPtr<CanvasLayoutItem> item = items[0];
+  if(!item)
+    return;
+
+  double x = 0;
+  double y = 0;
+  item->get_xy(x, y);
+
+  item->set_xy(
+    x,
+    m_spinbutton_y->get_value());
+}
+
+void Window_PrintLayout_Edit::on_spinbutton_width()
+{
+  Canvas_PrintLayout::type_vec_items items = m_canvas.get_selected_items();
+  if(items.empty())
+    return;
+
+  Glib::RefPtr<CanvasLayoutItem> item = items[0];
+  if(!item)
+    return;
+
+  double width = 0;
+  double height = 0;
+  item->get_width_height(width, height);
+
+  item->set_width_height(
+    m_spinbutton_width->get_value(),
+    height);
+}
+
+void Window_PrintLayout_Edit::on_spinbutton_height()
+{
+  Canvas_PrintLayout::type_vec_items items = m_canvas.get_selected_items();
+  if(items.empty())
+    return;
+
+  Glib::RefPtr<CanvasLayoutItem> item = items[0];
+  if(!item)
+    return;
+
+  double width = 0;
+  double height = 0;
+  item->get_width_height(width, height);
+
+  item->set_width_height(
+    width,
+    m_spinbutton_height->get_value());
+}
+
 
 } //namespace Glom
 
diff --git a/glom/mode_design/print_layouts/window_print_layout_edit.h b/glom/mode_design/print_layouts/window_print_layout_edit.h
index 3605b03..9284971 100644
--- a/glom/mode_design/print_layouts/window_print_layout_edit.h
+++ b/glom/mode_design/print_layouts/window_print_layout_edit.h
@@ -89,6 +89,13 @@ private:
   void on_canvas_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint timestamp);
   void on_canvas_drag_leave(const Glib::RefPtr<Gdk::DragContext>& drag_context, guint timestamp);
 
+  void on_canvas_selection_changed();
+
+  void on_spinbutton_x();
+  void on_spinbutton_y();
+  void on_spinbutton_width();
+  void on_spinbutton_height();
+
   //override:
   virtual bool on_configure_event(GdkEventConfigure* event);
 
@@ -122,6 +129,13 @@ private:
   Gtk::ScrolledWindow m_scrolled_window;
   Canvas_PrintLayout m_canvas;
 
+  //Widgets that let the user edit item position and size:
+  Gtk::Box* m_box_item_position;
+  Gtk::SpinButton* m_spinbutton_x;
+  Gtk::SpinButton* m_spinbutton_y;
+  Gtk::SpinButton* m_spinbutton_width;
+  Gtk::SpinButton* m_spinbutton_height;
+
   //A preview of the item being dragged onto the canvas:
   bool m_drag_preview_requested;
   Glib::RefPtr<CanvasLayoutItem> m_layout_item_dropping;
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index 229c17e..91ad6e3 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -870,4 +870,43 @@ Base_DB::type_vecConstLayoutFields Canvas_PrintLayout::get_portal_fields_to_show
 }
 
 
+Canvas_PrintLayout::type_vec_items Canvas_PrintLayout::get_selected_items()
+{
+  type_vec_items result;
+
+  //TODO: Do this recursively.
+  Glib::RefPtr<Goocanvas::Item> root = m_items_group;
+  if(!root)
+    return result;
+
+  const int count = root->get_n_children();
+  for(int i = 0; i < count; ++i)
+  {
+    Glib::RefPtr<Goocanvas::Item> child = root->get_child(i);
+    Glib::RefPtr<CanvasLayoutItem> derived =
+      Glib::RefPtr<CanvasLayoutItem>::cast_dynamic(child);
+    if(!derived)
+      continue;
+
+    if(derived->get_selected())
+      result.push_back(derived);
+  }
+
+  return result;
+}
+
+Canvas_PrintLayout::type_vec_const_items Canvas_PrintLayout::get_selected_items() const
+{
+  //TODO: This is inefficient. 
+  //We copy the vector items just to make them const.
+  Canvas_PrintLayout* unconst_this = const_cast<Canvas_PrintLayout*>(this); 
+  const type_vec_items unconst_result = unconst_this->get_selected_items();
+
+  type_vec_const_items result;
+  result.insert(result.begin(), 
+    unconst_result.begin(), unconst_result.end());
+
+  return result;
+}
+
 } //namespace Glom
diff --git a/glom/print_layout/canvas_print_layout.h b/glom/print_layout/canvas_print_layout.h
index 73ca62a..0fa3811 100644
--- a/glom/print_layout/canvas_print_layout.h
+++ b/glom/print_layout/canvas_print_layout.h
@@ -62,6 +62,15 @@ public:
   void fill_with_data(const FoundSet& found_set);
 
   virtual void set_grid_gap(double gap = 20.0);
+
+  typedef std::vector< Glib::RefPtr<CanvasLayoutItem> > type_vec_items;
+
+  /** Get any items that have get_selected()==true.
+   */
+  type_vec_items get_selected_items();
+
+  typedef std::vector< Glib::RefPtr<const CanvasLayoutItem> > type_vec_const_items;
+  type_vec_const_items get_selected_items() const;
   
 private:
 
@@ -97,7 +106,7 @@ private:
   static void update_layout_position_from_canvas(const sharedptr<LayoutItem> layout_item, const Glib::RefPtr<const CanvasLayoutItem>& canvas_item);
 
   Glib::ustring m_table_name;
-  bool m_modified;
+  bool m_modified; //TODO: Actually check this?
 
   //A group containing the layout items, so we can remove them without removing anything else:
   Glib::RefPtr<Goocanvas::Group> m_items_group;
diff --git a/glom/utility_widgets/canvas/canvas_editable.cc b/glom/utility_widgets/canvas/canvas_editable.cc
index c0b2e7b..2272bc9 100644
--- a/glom/utility_widgets/canvas/canvas_editable.cc
+++ b/glom/utility_widgets/canvas/canvas_editable.cc
@@ -90,7 +90,13 @@ void CanvasEditable::add_item(const Glib::RefPtr<Goocanvas::Item>& item, const G
 
   Glib::RefPtr<CanvasItemMovable> movable = CanvasItemMovable::cast_to_movable(item);
   if(movable)
+  {
     movable->set_grid(m_grid);
+
+    //Let this canvas item signal whenever any of its children are selected or deselected:
+    movable->signal_selected().connect(
+      sigc::mem_fun(*this, &CanvasEditable::on_item_selected));
+  }
 }
 
 void CanvasEditable::remove_all_items()
@@ -144,4 +150,14 @@ CanvasEditable::type_signal_show_context CanvasEditable::signal_show_context()
   return m_signal_show_context;
 }
 
+CanvasEditable::type_signal_selection_changed CanvasEditable::signal_selection_changed()
+{
+  return m_signal_selection_changed;
+}
+
+void CanvasEditable::on_item_selected()
+{
+  m_signal_selection_changed.emit();
+}
+
 } //namespace Glom
diff --git a/glom/utility_widgets/canvas/canvas_editable.h b/glom/utility_widgets/canvas/canvas_editable.h
index e51c462..fdd0285 100644
--- a/glom/utility_widgets/canvas/canvas_editable.h
+++ b/glom/utility_widgets/canvas/canvas_editable.h
@@ -22,7 +22,8 @@
 #define GLOM_UTILITY_WIDGETS_CANVAS_EDITABLE_H
 
 #include <goocanvasmm.h>
-#include "canvas_group_grid.h"
+#include <glom/utility_widgets/canvas/canvas_group_grid.h>
+#include <glom/utility_widgets/canvas/canvas_item_movable.h>
 #include <map>
 #include "config.h" // For GLOM_ENABLE_CLIENT_ONLY
 
@@ -54,13 +55,27 @@ public:
   void add_vertical_rule(double x);
   void add_horizontal_rule(double x);
 
+  //TODO: Actually emit this, so we actually show the context menu when clicking on blank space:
   /** void on_show_context(guint button, guint32 activate_time);
    */
   typedef sigc::signal<void, guint, guint32> type_signal_show_context;
   type_signal_show_context signal_show_context();
 
+
+  /** For instance,
+   *   void on_selection_changed();
+   */
+  typedef sigc::signal<void> type_signal_selection_changed;
+
+  /** This signal is emitted if the user causes items 
+   * to be selected or deselected. See get_selected_items().
+   */
+  type_signal_selection_changed signal_selection_changed();
+
 private:
   
+  void on_item_selected();
+
   static Glib::RefPtr<Goocanvas::Item> get_parent_container_or_self(const Glib::RefPtr<Goocanvas::Item>& item);
 
   bool m_dragging;
@@ -79,8 +94,9 @@ private:
 protected:
   Glib::RefPtr<CanvasGroupGrid> m_grid;
 
-public:
+private:
   type_signal_show_context m_signal_show_context;
+  type_signal_selection_changed m_signal_selection_changed;
 };
 
 } //namespace Glom
diff --git a/glom/utility_widgets/canvas/canvas_item_movable.cc b/glom/utility_widgets/canvas/canvas_item_movable.cc
index c0f3490..f288877 100644
--- a/glom/utility_widgets/canvas/canvas_item_movable.cc
+++ b/glom/utility_widgets/canvas/canvas_item_movable.cc
@@ -171,7 +171,8 @@ bool CanvasItemMovable::on_button_release_event(const Glib::RefPtr<Goocanvas::It
 
 
   // A click without a move should select or deselect:
-  bool selected = !get_selected();
+  const bool old_selected = get_selected();
+  bool selected = !old_selected;
 
   // A drag-to-move should always select and never deselect:
   if(!selected)
@@ -187,8 +188,15 @@ bool CanvasItemMovable::on_button_release_event(const Glib::RefPtr<Goocanvas::It
   }
 
   //This will also ask derived classes to indicate it visually:
+
   set_selected(selected);
 
+  //Notify of the selection change, if any:
+  if(selected != old_selected)
+  {
+    m_signal_selected.emit();
+  }
+
   return true;
 }
 
@@ -217,6 +225,11 @@ CanvasItemMovable::type_signal_show_context CanvasItemMovable::signal_show_conte
   return m_signal_show_context;
 }
 
+CanvasItemMovable::type_signal_selected CanvasItemMovable::signal_selected()
+{
+  return m_signal_selected;
+}
+
 void CanvasItemMovable::set_drag_cursor(const Glib::RefPtr<Gdk::Cursor>& cursor)
 {
   m_drag_cursor = cursor;
diff --git a/glom/utility_widgets/canvas/canvas_item_movable.h b/glom/utility_widgets/canvas/canvas_item_movable.h
index a3846ca..152b0b4 100644
--- a/glom/utility_widgets/canvas/canvas_item_movable.h
+++ b/glom/utility_widgets/canvas/canvas_item_movable.h
@@ -70,6 +70,17 @@ public:
   typedef sigc::signal<void, guint, guint32> type_signal_show_context;
   type_signal_show_context signal_show_context();
 
+  /** For instance,
+   *   void on_selected();
+   */
+  typedef sigc::signal<void> type_signal_selected;
+
+  /** This signal is emitted if the user causes the item 
+   * to be selected or deselected. See get_selected().
+   */
+  type_signal_selected signal_selected();
+
+
   /** Provide information about a grid or rules,
    * to which the item should snap when moving:
    *
@@ -136,6 +147,7 @@ private:
 
   type_signal_moved m_signal_moved;
   type_signal_show_context m_signal_show_context;
+  type_signal_selected m_signal_selected;
 };
 
 } //namespace Glom
diff --git a/ui/developer/window_print_layout_edit.glade b/ui/developer/window_print_layout_edit.glade
index 87af006..e0948ee 100644
--- a/ui/developer/window_print_layout_edit.glade
+++ b/ui/developer/window_print_layout_edit.glade
@@ -27,12 +27,12 @@
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="border_width">12</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkVBox" id="vbox_inner">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="border_width">6</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkHBox" id="hbox20">
@@ -146,6 +146,117 @@
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkBox" id="box_item_position">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label_x">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">X:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spinbutton_x">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_y">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Y:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spinbutton_y">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_width">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Width:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spinbutton_width">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_height">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Height:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">6</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spinbutton_height">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">7</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkHButtonBox" id="hbuttonbox43">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
@@ -170,7 +281,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">2</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
               </object>



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