yacreader/YACReader/magnifying_glass.cpp
Luis Ángel San Martín a7e3c41f34 QLabel QPixmap *pixmap() method is deprecated
const QPixmap should perform as fast as a pointer
there is a replacement version for Qt5 but it requires Qt5.15, so we are using indirection witch is unsafer but it should be ok as all the action is happen in the main thread
2021-10-19 00:00:08 +02:00

271 lines
7.3 KiB
C++

#include "magnifying_glass.h"
#include "viewer.h"
#include "configuration.h"
#include "shortcuts_manager.h"
#include <QScrollBar>
MagnifyingGlass::MagnifyingGlass(int w, int h, QWidget *parent)
: QLabel(parent), zoomLevel(0.5)
{
setup(QSize(w, h));
}
MagnifyingGlass::MagnifyingGlass(const QSize &size, QWidget *parent)
: QLabel(parent), zoomLevel(0.5)
{
setup(size);
}
void MagnifyingGlass::setup(const QSize &size)
{
resize(size);
setScaledContents(true);
setMouseTracking(true);
setCursor(QCursor(QBitmap(1, 1), QBitmap(1, 1)));
}
void MagnifyingGlass::mouseMoveEvent(QMouseEvent *event)
{
updateImage();
event->accept();
}
void MagnifyingGlass::updateImage(int x, int y)
{
// image section augmented
int zoomWidth = static_cast<int>(width() * zoomLevel);
int zoomHeight = static_cast<int>(height() * zoomLevel);
auto p = (Viewer *)parent();
int currentPos = p->verticalScrollBar()->sliderPosition();
const QPixmap image = p->pixmap();
int iWidth = image.width();
int iHeight = image.height();
float wFactor = static_cast<float>(iWidth) / p->widget()->width();
float hFactor = static_cast<float>(iHeight) / p->widget()->height();
zoomWidth *= wFactor;
zoomHeight *= hFactor;
if (p->verticalScrollBar()->minimum() == p->verticalScrollBar()->maximum()) {
int xp = static_cast<int>(((x - p->widget()->pos().x()) * wFactor) - zoomWidth / 2);
int yp = static_cast<int>((y - p->widget()->pos().y() + currentPos) * hFactor - zoomHeight / 2);
int xOffset = 0;
int yOffset = 0;
int zw = zoomWidth;
int zh = zoomHeight;
// int wOffset,hOffset=0;
bool outImage = false;
if (xp < 0) {
xOffset = -xp;
xp = 0;
zw = zw - xOffset;
outImage = true;
}
if (yp < 0) {
yOffset = -yp;
yp = 0;
zh = zh - yOffset;
outImage = true;
}
if (xp + zoomWidth >= image.width()) {
zw -= xp + zw - image.width();
outImage = true;
}
if (yp + zoomHeight >= image.height()) {
zh -= yp + zh - image.height();
outImage = true;
}
if (outImage) {
QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32);
img.setDevicePixelRatio(devicePixelRatio());
img.fill(Configuration::getConfiguration().getBackgroundColor());
if (zw > 0 && zh > 0) {
QPainter painter(&img);
painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh));
}
setPixmap(QPixmap().fromImage(img));
} else
setPixmap(image.copy(xp, yp, zoomWidth, zoomHeight));
} else {
int xp = static_cast<int>(((x - p->widget()->pos().x()) * wFactor) - zoomWidth / 2);
int yp = static_cast<int>((y + currentPos) * hFactor - zoomHeight / 2);
int xOffset = 0;
int yOffset = 0;
int zw = zoomWidth;
int zh = zoomHeight;
// int wOffset,hOffset=0;
bool outImage = false;
if (xp < 0) {
xOffset = -xp;
xp = 0;
zw = zw - xOffset;
outImage = true;
}
if (yp < 0) {
yOffset = -yp;
yp = 0;
zh = zh - yOffset;
outImage = true;
}
if (xp + zoomWidth >= image.width()) {
zw -= xp + zw - image.width();
outImage = true;
}
if (yp + zoomHeight >= image.height()) {
zh -= yp + zh - image.height();
outImage = true;
}
if (outImage) {
QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32);
img.setDevicePixelRatio(devicePixelRatio());
img.fill(Configuration::getConfiguration().getBackgroundColor());
if (zw > 0 && zh > 0) {
QPainter painter(&img);
painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh));
}
setPixmap(QPixmap().fromImage(img));
} else
setPixmap(image.copy(xp, yp, zoomWidth, zoomHeight));
}
move(static_cast<int>(x - float(width()) / 2), static_cast<int>(y - float(height()) / 2));
}
void MagnifyingGlass::updateImage()
{
if (isVisible()) {
QPoint p = QPoint(cursor().pos().x(), cursor().pos().y());
p = this->parentWidget()->mapFromGlobal(p);
updateImage(p.x(), p.y());
}
}
void MagnifyingGlass::wheelEvent(QWheelEvent *event)
{
switch (event->modifiers()) {
// size
case Qt::NoModifier:
if (event->angleDelta().y() < 0)
sizeUp();
else
sizeDown();
break;
// size height
case Qt::ControlModifier:
if (event->angleDelta().y() < 0)
heightUp();
else
heightDown();
break;
// size width
case Qt::AltModifier:
if (event->angleDelta().y() < 0)
widthUp();
else
widthDown();
break;
// zoom level
case Qt::ShiftModifier:
if (event->angleDelta().y() < 0)
zoomIn();
else
zoomOut();
break;
}
updateImage();
event->setAccepted(true);
}
void MagnifyingGlass::zoomIn()
{
if (zoomLevel > 0.2f)
zoomLevel -= 0.025f;
}
void MagnifyingGlass::zoomOut()
{
if (zoomLevel < 0.9f)
zoomLevel += 0.025f;
}
void MagnifyingGlass::sizeUp()
{
auto p = (Viewer *)parent();
if (width() < (p->width() * 0.90f))
resize(width() + 30, height() + 15);
}
void MagnifyingGlass::sizeDown()
{
if (width() > 175)
resize(width() - 30, height() - 15);
}
void MagnifyingGlass::heightUp()
{
auto p = (Viewer *)parent();
if (height() < (p->height() * 0.90f))
resize(width(), height() + 15);
}
void MagnifyingGlass::heightDown()
{
if (height() > 80)
resize(width(), height() - 15);
}
void MagnifyingGlass::widthUp()
{
auto p = (Viewer *)parent();
if (width() < (p->width() * 0.90f))
resize(width() + 30, height());
}
void MagnifyingGlass::widthDown()
{
if (width() > 175)
resize(width() - 30, height());
}
void MagnifyingGlass::keyPressEvent(QKeyEvent *event)
{
bool validKey = false;
int _key = event->key();
Qt::KeyboardModifiers modifiers = event->modifiers();
if (modifiers & Qt::ShiftModifier)
_key |= Qt::SHIFT;
if (modifiers & Qt::ControlModifier)
_key |= Qt::CTRL;
if (modifiers & Qt::MetaModifier)
_key |= Qt::META;
if (modifiers & Qt::AltModifier)
_key |= Qt::ALT;
QKeySequence key(_key);
if (key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_UP_MGLASS_ACTION_Y)) {
sizeUp();
validKey = true;
}
else if (key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_DOWN_MGLASS_ACTION_Y)) {
sizeDown();
validKey = true;
}
else if (key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_IN_MGLASS_ACTION_Y)) {
zoomIn();
validKey = true;
}
else if (key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_OUT_MGLASS_ACTION_Y)) {
zoomOut();
validKey = true;
}
if (validKey) {
updateImage();
event->setAccepted(true);
}
}