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