Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
.
[graphlib.git] / DrawingWindow.cpp
index fe759a8..e5ab690 100644 (file)
@@ -1,19 +1,43 @@
+/*
+ * Copyright (c) 2007-2010, Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include "DrawingWindow.h"
 #include <QApplication>
 #include <QPaintEvent>
 #include <QThread>
 #include <QTimerEvent>
 
-/*! \mainpage
- *
- * Bla bla bla...
- */
-
 /*! \class DrawingWindow
  *  \brief Fenêtre de dessin.
  *
  * \author Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
- * \date novenbre 2007
+ * \date 2007-2010
  *
  * Cette classe décrit un widget Qt permettant d'écrire des
  * applications graphiques simples.  Pour cela, il faut définir une
  * La fonction devra ensuite être passée en paramètre pour les
  * constructeurs de la classe, ainsi que les dimension requises pour
  * la fenêtre graphique.  Le programme est ensuite compilé comme
- * n'importe programme Qt.
+ * n'importe quel programme Qt.
  *
  * Concrètement, la fonction sera exécutée dans un nouveau thread,
  * tandis que le thread principal s'occupera de la gestion des
- * évènements et du rendu.
+ * évènements et du rendu dans la fenêtre.
+ *
+ * <b>NB.</b> Pour toutes les méthodes de dessin, le coin en haut à gauche
+ * de la fenêtre a les coordonnées (0, 0).  Le coin en bas à droite de
+ * la fenêtre a les coordonnées (largeur - 1, hauteur - 1), si la
+ * fenêtre est de dimension largeur × hauteur.
+ *
+ * Un appui sur la touche &lt;Esc&gt; provoque la fermeture de la fenêtre.
+ * Comme pour la plupart des applications, il est également possible
+ * de fermer la fenêtre via le gestionnaire de fenêtres.
+ *
+ * Il est possible, dans une application, d'ouvrir plusieurs fenêtres,
+ * avec des fonctions de dessin éventuellement différentes.
+ * L'application se terminera normalement lorsque la dernière fenêtre
+ * sera fermée.
  */
 
 /*! \example hello.cpp
@@ -57,7 +95,7 @@
  *
  * <b>4. Exécuter le programme avec la commande :</b>
  *
- * \verbatim ./exemple \endverbatim
+ * \verbatim ./hello \endverbatim
  *
  * <b>Code source de l'exemple</b>
  */
@@ -496,6 +534,46 @@ unsigned int DrawingWindow::getPointColor(int x, int y)
     return image->pixel(x, y);
 }
 
+//! Attend l'appui sur un des boutons de la souris.
+/*!
+ * Attend l'appui sur un des boutons de la souris.  Retourne le bouton
+ * qui a été pressé et les coordonnées du pointeur de souris à ce
+ * moment-là.
+ *
+ * \param x, y          coordonnées du pointeur de souris
+ * \param button        numéro du bouton qui a été pressé
+ *                      (1: gauche, 2: droit, 3: milieu, 0 sinon)
+ * \param time          durée maximale de l'attente
+ * \return              true si un bouton a été pressé
+ *
+ * \bug                 expérimental
+ */
+bool DrawingWindow::waitMousePress(int &x, int &y, int &button,
+                                   unsigned long time)
+{
+    bool pressed;
+    safeLock(mouseMutex);
+    if (terminateThread) {
+        pressed = false;
+    } else {
+        pressed = mouseCondition.wait(&mouseMutex, time);
+        if (pressed) {
+            x = mousePos.x();
+            y = mousePos.y();
+            if (mouseButton & Qt::LeftButton)
+                button = 1;
+            else if (mouseButton & Qt::RightButton)
+                button = 2;
+            else if (mouseButton & Qt::MidButton)
+                button = 3;
+            else
+                button = 0;
+        }
+    }
+    safeUnlock(mouseMutex);
+    return pressed;
+}
+
 //! Synchronise le contenu de la fenêtre.
 /*!
  * Pour des raisons d'efficacités, le résultat des fonctions de dessin
@@ -562,6 +640,7 @@ void DrawingWindow::closeEvent(QCloseEvent *ev)
     timer.stop();
     thread->terminate();
     syncMutex.lock();
+    mouseMutex.lock();
     terminateThread = true;     // this flag is needed for the case
                                 // where the following wakeAll() call
                                 // occurs between the
@@ -569,6 +648,8 @@ void DrawingWindow::closeEvent(QCloseEvent *ev)
                                 // mutex lock in safeLock() called
                                 // from sync()
     syncCondition.wakeAll();
+    mouseCondition.wakeAll();
+    mouseMutex.unlock();
     syncMutex.unlock();
     QWidget::closeEvent(ev);
     thread->wait();
@@ -593,6 +674,21 @@ void DrawingWindow::customEvent(QEvent *ev)
     }
 }
 
+/*!
+ * \see QWidget
+ *
+ * \bug                 expérimental
+ */
+void DrawingWindow::mousePressEvent(QMouseEvent *ev)
+{
+    mouseMutex.lock();
+    mousePos = ev->pos();
+    mouseButton = ev->button();
+    ev->accept();
+    mouseCondition.wakeAll();
+    mouseMutex.unlock();
+}
+
 /*!
  * \see QWidget
  */