blob: cd034138f9aaa52ce79dc58b4aa638a24171293e [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 Rusin5cb6b872011-04-10 02:19:59 -04003
José Fonsecad562b8e2011-11-25 15:51:09 +00004#include <QDebug>
Zack Rusin2ffe9f82011-09-23 20:25:47 -04005#include <QDesktopWidget>
Zack Rusin5cb6b872011-04-10 02:19:59 -04006#include <QPainter>
7#include <QPixmap>
Zack Rusin2ffe9f82011-09-23 20:25:47 -04008#include <QScrollBar>
Zack Rusin5cb6b872011-04-10 02:19:59 -04009
10ImageViewer::ImageViewer(QWidget *parent)
11 : QDialog(parent)
12{
13 setupUi(this);
14
José Fonsecad562b8e2011-11-25 15:51:09 +000015 connect(lowerSpinBox, SIGNAL(valueChanged(double)),
16 SLOT(slotUpdate()));
17 connect(upperSpinBox, SIGNAL(valueChanged(double)),
18 SLOT(slotUpdate()));
19 connect(flipCheckBox, SIGNAL(stateChanged(int)),
20 SLOT(slotUpdate()));
José Fonsecafe13f772012-03-21 08:49:40 +000021 connect(opaqueCheckBox, SIGNAL(stateChanged(int)),
22 SLOT(slotUpdate()));
gregory8f0aa382012-07-01 17:18:04 +020023 connect(alphaCheckBox, SIGNAL(stateChanged(int)),
24 SLOT(slotUpdate()));
José Fonsecad562b8e2011-11-25 15:51:09 +000025
Zack Rusin5cb6b872011-04-10 02:19:59 -040026 QPixmap px(32, 32);
27 QPainter p(&px);
28 p.fillRect(0, 0, 32, 32, Qt::white);
29 p.fillRect(0, 0, 16, 16, QColor(193, 193, 193));
30 p.fillRect(16, 16, 16, 16, QColor(193, 193, 193));
31 p.end();
32 QPalette pal = scrollAreaWidgetContents->palette();
33 pal.setBrush(QPalette::Background,
34 QBrush(px));
35 pal.setBrush(QPalette::Base,
36 QBrush(px));
37 scrollAreaWidgetContents->setPalette(pal);
Zack Rusin66ce10a2013-09-10 20:30:59 -040038
39 m_pixelWidget = new PixelWidget(scrollAreaWidgetContents);
40 verticalLayout_2->addWidget(m_pixelWidget);
41
42 rectLabel->hide();
43 pixelLabel->hide();
44
45 connect(m_pixelWidget, SIGNAL(zoomChanged(int)),
46 zoomSpinBox, SLOT(setValue(int)));
47 connect(zoomSpinBox, SIGNAL(valueChanged(int)),
48 m_pixelWidget, SLOT(setZoom(int)));
49 connect(m_pixelWidget, SIGNAL(mousePosition(int, int)),
50 this, SLOT(showPixel(int, int)));
51 connect(m_pixelWidget, SIGNAL(gridGeometry(const QRect &)),
52 this, SLOT(showGrid(const QRect &)));
Zack Rusin5cb6b872011-04-10 02:19:59 -040053}
54
55void ImageViewer::setImage(const QImage &image)
56{
Zack Rusin2ffe9f82011-09-23 20:25:47 -040057 m_image = image;
José Fonsecad562b8e2011-11-25 15:51:09 +000058 m_temp = m_image;
Zack Rusin66ce10a2013-09-10 20:30:59 -040059 m_pixelWidget->setSurface(m_image);
Zack Rusin2ffe9f82011-09-23 20:25:47 -040060 updateGeometry();
61}
62
José Fonsecad562b8e2011-11-25 15:51:09 +000063static inline int clamp(int x)
64{
65 if (x <= 0) {
66 return 0;
67 }
68 if (x > 255) {
69 return 255;
70 }
71 return x;
72}
73
74void ImageViewer::slotUpdate()
75{
76 m_temp = m_image.mirrored(false, flipCheckBox->isChecked());
77
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
gregory8f0aa382012-07-01 17:18:04 +020084 if (lowerValue != 0.0 || upperValue != 1.0 || opaque || alpha) {
José Fonsecad562b8e2011-11-25 15:51:09 +000085 /*
86 * Rescale the image.
87 *
88 * XXX: This would be much more useful if done with the full precision
89 * of the original image
90 */
91
92 int offset = - lowerValue * 255;
93 int scale = 256 / (upperValue - lowerValue);
94
95 m_temp = m_temp.convertToFormat(QImage::Format_ARGB32);
96
97 if (0) {
98 qDebug()
99 << "offset = " << offset << "\n"
100 << "scale = " << scale << "\n";
101 }
102
103 int width = m_temp.width();
104 int height = m_temp.height();
105
José Fonsecafe13f772012-03-21 08:49:40 +0000106 int aMask = opaque ? 0xff : 0;
107
José Fonsecad562b8e2011-11-25 15:51:09 +0000108 for (int y = 0; y < height; ++y) {
109 QRgb *scanline = (QRgb *)m_temp.scanLine(y);
110 for (int x = 0; x < width; ++x) {
111 QRgb pixel = scanline[x];
112 int r = qRed(pixel);
113 int g = qGreen(pixel);
114 int b = qBlue(pixel);
José Fonsecafe13f772012-03-21 08:49:40 +0000115 int a = qAlpha(pixel);
gregory8f0aa382012-07-01 17:18:04 +0200116 if (alpha) {
117 a = clamp(((a + offset) * scale) >> 8);
118 scanline[x] = qRgba(a, a, a, 0xff);
119 } else {
120 r = clamp(((r + offset) * scale) >> 8);
121 g = clamp(((g + offset) * scale) >> 8);
122 b = clamp(((b + offset) * scale) >> 8);
123 a |= aMask;
124 scanline[x] = qRgba(r, g, b, a);
125 }
José Fonsecad562b8e2011-11-25 15:51:09 +0000126 }
127 }
128 }
129
Zack Rusin66ce10a2013-09-10 20:30:59 -0400130 m_pixelWidget->setSurface(m_temp);
José Fonsecad562b8e2011-11-25 15:51:09 +0000131
132 updateGeometry();
133}
134
Zack Rusin2ffe9f82011-09-23 20:25:47 -0400135QSize ImageViewer::sizeHint() const
136{
137 QSize size;
138
139 int vScrollWidth = scrollArea->verticalScrollBar() ?
140 scrollArea->verticalScrollBar()->width() : 0;
141 int hScrollHeight = scrollArea->horizontalScrollBar() ?
142 scrollArea->horizontalScrollBar()->height() : 0;
143 QSize optimalWindowSize(m_image.width() + vScrollWidth,
144 m_image.height() + hScrollHeight);
145
146 QRect screenRect = QApplication::desktop()->availableGeometry();
José Fonseca5d7fc052012-11-13 19:53:47 +0000147 const float maxPercentOfDesktopSpace = 0.8f;
Zack Rusin2ffe9f82011-09-23 20:25:47 -0400148 QSize maxAvailableSize(maxPercentOfDesktopSpace * screenRect.width(),
149 maxPercentOfDesktopSpace * screenRect.height());
150
151 return QSize(qMin(optimalWindowSize.width(), maxAvailableSize.width()),
152 qMin(optimalWindowSize.height(), maxAvailableSize.height()));
Zack Rusin5cb6b872011-04-10 02:19:59 -0400153}
154
Zack Rusin66ce10a2013-09-10 20:30:59 -0400155void ImageViewer::resizeEvent(QResizeEvent *e)
156{
157 QWidget::resizeEvent(e);
158}
159
160void ImageViewer::showPixel(int x, int y)
161{
162 xSpinBox->setValue(x);
163 ySpinBox->setValue(y);
164 QColor clr = m_pixelWidget->colorAtCurrentPosition();
165 pixelLabel->setText(tr("RGBA: (%1, %2, %3, %4)")
166 .arg(clr.red())
167 .arg(clr.green())
168 .arg(clr.blue())
169 .arg(clr.alpha()));
170 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"