Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
geom_drawing_area.cpp
1 
2 /***************************************************************************
3  * geom_drawing_area.cpp - A Gtk::DrawingArea for objects of the Fawkes
4  * geometry library
5  *
6  * Created: Wed Oct 08 18:52:10 2008
7  * Copyright 2008 Daniel Beck
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version. A runtime exception applies to
15  * this software (see LICENSE.GPL_WRE file mentioned below for details).
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Library General Public License for more details.
21  *
22  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23  */
24 
25 #include <geometry/gtk/geom_drawing_area.h>
26 #include <geometry/hom_point.h>
27 #include <geometry/gtk/hom_point_drawer.h>
28 #include <geometry/hom_vector.h>
29 #include <geometry/gtk/hom_vector_drawer.h>
30 #include <geometry/line_segment.h>
31 #include <geometry/gtk/line_segment_drawer.h>
32 #include <geometry/bezier.h>
33 #include <geometry/gtk/spline_drawer.h>
34 #include <geometry/spline.h>
35 #include <geometry/gtk/bezier_drawer.h>
36 #include <geometry/gtk/drawing_manipulator.h>
37 #include <cmath>
38 
39 using namespace std;
40 
41 namespace fawkes{
42 
43 /** @class fawkes::GeomDrawingArea <geometry/gtk/geom_drawing_area.h>
44  * A Gtk::DrawingArea that allows to easily display drawable objects
45  * of the geometry library.
46  * @author Daniel Beck
47  */
48 
49 /** @var fawkes::GeomDrawingArea::m_drawers
50  * A list of drawers for objects that have been requested to be drawn.
51  */
52 
53 /** @var fawkes::GeomDrawingArea::m_max_x
54  * Right boundary of the drawing area.
55  */
56 
57 /** @var fawkes::GeomDrawingArea::m_max_y
58  * Top boundary of the drawing area.
59  */
60 
61 /** @var fawkes::GeomDrawingArea::m_min_x
62  * Left boundary of the drawing area.
63  */
64 
65 /** @var fawkes::GeomDrawingArea::m_min_y
66  * Bottom boundary of the drawing area.
67  */
68 
69 /** Constructor.
70  * @param max_x top right corner
71  * @param max_y top right corner
72  * @param min_x bottom left corner
73  * @param min_y bottom left corner
74  */
75 GeomDrawingArea::GeomDrawingArea( float max_x,
76  float max_y,
77  float min_x,
78  float min_y )
79  : m_max_x(max_x),
80  m_max_y(max_y),
81  m_min_x(min_x),
82  m_min_y(min_y)
83 {
84  m_cur_drawing_manipulator = NULL;
85 }
86 
87 #ifdef HAVE_GLADEMM
88 /** Constructor.
89  * @param cobject pointer to the base object
90  * @param ref_xml Glade XML file
91  */
92 GeomDrawingArea::GeomDrawingArea( BaseObjectType* cobject,
93  const Glib::RefPtr<Gnome::Glade::Xml>& ref_xml )
94  : Gtk::DrawingArea(cobject)
95 {
96  m_max_x = 5.0;
97  m_max_y = 5.0;
98  m_min_x = -5.0;
99  m_min_y = -5.0;
100 
101  m_cur_drawing_manipulator = NULL;
102 }
103 #endif
104 
105 /** Destructor. */
107 {
108  clear();
109 }
110 
111 /** Clear the drawing area. */
112 void
114 {
115  for ( vector<GeomDrawer*>::iterator iter = m_drawers.begin();
116  iter != m_drawers.end();
117  ++iter )
118  {
119  delete *iter;
120  }
121 
122  m_drawers.clear();
123 
124  m_cur_drawing_manipulator = NULL;
125 }
126 
127 /** <<-operator for HomPoint objects
128  * @param p a HomPoint object
129  * @return a reference to the drawing area
130  */
133 {
134  HomPointDrawer* d = new HomPointDrawer(p);
135 
136  if (m_cur_drawing_manipulator)
137  { d->set_point_size( m_cur_drawing_manipulator->get_point_size() ); }
138 
139  m_drawers.push_back(d);
140 
141  return *this;
142 }
143 
144 /** <<-operator for HomPoint objects
145  * @param p a HomPoint object
146  * @return a reference to the drawing area
147  */
150 {
151  HomPointDrawer* d = new HomPointDrawer(p);
152 
153  if (m_cur_drawing_manipulator)
154  { d->set_point_size( m_cur_drawing_manipulator->get_point_size() ); }
155 
156  m_drawers.push_back(d);
157 
158  return *this;
159 }
160 
161 /** <<-operator for HomVector objects
162  * @param vp a pair constisting of the vector and the offset
163  * @return a reference to the drawing area
164  */
166 GeomDrawingArea::operator<<(std::pair<HomVector, HomPoint> vp)
167 {
168  const HomVector& v = vp.first;
169  const HomPoint& offset = vp.second;
170  HomVectorDrawer* d = new HomVectorDrawer(v, offset);
171  m_drawers.push_back(d);
172 
173  return *this;
174 }
175 
176 /** <<-operator for LineSegments objects
177  * @param l a LineSegment object
178  * @return a reference to the drawing area
179  */
182 {
184  m_drawers.push_back(d);
185 
186  return *this;
187 }
188 
189 /** <<-operator for Bezier objects.
190  * @param b a Bezier object
191  * @return a reference to the drawing area
192  */
195 {
196  BezierDrawer* d = new BezierDrawer(b);
197  m_drawers.push_back(d);
198 
199  return *this;
200 }
201 
202 /** <<-operator for Spline objects.
203  * @param s a Spline object
204  * @return a reference to the drawing area
205  */
208 {
209  SplineDrawer* d = new SplineDrawer(s);
210  m_drawers.push_back(d);
211 
212  return *this;
213 }
214 
215 /** <<-operator for Spline objects.
216  * @param s a Spline object
217  * @return a reference to the drawing area
218  */
221 {
222  SplineDrawer* d = new SplineDrawer(s);
223  m_drawers.push_back(d);
224 
225  return *this;
226 }
227 
228 /** <<-operator for DrawingManipulator objects.
229  * Note: the drawing area takes over the ownwership of the manipulator.
230  * @param m a DrawingManipulator object
231  * @return a reference to the drawing area
232  */
235 {
236  if (m_cur_drawing_manipulator)
237  { m->integrate(m_cur_drawing_manipulator); }
238 
239  m_cur_drawing_manipulator = m;
240  m_drawers.push_back(m);
241 
242  return *this;
243 }
244 
245 /** Signal handler for the expose event.
246  * @param event the event
247  * @return true if event has been handled
248  */
249 bool
250 GeomDrawingArea::on_expose_event(GdkEventExpose* event)
251 {
252  Glib::RefPtr<Gdk::Window> window = get_window();
253  if (window)
254  {
255  Gtk::Allocation allocation = get_allocation();
256  m_window_width = allocation.get_width();
257  m_window_height = allocation.get_height();
258 
259  Cairo::RefPtr<Cairo::Context> context = window->create_cairo_context();
260 
261  if (event)
262  {
263  context->rectangle( event->area.x, event->area.y,
264  event->area.width, event->area.height );
265  context->clip();
266  }
267 
268  float unit_width = fabs(m_max_x) + fabs(m_min_x);
269  float unit_height = fabs(m_max_y) + fabs(m_min_y);
270  if ( (m_window_width / unit_width) <= (m_window_height / unit_height) )
271  { m_unit = m_window_width / unit_width; }
272  else
273  { m_unit = m_window_height / unit_height; }
274 
275  pre_draw(context);
276 
277  for ( vector<GeomDrawer*>::iterator iter = m_drawers.begin();
278  iter != m_drawers.end();
279  ++iter )
280  {
281  GeomDrawer* d = *iter;
282  d->draw(context);
283  }
284 
285  post_draw(context);
286 
287  context->stroke();
288  }
289 
290  return true;
291 }
292 
293 /** Convert the given window coordinates into the frame of the drawing area.
294  * @param window_x the window coordinate
295  * @param window_y the window coordinate
296  * @param drawing_x the drawing coordinate
297  * @param drawing_y the drawing coordinate
298  */
299 void
300 GeomDrawingArea::to_drawing_coords( int window_x, int window_y,
301  float& drawing_x, float& drawing_y )
302 {
303  float unit_width = fabs(m_max_x) + fabs(m_min_x);
304 
305  float pixel_per_unit = m_window_width / unit_width;
306 
307  drawing_x = window_x / pixel_per_unit + m_min_x;
308  drawing_y = -(window_y / pixel_per_unit + m_min_y);
309 }
310 
311 /** This method is called by the expose signal handler before the draw
312  * routines of the registered drawers are called.
313  * Derived classes might want to change this to add static drawing
314  * elements or to change the viewing matrix.
315  * @param context the drawing context
316  */
317 void
318 GeomDrawingArea::pre_draw(Cairo::RefPtr<Cairo::Context>& context)
319 {
320  context->translate( m_window_width / 2.0, m_window_height / 2.0 );
321  context->scale(m_unit, -m_unit);
322 }
323 
324 /** This method is called by the expose signal handler after the
325  * draw routines of the registered drawers are called.
326  * Derived classes might want to change this to add static drawing
327  * elements.
328  * @param context the drawing context
329  */
330 void
331 GeomDrawingArea::post_draw(Cairo::RefPtr<Cairo::Context>& context)
332 {
333 }
334 
335 } // end namespace fawkes
float get_point_size() const
Get the point size.
A spline made up of cubic Bezier curves.
Definition: spline.h:36
Drawer for HomPoint objects.
A line segment.
Definition: line_segment.h:34
Drawer for Spline objects.
Definition: spline_drawer.h:33
A Bezier curve class.
Definition: bezier.h:34
A Gtk::DrawingArea that allows to easily display drawable objects of the geometry library...
GeomDrawingArea(float max_x=5.0, float max_y=5.0, float min_x=-5.0, float min_y=-5.0)
Constructor.
void clear()
Clear the drawing area.
virtual void post_draw(Cairo::RefPtr< Cairo::Context > &context)
This method is called by the expose signal handler after the draw routines of the registered drawers ...
A homogeneous point.
Definition: hom_point.h:33
void integrate(const DrawingManipulator *m)
Integrates the parameters of another manipulator.
Drawer for HomVector objects.
Drawer for Bezier objects.
Definition: bezier_drawer.h:33
virtual void to_drawing_coords(int window_x, int window_y, float &drawing_x, float &drawing_y)
Convert the given window coordinates into the frame of the drawing area.
A homogeneous vector.
Definition: hom_vector.h:31
void set_point_size(float s)
Set the point size with which points a drawn by this drawer.
GeomDrawingArea & operator<<(fawkes::HomPoint &p)
<<-operator for HomPoint objects
Allows to control some aspects of the rendering of objects.
Drawer for LineSegment objects.
virtual ~GeomDrawingArea()
Destructor.
virtual void pre_draw(Cairo::RefPtr< Cairo::Context > &context)
This method is called by the expose signal handler before the draw routines of the registered drawers...