mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-19 13:10:51 +01:00
Move/Zoom functionality
This commit is contained in:
parent
d4087eae1a
commit
4d7eaf7587
@ -27,7 +27,7 @@ namespace pdf
|
|||||||
PDFDrawSpaceController::PDFDrawSpaceController(QObject* parent) :
|
PDFDrawSpaceController::PDFDrawSpaceController(QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_document(nullptr),
|
m_document(nullptr),
|
||||||
m_pageLayoutMode(PageLayout::SinglePage),
|
m_pageLayoutMode(PageLayout::OneColumn),
|
||||||
m_verticalSpacingMM(5.0),
|
m_verticalSpacingMM(5.0),
|
||||||
m_horizontalSpacingMM(1.0)
|
m_horizontalSpacingMM(1.0)
|
||||||
{
|
{
|
||||||
@ -353,6 +353,10 @@ void PDFDrawWidgetProxy::init(PDFWidget* widget)
|
|||||||
m_horizontalScrollbar = widget->getHorizontalScrollbar();
|
m_horizontalScrollbar = widget->getHorizontalScrollbar();
|
||||||
m_verticalScrollbar = widget->getVerticalScrollbar();
|
m_verticalScrollbar = widget->getVerticalScrollbar();
|
||||||
|
|
||||||
|
connect(m_horizontalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged);
|
||||||
|
connect(m_verticalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onVerticalScrollbarValueChanged);
|
||||||
|
connect(this, &PDFDrawWidgetProxy::drawSpaceChanged, m_widget, QOverload<void>::of(&PDFDrawWidget::update));
|
||||||
|
|
||||||
// We must update the draw space - widget has been set
|
// We must update the draw space - widget has been set
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@ -426,8 +430,9 @@ void PDFDrawWidgetProxy::update()
|
|||||||
m_horizontalScrollbar->setMinimum(0);
|
m_horizontalScrollbar->setMinimum(0);
|
||||||
m_horizontalScrollbar->setMaximum(horizontalDifference);
|
m_horizontalScrollbar->setMaximum(horizontalDifference);
|
||||||
|
|
||||||
m_horizontalOffset = qBound<PDFInteger>(0, m_horizontalOffset, horizontalDifference);
|
m_horizontalOffsetRange = Range<PDFInteger>(-horizontalDifference, 0);
|
||||||
m_horizontalScrollbar->setValue(m_horizontalOffset);
|
m_horizontalOffset = m_horizontalOffsetRange.bound(m_horizontalOffset);
|
||||||
|
m_horizontalScrollbar->setValue(-m_horizontalOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -435,6 +440,7 @@ void PDFDrawWidgetProxy::update()
|
|||||||
// We set the offset to the half of available empty space.
|
// We set the offset to the half of available empty space.
|
||||||
m_horizontalScrollbar->setVisible(false);
|
m_horizontalScrollbar->setVisible(false);
|
||||||
m_horizontalOffset = -horizontalDifference / 2;
|
m_horizontalOffset = -horizontalDifference / 2;
|
||||||
|
m_horizontalOffsetRange = Range<PDFInteger>(m_horizontalOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical scrollbar - has two meanings, in block mode, it switches between blocks,
|
// Vertical scrollbar - has two meanings, in block mode, it switches between blocks,
|
||||||
@ -465,6 +471,12 @@ void PDFDrawWidgetProxy::update()
|
|||||||
if (verticalDifference < 0)
|
if (verticalDifference < 0)
|
||||||
{
|
{
|
||||||
m_verticalOffset = -verticalDifference / 2;
|
m_verticalOffset = -verticalDifference / 2;
|
||||||
|
m_verticalOffsetRange = Range<PDFInteger>(m_verticalOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_verticalOffsetRange = Range<PDFInteger>(-verticalDifference, 0);
|
||||||
|
m_verticalOffset = m_verticalOffsetRange.bound(m_verticalOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -489,13 +501,15 @@ void PDFDrawWidgetProxy::update()
|
|||||||
m_verticalScrollbar->setSingleStep(singleStep);
|
m_verticalScrollbar->setSingleStep(singleStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_verticalOffset = qBound<PDFInteger>(0, m_verticalOffset, verticalDifference);
|
m_verticalOffsetRange = Range<PDFInteger>(-verticalDifference, 0);
|
||||||
m_verticalScrollbar->setValue(m_verticalOffset);
|
m_verticalOffset = m_verticalOffsetRange.bound(m_verticalOffset);
|
||||||
|
m_verticalScrollbar->setValue(-m_verticalOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_verticalScrollbar->setVisible(false);
|
m_verticalScrollbar->setVisible(false);
|
||||||
m_verticalOffset = -verticalDifference / 2;
|
m_verticalOffset = -verticalDifference / 2;
|
||||||
|
m_verticalOffsetRange = Range<PDFInteger>(m_verticalOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,10 +531,105 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
|
|||||||
{
|
{
|
||||||
// Clear the page space by white color
|
// Clear the page space by white color
|
||||||
painter->fillRect(placedRect, Qt::white);
|
painter->fillRect(placedRect, Qt::white);
|
||||||
|
|
||||||
|
QFont font = m_widget->font();
|
||||||
|
font.setPixelSize(placedRect.height() * 0.75);
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->drawText(placedRect, Qt::AlignCenter, QString::number(item.pageIndex + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::performOperation(Operation operation)
|
||||||
|
{
|
||||||
|
switch (operation)
|
||||||
|
{
|
||||||
|
case NavigateDocumentStart:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NavigateDocumentEnd:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(m_verticalScrollbar->maximum());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NavigateNextPage:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(m_verticalScrollbar->value() + m_verticalScrollbar->pageStep());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NavigatePreviousPage:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(m_verticalScrollbar->value() - m_verticalScrollbar->pageStep());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NavigateNextStep:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(m_verticalScrollbar->value() + m_verticalScrollbar->singleStep());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NavigatePreviousStep:
|
||||||
|
{
|
||||||
|
if (m_verticalScrollbar->isVisible())
|
||||||
|
{
|
||||||
|
m_verticalScrollbar->setValue(m_verticalScrollbar->value() - m_verticalScrollbar->singleStep());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::scrollByPixels(QPoint offset)
|
||||||
|
{
|
||||||
|
setHorizontalOffset(m_horizontalOffset + offset.x());
|
||||||
|
setVerticalOffset(m_verticalOffset + offset.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::zoom(PDFReal zoom)
|
||||||
|
{
|
||||||
|
const PDFReal clampedZoom = qBound(MIN_ZOOM, zoom, MAX_ZOOM);
|
||||||
|
if (m_zoom != clampedZoom)
|
||||||
|
{
|
||||||
|
const PDFReal oldHorizontalOffsetMM = m_horizontalOffset * m_pixelToDeviceSpaceUnit;
|
||||||
|
const PDFReal oldVerticalOffsetMM = m_verticalOffset * m_pixelToDeviceSpaceUnit;
|
||||||
|
|
||||||
|
m_zoom = clampedZoom;
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
// Try to restore offsets, so we are in the same place
|
||||||
|
setHorizontalOffset(oldHorizontalOffsetMM * m_deviceSpaceUnitToPixel);
|
||||||
|
setVerticalOffset(oldVerticalOffsetMM * m_deviceSpaceUnitToPixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QRectF PDFDrawWidgetProxy::fromDeviceSpace(const QRectF& rect) const
|
QRectF PDFDrawWidgetProxy::fromDeviceSpace(const QRectF& rect) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(rect.isValid());
|
Q_ASSERT(rect.isValid());
|
||||||
@ -550,4 +659,78 @@ bool PDFDrawWidgetProxy::isBlockMode() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged(int value)
|
||||||
|
{
|
||||||
|
if (!m_updateDisabled && !m_horizontalScrollbar->isHidden())
|
||||||
|
{
|
||||||
|
setHorizontalOffset(-value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::onVerticalScrollbarValueChanged(int value)
|
||||||
|
{
|
||||||
|
if (!m_updateDisabled && !m_verticalScrollbar->isHidden())
|
||||||
|
{
|
||||||
|
if (isBlockMode())
|
||||||
|
{
|
||||||
|
setBlockIndex(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setVerticalOffset(-value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::setHorizontalOffset(int value)
|
||||||
|
{
|
||||||
|
const PDFInteger horizontalOffset = m_horizontalOffsetRange.bound(value);
|
||||||
|
|
||||||
|
if (m_horizontalOffset != horizontalOffset)
|
||||||
|
{
|
||||||
|
m_horizontalOffset = horizontalOffset;
|
||||||
|
updateHorizontalScrollbarFromOffset();
|
||||||
|
emit drawSpaceChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::setVerticalOffset(int value)
|
||||||
|
{
|
||||||
|
const PDFInteger verticalOffset = m_verticalOffsetRange.bound(value);
|
||||||
|
|
||||||
|
if (m_verticalOffset != verticalOffset)
|
||||||
|
{
|
||||||
|
m_verticalOffset = verticalOffset;
|
||||||
|
updateVerticalScrollbarFromOffset();
|
||||||
|
emit drawSpaceChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::setBlockIndex(int index)
|
||||||
|
{
|
||||||
|
if (m_currentBlock != index)
|
||||||
|
{
|
||||||
|
m_currentBlock = static_cast<size_t>(index);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::updateHorizontalScrollbarFromOffset()
|
||||||
|
{
|
||||||
|
if (!m_horizontalScrollbar->isHidden())
|
||||||
|
{
|
||||||
|
PDFBoolGuard guard(m_updateDisabled);
|
||||||
|
m_horizontalScrollbar->setValue(-m_horizontalOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::updateVerticalScrollbarFromOffset()
|
||||||
|
{
|
||||||
|
if (!m_verticalScrollbar->isHidden() && !isBlockMode())
|
||||||
|
{
|
||||||
|
PDFBoolGuard guard(m_updateDisabled);
|
||||||
|
m_verticalScrollbar->setValue(-m_verticalOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#ifndef PDFDRAWSPACECONTROLLER_H
|
#ifndef PDFDRAWSPACECONTROLLER_H
|
||||||
#define PDFDRAWSPACECONTROLLER_H
|
#define PDFDRAWSPACECONTROLLER_H
|
||||||
|
|
||||||
|
#include "pdfglobal.h"
|
||||||
#include "pdfdocument.h"
|
#include "pdfdocument.h"
|
||||||
|
|
||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
@ -115,7 +116,7 @@ private:
|
|||||||
|
|
||||||
/// This is a proxy class to draw space controller using widget. We have two spaces, pixel space
|
/// This is a proxy class to draw space controller using widget. We have two spaces, pixel space
|
||||||
/// (on the controlled widget) and device space (device is draw space controller).
|
/// (on the controlled widget) and device space (device is draw space controller).
|
||||||
class PDFDrawWidgetProxy : public QObject
|
class PDFFORQTLIBSHARED_EXPORT PDFDrawWidgetProxy : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -138,6 +139,36 @@ public:
|
|||||||
/// \param rect Rectangle in which the content is painted
|
/// \param rect Rectangle in which the content is painted
|
||||||
void draw(QPainter* painter, QRect rect);
|
void draw(QPainter* painter, QRect rect);
|
||||||
|
|
||||||
|
enum Operation
|
||||||
|
{
|
||||||
|
NavigateDocumentStart,
|
||||||
|
NavigateDocumentEnd,
|
||||||
|
NavigateNextPage,
|
||||||
|
NavigatePreviousPage,
|
||||||
|
NavigateNextStep,
|
||||||
|
NavigatePreviousStep
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Performs the desired operation (for example navigation).
|
||||||
|
/// \param operation Operation to be performed
|
||||||
|
void performOperation(Operation operation);
|
||||||
|
|
||||||
|
/// Scrolls by pixels, if it is possible. If it is not possible to scroll,
|
||||||
|
/// then nothing happens.
|
||||||
|
/// \param offset Offset in pixels
|
||||||
|
void scrollByPixels(QPoint offset);
|
||||||
|
|
||||||
|
/// Sets the zoom. Tries to preserve current offsets (so the current visible
|
||||||
|
/// area will be visible after the zoom).
|
||||||
|
/// \param zoom New zoom
|
||||||
|
void zoom(PDFReal zoom);
|
||||||
|
|
||||||
|
/// Returns current zoom from widget space to device space. So, for example 2.00 corresponds to 200% zoom,
|
||||||
|
/// and each 1 cm of widget area corresponds to 0.5 cm of the device space area.
|
||||||
|
PDFReal getZoom() const { return m_zoom; }
|
||||||
|
|
||||||
|
static constexpr PDFReal ZOOM_STEP = 1.2;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void drawSpaceChanged();
|
void drawSpaceChanged();
|
||||||
|
|
||||||
@ -181,6 +212,29 @@ private:
|
|||||||
/// or continuous mode (single block with continuous list of separated pages).
|
/// or continuous mode (single block with continuous list of separated pages).
|
||||||
bool isBlockMode() const;
|
bool isBlockMode() const;
|
||||||
|
|
||||||
|
void onHorizontalScrollbarValueChanged(int value);
|
||||||
|
void onVerticalScrollbarValueChanged(int value);
|
||||||
|
|
||||||
|
void setHorizontalOffset(int value);
|
||||||
|
void setVerticalOffset(int value);
|
||||||
|
void setBlockIndex(int index);
|
||||||
|
|
||||||
|
void updateHorizontalScrollbarFromOffset();
|
||||||
|
void updateVerticalScrollbarFromOffset();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Range
|
||||||
|
{
|
||||||
|
constexpr inline Range() : min(T()), max(T()) { }
|
||||||
|
constexpr inline Range(T value) : min(value), max(value) { }
|
||||||
|
constexpr inline Range(T min, T max) : min(min), max(max) { }
|
||||||
|
|
||||||
|
T min;
|
||||||
|
T max;
|
||||||
|
|
||||||
|
constexpr inline T bound(T value) { return qBound(min, value, max); }
|
||||||
|
};
|
||||||
|
|
||||||
/// Flag, disables the update
|
/// Flag, disables the update
|
||||||
bool m_updateDisabled;
|
bool m_updateDisabled;
|
||||||
|
|
||||||
@ -205,10 +259,16 @@ private:
|
|||||||
/// with this vertical offset)
|
/// with this vertical offset)
|
||||||
PDFInteger m_verticalOffset;
|
PDFInteger m_verticalOffset;
|
||||||
|
|
||||||
|
/// Range of vertical offset
|
||||||
|
Range<PDFInteger> m_verticalOffsetRange;
|
||||||
|
|
||||||
/// Actual horizontal offset of the draw space area in the widget (so block will be drawn
|
/// Actual horizontal offset of the draw space area in the widget (so block will be drawn
|
||||||
/// with this horizontal offset)
|
/// with this horizontal offset)
|
||||||
PDFInteger m_horizontalOffset;
|
PDFInteger m_horizontalOffset;
|
||||||
|
|
||||||
|
/// Range for horizontal offset
|
||||||
|
Range<PDFInteger> m_horizontalOffsetRange;
|
||||||
|
|
||||||
/// Draw space controller
|
/// Draw space controller
|
||||||
PDFDrawSpaceController* m_controller;
|
PDFDrawSpaceController* m_controller;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -62,7 +63,8 @@ void PDFWidget::setDocument(const PDFDocument* document)
|
|||||||
|
|
||||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
m_widget(widget)
|
m_widget(widget),
|
||||||
|
m_mouseOperation(MouseOperation::None)
|
||||||
{
|
{
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
}
|
}
|
||||||
@ -99,21 +101,125 @@ void PDFDrawWidget::keyPressEvent(QKeyEvent* event)
|
|||||||
// Vertical navigation
|
// Vertical navigation
|
||||||
if (verticalScrollbar->isVisible())
|
if (verticalScrollbar->isVisible())
|
||||||
{
|
{
|
||||||
if (event->matches(QKeySequence::MoveToStartOfDocument))
|
constexpr std::pair<QKeySequence::StandardKey, PDFDrawWidgetProxy::Operation> keyToOperations[] =
|
||||||
{
|
{
|
||||||
verticalScrollbar->setValue(0);
|
{ QKeySequence::MoveToStartOfDocument, PDFDrawWidgetProxy::NavigateDocumentStart },
|
||||||
}
|
{ QKeySequence::MoveToEndOfDocument, PDFDrawWidgetProxy::NavigateDocumentEnd },
|
||||||
else if (event->matches(QKeySequence::MoveToEndOfDocument))
|
{ QKeySequence::MoveToNextPage, PDFDrawWidgetProxy::NavigateNextPage },
|
||||||
|
{ QKeySequence::MoveToPreviousPage, PDFDrawWidgetProxy::NavigatePreviousPage },
|
||||||
|
{ QKeySequence::MoveToNextLine, PDFDrawWidgetProxy::NavigateNextStep },
|
||||||
|
{ QKeySequence::MoveToPreviousLine, PDFDrawWidgetProxy::NavigatePreviousStep }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const std::pair<QKeySequence::StandardKey, PDFDrawWidgetProxy::Operation>& keyToOperation : keyToOperations)
|
||||||
{
|
{
|
||||||
verticalScrollbar->setValue(verticalScrollbar->maximum());
|
if (event->matches(keyToOperation.first))
|
||||||
}
|
{
|
||||||
else if (event->matches(QKeySequence::MoveToNextPage))
|
m_widget->getDrawWidgetProxy()->performOperation(keyToOperation.second);
|
||||||
{
|
}
|
||||||
verticalScrollbar->setValue(verticalScrollbar->value() + verticalScrollbar->pageStep());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidget::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
m_mouseOperation = MouseOperation::Translate;
|
||||||
|
m_lastMousePosition = event->pos();
|
||||||
|
setCursor(Qt::ClosedHandCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
performMouseOperation(event->pos());
|
||||||
|
|
||||||
|
switch (m_mouseOperation)
|
||||||
|
{
|
||||||
|
case MouseOperation::None:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseOperation::Translate:
|
||||||
|
{
|
||||||
|
m_mouseOperation = MouseOperation::None;
|
||||||
|
unsetCursor();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidget::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
performMouseOperation(event->pos());
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||||
|
{
|
||||||
|
Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers();
|
||||||
|
|
||||||
|
if (keyboardModifiers.testFlag(Qt::ControlModifier))
|
||||||
|
{
|
||||||
|
// Zoom in/Zoom out
|
||||||
|
const int angleDeltaY = event->angleDelta().y();
|
||||||
|
const PDFReal zoom = m_widget->getDrawWidgetProxy()->getZoom();
|
||||||
|
const PDFReal zoomStep = std::pow(PDFDrawWidgetProxy::ZOOM_STEP, static_cast<PDFReal>(angleDeltaY) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep));
|
||||||
|
const PDFReal newZoom = zoom * zoomStep;
|
||||||
|
m_widget->getDrawWidgetProxy()->zoom(newZoom);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move Up/Down. Angle is negative, if wheel is scrolled down. First we try to scroll by pixel delta.
|
||||||
|
// Otherwise we compute scroll using angle.
|
||||||
|
QPoint scrollByPixels = event->pixelDelta();
|
||||||
|
if (scrollByPixels.isNull())
|
||||||
|
{
|
||||||
|
const QPoint angleDelta = event->angleDelta();
|
||||||
|
const bool shiftModifier = keyboardModifiers.testFlag(Qt::ShiftModifier);
|
||||||
|
const int stepVertical = shiftModifier ? m_widget->getVerticalScrollbar()->pageStep() : m_widget->getVerticalScrollbar()->singleStep();
|
||||||
|
const int stepHorizontal = shiftModifier ? m_widget->getHorizontalScrollbar()->pageStep() : m_widget->getHorizontalScrollbar()->singleStep();
|
||||||
|
|
||||||
|
const int scrollVertical = stepVertical * static_cast<PDFReal>(angleDelta.y()) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep);
|
||||||
|
const int scrollHorizontal = stepHorizontal * static_cast<PDFReal>(angleDelta.x()) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep);
|
||||||
|
|
||||||
|
scrollByPixels = QPoint(scrollHorizontal, scrollVertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_widget->getDrawWidgetProxy()->scrollByPixels(scrollByPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidget::performMouseOperation(QPoint currentMousePosition)
|
||||||
|
{
|
||||||
|
switch (m_mouseOperation)
|
||||||
|
{
|
||||||
|
case MouseOperation::None:
|
||||||
|
// No operation performed
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseOperation::Translate:
|
||||||
|
{
|
||||||
|
QPoint difference = currentMousePosition - m_lastMousePosition;
|
||||||
|
m_widget->getDrawWidgetProxy()->scrollByPixels(difference);
|
||||||
|
m_lastMousePosition = currentMousePosition;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -69,9 +69,25 @@ protected:
|
|||||||
virtual void paintEvent(QPaintEvent* event) override;
|
virtual void paintEvent(QPaintEvent* event) override;
|
||||||
virtual void resizeEvent(QResizeEvent* event) override;
|
virtual void resizeEvent(QResizeEvent* event) override;
|
||||||
virtual void keyPressEvent(QKeyEvent* event) override;
|
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
virtual void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
|
virtual void wheelEvent(QWheelEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class MouseOperation
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Translate
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Performs the mouse operation (under the current mouse position)
|
||||||
|
/// \param currentMousePosition Current position of the mouse
|
||||||
|
void performMouseOperation(QPoint currentMousePosition);
|
||||||
|
|
||||||
PDFWidget* m_widget;
|
PDFWidget* m_widget;
|
||||||
|
QPoint m_lastMousePosition;
|
||||||
|
MouseOperation m_mouseOperation;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "pdfvisitor.h"
|
#include "pdfvisitor.h"
|
||||||
#include "pdfstreamfilters.h"
|
#include "pdfstreamfilters.h"
|
||||||
#include "pdfdrawwidget.h"
|
#include "pdfdrawwidget.h"
|
||||||
|
#include "pdfdrawspacecontroller.h"
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -50,6 +51,26 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) :
|
|||||||
connect(ui->actionClose, &QAction::triggered, this, &PDFViewerMainWindow::onActionCloseTriggered);
|
connect(ui->actionClose, &QAction::triggered, this, &PDFViewerMainWindow::onActionCloseTriggered);
|
||||||
connect(ui->actionQuit, &QAction::triggered, this, &PDFViewerMainWindow::onActionQuitTriggered);
|
connect(ui->actionQuit, &QAction::triggered, this, &PDFViewerMainWindow::onActionQuitTriggered);
|
||||||
|
|
||||||
|
auto createGoToAction = [this](QMenu* menu, QString text, QKeySequence::StandardKey key, pdf::PDFDrawWidgetProxy::Operation operation)
|
||||||
|
{
|
||||||
|
QAction* action = new QAction(text, this);
|
||||||
|
action->setShortcut(key);
|
||||||
|
menu->addAction(action);
|
||||||
|
|
||||||
|
auto onTriggered = [this, operation]()
|
||||||
|
{
|
||||||
|
m_pdfWidget->getDrawWidgetProxy()->performOperation(operation);
|
||||||
|
};
|
||||||
|
connect(action, &QAction::triggered, this, onTriggered);
|
||||||
|
};
|
||||||
|
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to document start"), QKeySequence::MoveToStartOfDocument, pdf::PDFDrawWidgetProxy::NavigateDocumentStart);
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to document end"), QKeySequence::MoveToEndOfDocument, pdf::PDFDrawWidgetProxy::NavigateDocumentEnd);
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to next page"), QKeySequence::MoveToNextPage, pdf::PDFDrawWidgetProxy::NavigateNextPage);
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to previous page"), QKeySequence::MoveToPreviousPage, pdf::PDFDrawWidgetProxy::NavigatePreviousPage);
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to next line"), QKeySequence::MoveToNextLine, pdf::PDFDrawWidgetProxy::NavigateNextStep);
|
||||||
|
createGoToAction(ui->menuGoTo, tr("Go to previous line"), QKeySequence::MoveToPreviousLine, pdf::PDFDrawWidgetProxy::NavigatePreviousStep);
|
||||||
|
|
||||||
m_pdfWidget = new pdf::PDFWidget(this);
|
m_pdfWidget = new pdf::PDFWidget(this);
|
||||||
setCentralWidget(m_pdfWidget);
|
setCentralWidget(m_pdfWidget);
|
||||||
setFocusProxy(m_pdfWidget);
|
setFocusProxy(m_pdfWidget);
|
||||||
|
@ -31,7 +31,13 @@
|
|||||||
<addaction name="actionClose"/>
|
<addaction name="actionClose"/>
|
||||||
<addaction name="actionQuit"/>
|
<addaction name="actionQuit"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuGoTo">
|
||||||
|
<property name="title">
|
||||||
|
<string>Go To</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuGoTo"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QToolBar" name="mainToolBar">
|
<widget class="QToolBar" name="mainToolBar">
|
||||||
<attribute name="toolBarArea">
|
<attribute name="toolBarArea">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user