cgal/Packages/Qt_widget/include/CGAL/IO/Qt_Window.h

665 lines
15 KiB
C++

// ============================================================================
//
// Copyright (c) 1997-2000 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------------
//
// file : include/CGAL/IO/Qt_Window.h
// package : QT_window
// author(s) : Laurent Rineau
// release :
// release_date :
//
// coordinator : Laurent Rineau <rineau@clipper.ens.fr>
//
// ============================================================================
#ifndef CGAL_QT_WINDOW_H
#define CGAL_QT_WINDOW_H
#include <qwidget.h>
#include <qpainter.h>
#include <qcolor.h>
#include <qpixmap.h>
#include <CGAL/Cartesian.h>
#include <CGAL/IO/Color.h>
namespace CGAL {
class Qt_widget_tool;
enum PointStyle { PIXEL, CROSS, PLUS, CIRCLE, DISC, RECT, BOX };
class Qt_widget : public QWidget {
Q_OBJECT
Q_PROPERTY( QColor color READ color WRITE setColor )
Q_PROPERTY( QColor backGroundColor READ backgroundColor WRITE
setBackgroundColor )
Q_PROPERTY( QColor fillColor READ fillColor WRITE
setFillColor )
Q_PROPERTY( bool isFilled READ isFilled WRITE setFilled )
Q_PROPERTY( uint lineWidth READ lineWidth WRITE setLineWidth )
Q_PROPERTY( uint pointSize READ pointSize WRITE setPointSize )
// Q_PROPERTY( PointStyle pointStyle READ pointStyle WRITE
// setPointStyle )
// Q_ENUMS( PointStyle )
public:
// constructor
Qt_widget(QWidget *parent = 0, const char *name = 0);
// destructor
~Qt_widget() {};
// initialization of coordinates system
void init(double x_min, double x_max, double y_min, double y_max);
void init(double x_min, double x_max, double y_min);
bool isInitialized() const; // tell if init has been called
// painting system
inline QPainter& painter() { return paint; };
void lock() { ++Locked; };
void unlock() { if (Locked>0) --Locked; doPaint(); };
void doPaint() { if (Locked==0) repaint(FALSE); };
// properties
// ~~~~~~~~~~
// color
QColor color() const;
void setColor(QColor c);
// backGroundColor
QColor backgroundColor() const;
void setBackgroundColor(QColor c);
// fillColor
QColor fillColor() const;
void setFillColor(QColor c);
// isFilled
bool isFilled() const;
void setFilled(bool f);
// lineWidth
uint lineWidth() const;
void setLineWidth(uint i);
// pointSize
uint pointSize() const;
void setPointSize(uint i);
// pointStyle
typedef CGAL::PointStyle PointStyle;
PointStyle pointStyle() const;
void setPointStyle(PointStyle s);
// CGAL version of setFooColor
// used by the manipulators system
// DO NOT USE THESE THREE UNDOCUMENTED FUNCTIONS !!
inline void setColor(Color c)
{ setColor(CGAL2Qt_Color(c)); };
inline void setBackgroundColor(Color c)
{ setBackgroundColor(CGAL2Qt_Color(c)); };
inline void setFillColor(Color c)
{ setFillColor(CGAL2Qt_Color(c)); };
// set pen() color to c, cf. manipulators below for setting
// backgroundColor and fillColor
Qt_widget& operator<<(const Color& c);
// set point style
Qt_widget& operator<<(const PointStyle& ps);
// clear the Widget, fill it with backgroundColor()
void clear();
// coordinates system
// ~~~~~~~~~~~~~~~~~~
// real coordinates
double x_real(int x) const;
double y_real(int y) const;
double x_real_dist(double d) const;
double y_real_dist(double d) const;
// pixel coordinates
int x_pixel(double x) const;
int y_pixel(double y) const;
int x_pixel_dist(double d) const;
int y_pixel_dist(double d) const;
inline double x_min() const { return xmin; };
inline double y_min() const { return ymin; };
inline double x_max() const { return xmax; };
inline double y_max() const { return ymax; };
// tool system
// ~~~~~~~~~~~
inline bool has_tool() const { return _has_tool; };
Qt_widget& operator<<(Qt_widget_tool* tool);
signals:
void mousePressed(QMouseEvent *e);
void mouseReleased(QMouseEvent *e);
void mouseMoved(QMouseEvent *e);
void resized();
protected:
void paintEvent(QPaintEvent *e);
void resizeEvent(QResizeEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void wheelEvent(QMouseEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
private:
void initialize(); // initialize initiale dimensions
bool initialized;
void setScales(); // set xscal and yscal
// color types convertors
static QColor CGAL2Qt_Color(Color c);
static Color Qt2CGAL_color(QColor c);
unsigned int Locked;
// point style and size
uint _pointSize;
PointStyle _pointStyle;
QPixmap pixmap; // the pixmap on which paints the painter
QPainter paint; // the painter
QBrush savedBrush; // saved brush, to be able to restore it on
// setFilled(true)
double xmin, xmax, ymin, ymax; // real dimensions
double xscal, yscal; // scalings int/double
// current tool
bool _has_tool;
Qt_widget_tool *current_tool;
};
typedef Qt_widget Window_stream;
inline
bool Qt_widget:: isInitialized() const
{
return initialized;
}
// manipulators
// ~~~~~~~~~~~~
// single manipulators
inline
Qt_widget& operator<<(Qt_widget& w, Qt_widget& (*m)(Qt_widget&))
{
return m(w);
};
// w << noFill << ... stop the filling of geometrical object
inline
Qt_widget& noFill(Qt_widget& w)
{
w.setFilled(false);
return w;
}
// manipulators with one argument
template <class Param>
struct Qt_widgetManip {
Qt_widget& (*f)(Qt_widget&, Param);
Param p;
Qt_widgetManip(Qt_widget& (*ff)(Qt_widget&, Param),
Param pp) : f(ff), p(pp) {}
};
// usage: w << manip(Param) << ...
template <class Param>
Qt_widget& operator<<(Qt_widget& w, Qt_widgetManip<Param> m)
{
return m.f(w, m.p);
}
#define CGAL_QTWIDGET_MANIP(param,function) \
inline \
Qt_widget& __Qt_widgetManip##function##Aux (Qt_widget& w, param p) \
{ w.set##function(p); return w; } \
inline \
Qt_widgetManip<param> function(param p) \
{ return Qt_widgetManip<param>( __Qt_widgetManip##function##Aux, p); }
// w << BackgroundColor(c) << ... sets the background color
CGAL_QTWIDGET_MANIP( Color, BackgroundColor )
// w << FillColor(c) << ... sets the fill color
CGAL_QTWIDGET_MANIP( Color, FillColor )
// w << LineWidth(i) << ... sets lines width
CGAL_QTWIDGET_MANIP( uint, LineWidth )
// w << PointSize(i) << ... sets points size
CGAL_QTWIDGET_MANIP( uint, PointSize )
// color types convertors
// ~~~~~~~~~~~~~~~~~~~~~~
inline
QColor Qt_widget::CGAL2Qt_Color(Color c)
{
return QColor(c.red(), c.green(), c.blue());
}
inline
Color Qt_widget::Qt2CGAL_color(QColor c)
{
return Color(c.red(),c.green(),c.blue());
}
// properties
// ~~~~~~~~~~
inline
QColor Qt_widget::color() const
{
return paint.pen().color();
};
inline
void Qt_widget::setColor(QColor c)
{
QPen p=painter().pen();
p.setColor(c);
painter().setPen(p);
}
inline
QColor Qt_widget::backgroundColor() const
{
return paint.backgroundColor();
}
inline
void Qt_widget::setBackgroundColor(QColor c)
{
QWidget::setBackgroundColor(c);
painter().setBackgroundColor(c);
clear();
}
inline
QColor Qt_widget::fillColor() const
{
return paint.brush().color();
}
inline
void Qt_widget::setFillColor(QColor c)
{
setFilled(true);
painter().setBrush(c);
}
inline
bool Qt_widget::isFilled() const
{
return( paint.brush().style()==Qt::NoBrush );
}
inline
void Qt_widget::setFilled(bool f)
{
if (f)
paint.setBrush(savedBrush);
else
{
savedBrush=paint.brush();
paint.setBrush(QBrush());
};
}
inline
uint Qt_widget::lineWidth() const
{
return( paint.pen().width());
}
inline
void Qt_widget::setLineWidth(uint i)
{
QPen p=painter().pen();
p.setWidth(i);
painter().setPen(p);
}
inline
uint Qt_widget::pointSize() const
{
return _pointSize;
}
inline
void Qt_widget::setPointSize(uint i)
{
_pointSize=i;
}
inline
PointStyle Qt_widget::pointStyle() const
{
return _pointStyle;
}
inline
void Qt_widget::setPointStyle(PointStyle ps)
{
_pointStyle=ps;
}
// drawing methods
// ~~~~~~~~~~~~~~~
template <class R>
Qt_widget& operator<<(Qt_widget& w, const Point_2<R>& p)
{
int
x=w.x_pixel(to_double(p.x())),
y=w.y_pixel(to_double(p.y()));
uint size=w.pointSize();
PointStyle ps=w.pointStyle();
switch (ps)
{
case PIXEL:
{
w.painter().drawPoint(x,y);
break;
}
case CROSS:
{
w.painter().drawLine(x-size/2, y-size/2, x+size/2, y+size/2);
w.painter().drawLine(x-size/2, y+size/2, x+size/2, y-size/2);
break;
}
case PLUS:
{
w.painter().drawLine(x, y-size/2, x, y+size/2);
w.painter().drawLine(x-size/2, y, x+size/2, y);
break;
}
case CIRCLE:
{
QBrush old_brush=w.painter().brush();
w.painter().setBrush(QBrush());
w.painter().drawEllipse(x-size/2, y-size/2, size, size);
w.painter().setBrush(old_brush);
break;
}
case DISC:
{
QBrush old_brush=w.painter().brush();
w.painter().setBrush(w.painter().pen().color());
w.painter().drawEllipse(x-size/2, y-size/2, size, size);
w.painter().setBrush(old_brush);
break;
}
case RECT:
{
QBrush old_brush=w.painter().brush();
w.painter().setBrush(QBrush());
w.painter().drawRect(x-size/2, y-size/2, size, size);
w.painter().setBrush(old_brush);
break;
}
case BOX:
{
QBrush old_brush=w.painter().brush();
w.painter().setBrush(w.painter().pen().color());
w.painter().drawRect(x-size/2, y-size/2, size, size);
w.painter().setBrush(old_brush);
break;
}
};
w.doPaint();
return w;
}
#ifdef CGAL_SEGMENT_2_H
template <class R>
Qt_widget& operator<<(Qt_widget& w, const Segment_2<R>& s)
{
const int
x1=w.x_pixel(to_double(s.source().x())),
y1=w.y_pixel(to_double(s.source().y())),
x2=w.x_pixel(to_double(s.target().x())),
y2=w.y_pixel(to_double(s.target().y()));
w.painter().drawLine(x1,y1,x2,y2);
w.doPaint();
return w;
}
#endif // CGAL_SEGMENT_2_H
#ifdef CGAL_LINE_2_H
template <class R>
Qt_widget& operator<<(Qt_widget& w, const Line_2<R>& l)
{
typedef Cartesian<double> Rep;
typedef Point_2<Rep> Point;
const Point_2<R>
p1=l.point(),
p2=p1+l.direction().vector();
const Point
p1d=Point(to_double(p1.x()),to_double(p1.y())),
p2d=Point(to_double(p2.x()),to_double(p2.y()));
double
x1=w.x_min(),
y1=w.y_min(),
x2=w.x_max(),
y2=w.y_max();
const double
dx=p1d.x()-p2d.x(),
dy=p1d.y()-p2d.y();
if (dx==0 && dy==0) return w;
if (fabs(dx)>fabs(dy))
{
y1=p1d.y()+(x1-p1d.x())*dy/dx;
y2=p1d.y()+(x2-p1d.x())*dy/dx;
}
else
{
x1=p1d.x()+(y1-p1d.y())*dx/dy;
x2=p1d.x()+(y2-p1d.y())*dx/dy;
}
w.painter().drawLine(w.x_pixel(x1),w.y_pixel(y1),
w.x_pixel(x2),w.y_pixel(y2));
return w;
}
#endif // CGAL_LINE_2_H
#ifdef CGAL_RAY_2_H
template <class R>
Qt_widget& operator<<(Qt_widget& w, const Ray_2<R>& r)
{
typedef Cartesian<double> Rep;
typedef Point_2<Rep> Point;
const Point_2<R>
p1=r.point(0),
p2=r.point(1);
const Point
p1d=Point(to_double(p1.x()),to_double(p1.y())),
p2d=Point(to_double(p2.x()),to_double(p2.y()));
const double
dx=p1d.x()-p2d.x(),
dy=p1d.y()-p2d.y();
if (dx==0 && dy==0) return w;
double x,y;
if (fabs(dx)>fabs(dy))
{
if (p1d.x()<p2d.x())
x = w.x_max();
else
x = w.x_min();
y=p1d.y()+(x-p1d.x())*dy/dx;
}
else
{
if (p1d.y()<p2d.y())
y = w.y_max();
else
y = w.y_min();
x=p1d.x()+(y-p1d.y())*dx/dy;
}
w.painter().drawLine(w.x_pixel(p1d.x()),w.y_pixel(p1d.y()),
w.x_pixel(x),w.y_pixel(y));
return w;
}
#endif //CGAL_RAY_2_H
#ifdef CGAL_TRIANGLE_2_H
template< class R >
Qt_widget&
operator<<(Qt_widget& w, const Triangle_2<R>& t)
{
const int
ax = w.x_pixel(to_double(t.vertex(0).x())),
ay = w.y_pixel(to_double(t.vertex(0).y())),
bx = w.x_pixel(to_double(t.vertex(1).x())),
by = w.y_pixel(to_double(t.vertex(1).y())),
cx = w.x_pixel(to_double(t.vertex(2).x())),
cy = w.y_pixel(to_double(t.vertex(2).y()));
QPointArray array;
array.setPoints(3,ax,ay,bx,by,cx,cy);
w.painter().drawPolygon(array);
w.doPaint();
return w;
}
#endif
#ifdef CGAL_CIRCLE_2_H
template < class R>
Qt_widget& operator<<(Qt_widget& w, const Circle_2<R>& c)
{
int
cx=w.x_pixel(to_double(c.center().x())),
cy=w.y_pixel(to_double(c.center().y())),
rx=w.x_pixel_dist((std::sqrt(to_double(c.squared_radius())))),
ry=w.y_pixel_dist((std::sqrt(to_double(c.squared_radius()))));
w.painter().drawEllipse(cx-rx,cy-ry,2*rx,2*ry);
w.doPaint();
return w;
}
#endif // CGAL_CIRCLE_2_H
#ifdef CGAL_ISO_RECTANGLE_2_H
template< class R >
Qt_widget&
operator<<(Qt_widget& w, const Iso_rectangle_2<R>& r)
{
int
xmin = w.x_pixel(to_double(r.min().x())),
ymin = w.y_pixel(to_double(r.min().y())),
xmax = w.x_pixel(to_double(r.max().x())),
ymax = w.y_pixel(to_double(r.max().y()));
w.painter().drawRect(xmin,ymin,xmax-xmin,ymax-ymin);
w.doPaint();
return w;
}
#endif // CGAL_ISO_RECTANGLE_2_H
#ifdef CGAL_BBOX_2_H
Qt_widget& operator<<(Qt_widget& w, const Bbox_2& r);
// see Qt_Window for the implementation of this non-template function
#endif // CGAL_BBOX_2_H
#ifdef CGAL_POLYGON_2_H
template <class Tr,class Co>
Qt_widget& operator<<(Qt_widget& w, const Polygon_2<Tr,Co>& pol)
{
typedef Polygon_2<Tr,Co>::Vertex_const_iterator VI;
QPointArray array;
array.resize(pol.size());
unsigned int n=0;
for(VI i=pol.vertices_begin();i!=pol.vertices_end();i++)
{
array.setPoint(n++,w.x_pixel(to_double(i->x())),
w.y_pixel(to_double(i->y())));
}
w.painter().drawPolygon(array);
w.doPaint();
return w;
}
#endif // CGAL_POLYGON_2_H
#ifdef CGAL_TRIANGULATION_2_H
template < class Gt, class Tds>
Qt_widget&
operator<<(Qt_widget& w, const Triangulation_2<Gt, Tds> &t)
{
w.lock();
t.draw_triangulation(w);
w.unlock();
return w;
}
#endif // CGAL_TRIANGULATION_2_H
#ifdef CGAL_DELAUNAY_TRIANGULATION_2_H
template < class Gt, class Tds >
Qt_widget&
operator<<(Qt_widget& w, const Delaunay_triangulation_2<Gt,Tds> &dt)
{
w.lock();
dt.draw_triangulation(w);
w.unlock();
w.doPaint();
return w;
}
#endif // CGAL_DELAUNAY_TRIANGULATION_2_H
#ifdef CGAL_CONSTRAINED_TRIANGULATION_2_H
template < class Gt, class Tds>
Qt_widget&
operator<<(Qt_widget& w, const Constrained_triangulation_2<Gt,Tds> &t)
{
w.lock();
t.draw_triangulation(w);
w.unlock();
return w;
}
#endif // CGAL_CONSTRAINED_TRIANGULATION_2_H
#ifdef CGAL_REGULAR_TRIANGULATION_2_H
template < class Gt, class Tds >
Qt_widget&
operator<<(Qt_widget& w, Regular_triangulation_2<Gt,Tds> &t)
{
w.lock();
t.draw_triangulation(w);
w.unlock();
return w;
}
#endif // CGAL_REGULAR_TRIANGULATION_2_H
} // namespace CGAL
#endif // QT_WINDOW_H