Logo AND Algorithmique Numérique Distribuée

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