It has been a while since I last worked on Aesalon proper.
[aesalon.git] / visualizer / src / visualization / Visualization.cpp
blob02a787eb2658ab42ae79ce9a7a3c986e26636cd1
1 #include <QPointF>
2 #include <QPainter>
3 #include <QMutex>
5 #include "Visualization.h"
6 #include "VisualizationController.h"
8 Visualization::Visualization(QSize renderSize, DataRange range) : m_range(range) {
9 /*qDebug("renderSize: (%ix%i)", renderSize.width(), renderSize.height());*/
10 if(renderSize.width() == 0) renderSize.setWidth(1);
11 if(renderSize.height() == 0) renderSize.setHeight(1);
12 m_image = QImage(qAbs(renderSize.width()), qAbs(renderSize.height()), QImage::Format_ARGB32);
13 m_image.fill(Qt::white);
16 Visualization::~Visualization() {
20 void Visualization::merge(Visualization *other) {
21 lock();
22 other->lock();
23 QRectF otherRect = translate(other->m_range).normalized();
25 qDebug("merge: this size is (%i,%i) . . .", m_image.width(), m_image.height());
26 qDebug("merge: otherRect is (%f,%f),(%f,%f) . . .", otherRect.left(), otherRect.top(), otherRect.right(), otherRect.bottom());
28 m_painter.setBrush(Qt::white);
29 m_painter.setPen(Qt::NoPen);
30 m_painter.drawRect(otherRect.toRect());
31 m_painter.drawImage(otherRect.toRect(), other->m_image);
33 other->unlock();
34 unlock();
37 void Visualization::clear() {
38 lock();
39 m_image.fill(qRgb(255, 255, 255));
40 unlock();
43 void Visualization::lock() {
44 m_paintLock.lock();
45 /*qDebug("Locked surface . . .");*/
46 if(!m_painter.begin(&m_image)) {
47 qWarning("Note: couldn't lock surface . . .");
51 void Visualization::unlock() {
52 /*qDebug("Unlocking surface . . .");*/
53 m_painter.end();
54 m_paintLock.unlock();
57 void Visualization::resize(const QSize &newSize) {
58 /*qDebug("Resizing . . .");*/
59 m_paintLock.lock();
60 QImage temporary = m_image;
61 m_image = QImage(newSize, QImage::Format_ARGB32);
62 m_painter.begin(&m_image);
63 m_painter.drawImage(QRect(0, 0, temporary.width(), temporary.height()), temporary);
64 m_painter.end();
65 m_paintLock.unlock();
68 void Visualization::setPenColour(int r, int g, int b, int a) {
69 QPen pen = m_painter.pen();
70 pen.setColor(qRgba(r, g, b, a));
71 m_painter.setPen(pen);
74 void Visualization::setFillColour(int r, int g, int b, int a) {
75 QBrush brush = m_painter.brush();
76 brush.setStyle(Qt::SolidPattern);
77 brush.setColor(qRgba(r, g, b, a));
78 m_painter.setBrush(brush);
81 void Visualization::drawLine(DataCoord from, DataCoord to) {
82 if(!isLocked()) {
83 qWarning("drawLine() called when visualization is not locked.");
84 return;
86 QLineF line(translate(from), translate(to));
87 /*qDebug("Asked to draw line from (%f, %f) to (%f, %f) . . .", line.x1(), line.y1(), line.x2(), line.y2());*/
89 m_painter.drawLine(line);
90 m_controller->modifiedPoint(from);
91 m_controller->modifiedPoint(to);
94 void Visualization::drawBox(DataRange range) {
95 if(!isLocked()) {
96 qWarning("drawBox() called when visualization is not locked.");
97 return;
99 QRectF rect(translate(range).normalized());
101 if(rect.left() < 0) rect.setLeft(0.0);
102 else if(rect.right() > m_image.width()) rect.setRight(m_image.width());
104 if(rect.top() < 0) rect.setTop(0.0);
105 else if(rect.bottom() > m_image.height()) rect.setBottom(m_image.height());
107 qDebug("Drawing box from (%f, %f) to (%f, %f) . . .", rect.left(), rect.top(), rect.right(), rect.bottom());
109 m_painter.drawRect(rect);
110 m_controller->modifiedPoint(range.begin());
111 m_controller->modifiedPoint(range.end());
114 void Visualization::touch(Timestamp timestamp) {
115 m_controller->modifiedTime(timestamp);
118 Visualization *Visualization::subVisualization(const DataRange &range) {
119 Visualization *sv = new Visualization(translate(range).toAlignedRect().size(), range);
120 sv->setController(m_controller);
121 return sv;
124 void Visualization::shift(DataCoord by) {
125 m_paintLock.lock();
127 qDebug("\n\tbeginTime(): %li\n", m_controller->totalRange().beginTime());
128 if(by.time() < 0 && m_range.beginTime() + by.time() < m_controller->totalRange().beginTime()) by.time() = 0.0;
129 if(by.time() > 0 && m_range.endTime() + by.time() > m_controller->totalRange().endTime()) by.time() = 0.0;
131 if(by.data() < 0 && m_range.beginData() + by.data() < m_controller->totalRange().beginData()) by.data() = 0.0;
132 if(by.data() > 0 && m_range.endData() + by.data() > m_controller->totalRange().endData()) by.data() = 0.0;
134 QPointF pixels = translateOffset(by);
135 qDebug("by: %li, %f", by.time(), by.data());
136 qDebug("pixels: %f,%f", pixels.x(), pixels.y());
137 QImage temporary = m_image.copy();
138 m_painter.begin(&m_image);
140 m_image.fill(qRgb(255, 192, 192));
142 m_painter.drawImage(pixels, temporary);
144 /*m_painter.setBrush(Qt::white);
145 m_painter.setPen(Qt::NoPen);*/
147 m_range.begin() += by;
148 m_range.end() += by;
150 m_painter.end();
151 m_paintLock.unlock();
154 void Visualization::scale(qreal x, qreal y) {
155 m_paintLock.lock();
157 Timestamp xSize = m_range.endTime() - m_range.beginTime();
158 double ySize = m_range.endData() - m_range.beginData();
160 Timestamp xCentre = (m_range.endTime() + m_range.beginTime()) / 2;
161 double yCentre = (m_range.endData() + m_range.beginData()) / 2.0;
163 DataCoord newBegin = DataCoord((Timestamp)(xCentre - ((xSize / 2) * x)), yCentre - ((ySize / 2) * y));
164 DataCoord newEnd = DataCoord((Timestamp)(xCentre + ((xSize / 2) * x)), yCentre + ((ySize / 2) * y));
166 QImage temporary = m_image;
167 m_painter.begin(&m_image);
169 m_image.fill(qRgb(255, 255, 255));
170 QRectF rect = translate(DataRange(newBegin, newEnd)).normalized();
171 /*qDebug("rect: (%f,%f),(%f,%f)", rect.left(), rect.top(), rect.right(), rect.bottom());*/
172 m_painter.drawImage(translate(DataRange(
173 DataCoord((Timestamp)(xCentre - ((xSize / 2) * 1/x)), yCentre - ((ySize / 2) * 1/y)),
174 DataCoord((Timestamp)(xCentre + ((xSize / 2) * 1/x)), yCentre + ((ySize / 2) * 1/y))
175 )).normalized(), temporary);
177 m_painter.end();
179 m_range.setBegin(newBegin);
180 m_range.setEnd(newEnd);
182 m_paintLock.unlock();
184 m_controller->fullVisualization();
187 QPointF Visualization::translate(const DataCoord &coord) {
188 Timestamp xSize = m_range.endTime() - m_range.beginTime();
189 qreal ySize = m_range.endData() - m_range.beginData();
191 qreal xPercentage = ((qreal)coord.time() - (qreal)m_range.beginTime()) / qreal(xSize);
192 qreal yPercentage = (coord.data() - m_range.beginData()) / ySize;
194 return QPointF((m_image.width()-1) * xPercentage, (m_image.height()-1) - ((m_image.height()-1) * yPercentage));
197 QRectF Visualization::translate(const DataRange &range) {
198 return QRectF(translate(range.begin()), translate(range.end()));
201 DataCoord Visualization::translate(const QPoint &point) {
202 qreal xPercentage = point.x() / (qreal)(m_image.width()-1);
203 qreal yPercentage = point.y() / (qreal)(m_image.height()-1);
205 Timestamp xSize = m_range.endTime() - m_range.beginTime();
206 qreal ySize = m_range.endData() - m_range.beginData();
208 return DataCoord((xPercentage * xSize) + m_range.beginTime(), (yPercentage * ySize) + m_range.beginData());
211 DataRange Visualization::translate(const QRect &rect) {
212 return DataRange(translate(rect.topLeft()), translate(rect.bottomRight()));
215 DataCoord Visualization::translateOffset(const QPoint &point) {
216 qreal xPercentage = point.x() / (qreal)(m_image.width()-1);
217 qreal yPercentage = point.y() / (qreal)(m_image.height()-1);
219 Timestamp xSize = m_range.endTime() - m_range.beginTime();
220 qreal ySize = m_range.endData() - m_range.beginData();
222 return DataCoord((xPercentage * xSize), (yPercentage * ySize));
225 QPointF Visualization::translateOffset(const DataCoord &coord) {
226 DataCoord c = coord;
227 c.time() += m_range.beginTime();
228 c.data() += m_range.endData();
229 QPointF translated = translate(c);
230 translated.setX(-translated.x());
231 translated.setY(-translated.y());
232 return translated;