blob: 5798d2e89018233aec1fcead6f03b3f5757eb135 [file] [log] [blame]
Zack Rusin5cb6b872011-04-10 02:19:59 -04001#include "imageviewer.h"
Zack Rusin66ce10a2013-09-10 20:30:59 -04002#include "pixelwidget.h"
Zack Rusina69f0de2013-09-12 17:21:51 -04003#include "apisurface.h"
4
Jose Fonsecabceafec2016-05-05 11:09:52 +01005#include "image.hpp"
Zack Rusin5cb6b872011-04-10 02:19:59 -04006
José Fonsecad562b8e2011-11-25 15:51:09 +00007#include <QDebug>
Zack Rusin2ffe9f82011-09-23 20:25:47 -04008#include <QDesktopWidget>
Zack Rusin5cb6b872011-04-10 02:19:59 -04009#include <QPainter>
10#include <QPixmap>
Zack Rusin2ffe9f82011-09-23 20:25:47 -040011#include <QScrollBar>
Zack Rusin5cb6b872011-04-10 02:19:59 -040012
Martin Schulzeb44232b2016-04-16 19:06:16 +020013ImageViewer::ImageViewer(QWidget *parent, bool opaque, bool alpha)
Zack Rusina69f0de2013-09-12 17:21:51 -040014 : QDialog(parent),
15 m_image(0)
Zack Rusin5cb6b872011-04-10 02:19:59 -040016{
17 setupUi(this);
Martin Schulzeb44232b2016-04-16 19:06:16 +020018 opaqueCheckBox->setChecked(opaque);
19 alphaCheckBox->setChecked(alpha);
Zack Rusin5cb6b872011-04-10 02:19:59 -040020
José Fonsecad562b8e2011-11-25 15:51:09 +000021 connect(lowerSpinBox, SIGNAL(valueChanged(double)),
22 SLOT(slotUpdate()));
23 connect(upperSpinBox, SIGNAL(valueChanged(double)),
24 SLOT(slotUpdate()));
25 connect(flipCheckBox, SIGNAL(stateChanged(int)),
26 SLOT(slotUpdate()));
José Fonsecafe13f772012-03-21 08:49:40 +000027 connect(opaqueCheckBox, SIGNAL(stateChanged(int)),
28 SLOT(slotUpdate()));
gregory8f0aa382012-07-01 17:18:04 +020029 connect(alphaCheckBox, SIGNAL(stateChanged(int)),
30 SLOT(slotUpdate()));
José Fonsecad562b8e2011-11-25 15:51:09 +000031
Zack Rusin5cb6b872011-04-10 02:19:59 -040032 QPixmap px(32, 32);
33 QPainter p(&px);
34 p.fillRect(0, 0, 32, 32, Qt::white);
35 p.fillRect(0, 0, 16, 16, QColor(193, 193, 193));
36 p.fillRect(16, 16, 16, 16, QColor(193, 193, 193));
37 p.end();
38 QPalette pal = scrollAreaWidgetContents->palette();
39 pal.setBrush(QPalette::Background,
40 QBrush(px));
41 pal.setBrush(QPalette::Base,
42 QBrush(px));
43 scrollAreaWidgetContents->setPalette(pal);
Zack Rusin66ce10a2013-09-10 20:30:59 -040044
45 m_pixelWidget = new PixelWidget(scrollAreaWidgetContents);
46 verticalLayout_2->addWidget(m_pixelWidget);
47
48 rectLabel->hide();
49 pixelLabel->hide();
50
51 connect(m_pixelWidget, SIGNAL(zoomChanged(int)),
52 zoomSpinBox, SLOT(setValue(int)));
53 connect(zoomSpinBox, SIGNAL(valueChanged(int)),
54 m_pixelWidget, SLOT(setZoom(int)));
55 connect(m_pixelWidget, SIGNAL(mousePosition(int, int)),
56 this, SLOT(showPixel(int, int)));
57 connect(m_pixelWidget, SIGNAL(gridGeometry(const QRect &)),
58 this, SLOT(showGrid(const QRect &)));
Zack Rusin5cb6b872011-04-10 02:19:59 -040059}
60
Zack Rusina69f0de2013-09-12 17:21:51 -040061ImageViewer::~ImageViewer()
Zack Rusin5cb6b872011-04-10 02:19:59 -040062{
Zack Rusina69f0de2013-09-12 17:21:51 -040063 delete m_image;
64}
65
Jose Fonseca93a7c0c2015-05-27 20:52:51 +010066void ImageViewer::setData(const QByteArray &data)
Zack Rusina69f0de2013-09-12 17:21:51 -040067{
68 delete m_image;
Jose Fonseca93a7c0c2015-05-27 20:52:51 +010069 m_image = ApiSurface::imageFromData(data);
Martin Schulzeb44232b2016-04-16 19:06:16 +020070 slotUpdate();
Zack Rusin2ffe9f82011-09-23 20:25:47 -040071}
72
José Fonsecad562b8e2011-11-25 15:51:09 +000073void ImageViewer::slotUpdate()
74{
Zack Rusina69f0de2013-09-12 17:21:51 -040075 m_convertedImage =
76 m_convertedImage.mirrored(false, flipCheckBox->isChecked());
José Fonsecad562b8e2011-11-25 15:51:09 +000077
78 double lowerValue = lowerSpinBox->value();
79 double upperValue = upperSpinBox->value();
80
José Fonsecafe13f772012-03-21 08:49:40 +000081 bool opaque = opaqueCheckBox->isChecked();
gregory8f0aa382012-07-01 17:18:04 +020082 bool alpha = alphaCheckBox->isChecked();
José Fonsecafe13f772012-03-21 08:49:40 +000083
José Fonseca36509be2013-09-17 15:22:50 +010084 m_convertedImage = ApiSurface::qimageFromRawImage(m_image,
85 lowerValue, upperValue,
86 opaque, alpha);
José Fonsecad562b8e2011-11-25 15:51:09 +000087
José Fonseca36509be2013-09-17 15:22:50 +010088 if (flipCheckBox->isChecked()) {
89 m_convertedImage = m_convertedImage.mirrored(false, true);
José Fonsecad562b8e2011-11-25 15:51:09 +000090 }
91
Zack Rusina69f0de2013-09-12 17:21:51 -040092 m_pixelWidget->setSurface(m_convertedImage);
José Fonsecad562b8e2011-11-25 15:51:09 +000093
94 updateGeometry();
95}
96
Zack Rusin2ffe9f82011-09-23 20:25:47 -040097QSize ImageViewer::sizeHint() const
98{
99 QSize size;
100
101 int vScrollWidth = scrollArea->verticalScrollBar() ?
102 scrollArea->verticalScrollBar()->width() : 0;
103 int hScrollHeight = scrollArea->horizontalScrollBar() ?
104 scrollArea->horizontalScrollBar()->height() : 0;
Zack Rusina69f0de2013-09-12 17:21:51 -0400105 QSize optimalWindowSize(m_convertedImage.width() + vScrollWidth,
106 m_convertedImage.height() + hScrollHeight);
Zack Rusin2ffe9f82011-09-23 20:25:47 -0400107
108 QRect screenRect = QApplication::desktop()->availableGeometry();
José Fonseca5d7fc052012-11-13 19:53:47 +0000109 const float maxPercentOfDesktopSpace = 0.8f;
Zack Rusin2ffe9f82011-09-23 20:25:47 -0400110 QSize maxAvailableSize(maxPercentOfDesktopSpace * screenRect.width(),
111 maxPercentOfDesktopSpace * screenRect.height());
112
113 return QSize(qMin(optimalWindowSize.width(), maxAvailableSize.width()),
114 qMin(optimalWindowSize.height(), maxAvailableSize.height()));
Zack Rusin5cb6b872011-04-10 02:19:59 -0400115}
116
Zack Rusin66ce10a2013-09-10 20:30:59 -0400117void ImageViewer::resizeEvent(QResizeEvent *e)
118{
119 QWidget::resizeEvent(e);
120}
121
Zack Rusina69f0de2013-09-12 17:21:51 -0400122template <class T>
123QString createPixelLabel(image::Image *img, int x, int y)
124{
125 QString pixelLabel;
126 unsigned char *pixelLocation = 0;
127 T *pixel;
128
Chris Forbes0870da22014-11-21 18:45:05 +1300129 if (x < 0 || y < 0 || x >= img->width || y >= img->height) {
130 return QString::fromLatin1("(Out of bounds)");
131 }
132
Zack Rusina69f0de2013-09-12 17:21:51 -0400133 pixelLocation = img->pixels + img->stride() * y;
134 pixelLocation += x * img->bytesPerPixel;
135 pixel = ((T*)pixelLocation);
136
137 pixelLabel += QLatin1String("[");
José Fonseca8c3fa762014-02-28 14:20:26 +0000138 pixelLabel += QString::fromLatin1("%1").arg((double)pixel[0], 0, 'g', 9);
Zack Rusina69f0de2013-09-12 17:21:51 -0400139
140 for (int channel = 1; channel < img->channels; ++channel) {
José Fonseca8c3fa762014-02-28 14:20:26 +0000141 pixelLabel += QString::fromLatin1(", %1").arg((double)pixel[channel], 0, 'g', 9);
Zack Rusina69f0de2013-09-12 17:21:51 -0400142 }
143 pixelLabel += QLatin1String("]");
144
145 return pixelLabel;
146}
147
Zack Rusin66ce10a2013-09-10 20:30:59 -0400148void ImageViewer::showPixel(int x, int y)
149{
150 xSpinBox->setValue(x);
151 ySpinBox->setValue(y);
Zack Rusina69f0de2013-09-12 17:21:51 -0400152
153 if (!m_image)
154 return;
155
156 QString label = tr("Pixel: ");
157
Zack Rusin7ec54f92013-10-11 18:32:25 -0400158 /* If the image is flipped, substitute y to match */
159 if (flipCheckBox->isChecked()) {
160 y = m_convertedImage.height() - y - 1;
161 }
162
Zack Rusina69f0de2013-09-12 17:21:51 -0400163 if (m_image->channelType == image::TYPE_UNORM8) {
164 label += createPixelLabel<unsigned char>(m_image, x, y);
165 } else {
166 label += createPixelLabel<float>(m_image, x, y);
167 }
168
169 pixelLabel->setText(label);
Zack Rusin66ce10a2013-09-10 20:30:59 -0400170 pixelLabel->show();
171}
172
173void ImageViewer::showGrid(const QRect &rect)
174{
175 if (rect.isEmpty()) {
176 rectLabel->hide();
177 return;
178 }
179 rectLabel->setText(tr("Grid: [%1, %2, %3, %4]")
180 .arg(rect.x())
181 .arg(rect.y())
182 .arg(rect.width())
183 .arg(rect.height()));
184 rectLabel->show();
185}
186
Zack Rusin5cb6b872011-04-10 02:19:59 -0400187#include "imageviewer.moc"