// Copyright (c) 1997 Tel-Aviv University (Israel). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $Source: /CVSROOT/CGAL/Packages/Planar_map/demo/Planar_map/snapping_layer.h,v $ // $Revision: 1.2.6.1 $ // $Name: $ // // author(s) : Radu Ursu #ifndef CGAL_SNAPPING_LAYER_H #define CGAL_SNAPPING_LAYER_H #include "cgal_types.h" #include #include #include #include #include #include #include template class Snapping_layer : public CGAL::Qt_widget_layer { public: typedef typename R::Point_2 Point; typedef typename R::FT FT; bool on_first, //true if the user selected the first vertex wasrepainted;//true when the widget was repainted Point old_point, //the last end point found current_v; //the current point QCursor cursor; std::list *curveslist; Curve selected_curve, old_curve; bool source, target; Planar_map *pm; //constructor Snapping_layer(const QCursor c=QCursor(Qt::crossCursor)) : on_first(false), cursor(c), source(false), target(false) {}; void pass_the_structure(std::list* l, Planar_map * p) { curveslist = l; pm = p; } private: void draw(){ wasrepainted = true; }; private: QCursor oldcursor; void mousePressEvent(QMouseEvent *e) { if(e->button() == Qt::LeftButton && on_first) { curveslist->remove(selected_curve); curveslist->push_back(old_curve); Locate_type i; Halfedge_handle hh; if(source) hh = pm->locate(selected_curve.source(), i); else hh = pm->locate(selected_curve.target(), i); pm->remove_edge(hh); pm->insert(old_curve); on_first = false; source = false; target = false; selected_curve = Curve(); widget->redraw(); } if(e->button() == Qt::RightButton && !on_first) { if(curveslist->empty()) QMessageBox::warning( widget, "There are no segments in the list!", "Input some segments before using this layer!"); else{ FT x, y; widget->x_real(e->x(), x); widget->y_real(e->y(), y); Point p(x, y); Point closest_p; //this point is the closest one to the mouse coordinates FT min_dist; typename std::list::const_iterator it = curveslist->begin(); min_dist = CGAL::squared_distance(p, (*it).source()); closest_p = (*it).source(); while(it!=curveslist->end()) { if (min_dist > CGAL::squared_distance(p, (*it).source())) { min_dist = CGAL::squared_distance(p, (*it).source()); closest_p = (*it).source(); selected_curve = (*it); old_curve = (*it); source = true; target = false; } if (min_dist > CGAL::squared_distance(p, (*it).target())) { min_dist = CGAL::squared_distance(p, (*it).target()); closest_p = (*it).target(); selected_curve = (*it); old_curve = (*it); target = true; source = false; } it++; } RasterOp old = widget->rasterOp(); //save the initial raster mode widget->setRasterOp(XorROP); widget->lock(); *widget << CGAL::GREEN << CGAL::PointSize (5) << CGAL::PointStyle (CGAL::DISC); *widget << closest_p; widget->unlock(); widget->setRasterOp(old); old_point = closest_p; current_v = closest_p; wasrepainted = false; on_first = true; } } }; void mouseMoveEvent(QMouseEvent *e) { if(on_first) { FT x, y; widget->x_real(e->x(), x); widget->y_real(e->y(), y); RasterOp old = widget->rasterOp(); //save the initial raster mode widget->setRasterOp(XorROP); widget->lock(); *widget << CGAL::GREEN << CGAL::PointSize (5) << CGAL::PointStyle (CGAL::DISC); if(!wasrepainted){ *widget << CGAL::RED << old_curve; *widget << CGAL::GREEN << old_point; } Point p(x,y); Point closest_p; FT min_dist; typename std::list::const_iterator it = curveslist->begin(); min_dist = CGAL::squared_distance(p, (*it).source()); closest_p = (*it).source(); while(it!=curveslist->end()) { if( (*it) == selected_curve){ it++; continue; } if (min_dist > CGAL::squared_distance(p, (*it).source())) { min_dist = CGAL::squared_distance(p, (*it).source()); closest_p = (*it).source(); } if (min_dist > CGAL::squared_distance(p, (*it).target())) { min_dist = CGAL::squared_distance(p, (*it).target()); closest_p = (*it).target(); } it++; } if(target) old_curve = Curve(old_curve.source(), closest_p); else old_curve = Curve(closest_p, old_curve.target()); *widget << CGAL::RED << old_curve; *widget << CGAL::GREEN << closest_p; widget->unlock(); widget->setRasterOp(old); old_point = closest_p; } }; void activating() { oldcursor = widget->cursor(); widget->setCursor(cursor); on_first = false; source = false; target = false; }; void deactivating() { widget->setCursor(oldcursor); }; }; #endif // CGAL_SNAPPING_LAYER_H