Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1f5bb6ba9aa14a4a645eb982fcf429f936ef6752
[graphlib.git] / DrawingWindow.cpp
1 #include "DrawingWindow.h"
2 #include <QPaintEvent>
3 #include <QThread>
4 #include <QTimerEvent>
5
6 #include <iostream>
7
8 /*
9   TODO :
10    class DrawingWindowPrivate { ... }
11    externalize class DrawingThread
12 */
13
14 DrawingWindow::DrawingWindow(ThreadFunction fun, int width, int height)
15     : QWidget()
16 {
17     initialize(fun, width, height);
18 }
19
20 DrawingWindow::DrawingWindow(QWidget *parent,
21                              ThreadFunction fun, int width, int height)
22     : QWidget(parent)
23 {
24     initialize(fun, width, height);
25 }
26
27 DrawingWindow::DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
28                              ThreadFunction fun, int width, int height)
29     : QWidget(parent, flags)
30 {
31     initialize(fun, width, height);
32 }
33
34 void DrawingWindow::initialize(ThreadFunction fun, int width, int height)
35 {
36     image = new QImage(width, height, QImage::Format_RGB32);
37     image->fill(QColor(Qt::white).rgb());
38
39     painter = new QPainter(image);
40
41     dirtyFlag = false;
42
43     setFocusPolicy(Qt::StrongFocus);
44     setFixedSize(image->size());
45     setAttribute(Qt::WA_OpaquePaintEvent);
46     setFocus();
47     timer.start(paintInterval, this);
48
49     thread = new DrawingThread(*this, fun);
50     thread_started = false;
51 }
52
53 DrawingWindow::~DrawingWindow()
54 {
55     delete thread;
56     delete painter;
57     delete image;
58 }
59
60 void DrawingWindow::setColor(const QColor &color)
61 {
62     QPen pen(painter->pen());
63     pen.setColor(color);
64     painter->setPen(pen);
65 }
66
67 void DrawingWindow::setColor(float red, float green, float blue)
68 {
69     QColor color;
70     color.setRgbF(red, green, blue);
71     this->setColor(color);
72 }
73
74 void DrawingWindow::drawPoint(int x, int y)
75 {
76     lock();
77     painter->drawPoint(x, y);
78     setDirtyRect(x, y);
79     unlock();
80 }
81
82 void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
83 {
84     lock();
85     painter->drawLine(x1, y1, x2, y2);
86     setDirtyRect(x1, y1, x2, y2);
87     unlock();
88 }
89
90 void DrawingWindow::closeEvent(QCloseEvent *ev)
91 {
92     thread->terminate();
93     QWidget::closeEvent(ev);
94     thread->wait();
95 }
96
97 void DrawingWindow::paintEvent(QPaintEvent *ev)
98 {
99     QPainter widgetPainter(this);
100     QRect rect = ev->rect();
101     mutex.lock();
102     QImage imageCopy(*image);
103     mutex.unlock();
104     widgetPainter.drawImage(rect, imageCopy, rect);
105 }
106
107 void DrawingWindow::showEvent(QShowEvent *ev)
108 {
109     if (!thread_started) {
110         thread->start();
111         thread_started = true;
112     }
113     QWidget::showEvent(ev);
114 }
115
116 void DrawingWindow::timerEvent(QTimerEvent *ev)
117 {
118     if (ev->timerId() == timer.timerId()) {
119         mutex.lock();
120         if (dirtyFlag) {
121             update(dirtyRect);
122             dirtyFlag = false;
123         }
124         mutex.unlock();
125         timer.start(paintInterval, this);
126     } else {
127         QWidget::timerEvent(ev);
128     }
129 }
130
131 void DrawingWindow::setDirtyRect(const QRect &rect)
132 {
133     if (dirtyFlag) {
134         dirtyRect |= rect;
135     } else {
136         dirtyFlag = true;
137         dirtyRect = rect;
138     }
139 }
140
141 DrawingWindow::DrawingThread::DrawingThread(DrawingWindow &w,
142                                             ThreadFunction f)
143     : drawingWindow(w)
144     , threadFunction(f)
145 {
146 }
147
148 void DrawingWindow::DrawingThread::run()
149 {
150     threadFunction(drawingWindow);
151 }