Skip to content

Commit

Permalink
GUI: Panel preview image code
Browse files Browse the repository at this point in the history
  • Loading branch information
fdde authored and DrMcCoy committed Dec 29, 2017
1 parent 213873e commit 65dd700
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 301 deletions.
222 changes: 137 additions & 85 deletions src/gui/panelpreviewimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,89 @@ namespace GUI {

W_OBJECT_IMPL(PanelPreviewImage)

PanelPreviewImage::PanelPreviewImage(QWidget *UNUSED(parent))
: _imageLabel(new QLabel(this))
, _scaleFactor(1)
{
_ui.setupUi(this);

// get rid of spacing between buttons
_ui.verticalLayout->insertStretch(-1, 1);

_imageLabel->setBackgroundRole(QPalette::Base);
_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
_ui.imageScrollArea->setWidget(_imageLabel);
_imageLabel->setScaledContents(true);

darknessSliderSlot(0);

connect(_ui.darkness, &QSlider::valueChanged, this, &PanelPreviewImage::darknessSliderSlot);
connect(_ui.zoomIn, &QPushButton::clicked, this, &PanelPreviewImage::zoomIn);
connect(_ui.zoomOut, &QPushButton::clicked, this, &PanelPreviewImage::zoomOut);
connect(_ui.zoomOriginal, &QPushButton::clicked, this, &PanelPreviewImage::zoomOriginal);
connect(_ui.fit, &QPushButton::clicked, this, &PanelPreviewImage::onZoomFit);
connect(_ui.fitWidth, &QPushButton::clicked, this, &PanelPreviewImage::onZoomFitWidth);
connect(_ui.fitShrink, &QPushButton::clicked, this, &PanelPreviewImage::onZoomShrinkFit);
connect(_ui.fitShrinkWidth, &QPushButton::clicked, this, &PanelPreviewImage::onZoomShrinkFitWidth);
connect(_ui.nearest, &QCheckBox::toggled, this, &PanelPreviewImage::nearestToggled);
PanelPreviewImage::PanelPreviewImage(QWidget *UNUSED(parent)) {
_zoomFactor = 1.0f;

_mode = Qt::SmoothTransformation;

_layoutGrid = new QGridLayout(this);
_layoutVertical = new QVBoxLayout();
_layoutHorizontal = new QHBoxLayout();

_buttonZoomIn = new QPushButton(this);
_buttonZoomOut = new QPushButton(this);
_buttonZoomOriginal = new QPushButton(this);
_buttonFit = new QPushButton(this);
_buttonFitWidth = new QPushButton(this);
_buttonShrinkFit = new QPushButton(this);
_buttonShrinkFitWidth = new QPushButton(this);

_labelDimensions = new QLabel(this);
_labelBrightness = new QLabel(this);
_labelZoomPercent = new QLabel(this);
_labelImage = new QLabel(this);

_scrollAreaImage = new QScrollArea(this);

_sliderBrightness = new QSlider(this);

_checkNearest = new QCheckBox("Nearest", this);

_buttonZoomIn->setText(tr("Zoom in"));
_buttonZoomOut->setText(tr("Zoom out"));
_buttonZoomOriginal->setText(tr("Zoom 100%"));
_buttonFit->setText(tr("Fit"));
_buttonFitWidth->setText(tr("Fit width"));
_buttonShrinkFit->setText(tr("Shrink fit"));
_buttonShrinkFitWidth->setText(tr("Shrink fit width"));

_layoutVertical->addWidget(_labelZoomPercent);
_layoutVertical->addWidget(_buttonZoomIn);
_layoutVertical->addWidget(_buttonZoomOut);
_layoutVertical->addWidget(_buttonZoomOriginal);
_layoutVertical->addWidget(_buttonFit);
_layoutVertical->addWidget(_buttonFitWidth);
_layoutVertical->addWidget(_buttonShrinkFit);
_layoutVertical->addWidget(_buttonShrinkFitWidth);
_layoutVertical->addWidget(_checkNearest);
_layoutVertical->insertStretch(-1, 1); // get rid of spacing between buttons
_labelZoomPercent->setAlignment(Qt::AlignCenter);

_layoutGrid->addWidget(_labelDimensions, 0, 0);
_layoutGrid->addWidget(_labelBrightness, 1, 0);
_layoutGrid->addWidget(_sliderBrightness, 1, 1);
_layoutGrid->addLayout(_layoutVertical, 2, 0);
_layoutGrid->addWidget(_scrollAreaImage, 2, 1);

_labelDimensions->setText(tr("(WxH)"));
_labelBrightness->setText(tr("Background brightness"));
_labelZoomPercent->setText(tr("100%"));

_labelImage->setBackgroundRole(QPalette::Base);
_labelImage->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
_labelImage->setScaledContents(true);

_scrollAreaImage->setWidget(_labelImage);

_sliderBrightness->setOrientation(Qt::Horizontal);

slotSliderBrightness(0);

connect(_sliderBrightness, &QSlider::valueChanged, this, &PanelPreviewImage::slotSliderBrightness);
connect(_buttonZoomIn, &QPushButton::clicked, this, &PanelPreviewImage::slotZoomIn);
connect(_buttonZoomOut, &QPushButton::clicked, this, &PanelPreviewImage::slotZoomOut);
connect(_buttonZoomOriginal, &QPushButton::clicked, this, &PanelPreviewImage::slotZoomOriginal);
connect(_buttonFit, &QPushButton::clicked, this, &PanelPreviewImage::slotFit);
connect(_buttonFitWidth, &QPushButton::clicked, this, &PanelPreviewImage::slotFitWidth);
connect(_buttonShrinkFit, &QPushButton::clicked, this, &PanelPreviewImage::slotShrinkFit);
connect(_buttonShrinkFitWidth, &QPushButton::clicked, this, &PanelPreviewImage::slotShrinkFitWidth);
connect(_checkNearest, &QCheckBox::toggled, this, &PanelPreviewImage::slotNearest);
}

void PanelPreviewImage::setItem(const ResourceTreeItem *item) {
_scaleFactor = 1.0;
_zoomFactor = 1.0f;
_originalPixmap = QPixmap();
_imageLabel->setPixmap(_originalPixmap);
_labelImage->setPixmap(_originalPixmap);

if (item->getResourceType() != Aurora::kResourceImage &&
item->getFileType() != Aurora::FileType::kFileTypeICO)
Expand All @@ -65,11 +117,11 @@ void PanelPreviewImage::loadImage() {

_originalPixmap = QPixmap::fromImage(newImage);
_originalSize = _originalPixmap.size();
_imageLabel->setPixmap(_originalPixmap);
_imageLabel->setFixedSize(_originalSize);
_labelImage->setPixmap(_originalPixmap);
_labelImage->setFixedSize(_originalSize);

_ui.dimensions->setText(QString("(%1x%2)").arg(_originalPixmap.width()).arg(_originalPixmap.height()));
_ui.imageScrollArea->show();
_labelDimensions->setText(QString("(%1x%2)").arg(_originalPixmap.width()).arg(_originalPixmap.height()));
_scrollAreaImage->show();
return;
}
}
Expand All @@ -85,7 +137,7 @@ void PanelPreviewImage::loadImage() {
if ((width <= 0) || (height <= 0))
throw Common::Exception("Invalid image dimensions (%d x %d)", width, height);

_ui.dimensions->setText(QString("(%1x%2)").arg(width).arg(height));
_labelDimensions->setText(QString("(%1x%2)").arg(width).arg(height));

Common::ScopedArray<byte, Common::DeallocatorFree> data ((byte *) malloc(width * height * 4));
std::memset(data.get(), 0, width * height * 4);
Expand All @@ -95,9 +147,9 @@ void PanelPreviewImage::loadImage() {

_originalPixmap = QPixmap::fromImage(QImage(data.get(), width, height, format).mirrored());
_originalSize = _originalPixmap.size();
_imageLabel->setPixmap(_originalPixmap);
_imageLabel->adjustSize();
_imageLabel->setFixedSize(_originalSize);
_labelImage->setPixmap(_originalPixmap);
_labelImage->adjustSize();
_labelImage->setFixedSize(_originalSize);

data.release();
}
Expand Down Expand Up @@ -180,34 +232,34 @@ void PanelPreviewImage::getImageDimensions(const Images::Decoder &image, int32 &
}
}

void PanelPreviewImage::darknessSliderSlot(int value) {
int rgb = static_cast<int>(((float)value / (float)_ui.darkness->maximum()) * 255.f);
_ui.imageScrollArea->setStyleSheet(QString("background-color: rgb(%1,%2,%3)").arg(rgb).arg(rgb).arg(rgb));
void PanelPreviewImage::slotSliderBrightness(int value) {
int rgb = static_cast<int>(((float)value / (float)_sliderBrightness->maximum()) * 255.f);
_scrollAreaImage->setStyleSheet(QString("background-color: rgb(%1,%2,%3)").arg(rgb).arg(rgb).arg(rgb));
}

void PanelPreviewImage::updateButtons() {
_ui.zoomOut->setEnabled(_scaleFactor <= 5.0);
_ui.zoomIn->setEnabled(_scaleFactor >= 0.1);
_ui.zoomOriginal->setEnabled(_scaleFactor <= 0.95 || _scaleFactor >= 1.05);
_buttonZoomOut->setEnabled(_zoomFactor <= 5.0f);
_buttonZoomIn->setEnabled(_zoomFactor >= 0.1f);
_buttonZoomOriginal->setEnabled(_zoomFactor <= 0.95f || _zoomFactor >= 1.05f);
}

void PanelPreviewImage::zoomTo(int width, int height, double zoom) {
double aspect = ((double) width) / ((double) height);
void PanelPreviewImage::zoomTo(int width, int height, float zoom) {
float aspect = ((float) width) / ((float) height);

// Calculate width using the zoom level and height using the aspect ratio
width = MAX<int>(width * zoom , 1);
height = MAX<int>(width / aspect, 1);

QSize newSize(width, height);
_imageLabel->setPixmap(_originalPixmap.scaled(newSize, Qt::IgnoreAspectRatio, _mode));
_imageLabel->setFixedSize(newSize);
_labelImage->setPixmap(_originalPixmap.scaled(newSize, Qt::IgnoreAspectRatio, _mode));
_labelImage->setFixedSize(newSize);

_scaleFactor = zoom;
_zoomFactor = zoom;
updateButtons();
_ui.zoomPercent->setText(QString("%1%").arg((int)(_scaleFactor*100)));
_labelZoomPercent->setText(QString("%1%").arg((int)(_zoomFactor*100)));
}

void PanelPreviewImage::zoomTo(double zoom) {
void PanelPreviewImage::zoomTo(float zoom) {
int fullWidth, fullHeight, currentWidth, currentHeight;

getSize(fullWidth, fullHeight, currentWidth, currentHeight);
Expand All @@ -217,100 +269,100 @@ void PanelPreviewImage::zoomTo(double zoom) {
zoomTo(fullWidth, fullHeight, zoom);
}

void PanelPreviewImage::zoomStep(double step) {
void PanelPreviewImage::zoomStep(float step) {
int fullWidth, fullHeight, currentWidth, currentHeight;

getSize(fullWidth, fullHeight, currentWidth, currentHeight);
if ((fullWidth <= 0) || (fullHeight <= 0) || (currentWidth <= 0) || (currentHeight <= 0))
return;

double zoom = ((double) currentWidth) / ((double) fullWidth);
float zoom = ((float) currentWidth) / ((float) fullWidth);

// Only allow zoom from 10% to 500%
double newZoom = CLIP<double>(zoom + step, 0.1, 5.0);
float newZoom = CLIP<float>(zoom + step, 0.1f, 5.0f);
if (zoom == newZoom)
return;

zoomTo(fullWidth, fullHeight, newZoom);
}

void PanelPreviewImage::zoomIn() {
zoomStep(0.1);
void PanelPreviewImage::slotZoomIn() {
zoomStep(0.1f);
}

void PanelPreviewImage::zoomOut() {
zoomStep(-0.1);
void PanelPreviewImage::slotZoomOut() {
zoomStep(-0.1f);
}

void PanelPreviewImage::zoomOriginal() {
_imageLabel->setPixmap(_originalPixmap.scaled(_originalSize, Qt::IgnoreAspectRatio, _mode));
_imageLabel->setFixedSize(_originalSize);
_scaleFactor = 1.0;
void PanelPreviewImage::slotZoomOriginal() {
_labelImage->setPixmap(_originalPixmap.scaled(_originalSize, Qt::IgnoreAspectRatio, _mode));
_labelImage->setFixedSize(_originalSize);
_zoomFactor = 1.0f;
updateButtons();
_ui.zoomPercent->setText("100%");
_labelZoomPercent->setText("100%");
// fixme: there's probably a better way
}

void PanelPreviewImage::onZoomFit() {
zoomFit(false, true);
void PanelPreviewImage::slotFit() {
fit(false, true);
}

void PanelPreviewImage::onZoomFitWidth() {
zoomFit(true, true);
void PanelPreviewImage::slotFitWidth() {
fit(true, true);
}

void PanelPreviewImage::onZoomShrinkFit() {
zoomFit(false, false);
void PanelPreviewImage::slotShrinkFit() {
fit(false, false);
}

void PanelPreviewImage::onZoomShrinkFitWidth() {
zoomFit(true, false);
void PanelPreviewImage::slotShrinkFitWidth() {
fit(true, false);
}

// fixme: zoom to 100% and shrink fit width are equal, and don't cause a
// re-draw after this is toggled
void PanelPreviewImage::nearestToggled(bool checked) {
void PanelPreviewImage::slotNearest(bool checked) {
if (checked)
_mode = Qt::FastTransformation;
else
_mode = Qt::SmoothTransformation;

_imageLabel->setPixmap(_originalPixmap.scaled(_imageLabel->size(), Qt::IgnoreAspectRatio, _mode));
_labelImage->setPixmap(_originalPixmap.scaled(_labelImage->size(), Qt::IgnoreAspectRatio, _mode));
// fixme: there's probably a better way
}

void PanelPreviewImage::getSize(int &fullWidth, int &fullHeight, int &currentWidth, int &currentHeight) const {
if (!_imageLabel) {
if (!_labelImage) {
fullWidth = fullHeight = currentWidth = currentHeight = 0;
return;
}

fullWidth = _originalPixmap.width();
fullHeight = _originalPixmap.height();
currentWidth = _imageLabel->width();
currentHeight = _imageLabel->height();
currentWidth = _labelImage->width();
currentHeight = _labelImage->height();
}

double PanelPreviewImage::getCurrentZoomLevel() const {
float PanelPreviewImage::getCurrentZoomLevel() const {
int fullWidth, fullHeight, currentWidth, currentHeight;

getSize(fullWidth, fullHeight, currentWidth, currentHeight);
if ((fullWidth <= 0) || (fullHeight <= 0) || (currentWidth <= 0) || (currentHeight <= 0))
return 1.0;
return 1.0f;

return ((double) currentWidth) / ((double) fullWidth);
return ((float) currentWidth) / ((float) fullWidth);
}

void PanelPreviewImage::zoomFit(bool onlyWidth, bool grow) {
void PanelPreviewImage::fit(bool onlyWidth, bool grow) {
int fullWidth, fullHeight, currentWidth, currentHeight;

getSize(fullWidth, fullHeight, currentWidth, currentHeight);
if ((fullWidth <= 0) || (fullHeight <= 0) || (currentWidth <= 0) || (currentHeight <= 0))
return;

double aspect = ((double) fullWidth) / ((double) fullHeight);
float aspect = ((float) fullWidth) / ((float) fullHeight);

QRect rect = _ui.imageScrollArea->contentsRect();
QRect rect = _scrollAreaImage->contentsRect();
int areaWidth = rect.width();
int areaHeight = rect.height();

Expand All @@ -329,14 +381,14 @@ void PanelPreviewImage::zoomFit(bool onlyWidth, bool grow) {
}

QSize newSize(newWidth, newHeight);
_imageLabel->setPixmap(_originalPixmap.scaled(newSize, Qt::IgnoreAspectRatio, _mode));
_imageLabel->setFixedSize(newSize);
_labelImage->setPixmap(_originalPixmap.scaled(newSize, Qt::IgnoreAspectRatio, _mode));
_labelImage->setFixedSize(newSize);

double zoomLevel = getCurrentZoomLevel() * 100;
_scaleFactor = 100 / zoomLevel;
_ui.zoomPercent->setText(QString("%1%").arg((int)zoomLevel));
float zoomLevel = getCurrentZoomLevel() * 100;
_zoomFactor = 100 / zoomLevel;
_labelZoomPercent->setText(QString("%1%").arg((int)zoomLevel));

_ui.zoomOriginal->setEnabled(true);
_buttonZoomOriginal->setEnabled(true);
}

} // End of namespace GUI

0 comments on commit 65dd700

Please sign in to comment.