File indexing completed on 2024-05-12 12:58:01

0001 /*
0002  * This file is part of the KDE project
0003  *
0004  * SPDX-FileCopyrightText: 2013 Arjen Hiemstra <ahiemstra@heimr.nl>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.0-or-later
0007  *
0008  */
0009 
0010 #ifndef CALLIGRA_COMPONENTS_VIEWCONTROLLER_H
0011 #define CALLIGRA_COMPONENTS_VIEWCONTROLLER_H
0012 
0013 #include <QQuickItem>
0014 
0015 namespace Calligra {
0016 namespace Components {
0017 
0018 class View;
0019 
0020 /**
0021  * \brief Provides an object to control the document transformation within a View.
0022  *
0023  * Due to API restrictions it is not easily possible to inherit Flickable's behaviour
0024  * in custom QtQuick items. This object works around that by providing an item that
0025  * can be put inside a Flickable and will scroll a View object based on the Flickable's
0026  * scrolling.
0027  *
0028  * In addition, this object controls the zoom level of a view. It can clamps zoom to a
0029  * minimum and maximum value and can optionally use an image during zoom operations to
0030  * accelerate the zoom operation, since zooming an actual document can be an expensive
0031  * operation.
0032  *
0033  * \note This object will control its own width and height as well as the contentWidth
0034  * and contentHeight of #flickable. While it is possible to put this item outside of a
0035  * flickable this is not recommended.
0036  */
0037 
0038 class ViewController : public QQuickItem
0039 {
0040     Q_OBJECT
0041     /**
0042      * \property view
0043      * \brief The view to control.
0044      *
0045      * \default null
0046      * \get view() const
0047      * \set setView()
0048      * \notify viewChanged()
0049      */
0050     Q_PROPERTY(Calligra::Components::View* view READ view WRITE setView NOTIFY viewChanged)
0051     /**
0052      * \property flickable
0053      * \brief The flickable that is used to control scrolling.
0054      *
0055      * \default null
0056      * \get flickable() const
0057      * \set setFlickable()
0058      * \notify flickableChanged()
0059      */
0060     Q_PROPERTY(QQuickItem* flickable READ flickable WRITE setFlickable NOTIFY flickableChanged)
0061     /**
0062      * \property minimumZoom
0063      * \brief The minimum zoom level.
0064      *
0065      * \default 0.5
0066      * \get minimumZoom() const
0067      * \set setMinimumZoom()
0068      * \notify minimumZoomChanged()
0069      */
0070     Q_PROPERTY(float minimumZoom READ minimumZoom WRITE setMinimumZoom NOTIFY minimumZoomChanged)
0071     /**
0072      * \property minimumZoomFitsWidth
0073      * \brief Should the ViewController determine minimum zoom level automatically?
0074      *
0075      * When true, the minimum zoom level will be determined automatically  based on the width of
0076      * the item assigned to this controller's #flickable property.
0077      *
0078      * \default false
0079      * \get minimumZoomFitsWidth() const
0080      * \set setMinimumZoomFitsWidth()
0081      * \notify minimumZoomFitsWidthChanged()
0082      */
0083     Q_PROPERTY(bool minimumZoomFitsWidth READ minimumZoomFitsWidth WRITE setMinimumZoomFitsWidth NOTIFY minimumZoomFitsWidthChanged)
0084     /**
0085      * \property zoom
0086      * \brief The zoom amount of the view.
0087      *
0088      * \default 1.0
0089      * \get zoom() const
0090      * \set setZoom()
0091      * \notify zoomChanged()
0092      */
0093     Q_PROPERTY(float zoom READ zoom WRITE setZoom NOTIFY zoomChanged)
0094     /**
0095      * \property maximumZoom
0096      * \brief The maximum zoom amount.
0097      *
0098      * \default 2.0
0099      * \get maximumZoom() const
0100      * \set setMaximumZoom()
0101      * \notify maximumZoomChanged()
0102      */
0103     Q_PROPERTY(float maximumZoom READ maximumZoom WRITE setMaximumZoom NOTIFY maximumZoomChanged)
0104     /**
0105      * \property useZoomProxy
0106      * \brief Should the ViewController use a proxy image when zooming?
0107      *
0108      * When true, during zooming, apply the zoom to a proxy image that is scaled and shown for a
0109      * short duration before applying it to the view. This makes continuous zooming operations
0110      * far smoother.
0111      *
0112      * \default true
0113      * \get useZoomProxy() const
0114      * \set setUseZoomProxy()
0115      * \notify useZoomProxyChanged()
0116      */
0117     Q_PROPERTY(bool useZoomProxy READ useZoomProxy WRITE setUseZoomProxy NOTIFY useZoomProxyChanged)
0118 
0119 public:
0120     /**
0121      * Constructor.
0122      *
0123      * \param parent The parent item.
0124      */
0125     explicit ViewController(QQuickItem* parent = 0);
0126     /**
0127      * Destructor.
0128      */
0129     ~ViewController() override;
0130 
0131     /**
0132      * Getter for property #view
0133      */
0134     View* view() const;
0135     /**
0136      * Setter for property #view
0137      */
0138     void setView(View* newView);
0139     /**
0140      * Getter for property #flickable
0141      */
0142     QQuickItem* flickable() const;
0143     /**
0144      * Setter for property #flickable
0145      */
0146     void setFlickable(QQuickItem* item);
0147     /**
0148      * Getter for property #minimumZoom
0149      */
0150     float minimumZoom() const;
0151     /**
0152      * Setter for property #minimumZoom
0153      */
0154     void setMinimumZoom(float newValue);
0155     /**
0156      * Getter for property #minimumZoomFitsWidth
0157      */
0158     bool minimumZoomFitsWidth() const;
0159     /**
0160      * Setter for property #minimumZoomFitsWidth
0161      */
0162     void setMinimumZoomFitsWidth(bool newValue);
0163     /**
0164      * Getter for property #zoom
0165      */
0166     float zoom() const;
0167     /**
0168      * Setter for property #zoom
0169      */
0170     void setZoom(float newZoom);
0171     /**
0172      * Getter for property #maximumZoom
0173      */
0174     float maximumZoom() const;
0175     /**
0176      * Setter for property #maximumZoom
0177      */
0178     void setMaximumZoom(float newValue);
0179     /**
0180      * Getter for property #useZoomProxy
0181      */
0182     bool useZoomProxy() const;
0183     /**
0184      * Setter for property #useZoomProxy
0185      */
0186     void setUseZoomProxy(bool proxy);
0187 
0188     /**
0189      * Reimlemented from superclass
0190      */
0191     bool event(QEvent* event) override;
0192 public Q_SLOTS:
0193     /**
0194      * \brief Zoom by a specific amount around a centre point.
0195      *
0196      * \note The centre point should be relative to this item. The easiest way
0197      * to achieve this in QML is to use the following:
0198      *
0199      * \code
0200      * var newCenter = mapToItem(controller, center.x, center.y);
0201      * controller.zoomAroundPoint(amount, newCenter.x, newCenter.y);
0202      * \endcode
0203      *
0204      * \param amount The amount to zoom by, relative to the current zoom level.
0205      * \param x The horizontal coordinate of the centre point.
0206      * \param y The vertical coordinate of the centre point.
0207      */
0208     void zoomAroundPoint(float amount, float x, float y);
0209     /**
0210      * \brief Zoom the item such that it will fit a certain width.
0211      *
0212      * This will zoom the view to make sure that the document fits the specified
0213      * width, as long as the resulting zoom level is not less than #minimumZoom or
0214      * more than #maximumZoom.
0215      *
0216      * \param width The width to fit to.
0217      */
0218     void zoomToFitWidth(float width);
0219 
0220 Q_SIGNALS:
0221     /**
0222      * Notify signal for property #view.
0223      */
0224     void viewChanged();
0225     /**
0226      * Notify signal for property #flickable.
0227      */
0228     void flickableChanged();
0229     /**
0230      * Notify signal for property #minimumZoom.
0231      */
0232     void minimumZoomChanged();
0233     /**
0234      * Notify signal for property #minimumZoomFitsWidth.
0235      */
0236     void minimumZoomFitsWidthChanged();
0237     /**
0238      * Notify signal for property #zoom.
0239      */
0240     void zoomChanged();
0241     /**
0242      * Notify signal for property #maximumZoom.
0243      */
0244     void maximumZoomChanged();
0245     /**
0246      * Notify signal for property #useZoomProxy.
0247      */
0248     void useZoomProxyChanged();
0249 
0250 protected:
0251     QSGNode* updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeData* ) override;
0252 
0253 private Q_SLOTS:
0254     void documentChanged();
0255     void contentPositionChanged();
0256     void documentSizeChanged();
0257     void documentStatusChanged();
0258     void documentOffsetChanged(const QPoint& offset);
0259     void zoomTimeout();
0260     void flickableWidthChanged();
0261 
0262 private:
0263     class Private;
0264     Private* const d;
0265 };
0266 
0267 } // Namespace Components
0268 } // Namespace Calligra
0269 
0270 #endif // CALLIGRA_COMPONENTS_VIEWCONTROLLER_H