Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * geom_drawing_area.cpp - A Gtk::DrawingArea for objects of the Fawkes 00004 * geometry library 00005 * 00006 * Created: Wed Oct 08 18:52:10 2008 00007 * Copyright 2008 Daniel Beck 00008 * 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. A runtime exception applies to 00015 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00023 */ 00024 00025 #include <geometry/gtk/geom_drawing_area.h> 00026 #include <geometry/hom_point.h> 00027 #include <geometry/gtk/hom_point_drawer.h> 00028 #include <geometry/hom_vector.h> 00029 #include <geometry/gtk/hom_vector_drawer.h> 00030 #include <geometry/line_segment.h> 00031 #include <geometry/gtk/line_segment_drawer.h> 00032 #include <geometry/bezier.h> 00033 #include <geometry/gtk/spline_drawer.h> 00034 #include <geometry/spline.h> 00035 #include <geometry/gtk/bezier_drawer.h> 00036 #include <geometry/gtk/drawing_manipulator.h> 00037 #include <cmath> 00038 00039 using namespace std; 00040 00041 namespace fawkes{ 00042 00043 /** @class fawkes::GeomDrawingArea <geometry/gtk/geom_drawing_area.h> 00044 * A Gtk::DrawingArea that allows to easily display drawable objects 00045 * of the geometry library. 00046 * @author Daniel Beck 00047 */ 00048 00049 /** @var fawkes::GeomDrawingArea::m_drawers 00050 * A list of drawers for objects that have been requested to be drawn. 00051 */ 00052 00053 /** @var fawkes::GeomDrawingArea::m_max_x 00054 * Right boundary of the drawing area. 00055 */ 00056 00057 /** @var fawkes::GeomDrawingArea::m_max_y 00058 * Top boundary of the drawing area. 00059 */ 00060 00061 /** @var fawkes::GeomDrawingArea::m_min_x 00062 * Left boundary of the drawing area. 00063 */ 00064 00065 /** @var fawkes::GeomDrawingArea::m_min_y 00066 * Bottom boundary of the drawing area. 00067 */ 00068 00069 /** Constructor. 00070 * @param max_x top right corner 00071 * @param max_y top right corner 00072 * @param min_x bottom left corner 00073 * @param min_y bottom left corner 00074 */ 00075 GeomDrawingArea::GeomDrawingArea( float max_x, 00076 float max_y, 00077 float min_x, 00078 float min_y ) 00079 : m_max_x(max_x), 00080 m_max_y(max_y), 00081 m_min_x(min_x), 00082 m_min_y(min_y) 00083 { 00084 m_cur_drawing_manipulator = NULL; 00085 } 00086 00087 #ifdef HAVE_GLADEMM 00088 /** Constructor. 00089 * @param cobject pointer to the base object 00090 * @param ref_xml Glade XML file 00091 */ 00092 GeomDrawingArea::GeomDrawingArea( BaseObjectType* cobject, 00093 const Glib::RefPtr<Gnome::Glade::Xml>& ref_xml ) 00094 : Gtk::DrawingArea(cobject) 00095 { 00096 m_max_x = 5.0; 00097 m_max_y = 5.0; 00098 m_min_x = -5.0; 00099 m_min_y = -5.0; 00100 00101 m_cur_drawing_manipulator = NULL; 00102 } 00103 #endif 00104 00105 /** Destructor. */ 00106 GeomDrawingArea::~GeomDrawingArea() 00107 { 00108 clear(); 00109 } 00110 00111 /** Clear the drawing area. */ 00112 void 00113 GeomDrawingArea::clear() 00114 { 00115 for ( vector<GeomDrawer*>::iterator iter = m_drawers.begin(); 00116 iter != m_drawers.end(); 00117 ++iter ) 00118 { 00119 delete *iter; 00120 } 00121 00122 m_drawers.clear(); 00123 00124 m_cur_drawing_manipulator = NULL; 00125 } 00126 00127 /** <<-operator for HomPoint objects 00128 * @param p a HomPoint object 00129 * @return a reference to the drawing area 00130 */ 00131 GeomDrawingArea& 00132 GeomDrawingArea::operator<<(fawkes::HomPoint& p) 00133 { 00134 HomPointDrawer* d = new HomPointDrawer(p); 00135 00136 if (m_cur_drawing_manipulator) 00137 { d->set_point_size( m_cur_drawing_manipulator->get_point_size() ); } 00138 00139 m_drawers.push_back(d); 00140 00141 return *this; 00142 } 00143 00144 /** <<-operator for HomPoint objects 00145 * @param p a HomPoint object 00146 * @return a reference to the drawing area 00147 */ 00148 GeomDrawingArea& 00149 GeomDrawingArea::operator<<(const fawkes::HomPoint& p) 00150 { 00151 HomPointDrawer* d = new HomPointDrawer(p); 00152 00153 if (m_cur_drawing_manipulator) 00154 { d->set_point_size( m_cur_drawing_manipulator->get_point_size() ); } 00155 00156 m_drawers.push_back(d); 00157 00158 return *this; 00159 } 00160 00161 /** <<-operator for HomVector objects 00162 * @param vp a pair constisting of the vector and the offset 00163 * @return a reference to the drawing area 00164 */ 00165 GeomDrawingArea& 00166 GeomDrawingArea::operator<<(std::pair<HomVector, HomPoint> vp) 00167 { 00168 const HomVector& v = vp.first; 00169 const HomPoint& offset = vp.second; 00170 HomVectorDrawer* d = new HomVectorDrawer(v, offset); 00171 m_drawers.push_back(d); 00172 00173 return *this; 00174 } 00175 00176 /** <<-operator for LineSegments objects 00177 * @param l a LineSegment object 00178 * @return a reference to the drawing area 00179 */ 00180 GeomDrawingArea& 00181 GeomDrawingArea::operator<<(fawkes::LineSegment& l) 00182 { 00183 LineSegmentDrawer* d = new LineSegmentDrawer(l); 00184 m_drawers.push_back(d); 00185 00186 return *this; 00187 } 00188 00189 /** <<-operator for Bezier objects. 00190 * @param b a Bezier object 00191 * @return a reference to the drawing area 00192 */ 00193 GeomDrawingArea& 00194 GeomDrawingArea::operator<<(fawkes::Bezier& b) 00195 { 00196 BezierDrawer* d = new BezierDrawer(b); 00197 m_drawers.push_back(d); 00198 00199 return *this; 00200 } 00201 00202 /** <<-operator for Spline objects. 00203 * @param s a Spline object 00204 * @return a reference to the drawing area 00205 */ 00206 GeomDrawingArea& 00207 GeomDrawingArea::operator<<(fawkes::Spline& s) 00208 { 00209 SplineDrawer* d = new SplineDrawer(s); 00210 m_drawers.push_back(d); 00211 00212 return *this; 00213 } 00214 00215 /** <<-operator for Spline objects. 00216 * @param s a Spline object 00217 * @return a reference to the drawing area 00218 */ 00219 GeomDrawingArea& 00220 GeomDrawingArea::operator<<(const fawkes::Spline& s) 00221 { 00222 SplineDrawer* d = new SplineDrawer(s); 00223 m_drawers.push_back(d); 00224 00225 return *this; 00226 } 00227 00228 /** <<-operator for DrawingManipulator objects. 00229 * Note: the drawing area takes over the ownwership of the manipulator. 00230 * @param m a DrawingManipulator object 00231 * @return a reference to the drawing area 00232 */ 00233 GeomDrawingArea& 00234 GeomDrawingArea::operator<<(fawkes::DrawingManipulator* m) 00235 { 00236 if (m_cur_drawing_manipulator) 00237 { m->integrate(m_cur_drawing_manipulator); } 00238 00239 m_cur_drawing_manipulator = m; 00240 m_drawers.push_back(m); 00241 00242 return *this; 00243 } 00244 00245 /** Signal handler for the expose event. 00246 * @param event the event 00247 * @return true if event has been handled 00248 */ 00249 bool 00250 GeomDrawingArea::on_expose_event(GdkEventExpose* event) 00251 { 00252 Glib::RefPtr<Gdk::Window> window = get_window(); 00253 if (window) 00254 { 00255 Gtk::Allocation allocation = get_allocation(); 00256 m_window_width = allocation.get_width(); 00257 m_window_height = allocation.get_height(); 00258 00259 Cairo::RefPtr<Cairo::Context> context = window->create_cairo_context(); 00260 00261 if (event) 00262 { 00263 context->rectangle( event->area.x, event->area.y, 00264 event->area.width, event->area.height ); 00265 context->clip(); 00266 } 00267 00268 float unit_width = fabs(m_max_x) + fabs(m_min_x); 00269 float unit_height = fabs(m_max_y) + fabs(m_min_y); 00270 if ( (m_window_width / unit_width) <= (m_window_height / unit_height) ) 00271 { m_unit = m_window_width / unit_width; } 00272 else 00273 { m_unit = m_window_height / unit_height; } 00274 00275 pre_draw(context); 00276 00277 for ( vector<GeomDrawer*>::iterator iter = m_drawers.begin(); 00278 iter != m_drawers.end(); 00279 ++iter ) 00280 { 00281 GeomDrawer* d = *iter; 00282 d->draw(context); 00283 } 00284 00285 post_draw(context); 00286 00287 context->stroke(); 00288 } 00289 00290 return true; 00291 } 00292 00293 /** Convert the given window coordinates into the frame of the drawing area. 00294 * @param window_x the window coordinate 00295 * @param window_y the window coordinate 00296 * @param drawing_x the drawing coordinate 00297 * @param drawing_y the drawing coordinate 00298 */ 00299 void 00300 GeomDrawingArea::to_drawing_coords( int window_x, int window_y, 00301 float& drawing_x, float& drawing_y ) 00302 { 00303 float unit_width = fabs(m_max_x) + fabs(m_min_x); 00304 00305 float pixel_per_unit = m_window_width / unit_width; 00306 00307 drawing_x = window_x / pixel_per_unit + m_min_x; 00308 drawing_y = -(window_y / pixel_per_unit + m_min_y); 00309 } 00310 00311 /** This method is called by the expose signal handler before the draw 00312 * routines of the registered drawers are called. 00313 * Derived classes might want to change this to add static drawing 00314 * elements or to change the viewing matrix. 00315 * @param context the drawing context 00316 */ 00317 void 00318 GeomDrawingArea::pre_draw(Cairo::RefPtr<Cairo::Context>& context) 00319 { 00320 context->translate( m_window_width / 2.0, m_window_height / 2.0 ); 00321 context->scale(m_unit, -m_unit); 00322 } 00323 00324 /** This method is called by the expose signal handler after the 00325 * draw routines of the registered drawers are called. 00326 * Derived classes might want to change this to add static drawing 00327 * elements. 00328 * @param context the drawing context 00329 */ 00330 void 00331 GeomDrawingArea::post_draw(Cairo::RefPtr<Cairo::Context>& context) 00332 { 00333 } 00334 00335 } // end namespace fawkes