Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
.
authorgiersch <giersch>
Tue, 6 Nov 2007 11:17:24 +0000 (11:17 +0000)
committergiersch <giersch>
Tue, 6 Nov 2007 11:17:24 +0000 (11:17 +0000)
DrawingWindow.cpp
DrawingWindow.h
test/hello.cpp

index 1f5bb6b..69e1d27 100644 (file)
 #include "DrawingWindow.h"
 #include "DrawingWindow.h"
+#include <QBasicTimer>
+#include <QColor>
+#include <QImage>
+#include <QMutex>
 #include <QPaintEvent>
 #include <QPaintEvent>
+#include <QPainter>
+#include <QRect>
 #include <QThread>
 #include <QTimerEvent>
 
 #include <QThread>
 #include <QTimerEvent>
 
-#include <iostream>
+class DrawingThread: public QThread {
+public:
+    DrawingThread(DrawingWindow &w, DrawingWindow::ThreadFunction f);
+    void start_once(Priority priority = InheritPriority);
 
 
-/*
-  TODO :
-   class DrawingWindowPrivate { ... }
-   externalize class DrawingThread
-*/
+protected:
+    void run();
 
 
-DrawingWindow::DrawingWindow(ThreadFunction fun, int width, int height)
+private:
+    DrawingWindow &drawingWindow;
+    DrawingWindow::ThreadFunction threadFunction;
+    bool started_once;
+
+    friend class DrawingWindow;
+    friend class DrawingWindowPrivate;
+};
+
+class DrawingWindowPrivate {
+public:
+    static const int paintInterval = 33;
+
+    DrawingWindow * const q;
+
+    QBasicTimer timer;
+    QMutex mutex;
+
+    QImage *image;
+    QPainter *painter;
+
+    QColor fgColor;
+    QColor bgColor;
+
+    bool dirtyFlag;
+    QRect dirtyRect;
+
+    DrawingThread *thread;
+
+    DrawingWindowPrivate(DrawingWindow *w,
+                         DrawingWindow::ThreadFunction f);
+    ~DrawingWindowPrivate();
+
+    void initialize();
+
+    void lock();
+    void unlock();
+
+    void setDirtyRect();
+    void setDirtyRect(int x, int y);
+    void setDirtyRect(int x1, int y1, int x2, int y2);
+    void setDirtyRect(const QRect &rect);
+
+};
+
+//--- DrawingWindow ----------------------------------------------------
+
+DrawingWindow::DrawingWindow(ThreadFunction f, int w, int h)
     : QWidget()
     : QWidget()
+    , width(w)
+    , height(h)
+    , d(new DrawingWindowPrivate(this, f))
 {
 {
-    initialize(fun, width, height);
+    d->initialize();
 }
 
 DrawingWindow::DrawingWindow(QWidget *parent,
 }
 
 DrawingWindow::DrawingWindow(QWidget *parent,
-                             ThreadFunction fun, int width, int height)
+                             ThreadFunction f, int w, int h)
     : QWidget(parent)
     : QWidget(parent)
+    , width(w)
+    , height(h)
+    , d(new DrawingWindowPrivate(this, f))
 {
 {
-    initialize(fun, width, height);
+    d->initialize();
 }
 
 DrawingWindow::DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
 }
 
 DrawingWindow::DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
-                             ThreadFunction fun, int width, int height)
+                             ThreadFunction f, int w, int h)
     : QWidget(parent, flags)
     : QWidget(parent, flags)
+    , width(w)
+    , height(h)
+    , d(new DrawingWindowPrivate(this, f))
 {
 {
-    initialize(fun, width, height);
+    d->initialize();
 }
 
 }
 
-void DrawingWindow::initialize(ThreadFunction fun, int width, int height)
+DrawingWindow::~DrawingWindow()
 {
 {
-    image = new QImage(width, height, QImage::Format_RGB32);
-    image->fill(QColor(Qt::white).rgb());
+    delete d;
+}
 
 
-    painter = new QPainter(image);
+void DrawingWindow::setColor(float red, float green, float blue)
+{
+    d->fgColor.setRgbF(red, green, blue);
+    QPen pen(d->painter->pen());
+    pen.setColor(d->fgColor);
+    d->painter->setPen(pen);
+}
 
 
-    dirtyFlag = false;
+void DrawingWindow::setBgColor(float red, float green, float blue)
+{
+    d->bgColor.setRgbF(red, green, blue);
+}
 
 
-    setFocusPolicy(Qt::StrongFocus);
-    setFixedSize(image->size());
-    setAttribute(Qt::WA_OpaquePaintEvent);
-    setFocus();
-    timer.start(paintInterval, this);
+void DrawingWindow::clearGraph()
+{
+    d->lock();
+    d->painter->fillRect(d->image->rect(), d->bgColor);    
+    d->setDirtyRect();
+    d->unlock();
+}
 
 
-    thread = new DrawingThread(*this, fun);
-    thread_started = false;
+void DrawingWindow::drawPoint(int x, int y)
+{
+    d->lock();
+    d->painter->drawPoint(x, y);
+    d->setDirtyRect(x, y);
+    d->unlock();
 }
 
 }
 
-DrawingWindow::~DrawingWindow()
+void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
 {
 {
-    delete thread;
-    delete painter;
-    delete image;
+    d->lock();
+    d->painter->drawLine(x1, y1, x2, y2);
+    d->setDirtyRect(x1, y1, x2, y2);
+    d->unlock();
 }
 
 }
 
-void DrawingWindow::setColor(const QColor &color)
+void DrawingWindow::drawRect(int x1, int y1, int x2, int y2)
 {
 {
-    QPen pen(painter->pen());
-    pen.setColor(color);
-    painter->setPen(pen);
+    QRect r;
+    r.setCoords(x1, y1, x2, y2);
+    r = r.normalized();
+    d->lock();
+    d->painter->drawRect(r);
+    r.adjust(0, 0, 1, 1);
+    d->setDirtyRect(r);
+    d->unlock();
 }
 
 }
 
-void DrawingWindow::setColor(float red, float green, float blue)
+void DrawingWindow::sleep(unsigned long secs)
 {
 {
-    QColor color;
-    color.setRgbF(red, green, blue);
-    this->setColor(color);
+    DrawingThread::sleep(secs);
 }
 
 }
 
-void DrawingWindow::drawPoint(int x, int y)
+void DrawingWindow::msleep(unsigned long msecs)
 {
 {
-    lock();
-    painter->drawPoint(x, y);
-    setDirtyRect(x, y);
-    unlock();
+    DrawingThread::msleep(msecs);
 }
 
 }
 
-void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
+void DrawingWindow::usleep(unsigned long usecs)
 {
 {
-    lock();
-    painter->drawLine(x1, y1, x2, y2);
-    setDirtyRect(x1, y1, x2, y2);
-    unlock();
+    DrawingThread::usleep(usecs);
 }
 
 void DrawingWindow::closeEvent(QCloseEvent *ev)
 {
 }
 
 void DrawingWindow::closeEvent(QCloseEvent *ev)
 {
-    thread->terminate();
+    d->timer.stop();
+    d->thread->terminate();
     QWidget::closeEvent(ev);
     QWidget::closeEvent(ev);
-    thread->wait();
+    d->thread->wait();
 }
 
 void DrawingWindow::paintEvent(QPaintEvent *ev)
 {
     QPainter widgetPainter(this);
     QRect rect = ev->rect();
 }
 
 void DrawingWindow::paintEvent(QPaintEvent *ev)
 {
     QPainter widgetPainter(this);
     QRect rect = ev->rect();
-    mutex.lock();
-    QImage imageCopy(*image);
-    mutex.unlock();
+    d->mutex.lock();
+    QImage imageCopy(*d->image);
+    d->mutex.unlock();
     widgetPainter.drawImage(rect, imageCopy, rect);
 }
 
 void DrawingWindow::showEvent(QShowEvent *ev)
 {
     widgetPainter.drawImage(rect, imageCopy, rect);
 }
 
 void DrawingWindow::showEvent(QShowEvent *ev)
 {
-    if (!thread_started) {
-        thread->start();
-        thread_started = true;
-    }
+    d->timer.start(d->paintInterval, this);
+    d->thread->start_once(QThread::IdlePriority);
     QWidget::showEvent(ev);
 }
 
 void DrawingWindow::timerEvent(QTimerEvent *ev)
 {
     QWidget::showEvent(ev);
 }
 
 void DrawingWindow::timerEvent(QTimerEvent *ev)
 {
-    if (ev->timerId() == timer.timerId()) {
-        mutex.lock();
-        if (dirtyFlag) {
-            update(dirtyRect);
-            dirtyFlag = false;
+    if (ev->timerId() == d->timer.timerId()) {
+        d->mutex.lock();
+        if (d->dirtyFlag) {
+            update(d->dirtyRect);
+            d->dirtyFlag = false;
         }
         }
-        mutex.unlock();
-        timer.start(paintInterval, this);
+        d->mutex.unlock();
+        d->timer.start(d->paintInterval, this);
     } else {
         QWidget::timerEvent(ev);
     }
 }
 
     } else {
         QWidget::timerEvent(ev);
     }
 }
 
-void DrawingWindow::setDirtyRect(const QRect &rect)
+//--- DrawingWindowPrivate ---------------------------------------------
+
+DrawingWindowPrivate::DrawingWindowPrivate(DrawingWindow *w,
+                                           DrawingWindow::ThreadFunction f)
+    : q(w)
+    , image(new QImage(q->width, q->height, QImage::Format_RGB32))
+    , painter(new QPainter(image))
+    , thread(new DrawingThread(*q, f))
+{
+}
+
+void DrawingWindowPrivate::initialize()
+{
+    q->setFocusPolicy(Qt::StrongFocus);
+    q->setFixedSize(image->size());
+    q->setAttribute(Qt::WA_OpaquePaintEvent);
+    q->setFocus();
+
+    q->setColor(0.0, 0.0, 0.0);
+    q->setBgColor(1.0, 1.0, 1.0);
+    q->clearGraph();
+
+    dirtyFlag = false;
+}
+
+DrawingWindowPrivate::~DrawingWindowPrivate()
+{
+    delete thread;
+    delete painter;
+    delete image;
+}
+
+inline
+void DrawingWindowPrivate::lock()
+{
+    thread->setTerminationEnabled(false);
+    mutex.lock();
+}
+
+inline
+void DrawingWindowPrivate::unlock()
+{
+    mutex.unlock();
+    thread->setTerminationEnabled(true);
+}
+
+inline
+void DrawingWindowPrivate::setDirtyRect()
+{
+    dirtyFlag = true;
+    dirtyRect = image->rect();
+}
+
+inline
+void DrawingWindowPrivate::setDirtyRect(int x, int y)
+{
+    setDirtyRect(QRect(x, y, 1, 1));
+}
+
+inline
+void DrawingWindowPrivate::setDirtyRect(int x1, int y1, int x2, int y2)
+{
+    QRect r;
+    r.setCoords(x1, y1, x2, y2);
+    setDirtyRect(r.normalized());
+}
+
+void DrawingWindowPrivate::setDirtyRect(const QRect &rect)
 {
     if (dirtyFlag) {
         dirtyRect |= rect;
 {
     if (dirtyFlag) {
         dirtyRect |= rect;
@@ -138,14 +279,24 @@ void DrawingWindow::setDirtyRect(const QRect &rect)
     }
 }
 
     }
 }
 
-DrawingWindow::DrawingThread::DrawingThread(DrawingWindow &w,
-                                            ThreadFunction f)
+//--- DrawingThread ----------------------------------------------------
+
+DrawingThread::DrawingThread(DrawingWindow &w, DrawingWindow::ThreadFunction f)
     : drawingWindow(w)
     , threadFunction(f)
     : drawingWindow(w)
     , threadFunction(f)
+    , started_once(false)
 {
 }
 
 {
 }
 
-void DrawingWindow::DrawingThread::run()
+void DrawingThread::start_once(Priority priority)
+{
+    if (!started_once) {
+        started_once = true;
+        start(priority);
+    }
+}
+
+void DrawingThread::run()
 {
     threadFunction(drawingWindow);
 }
 {
     threadFunction(drawingWindow);
 }
index 7685d7d..9ddd4b7 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef DRAWING_WINDOW_H
 #define DRAWING_WINDOW_H
 
 #ifndef DRAWING_WINDOW_H
 #define DRAWING_WINDOW_H
 
-#include <QThread>
 #include <QWidget>
 #include <Qt>
 
 #include <QWidget>
 #include <Qt>
 
index d98d2a6..40432e3 100644 (file)
 
 void flip(DrawingWindow &w)
 {
 
 void flip(DrawingWindow &w)
 {
-    std::cout << "[ " << w.width() << " x " << w.height() << " ]\n";
+    std::cout << "[ " << w.width << " x " << w.height << " ]\n";
 
     int c = 0;
     int y = 0;
 
     int c = 0;
     int y = 0;
-//     int h = w.height();
-//     int w = w.width();
+//     int h = w.height;
+//     int w = w.width;
     int count = 50;//1 << 31;
     while (1) {
 //         std::cerr << "loooooooooooooooooooooop "
 //                   << y << " (" << c << ")\n";
         w.setColor(c, c, c);
         for (int yy = y; yy < y + 10; yy++)
     int count = 50;//1 << 31;
     while (1) {
 //         std::cerr << "loooooooooooooooooooooop "
 //                   << y << " (" << c << ")\n";
         w.setColor(c, c, c);
         for (int yy = y; yy < y + 10; yy++)
-            for (int x = 0; x < w.width(); x++)
+            for (int x = 0; x < w.width; x++)
                 w.drawPoint(x, yy);
                 w.drawPoint(x, yy);
-        if ((y += 10) >= w.height()) {
+        if ((y += 10) >= w.height) {
             y = 0;
             c = !c;
             if (!--count) break;
             y = 0;
             c = !c;
             if (!--count) break;
@@ -55,8 +55,8 @@ void flip(DrawingWindow &w)
 void mandel(DrawingWindow &w)
 {
     /* paramètres par défaut */
 void mandel(DrawingWindow &w)
 {
     /* paramètres par défaut */
-    int larg = w.width();
-    int haut = w.height();
+    int larg = w.width;
+    int haut = w.height;
     float Rmin = -2.05;
     float Rmax = 0.55;
     float Imin = -1.3;
     float Rmin = -2.05;
     float Rmax = 0.55;
     float Imin = -1.3;
@@ -120,8 +120,8 @@ void mandel(DrawingWindow &w)
 void lines(DrawingWindow &w)
 {
     int n = 100000;
 void lines(DrawingWindow &w)
 {
     int n = 100000;
-    int xmax = w.width();
-    int ymax = w.height();
+    int xmax = w.width;
+    int ymax = w.height;
     while (n-- > 0) {
         double r = rand() / (float )RAND_MAX;
         double g = rand() / (float )RAND_MAX;
     while (n-- > 0) {
         double r = rand() / (float )RAND_MAX;
         double g = rand() / (float )RAND_MAX;
@@ -135,15 +135,28 @@ void lines(DrawingWindow &w)
     }
 }
 
     }
 }
 
+void rectangles(DrawingWindow &w)
+{
+    int d = 5;
+    int z = (w.width > w.height ? w.height : w.width) / 2;
+    z = d * (z / d);
+    while (z > 0) {
+        w.drawRect(z, z, w.width - 1 - z, w.height - 1 - z);
+        z -= d;
+    }
+}
+
 int main(int argc, char *argv[])
 {
     const int w = 1000;
     const int h = 700;
     QApplication application(argc, argv);
 
 int main(int argc, char *argv[])
 {
     const int w = 1000;
     const int h = 700;
     QApplication application(argc, argv);
 
-    DrawingWindow dd(lines, w, h);
-    dd.show();
-//     return application.exec();
+    DrawingWindow dl(lines, w, h);
+    dl.show();
+
+    DrawingWindow dr(rectangles, w, h);
+    dr.show();
 
     const int nf = 1;
     const int nm = 1;
 
     const int nf = 1;
     const int nm = 1;