[glom] Print Layout: Allow rules to be moved.



commit 18fc62f111e86c03e3111b32a23f2c91e35fc6a0
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Aug 10 22:09:27 2011 +0200

    Print Layout: Allow rules to be moved.
    
    * glom/utility_widgets/canvas/canvas_line_movable.[h|cc]: Added
    set_hover_color() and make sure that color is used when the mouse is
    over the line.
    * glom/utility_widgets/canvas/canvas_group_grid.[h|cc]:
    Use CanvasLineMovable instead of PolyLine for rules, so it can
    be moved. Make it appear red when hovering over it. Store the
    lines instead of just the positions, so we can get the latest positions
    later. This is rather inefficient, but it works.

 ChangeLog                                          |   13 ++
 glom/utility_widgets/canvas/canvas_group_grid.cc   |  126 ++++++++++++--------
 glom/utility_widgets/canvas/canvas_group_grid.h    |   16 ++-
 glom/utility_widgets/canvas/canvas_line_movable.cc |   32 +++++-
 glom/utility_widgets/canvas/canvas_line_movable.h  |   15 ++-
 5 files changed, 140 insertions(+), 62 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5bfc026..f2f83a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2011-08-10  Murray Cumming  <murrayc murrayc com>
 
+	Print Layout: Allow rules to be moved.
+
+	* glom/utility_widgets/canvas/canvas_line_movable.[h|cc]: Added 
+	set_hover_color() and make sure that color is used when the mouse is 
+	over the line.
+	* glom/utility_widgets/canvas/canvas_group_grid.[h|cc]:
+	Use CanvasLineMovable instead of PolyLine for rules, so it can 
+	be moved. Make it appear red when hovering over it. Store the 
+	lines instead of just the positions, so we can get the latest positions 
+	later. This is rather inefficient, but it works.
+
+2011-08-10  Murray Cumming  <murrayc murrayc com>
+
 	Print Layout: Save the rules and the various show/hides.
 
 	* glom/glom_document.dtd: Add the new nodes and attributes.
diff --git a/glom/utility_widgets/canvas/canvas_group_grid.cc b/glom/utility_widgets/canvas/canvas_group_grid.cc
index 4ef449a..02942f6 100644
--- a/glom/utility_widgets/canvas/canvas_group_grid.cc
+++ b/glom/utility_widgets/canvas/canvas_group_grid.cc
@@ -19,10 +19,11 @@
  */
 
 #include "canvas_group_grid.h"
+#include "canvas_line_movable.h"
 #include <goocanvasmm/canvas.h>
+#include <goocanvasgroup.h>
 #include <math.h>
 #include <iostream>
-#include <goocanvasgroup.h>
 
 namespace Glom
 {
@@ -37,7 +38,7 @@ CanvasGroupGrid::CanvasGroupGrid()
   add_child(m_grid_rules_group);
 
   //Create the temp rule and hide it by default:
-  m_temp_rule = create_rule_line(10, 10, 100, 100);
+  m_temp_rule = create_rule_line(0, true); //Arbitrary defaults.
   m_temp_rule->property_visibility() = Goocanvas::ITEM_INVISIBLE;
   add_child(m_temp_rule);
 }
@@ -91,12 +92,14 @@ double CanvasGroupGrid::snap_position_rules(const type_vec_doubles& rules, doubl
 
 double CanvasGroupGrid::snap_position_rules_x(double x) const
 {
-  return snap_position_rules(m_rules_x, x);
+  const type_vec_doubles rules = get_vertical_rules();
+  return snap_position_rules(rules, x);
 }
 
 double CanvasGroupGrid::snap_position_rules_y(double y) const
 {
-  return snap_position_rules(m_rules_y, y);
+  const type_vec_doubles rules = get_horizontal_rules();
+  return snap_position_rules(rules, y);
 }
 
 double CanvasGroupGrid::snap_position_grid(double a) const
@@ -171,26 +174,55 @@ void CanvasGroupGrid::snap_position(double& x, double& y) const
   }
 }
 
-Glib::RefPtr<Goocanvas::Polyline> CanvasGroupGrid::create_rule_line(double x1, double y1, double x2, double y2)
+Glib::RefPtr<CanvasLineMovable> CanvasGroupGrid::create_rule_line(double pos, bool horizontal)
 {
-  Glib::RefPtr<Goocanvas::Polyline> line = Goocanvas::Polyline::create(x1, y1, x2, y2);
+  double left = 0.0;
+  double top = 0.0;
+  double right = 0.0;
+  double bottom = 0.0;
+  Goocanvas::Canvas* canvas = get_canvas();
+  if(canvas)
+    canvas->get_bounds(left, top, right, bottom);
+
+  Glib::RefPtr<CanvasLineMovable> line = CanvasLineMovable::create();
+
+  if(horizontal)
+  {
+    double data[4] = {left, pos, right, pos};
+    Goocanvas::Points points(2, data);
+    line->property_points() = points ;
+  }
+  else
+  {
+    double data[4] = {pos, top, pos, bottom};
+    Goocanvas::Points points(2, data);
+    line->property_points() = points ;
+  }
+
   line->property_line_width() = LINE_WIDTH;
   line->property_stroke_color() = "green";
+  line->set_hover_color("red"); //So the user knows when he can click to drag.
+
+  if(horizontal)
+    line->set_movement_allowed(true, false);
+  else
+    line->set_movement_allowed(false, true);
+
   return line;
 }
 
 void CanvasGroupGrid::add_vertical_rule(double x)
 {
-  m_rules_x.push_back(x);
-
-  create_rules();
+  Glib::RefPtr<CanvasLineMovable> line = create_rule_line(x, false);
+  m_rules_x.push_back(line);
+  m_grid_rules_group->add_child(line);
 }
 
 void CanvasGroupGrid::add_horizontal_rule(double y)
 {
-  m_rules_y.push_back(y);
-
-  create_rules();
+  Glib::RefPtr<CanvasLineMovable> line = create_rule_line(y, true);
+  m_rules_y.push_back(line);
+  m_grid_rules_group->add_child(line);
 }
 
 void CanvasGroupGrid::remove_rules()
@@ -198,17 +230,46 @@ void CanvasGroupGrid::remove_rules()
   m_rules_x.clear();
   m_rules_y.clear();
 
-  create_rules();
+  while(m_grid_rules_group && m_grid_rules_group->get_n_children())
+    m_grid_rules_group->remove_child(0);
 }
 
 CanvasGroupGrid::type_vec_doubles CanvasGroupGrid::get_horizontal_rules() const
 {
-  return m_rules_y;
+  type_vec_doubles result;
+  for(type_vec_lines::const_iterator iter = m_rules_y.begin();
+    iter != m_rules_y.end(); ++iter)
+  {
+    Glib::RefPtr<CanvasLineMovable> line = *iter;
+    if(!line)
+      continue;
+
+    double x = 0;
+    double y = 0;
+    line->get_xy(x, y);
+    result.push_back(y);
+  }
+
+  return result;
 }
 
 CanvasGroupGrid::type_vec_doubles CanvasGroupGrid::get_vertical_rules() const
 {
-  return m_rules_x;
+  type_vec_doubles result;
+  for(type_vec_lines::const_iterator iter = m_rules_x.begin();
+    iter != m_rules_x.end(); ++iter)
+  {
+    Glib::RefPtr<CanvasLineMovable> line = *iter;
+    if(!line)
+      continue;
+
+    double x = 0;
+    double y = 0;
+    line->get_xy(x, y);
+    result.push_back(x);
+  }
+
+  return result;
 }
 
 void CanvasGroupGrid::set_grid_gap(double gap)
@@ -225,41 +286,6 @@ void CanvasGroupGrid::remove_grid()
   create_grid_lines();
 }
 
-void CanvasGroupGrid::create_rules()
-{
-  while(m_grid_rules_group && m_grid_rules_group->get_n_children())
-    m_grid_rules_group->remove_child(0);
-
-  //Fill the parent canvas with lines:
-  double left = 0.0;
-  double top = 0.0;
-  double right = 0.0;
-  double bottom = 0.0;
-  Goocanvas::Canvas* canvas = get_canvas();
-  if(canvas)
-    canvas->get_bounds(left, top, right, bottom);
-
-  //Vertical rules:
-  for(CanvasGroupGrid::type_vec_doubles::const_iterator iter = m_rules_x.begin(); iter != m_rules_x.end(); ++iter)
-  {
-    const double x = *iter;
-    Glib::RefPtr<Goocanvas::Polyline> line = create_rule_line(x, top, x, bottom);
-    m_grid_rules_group->add_child(line);
-  }
-
-  //Horizontal rules:
-  for(CanvasGroupGrid::type_vec_doubles::const_iterator iter = m_rules_y.begin(); iter != m_rules_y.end(); ++iter)
-  {
-    const double y = *iter;
-    Glib::RefPtr<Goocanvas::Polyline> line = create_rule_line(left, y, right, y);
-    m_grid_rules_group->add_child(line);
-  }
-
-  //Make sure that the grid is below the rules, so that the rules are visible:
-  if(m_grid_lines && m_grid_rules_group)
-    m_grid_lines->lower(m_grid_rules_group);
-}
-
 void CanvasGroupGrid::create_grid_lines()
 {
   //Remove any existing lines:
diff --git a/glom/utility_widgets/canvas/canvas_group_grid.h b/glom/utility_widgets/canvas/canvas_group_grid.h
index 1427f47..c99f3d5 100644
--- a/glom/utility_widgets/canvas/canvas_group_grid.h
+++ b/glom/utility_widgets/canvas/canvas_group_grid.h
@@ -21,6 +21,7 @@
 #ifndef GLOM_UTILITY_WIDGETS_CANVAS_GROUP_GRID_H
 #define GLOM_UTILITY_WIDGETS_CANVAS_GROUP_GRID_H
 
+//#include <glom/utility_widgets/canvas/canvas_line_movable.h>
 #include <goocanvasmm/grid.h>
 #include <goocanvasmm/group.h>
 #include <goocanvasmm/polyline.h>
@@ -30,6 +31,8 @@
 namespace Glom
 {
 
+class CanvasLineMovable;
+
 class CanvasGroupGrid : public Goocanvas::Group
 {
 private:
@@ -70,8 +73,7 @@ public:
 
 private:
   void create_grid_lines();
-  void create_rules();
-  Glib::RefPtr<Goocanvas::Polyline> create_rule_line(double x1, double y1, double x2, double y2);
+  Glib::RefPtr<CanvasLineMovable> create_rule_line(double pos, bool horizontal);
 
   double snap_position_grid(double a) const;
   double snap_position_rules(const type_vec_doubles& rules, double a) const;
@@ -86,11 +88,13 @@ private:
   /// How close we have to be to a grid line to snap to it:
   double m_grid_sensitivity;
 
-  /// The x coordinates of any vertical rules:
-  type_vec_doubles m_rules_x;
+  typedef std::vector< Glib::RefPtr<CanvasLineMovable> > type_vec_lines;
+
+  /// The vertical rules:
+  type_vec_lines m_rules_x;
 
-  /// The y coordinates of any horizontal rules:
-  type_vec_doubles m_rules_y;
+  /// The horizontal rules:
+  type_vec_lines m_rules_y;
 
   Glib::RefPtr<Goocanvas::Grid> m_grid_lines;
   Glib::RefPtr<Goocanvas::Group> m_grid_rules_group;
diff --git a/glom/utility_widgets/canvas/canvas_line_movable.cc b/glom/utility_widgets/canvas/canvas_line_movable.cc
index 726d3cf..62988b3 100644
--- a/glom/utility_widgets/canvas/canvas_line_movable.cc
+++ b/glom/utility_widgets/canvas/canvas_line_movable.cc
@@ -35,8 +35,8 @@ CanvasLineMovable::CanvasLineMovable()
   signal_button_press_event().connect(sigc::mem_fun(*this, &CanvasItemMovable::on_button_press_event));
   signal_button_release_event().connect(sigc::mem_fun(*this, &CanvasItemMovable::on_button_release_event));
 
-  signal_enter_notify_event().connect(sigc::mem_fun(*this, &CanvasItemMovable::on_enter_notify_event));
-  signal_leave_notify_event().connect(sigc::mem_fun(*this, &CanvasItemMovable::on_leave_notify_event));
+  signal_enter_notify_event().connect(sigc::mem_fun(*this, &CanvasLineMovable::on_enter_notify_event));
+  signal_leave_notify_event().connect(sigc::mem_fun(*this, &CanvasLineMovable::on_leave_notify_event));
 }
 
 CanvasLineMovable::~CanvasLineMovable()
@@ -81,5 +81,33 @@ Goocanvas::Canvas* CanvasLineMovable::get_parent_canvas_widget()
   return get_canvas();
 }
 
+void CanvasLineMovable::set_hover_color(const Glib::ustring& color)
+{
+  m_hover_color = color;
+}
+
+bool CanvasLineMovable::on_enter_notify_event(const Glib::RefPtr<Item>& target, GdkEventCrossing* event)
+{
+  if(!m_hover_color.empty())
+  {
+    m_stroke_color = property_stroke_color_rgba();
+    property_stroke_color() = m_hover_color;
+  }
+
+  CanvasItemMovable::on_enter_notify_event(target, event);
+  return Goocanvas::Polyline::on_enter_notify_event(target, event);
+}
+
+bool CanvasLineMovable::on_leave_notify_event(const Glib::RefPtr<Item>& target, GdkEventCrossing* event)
+{ 
+  if(!m_hover_color.empty())
+    property_stroke_color_rgba() = m_stroke_color;
+
+  CanvasItemMovable::on_leave_notify_event(target, event);
+  return Goocanvas::Polyline::on_leave_notify_event(target, event);
+}
+
+
+
 } //namespace Glom
 
diff --git a/glom/utility_widgets/canvas/canvas_line_movable.h b/glom/utility_widgets/canvas/canvas_line_movable.h
index fb76b7d..75be468 100644
--- a/glom/utility_widgets/canvas/canvas_line_movable.h
+++ b/glom/utility_widgets/canvas/canvas_line_movable.h
@@ -32,21 +32,28 @@ class CanvasLineMovable
   : public Goocanvas::Polyline,
     public CanvasItemMovable
 {
-private:
+protected:
   CanvasLineMovable();
   virtual ~CanvasLineMovable();
 
+public:
+  static Glib::RefPtr<CanvasLineMovable> create();
+
+  void set_hover_color(const Glib::ustring& color);
+
   virtual void get_xy(double& x, double& y) const;
   virtual void set_xy(double x, double y);
   virtual void get_width_height(double& width, double& height) const;
   virtual void set_width_height(double width, double height);
 
-public:
-  static Glib::RefPtr<CanvasLineMovable> create();
-
 private:
   virtual Goocanvas::Canvas* get_parent_canvas_widget();
 
+  virtual bool on_enter_notify_event(const Glib::RefPtr<Item>& target, GdkEventCrossing* event);
+  virtual bool on_leave_notify_event(const Glib::RefPtr<Item>& target, GdkEventCrossing* event);
+
+  guint m_stroke_color;
+  Glib::ustring m_hover_color;
 };
 
 } //namespace Glom



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