Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add some words on installation.
[graphlib.git] / DrawingWindow.cpp
index ae740b7..3234441 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2010, Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
+ * Copyright (c) 2007-2013, Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
  *  \brief Fenêtre de dessin.
  *
  * \author Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
- * \date 2007-2010
+ * \date 2007-2013
  *
  * Cette classe décrit un widget Qt permettant d'écrire des
  * applications graphiques simples.  Pour cela, il faut définir une
@@ -142,14 +142,14 @@ public:
     { }
 };
 
-//! Demande de tracé de texte. 
+//! Demande de tracé de texte.
 class DrawTextEvent: public QEvent {
 public:
     const int x;
     const int y;
     const char *text;
     const int flags;
-    DrawTextEvent(int x_, int y_, const chartext_, int flags_)
+    DrawTextEvent(int x_, int y_, const char *text_, int flags_)
         : QEvent(static_cast<QEvent::Type>(DrawTextRequest))
         , x(x_), y(y_), text(text_), flags(flags_)
     { }
@@ -345,6 +345,51 @@ void DrawingWindow::setBgColor(float red, float green, float blue)
     setBgColor(QColor::fromRgbF(red, green, blue));
 }
 
+//! Change l'épaisseur du pinceau
+/*!
+ * Le pinceau à une épaisseur de 1 par défaut.
+ *
+ * \param width         épaisseur du pinceau
+ */
+void DrawingWindow::setPenWidth(int width)
+{
+    QPen pen(painter->pen());
+    pen.setWidth(width);
+    painter->setPen(pen);
+}
+
+//! Retourne la fonte courante utilisée pour dessiner du texte.
+/*!
+ * \see QFont, setFont
+ */
+const QFont &DrawingWindow::getFont() const
+{
+    return painter->font();
+}
+
+//! Applique une nouvelle font pour dessiner du texte.
+/*!
+ * \see QFont, getFont
+ */
+void DrawingWindow::setFont(const QFont &font)
+{
+    painter->setFont(font);
+}
+
+//! Active ou non l'antialiasing.
+/*!
+ * Permet de lisser le dessin.
+ * Fonctionnalité désactivée par défaut.
+ *
+ * \param state         état de l'antialiasing
+ *
+ * \bug                 expérimental
+ */
+void DrawingWindow::setAntialiasing(bool state)
+{
+    painter->setRenderHint(QPainter::Antialiasing, state);
+}
+
 //! Efface la fenêtre.
 /*!
  * La fenêtre est effacée avec la couleur de fond courante.
@@ -388,10 +433,14 @@ void DrawingWindow::drawPoint(int x, int y)
  */
 void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
 {
-    safeLock(imageMutex);
-    painter->drawLine(x1, y1, x2, y2);
-    dirty(x1, y1, x2, y2);
-    safeUnlock(imageMutex);
+    if (x1 == x2 && y1 == y2) {
+        drawPoint(x1, y1);
+    } else {
+        safeLock(imageMutex);
+        painter->drawLine(x1, y1, x2, y2);
+        dirty(x1, y1, x2, y2);
+        safeUnlock(imageMutex);
+    }
 }
 
 //! Dessine un rectangle.
@@ -407,14 +456,18 @@ void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
  */
 void DrawingWindow::drawRect(int x1, int y1, int x2, int y2)
 {
-    QRect r;
-    r.setCoords(x1, y1, x2 - 1, y2 - 1);
-    r = r.normalized();
-    safeLock(imageMutex);
-    painter->drawRect(r);
-    r.adjust(0, 0, 1, 1);
-    dirty(r);
-    safeUnlock(imageMutex);
+    if (x1 == x2 && y1 == y2) {
+        drawPoint(x1, y1);
+    } else {
+        QRect r;
+        r.setCoords(x1, y1, x2 - 1, y2 - 1);
+        r = r.normalized();
+        safeLock(imageMutex);
+        painter->drawRect(r);
+        r.adjust(0, 0, 1, 1);
+        dirty(r);
+        safeUnlock(imageMutex);
+    }
 }
 
 //! Dessine un rectangle plein.
@@ -473,6 +526,47 @@ void DrawingWindow::fillCircle(int x, int y, int r)
     painter->setBrush(Qt::NoBrush);
 }
 
+//! Dessine un triangle.
+/*!
+ * Dessine un triangle défini par les coordonnées de ses sommets:
+ * (x1, y1), (x2, y2) et (x3, y3).  Utilise la couleur de dessin
+ * courante.
+ *
+ * \param x1, y1        coordonnées du premier sommet du triangle
+ * \param x2, y2        coordonnées du deuxième sommet du triangle
+ * \param x3, y3        coordonnées du troisième sommet du triangle
+ *
+ * \see fillTriangle, setColor
+ */
+void DrawingWindow::drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
+{
+    QPolygon poly(3);
+    poly.putPoints(0, 3, x1, y1, x2, y2, x3, y3);
+    safeLock(imageMutex);
+    painter->drawConvexPolygon(poly);
+    dirty(poly.boundingRect());
+    safeUnlock(imageMutex);
+}
+
+//! Dessine un triangle plein.
+/*!
+ * Dessine un triangle plein défini par les coordonnées de ses
+ * sommets: (x1, y1), (x2, y2) et (x3, y3).  Utilise la couleur de
+ * dessin courante.
+ *
+ * \param x1, y1        coordonnées du premier sommet du triangle
+ * \param x2, y2        coordonnées du deuxième sommet du triangle
+ * \param x3, y3        coordonnées du troisième sommet du triangle
+ *
+ * \see drawTriangle, setColor
+ */
+void DrawingWindow::fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
+{
+    painter->setBrush(getColor());
+    drawTriangle(x1, y1, x2, y2, x3, y3);
+    painter->setBrush(Qt::NoBrush);
+}
+
 //! Écrit du texte.
 /*!
  * Écrit le texte text, aux coordonnées (x, y) et avec les paramètres
@@ -486,6 +580,7 @@ void DrawingWindow::fillCircle(int x, int y, int r)
  * \param text          texte à écrire
  * \param flags         paramètres d'alignement
  *
+ * \see drawText(int, int, const std::string &, int)
  * \see drawTextBg, setColor
  * \see QPainter::drawText
  */
@@ -499,6 +594,15 @@ void DrawingWindow::drawText(int x, int y, const char *text, int flags)
     safeUnlock(syncMutex);
 }
 
+//! Écrit du texte.
+/*!
+ * \see drawText(int, int, const char *, int)
+ */
+void DrawingWindow::drawText(int x, int y, const std::string &text, int flags)
+{
+    drawText(x, y, text.c_str(), flags);
+}
+
 //! Écrit du texte sur fond coloré.
 /*!
  * Écrit du texte comme drawText, mais l'arrière-plan est coloré avec
@@ -508,6 +612,7 @@ void DrawingWindow::drawText(int x, int y, const char *text, int flags)
  * \param text          texte à écrire
  * \param flags         paramètres d'alignement
  *
+ * \see drawTextBg(int, int, const std::string &, int)
  * \see drawText, setColor, setColorBg
  */
 void DrawingWindow::drawTextBg(int x, int y, const char *text, int flags)
@@ -517,6 +622,14 @@ void DrawingWindow::drawTextBg(int x, int y, const char *text, int flags)
     painter->setBackgroundMode(Qt::TransparentMode);
 }
 
+//! Écrit du texte sur fond coloré.
+/*!
+ * \see drawTextBg(int, int, const char *, int)
+ */
+void DrawingWindow::drawTextBg(int x, int y, const std::string &text, int flags)
+{
+    drawTextBg(x, y, text.c_str(), flags);
+}
 
 //! Retourne la couleur d'un pixel.
 /*!
@@ -529,7 +642,7 @@ void DrawingWindow::drawTextBg(int x, int y, const char *text, int flags)
  *
  * \see setColor(unsigned int), setBgColor(unsigned int)
  */
-unsigned int DrawingWindow::getPointColor(int x, int y)
+unsigned int DrawingWindow::getPointColor(int x, int y) const
 {
     return image->pixel(x, y);
 }
@@ -552,11 +665,11 @@ bool DrawingWindow::waitMousePress(int &x, int &y, int &button,
                                    unsigned long time)
 {
     bool pressed;
-    safeLock(mouseMutex);
+    safeLock(inputMutex);
     if (terminateThread) {
         pressed = false;
     } else {
-        pressed = mouseCondition.wait(&mouseMutex, time);
+        pressed = inputCondition.wait(&inputMutex, time) && !terminateThread;
         if (pressed) {
             x = mousePos.x();
             y = mousePos.y();
@@ -570,7 +683,7 @@ bool DrawingWindow::waitMousePress(int &x, int &y, int &button,
                 button = 0;
         }
     }
-    safeUnlock(mouseMutex);
+    safeUnlock(inputMutex);
     return pressed;
 }
 
@@ -632,15 +745,18 @@ void DrawingWindow::usleep(unsigned long usecs)
     DrawingThread::usleep(usecs);
 }
 
+//--- DrawingWindow (protected methods) --------------------------------
+//! \cond show_protected
+
 /*!
  * \see QWidget
  */
 void DrawingWindow::closeEvent(QCloseEvent *ev)
 {
     timer.stop();
-    thread->terminate();
+    thread->exit();
     syncMutex.lock();
-    mouseMutex.lock();
+    inputMutex.lock();
     terminateThread = true;     // this flag is needed for the case
                                 // where the following wakeAll() call
                                 // occurs between the
@@ -648,11 +764,14 @@ void DrawingWindow::closeEvent(QCloseEvent *ev)
                                 // mutex lock in safeLock() called
                                 // from sync()
     syncCondition.wakeAll();
-    mouseCondition.wakeAll();
-    mouseMutex.unlock();
+    inputCondition.wakeAll();
+    inputMutex.unlock();
     syncMutex.unlock();
     QWidget::closeEvent(ev);
-    thread->wait();
+    if (!thread->wait(250)) {
+        thread->terminate();
+        thread->wait();
+    }
 }
 
 /*!
@@ -668,7 +787,7 @@ void DrawingWindow::customEvent(QEvent *ev)
         close();
         break;
     case DrawTextRequest:
-        DrawTextEventtev = dynamic_cast<DrawTextEvent *>(ev);
+        DrawTextEvent *tev = dynamic_cast<DrawTextEvent *>(ev);
         realDrawText(tev->x, tev->y, tev->text, tev->flags);
         break;
     }
@@ -681,12 +800,12 @@ void DrawingWindow::customEvent(QEvent *ev)
  */
 void DrawingWindow::mousePressEvent(QMouseEvent *ev)
 {
-    mouseMutex.lock();
+    inputMutex.lock();
     mousePos = ev->pos();
     mouseButton = ev->button();
     ev->accept();
-    mouseCondition.wakeAll();
-    mouseMutex.unlock();
+    inputCondition.wakeAll();
+    inputMutex.unlock();
 }
 
 /*!
@@ -694,17 +813,10 @@ void DrawingWindow::mousePressEvent(QMouseEvent *ev)
  */
 void DrawingWindow::keyPressEvent(QKeyEvent *ev)
 {
-    bool accept = true;
-    switch (ev->key()) {
-    case Qt::Key_Escape:
+    if (ev->key() == Qt::Key_Escape) {
+        ev->accept();
         close();
-        break;
-    default:
-        accept = false;
-        break;
     }
-    if (accept)
-        ev->accept();
 }
 
 /*!
@@ -745,6 +857,8 @@ void DrawingWindow::timerEvent(QTimerEvent *ev)
     }
 }
 
+// \endcond
+
 //--- DrawingWindow (private methods) ----------------------------------
 
 //! Fonction d'initialisation.
@@ -778,7 +892,7 @@ void DrawingWindow::initialize(DrawingWindow::ThreadFunction fun)
  * \param color                 couleur
  */
 inline
-void DrawingWindow::setColor(const QColorcolor)
+void DrawingWindow::setColor(const QColor &color)
 {
     QPen pen(painter->pen());
     pen.setColor(color);
@@ -790,7 +904,7 @@ void DrawingWindow::setColor(const QColor& color)
  * \param color                 couleur
  */
 inline
-void DrawingWindow::setBgColor(const QColorcolor)
+void DrawingWindow::setBgColor(const QColor &color)
 {
     painter->setBackground(color);
 }
@@ -975,7 +1089,7 @@ void DrawingWindow::realDrawText(int x, int y, const char *text, int flags)
         r.setTop(y);
     }
     syncMutex.lock();
-    painter->drawText(r, flags, text, &r);
+    painter->drawText(r, flags, QString::fromUtf8(text), &r);
     dirty(r);
     syncCondition.wakeAll();
     syncMutex.unlock();