1 #include "DrawingWindow.h"
10 #include <QTimerEvent>
12 class DrawingThread: public QThread {
14 DrawingThread(DrawingWindow &w, DrawingWindow::ThreadFunction f);
15 void start_once(Priority priority = InheritPriority);
21 DrawingWindow &drawingWindow;
22 DrawingWindow::ThreadFunction threadFunction;
25 friend class DrawingWindow;
26 friend class DrawingWindowPrivate;
29 class DrawingWindowPrivate {
31 static const int paintInterval = 33;
33 DrawingWindow * const q;
47 DrawingThread *thread;
49 DrawingWindowPrivate(DrawingWindow *w,
50 DrawingWindow::ThreadFunction f);
51 ~DrawingWindowPrivate();
59 void setDirtyRect(int x, int y);
60 void setDirtyRect(int x1, int y1, int x2, int y2);
61 void setDirtyRect(const QRect &rect);
65 //--- DrawingWindow ----------------------------------------------------
67 DrawingWindow::DrawingWindow(ThreadFunction f, int w, int h)
71 , d(new DrawingWindowPrivate(this, f))
76 DrawingWindow::DrawingWindow(QWidget *parent,
77 ThreadFunction f, int w, int h)
81 , d(new DrawingWindowPrivate(this, f))
86 DrawingWindow::DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
87 ThreadFunction f, int w, int h)
88 : QWidget(parent, flags)
91 , d(new DrawingWindowPrivate(this, f))
96 DrawingWindow::~DrawingWindow()
101 void DrawingWindow::setColor(float red, float green, float blue)
103 d->fgColor.setRgbF(red, green, blue);
104 QPen pen(d->painter->pen());
105 pen.setColor(d->fgColor);
106 d->painter->setPen(pen);
109 void DrawingWindow::setBgColor(float red, float green, float blue)
111 d->bgColor.setRgbF(red, green, blue);
114 void DrawingWindow::clearGraph()
117 d->painter->fillRect(d->image->rect(), d->bgColor);
122 void DrawingWindow::drawPoint(int x, int y)
125 d->painter->drawPoint(x, y);
126 d->setDirtyRect(x, y);
130 void DrawingWindow::drawLine(int x1, int y1, int x2, int y2)
133 d->painter->drawLine(x1, y1, x2, y2);
134 d->setDirtyRect(x1, y1, x2, y2);
138 void DrawingWindow::drawRect(int x1, int y1, int x2, int y2)
141 r.setCoords(x1, y1, x2, y2);
144 d->painter->drawRect(r);
145 r.adjust(0, 0, 1, 1);
150 void DrawingWindow::sleep(unsigned long secs)
152 DrawingThread::sleep(secs);
155 void DrawingWindow::msleep(unsigned long msecs)
157 DrawingThread::msleep(msecs);
160 void DrawingWindow::usleep(unsigned long usecs)
162 DrawingThread::usleep(usecs);
165 void DrawingWindow::closeEvent(QCloseEvent *ev)
168 d->thread->terminate();
169 QWidget::closeEvent(ev);
173 void DrawingWindow::paintEvent(QPaintEvent *ev)
175 QPainter widgetPainter(this);
176 QRect rect = ev->rect();
178 QImage imageCopy(*d->image);
180 widgetPainter.drawImage(rect, imageCopy, rect);
183 void DrawingWindow::showEvent(QShowEvent *ev)
185 d->timer.start(d->paintInterval, this);
186 d->thread->start_once(QThread::IdlePriority);
187 QWidget::showEvent(ev);
190 void DrawingWindow::timerEvent(QTimerEvent *ev)
192 if (ev->timerId() == d->timer.timerId()) {
195 update(d->dirtyRect);
196 d->dirtyFlag = false;
199 d->timer.start(d->paintInterval, this);
201 QWidget::timerEvent(ev);
205 //--- DrawingWindowPrivate ---------------------------------------------
207 DrawingWindowPrivate::DrawingWindowPrivate(DrawingWindow *w,
208 DrawingWindow::ThreadFunction f)
210 , image(new QImage(q->width, q->height, QImage::Format_RGB32))
211 , painter(new QPainter(image))
212 , thread(new DrawingThread(*q, f))
216 void DrawingWindowPrivate::initialize()
218 q->setFocusPolicy(Qt::StrongFocus);
219 q->setFixedSize(image->size());
220 q->setAttribute(Qt::WA_OpaquePaintEvent);
223 q->setColor(0.0, 0.0, 0.0);
224 q->setBgColor(1.0, 1.0, 1.0);
230 DrawingWindowPrivate::~DrawingWindowPrivate()
238 void DrawingWindowPrivate::lock()
240 thread->setTerminationEnabled(false);
245 void DrawingWindowPrivate::unlock()
248 thread->setTerminationEnabled(true);
252 void DrawingWindowPrivate::setDirtyRect()
255 dirtyRect = image->rect();
259 void DrawingWindowPrivate::setDirtyRect(int x, int y)
261 setDirtyRect(QRect(x, y, 1, 1));
265 void DrawingWindowPrivate::setDirtyRect(int x1, int y1, int x2, int y2)
268 r.setCoords(x1, y1, x2, y2);
269 setDirtyRect(r.normalized());
272 void DrawingWindowPrivate::setDirtyRect(const QRect &rect)
282 //--- DrawingThread ----------------------------------------------------
284 DrawingThread::DrawingThread(DrawingWindow &w, DrawingWindow::ThreadFunction f)
287 , started_once(false)
291 void DrawingThread::start_once(Priority priority)
299 void DrawingThread::run()
301 threadFunction(drawingWindow);