]> git.cworth.org Git - apitrace/blob - gui/imageviewer.cpp
gui: fix pixel info on flipped images
[apitrace] / gui / imageviewer.cpp
1 #include "imageviewer.h"
2 #include "pixelwidget.h"
3 #include "apisurface.h"
4
5 #include "image/image.hpp"
6
7 #include <QDebug>
8 #include <QDesktopWidget>
9 #include <QPainter>
10 #include <QPixmap>
11 #include <QScrollBar>
12
13 ImageViewer::ImageViewer(QWidget *parent)
14     : QDialog(parent),
15       m_image(0)
16 {
17     setupUi(this);
18
19     connect(lowerSpinBox, SIGNAL(valueChanged(double)),
20             SLOT(slotUpdate()));
21     connect(upperSpinBox, SIGNAL(valueChanged(double)),
22             SLOT(slotUpdate()));
23     connect(flipCheckBox, SIGNAL(stateChanged(int)),
24             SLOT(slotUpdate()));
25     connect(opaqueCheckBox, SIGNAL(stateChanged(int)),
26             SLOT(slotUpdate()));
27     connect(alphaCheckBox, SIGNAL(stateChanged(int)),
28             SLOT(slotUpdate()));
29
30     QPixmap px(32, 32);
31     QPainter p(&px);
32     p.fillRect(0, 0, 32, 32, Qt::white);
33     p.fillRect(0, 0, 16, 16, QColor(193, 193, 193));
34     p.fillRect(16, 16, 16, 16, QColor(193, 193, 193));
35     p.end();
36     QPalette pal = scrollAreaWidgetContents->palette();
37     pal.setBrush(QPalette::Background,
38                  QBrush(px));
39     pal.setBrush(QPalette::Base,
40                  QBrush(px));
41     scrollAreaWidgetContents->setPalette(pal);
42
43     m_pixelWidget = new PixelWidget(scrollAreaWidgetContents);
44     verticalLayout_2->addWidget(m_pixelWidget);
45
46     rectLabel->hide();
47     pixelLabel->hide();
48
49     connect(m_pixelWidget, SIGNAL(zoomChanged(int)),
50             zoomSpinBox, SLOT(setValue(int)));
51     connect(zoomSpinBox, SIGNAL(valueChanged(int)),
52             m_pixelWidget, SLOT(setZoom(int)));
53     connect(m_pixelWidget, SIGNAL(mousePosition(int, int)),
54             this, SLOT(showPixel(int, int)));
55     connect(m_pixelWidget, SIGNAL(gridGeometry(const QRect &)),
56             this, SLOT(showGrid(const QRect &)));
57 }
58
59 ImageViewer::~ImageViewer()
60 {
61     delete m_image;
62 }
63
64 void ImageViewer::setBase64Data(const QByteArray &base64)
65 {
66     delete m_image;
67     m_image = ApiSurface::imageFromBase64(base64);
68     m_convertedImage = ApiSurface::qimageFromRawImage(m_image);
69     m_pixelWidget->setSurface(m_convertedImage);
70     updateGeometry();
71 }
72
73 void ImageViewer::slotUpdate()
74 {
75     m_convertedImage =
76         m_convertedImage.mirrored(false, flipCheckBox->isChecked());
77
78     double lowerValue = lowerSpinBox->value();
79     double upperValue = upperSpinBox->value();
80
81     bool opaque = opaqueCheckBox->isChecked();
82     bool alpha  = alphaCheckBox->isChecked();
83
84     m_convertedImage = ApiSurface::qimageFromRawImage(m_image,
85                                                       lowerValue, upperValue,
86                                                       opaque, alpha);
87
88     if (flipCheckBox->isChecked()) {
89         m_convertedImage = m_convertedImage.mirrored(false, true);
90     }
91
92     m_pixelWidget->setSurface(m_convertedImage);
93
94     updateGeometry();
95 }
96
97 QSize 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;
105     QSize optimalWindowSize(m_convertedImage.width() + vScrollWidth,
106                             m_convertedImage.height() + hScrollHeight);
107
108     QRect screenRect = QApplication::desktop()->availableGeometry();
109     const float maxPercentOfDesktopSpace = 0.8f;
110     QSize maxAvailableSize(maxPercentOfDesktopSpace * screenRect.width(),
111                            maxPercentOfDesktopSpace * screenRect.height());
112
113     return QSize(qMin(optimalWindowSize.width(), maxAvailableSize.width()),
114                  qMin(optimalWindowSize.height(), maxAvailableSize.height()));
115 }
116
117 void ImageViewer::resizeEvent(QResizeEvent *e)
118 {
119     QWidget::resizeEvent(e);
120 }
121
122 template <class T>
123 QString createPixelLabel(image::Image *img, int x, int y)
124 {
125     QString pixelLabel;
126     unsigned char *pixelLocation = 0;
127     T *pixel;
128
129     pixelLocation = img->pixels + img->stride() * y;
130     pixelLocation += x * img->bytesPerPixel;
131     pixel = ((T*)pixelLocation);
132
133     pixelLabel += QLatin1String("[");
134     pixelLabel += QString::fromLatin1("%1").arg(pixel[0]);
135
136     for (int channel = 1; channel < img->channels; ++channel) {
137         pixelLabel += QString::fromLatin1(", %1").arg(pixel[channel]);
138     }
139     pixelLabel += QLatin1String("]");
140
141     return pixelLabel;
142 }
143
144 void ImageViewer::showPixel(int x, int y)
145 {
146     xSpinBox->setValue(x);
147     ySpinBox->setValue(y);
148
149     if (!m_image)
150         return;
151
152     QString label = tr("Pixel: ");
153
154     /* If the image is flipped, substitute y to match */
155     if (flipCheckBox->isChecked()) {
156         y = m_convertedImage.height() - y - 1;
157     }
158
159     if (m_image->channelType == image::TYPE_UNORM8) {
160         label += createPixelLabel<unsigned char>(m_image, x, y);
161     } else {
162         label += createPixelLabel<float>(m_image, x, y);
163     }
164
165     pixelLabel->setText(label);
166     pixelLabel->show();
167 }
168
169 void ImageViewer::showGrid(const QRect &rect)
170 {
171     if (rect.isEmpty()) {
172         rectLabel->hide();
173         return;
174     }
175     rectLabel->setText(tr("Grid: [%1, %2, %3, %4]")
176                        .arg(rect.x())
177                        .arg(rect.y())
178                        .arg(rect.width())
179                        .arg(rect.height()));
180     rectLabel->show();
181 }
182
183 #include "imageviewer.moc"