diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,7 @@ widgets/ksaneoptionwidget.cpp ksaneviewer.cpp selectionitem.cpp + hiderectitem.cpp ksanedevicedialog.cpp ksanefinddevicesthread.cpp ksanewidget.cpp diff --git a/src/selectionitem.h b/src/hiderectitem.h copy from src/selectionitem.h copy to src/hiderectitem.h --- a/src/selectionitem.h +++ b/src/hiderectitem.h @@ -24,58 +24,30 @@ * License along with this program. If not, see . * * ============================================================ */ -#ifndef SELECTIONITEM_H -#define SELECTIONITEM_H -#include -#include +#ifndef HIDERECTITEM_H +#define HIDERECTITEM_H + +#include namespace KSaneIface { -class SelectionItem : public QGraphicsItem +class HideRectItem : public QGraphicsRectItem { public: - typedef enum { - None, - Top, - TopRight, - Right, - BottomRight, - Bottom, - BottomLeft, - Left, - TopLeft, - Move, - AddRemove - } Intersects; - - explicit SelectionItem(const QRectF &rect); - ~SelectionItem(); - - void setMaxRight(qreal maxRight); - void setMaxBottom(qreal maxBottom); - void setSaved(bool isSaved); - - Intersects intersects(const QPointF &point); - - void saveZoom(qreal zoom); + HideRectItem(); + QRectF rect() const; void setRect(const QRectF &rect); - QPointF fixTranslation( QPointF dp); - QRectF rect(); -public: - // Graphics Item methods - QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + qreal devicePixelRatio() const; + void setDevicePixelRatio(qreal dpr); private: - struct Private; - Private *const d; + qreal m_devicePixelRatio; }; } // NameSpace KSaneIface -#endif - +#endif // HIDERECTITEM_H diff --git a/src/selectionitem.h b/src/hiderectitem.cpp copy from src/selectionitem.h copy to src/hiderectitem.cpp --- a/src/selectionitem.h +++ b/src/hiderectitem.cpp @@ -24,58 +24,41 @@ * License along with this program. If not, see . * * ============================================================ */ -#ifndef SELECTIONITEM_H -#define SELECTIONITEM_H -#include -#include +#include "hiderectitem.h" + +#include namespace KSaneIface { -class SelectionItem : public QGraphicsItem +HideRectItem::HideRectItem() + : m_devicePixelRatio(1.0) { -public: - typedef enum { - None, - Top, - TopRight, - Right, - BottomRight, - Bottom, - BottomLeft, - Left, - TopLeft, - Move, - AddRemove - } Intersects; - - explicit SelectionItem(const QRectF &rect); - ~SelectionItem(); - - void setMaxRight(qreal maxRight); - void setMaxBottom(qreal maxBottom); - void setSaved(bool isSaved); + setOpacity(0.4); + setPen(Qt::NoPen); + setBrush(Qt::black); +} - Intersects intersects(const QPointF &point); - - void saveZoom(qreal zoom); +QRectF HideRectItem::rect() const +{ + QRectF r = QGraphicsRectItem::rect(); + return QRectF(r.topLeft() * m_devicePixelRatio, r.size() * m_devicePixelRatio); +} - void setRect(const QRectF &rect); - QPointF fixTranslation( QPointF dp); - QRectF rect(); +void HideRectItem::setRect(const QRectF &rect) +{ + QGraphicsRectItem::setRect(QRectF(rect.topLeft() / m_devicePixelRatio, rect.size() / m_devicePixelRatio)); +} -public: - // Graphics Item methods - QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; +qreal HideRectItem::devicePixelRatio() const +{ + return m_devicePixelRatio; +} -private: - struct Private; - Private *const d; -}; +void HideRectItem::setDevicePixelRatio(qreal dpr) +{ + m_devicePixelRatio = dpr; +} } // NameSpace KSaneIface - -#endif - diff --git a/src/ksaneviewer.cpp b/src/ksaneviewer.cpp --- a/src/ksaneviewer.cpp +++ b/src/ksaneviewer.cpp @@ -29,6 +29,7 @@ #include "ksaneviewer.h" #include "selectionitem.h" +#include "hiderectitem.h" #include #include @@ -65,11 +66,11 @@ QAction *zoom2FitAction; QAction *clrSelAction; - QGraphicsRectItem *hideLeft; - QGraphicsRectItem *hideRight; - QGraphicsRectItem *hideTop; - QGraphicsRectItem *hideBottom; - QGraphicsRectItem *hideArea; + HideRectItem *hideLeft; + HideRectItem *hideRight; + HideRectItem *hideTop; + HideRectItem *hideBottom; + HideRectItem *hideArea; int wheelDelta = 0; }; @@ -84,7 +85,8 @@ // Init the scene d->scene = new QGraphicsScene(this); - d->scene->setSceneRect(0, 0, img->width(), img->height()); + const auto dpr = img->devicePixelRatio(); + d->scene->setSceneRect(0, 0, img->width() / dpr, img->height() / dpr); setScene(d->scene); d->selection = new SelectionItem(QRectF()); @@ -95,29 +97,13 @@ d->selection->setRect(d->scene->sceneRect()); d->selection->setVisible(false); - d->hideTop = new QGraphicsRectItem; - d->hideBottom = new QGraphicsRectItem; - d->hideRight = new QGraphicsRectItem; - d->hideLeft = new QGraphicsRectItem; - d->hideArea = new QGraphicsRectItem; - - d->hideTop->setOpacity(0.4); - d->hideBottom->setOpacity(0.4); - d->hideRight->setOpacity(0.4); - d->hideLeft->setOpacity(0.4); + d->hideTop = new HideRectItem; + d->hideBottom = new HideRectItem; + d->hideRight = new HideRectItem; + d->hideLeft = new HideRectItem; + d->hideArea = new HideRectItem; d->hideArea->setOpacity(0.6); - d->hideTop->setPen(Qt::NoPen); - d->hideBottom->setPen(Qt::NoPen); - d->hideRight->setPen(Qt::NoPen); - d->hideLeft->setPen(Qt::NoPen); - d->hideArea->setPen(Qt::NoPen); - - d->hideTop->setBrush(QBrush(Qt::black)); - d->hideBottom->setBrush(QBrush(Qt::black)); - d->hideRight->setBrush(QBrush(Qt::black)); - d->hideLeft->setBrush(QBrush(Qt::black)); - d->scene->addItem(d->selection); d->scene->addItem(d->hideLeft); d->scene->addItem(d->hideRight); @@ -156,7 +142,10 @@ void KSaneViewer::drawBackground(QPainter *painter, const QRectF &rect) { painter->fillRect(rect, QColor(0x70, 0x70, 0x70)); - painter->drawImage(rect, *d->img, rect); + QRectF r = rect & sceneRect(); + const qreal dpr = d->img->devicePixelRatio(); + QRectF srcRect = QRectF(r.topLeft() * dpr, r.size() * dpr); + painter->drawImage(r, *d->img, srcRect); } // ------------------------------------------------------------------------ @@ -181,9 +170,18 @@ // clear zoom setMatrix(QMatrix()); - d->scene->setSceneRect(0, 0, img->width(), img->height()); + const auto dpr = img->devicePixelRatio(); + d->scene->setSceneRect(0, 0, img->width() / dpr, img->height() / dpr); d->selection->setMaxRight(img->width()); d->selection->setMaxBottom(img->height()); + + d->selection->setDevicePixelRatio(dpr); + d->hideTop->setDevicePixelRatio(dpr); + d->hideBottom->setDevicePixelRatio(dpr); + d->hideRight->setDevicePixelRatio(dpr); + d->hideLeft->setDevicePixelRatio(dpr); + d->hideArea->setDevicePixelRatio(dpr); + d->img = img; } @@ -542,7 +540,7 @@ if (e->button() == Qt::LeftButton) { d->m_left_last_x = e->x(); d->m_left_last_y = e->y(); - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); d->lastSPoint = scenePoint; if (e->modifiers() != Qt::ControlModifier) { if (!d->selection->isVisible()) { @@ -571,7 +569,7 @@ clearActiveSelection(); } - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); for (int i = 0; i < d->selectionList.size(); i++) { if (d->selectionList[i]->intersects(scenePoint) == SelectionItem::AddRemove) { d->scene->removeItem(d->selectionList[i]); @@ -588,6 +586,7 @@ if (!removed && (d->selection->intersects(scenePoint) == SelectionItem::AddRemove)) { // add the current selection SelectionItem *tmp = new SelectionItem(d->selection->rect()); + tmp->setDevicePixelRatio(d->img->devicePixelRatio()); d->selectionList.push_back(tmp); d->selectionList.back()->setSaved(true); d->selectionList.back()->saveZoom(transform().m11()); @@ -619,7 +618,7 @@ // ------------------------------------------------------------------------ void KSaneViewer::mouseMoveEvent(QMouseEvent *e) { - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); if (e->buttons()&Qt::LeftButton) { if (e->modifiers() == Qt::ControlModifier) { @@ -928,6 +927,7 @@ float selArea = (float)(wSelEnd - wSelStart) * (float)(hSelEnd - hSelStart); if (selArea > (area * MIN_AREA_SIZE)) { SelectionItem *tmp = new SelectionItem(QRect(QPoint(x1, y1), QPoint(x2, y2))); + tmp->setDevicePixelRatio(d->img->devicePixelRatio()); d->selectionList.push_back(tmp); d->selectionList.back()->setSaved(true); d->selectionList.back()->saveZoom(transform().m11()); diff --git a/src/ksanewidget_p.cpp b/src/ksanewidget_p.cpp --- a/src/ksanewidget_p.cpp +++ b/src/ksanewidget_p.cpp @@ -715,7 +715,9 @@ x = (int)(SCALED_PREVIEW_MAX_SIDE / ratio); } - m_previewImg = QImage(x, y, QImage::Format_RGB32); + const qreal dpr = q->devicePixelRatioF(); + m_previewImg = QImage(QSize(x, y) * dpr, QImage::Format_RGB32); + m_previewImg.setDevicePixelRatio(dpr); m_previewImg.fill(0xFFFFFFFF); // set the new image diff --git a/src/selectionitem.h b/src/selectionitem.h --- a/src/selectionitem.h +++ b/src/selectionitem.h @@ -65,6 +65,9 @@ QPointF fixTranslation( QPointF dp); QRectF rect(); + qreal devicePixelRatio() const; + void setDevicePixelRatio(qreal dpr); + public: // Graphics Item methods QRectF boundingRect() const override; diff --git a/src/selectionitem.cpp b/src/selectionitem.cpp --- a/src/selectionitem.cpp +++ b/src/selectionitem.cpp @@ -54,6 +54,7 @@ qreal invZoom; qreal selMargin; QRectF addRemRect; + qreal devicePixelRatio; }; SelectionItem::SelectionItem(const QRectF &rect) : QGraphicsItem(), d(new Private) @@ -79,6 +80,8 @@ d->selMargin = selMargin; d->addRemRect = QRectF(0, 0, 0, 0); + + d->devicePixelRatio = 1.0; } SelectionItem::~SelectionItem() @@ -97,7 +100,7 @@ qreal margin = addRemMargin * d->invZoom; QPointF pMargin = addRemMarginPoint * d->invZoom; - d->addRemRect = QRectF(d->rect.center() - pMargin, QSizeF(margin * 2.0, margin * 2.0)); + d->addRemRect = QRectF(d->rect.center() / d->devicePixelRatio - pMargin, QSizeF(margin * 2.0, margin * 2.0)); d->penAddRemFg.setWidthF(3.0 * d->invZoom); } @@ -193,10 +196,7 @@ update(); } - if ((point.x() > d->addRemRect.left()) && - (point.x() < d->addRemRect.right()) && - (point.y() > d->addRemRect.top()) && - (point.y() < d->addRemRect.bottom())) { + if (d->addRemRect.contains(point / d->devicePixelRatio)) { return AddRemove; } return Move; @@ -225,7 +225,7 @@ // calculate the add/remove rectangle qreal margin = addRemMargin * d->invZoom; QPointF pMargin = addRemMarginPoint * d->invZoom; - d->addRemRect = QRectF(d->rect.center() - pMargin, QSizeF(margin * 2, margin * 2)); + d->addRemRect = QRectF(d->rect.center() / d->devicePixelRatio - pMargin, QSizeF(margin * 2, margin * 2)); } QPointF SelectionItem::fixTranslation(QPointF dp) @@ -250,46 +250,48 @@ return d->rect; } -QRectF SelectionItem::boundingRect() const +qreal SelectionItem::devicePixelRatio() const { - QRectF tmp(d->rect.topLeft() - boundMargin, d->rect.bottomRight() + boundMargin); - if (tmp.top() > d->addRemRect.top()) { - tmp.setTop(d->addRemRect.top()); - } - if (tmp.left() > d->addRemRect.left()) { - tmp.setLeft(d->addRemRect.left()); - } - - if (tmp.bottom() < d->addRemRect.bottom()) { - tmp.setBottom(d->addRemRect.bottom()); - } + return d->devicePixelRatio; +} - if (tmp.right() < d->addRemRect.right()) { - tmp.setRight(d->addRemRect.right()); - } +void SelectionItem::setDevicePixelRatio(qreal dpr) +{ + d->devicePixelRatio = dpr; + d->penDark.setWidthF(1 / dpr); + d->penLight.setWidthF(1 / dpr); + d->penAddRemFg.setWidthF(1 / dpr); +} - return tmp; +QRectF SelectionItem::boundingRect() const +{ + const auto dpr = d->devicePixelRatio; + QRectF tmp(d->rect.topLeft() / dpr - boundMargin, d->rect.bottomRight() / dpr + boundMargin); + return tmp.united(d->addRemRect); } void SelectionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { + const auto dpr = d->devicePixelRatio; + QRectF rect(d->rect.topLeft() / dpr, d->rect.size() / dpr); + painter->setPen(d->penDark); - painter->drawRect(d->rect); + painter->drawRect(rect); painter->setPen(d->penLight); - painter->drawRect(d->rect); + painter->drawRect(rect); if (d->showAddRem) { painter->fillRect(d->addRemRect, QBrush(Qt::white)); - QLineF minus(d->addRemRect.left() + 3 * d->invZoom, d->rect.center().y(), - d->addRemRect.right() - 3 * d->invZoom, d->rect.center().y()); + QLineF minus(d->addRemRect.left() + 3 * d->invZoom, d->addRemRect.center().y(), + d->addRemRect.right() - 3 * d->invZoom, d->addRemRect.center().y()); painter->setPen(d->penAddRemFg); painter->drawLine(minus); if (!d->isSaved) { - QLineF plus(d->rect.center().x(), d->addRemRect.top() + 3 * d->invZoom, - d->rect.center().x(), d->addRemRect.bottom() - 3 * d->invZoom); + QLineF plus(d->addRemRect.center().x(), d->addRemRect.top() + 3 * d->invZoom, + d->addRemRect.center().x(), d->addRemRect.bottom() - 3 * d->invZoom); painter->drawLine(plus); } }