Warning, file /office/calligra/libs/flake/KoCanvasController.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2006, 2008 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2007-2010 Boudewijn Rempt <boud@valdyas.org>
0004  * Copyright (C) 2007-2008 C. Boemann <cbo@boemann.dk>
0005  * Copyright (C) 2006-2007 Jan Hambrecht <jaham@gmx.net>
0006  * Copyright (C) 2009 Thorsten Zachmann <zachmann@kde.org>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  */
0023 
0024 #ifndef KOCANVASCONTROLLER_H
0025 #define KOCANVASCONTROLLER_H
0026 
0027 #include "flake_export.h"
0028 #include <QObject>
0029 
0030 #include <QSize>
0031 #include <QPoint>
0032 #include <QPointF>
0033 
0034 class KActionCollection;
0035 class QRect;
0036 class QRectF;
0037 
0038 
0039 class KoShape;
0040 class KoCanvasBase;
0041 class KoCanvasControllerProxyObject;
0042 
0043 /**
0044  * KoCanvasController is the base class for wrappers around your canvas
0045  * that provides scrolling and zooming for your canvas.
0046  *
0047  * Flake does not provide a canvas, the application will have to
0048  * implement a canvas themselves. You canvas can be QWidget-based, QGraphicsItem-based
0049  * or something we haven't invented yet -- as long the class that holds the canvas
0050  * implements KoCanvasController, tools, scrolling and zooming will work.
0051  *
0052  * A KoCanvasController implementation acts as a decorator around the canvas widget or
0053  * graphics item and provides a way to scroll the canvas, allows the canvas to be centered
0054  * in the viewArea and manages tool activation.
0055  *
0056  * <p>The using application can instantiate this class and add its
0057  * canvas using the setCanvas() call. Which is designed so it can be
0058  * called multiple times if you need to exchange one canvas
0059  * widget for another, for instance, switching between a plain QWidget or a QOpenGLWidget.
0060  *
0061  * <p>There is _one_ KoCanvasController per canvas in your
0062  * application.
0063  *
0064  * <p>The canvas widget is at most as big as the viewport of the scroll
0065  * area, and when the view on the document is near its edges, smaller.
0066  * In your canvas widget code, you can find the right place in your
0067  * document in view coordinates (pixels) by adding the documentOffset
0068  */
0069 class FLAKE_EXPORT KoCanvasController
0070 {
0071 public:
0072     /// An enum to alter the positioning and size of the canvas inside the canvas controller
0073     enum CanvasMode {
0074         AlignTop,     ///< canvas is top aligned if smaller than the viewport
0075         Centered,     ///< canvas is centered if smaller than the viewport
0076         Infinite,     ///< canvas is never smaller than the viewport
0077         Spreadsheet   ///< same as Infinite, but supports right-to-left layouts
0078     };
0079 
0080     // proxy QObject: use this to connect to slots and signals.
0081     KoCanvasControllerProxyObject *proxyObject;
0082 
0083     /**
0084      * Constructor.
0085      * @param actionCollection the action collection for this canvas
0086      */
0087     explicit KoCanvasController(KActionCollection* actionCollection);
0088     virtual ~KoCanvasController();
0089 
0090 public:
0091     /**
0092      * Returns the current margin that is used to pad the canvas with.
0093      * This value is read from the KConfig property "canvasmargin"
0094      */
0095     virtual int margin() const;
0096 
0097     /**
0098      * Set the new margin to pad the canvas with.
0099      */
0100     virtual void setMargin(int margin);
0101 
0102     /**
0103      * Sets the how the canvas behaves if the zoomed document becomes smaller than the viewport.
0104      * @param mode the new canvas mode, CanvasMode::Centered is the default value
0105      */
0106     virtual void setCanvasMode(KoCanvasController::CanvasMode mode);
0107 
0108     /// Returns the current canvas mode
0109     virtual KoCanvasController::CanvasMode canvasMode() const;
0110 
0111     /**
0112      * compatibility with QAbstractScrollArea
0113      */
0114     virtual void scrollContentsBy(int dx, int dy) = 0;
0115 
0116     /**
0117      * @return the size of the viewport
0118      */
0119     virtual QSize viewportSize() const = 0;
0120 
0121     /**
0122      * Set the shadow option -- by default the canvas controller draws
0123      * a black shadow around the canvas widget, which you may or may
0124      * not want.
0125      *
0126      * @param drawShadow if true, the shadow is drawn, if false, not
0127      */
0128     virtual void setDrawShadow(bool drawShadow) = 0;
0129 
0130     /**
0131      * Set the new canvas to be shown as a child
0132      * Calling this will emit canvasRemoved() if there was a canvas before, and will emit
0133      * canvasSet() with the new canvas.
0134      * @param canvas the new canvas. The KoCanvasBase::canvas() will be called to retrieve the
0135      *        actual widget which will then be added as child of this one.
0136      */
0137     virtual void setCanvas(KoCanvasBase *canvas) = 0;
0138 
0139     /**
0140      * Return the currently set canvas. The default implementation will return Null
0141      * @return the currently set canvas
0142      */
0143     virtual KoCanvasBase *canvas() const;
0144 
0145     /**
0146      * return the amount of pixels vertically visible of the child canvas.
0147      * @return the amount of pixels vertically visible of the child canvas.
0148      */
0149     virtual int visibleHeight() const = 0;
0150 
0151     /**
0152      * return the amount of pixels horizontally visible of the child canvas.
0153      * @return the amount of pixels horizontally visible of the child canvas.
0154      */
0155     virtual int visibleWidth() const = 0;
0156 
0157     /**
0158      * return the amount of pixels that are not visible on the left side of the canvas.
0159      * The leftmost pixel that is shown is returned.
0160      */
0161     virtual int canvasOffsetX() const = 0;
0162 
0163     /**
0164      * return the amount of pixels that are not visible on the top side of the canvas.
0165      * The topmost pixel that is shown is returned.
0166      */
0167     virtual int canvasOffsetY() const = 0;
0168 
0169     /**
0170      * @brief Scrolls the content of the canvas so that the given rect is visible.
0171      *
0172      * The rect is to be specified in view coordinates (pixels). The scrollbar positions
0173      * are changed so that the centerpoint of the rectangle is centered if possible.
0174      *
0175      * @param rect the rectangle to make visible
0176      * @param smooth if true the viewport translation will make be just enough to ensure visibility, no more.
0177      * @see KoViewConverter::documentToView()
0178      */
0179     virtual void ensureVisible(const QRectF &rect, bool smooth = false) = 0;
0180 
0181     /**
0182      * @brief Scrolls the content of the canvas so that the given shape is visible.
0183      *
0184      * This is just a wrapper function of the above function.
0185      *
0186      * @param shape the shape to make visible
0187      */
0188     virtual void ensureVisible(KoShape *shape) = 0;
0189 
0190     /**
0191      * @brief zooms in around the center.
0192      *
0193      * The center must be specified in view coordinates (pixels). The scrollbar positions
0194      * are changed so that the center becomes center if possible.
0195      *
0196      * @param center the position to zoom in on
0197      */
0198     virtual void zoomIn(const QPoint &center) = 0;
0199 
0200     /**
0201      * @brief zooms out around the center.
0202      *
0203      * The center must be specified in view coordinates (pixels). The scrollbar positions
0204      * are changed so that the center becomes center if possible.
0205      *
0206      * @param center the position to zoom out around
0207      */
0208     virtual void zoomOut(const QPoint &center) = 0;
0209 
0210     /**
0211      * @brief zooms around the center.
0212      *
0213      * The center must be specified in view coordinates (pixels). The scrollbar positions
0214      * are changed so that the center becomes center if possible.
0215      *
0216      * @param center the position to zoom around
0217      * @param zoom the zoom to apply
0218      */
0219     virtual void zoomBy(const QPoint &center, qreal zoom) = 0;
0220 
0221     /**
0222      * @brief zoom so that rect is exactly visible (as close as possible)
0223      *
0224      * The rect must be specified in view coordinates (pixels). The scrollbar positions
0225      * are changed so that the center of the rect becomes center if possible.
0226      *
0227      * @param rect the rect in view coordinates (pixels) that should fit the view afterwards
0228      */
0229     virtual void zoomTo(const QRect &rect) = 0;
0230 
0231     /**
0232      * @brief repositions the scrollbars so previous center is once again center
0233      *
0234      * The previous center is cached from when the user uses the scrollbars or zoomTo
0235      * are called. zoomTo is mostly used when a zoom tool of sorts have marked an area
0236      * to zoom in on
0237      *
0238      * The success of this method is limited by the size of thing. But we try our best.
0239      */
0240     virtual void recenterPreferred() = 0;
0241 
0242     /**
0243      * Sets the preferred center point in view coordinates (pixels).
0244      * @param viewPoint the new preferred center
0245      */
0246     virtual void setPreferredCenter(const QPointF &viewPoint) = 0;
0247 
0248     /// Returns the currently set preferred center point in view coordinates (pixels)
0249     virtual QPointF preferredCenter() const = 0;
0250 
0251     /**
0252      * Move the canvas over the x and y distance of the parameter distance
0253      * @param distance the distance in view coordinates (pixels).  A positive distance means moving the canvas up/left.
0254      */
0255     virtual void pan(const QPoint &distance) = 0;
0256 
0257     /**
0258      * Get the position of the scrollbar
0259      */
0260     virtual QPoint scrollBarValue() const = 0;
0261 
0262     /**
0263      * Set the position of the scrollbar
0264      * @param value the new values of the scroll bars
0265      */
0266     virtual void setScrollBarValue(const QPoint &value) = 0;
0267 
0268     /**
0269      * Called when the size of your document in view coordinates (pixels) changes, for instance when zooming.
0270      *
0271      * @param newSize the new size, in view coordinates (pixels), of the document.
0272      * @param recalculateCenter if true the offset in the document we center on after calling
0273      *      recenterPreferred() will be recalculated for the new document size so the visual offset stays the same.
0274      */
0275     virtual void updateDocumentSize(const QSize &sz, bool recalculateCenter) = 0;
0276 
0277     /**
0278      * Set mouse wheel to zoom behaviour
0279      * @param zoom if true wheel will zoom instead of scroll, control modifier will scroll
0280      */
0281     virtual void setZoomWithWheel(bool zoom) = 0;
0282 
0283     /**
0284      * Set scroll area to be bigger than actual document.
0285      * It allows the user to move the corner of the document
0286      * to e.g. the center of the screen
0287      *
0288      * @param factor the coefficient, defining how much we can scroll out,
0289      *     measured in parts of the widget size. Null value means vast
0290      *     scrolling is disabled.
0291      */
0292     virtual void setVastScrolling(qreal factor) = 0;
0293 
0294    /**
0295      * Returns the action collection for the canvas
0296      * @returns action collection for this canvas, can be 0
0297      */
0298     virtual KActionCollection* actionCollection() const;
0299 
0300     QPoint documentOffset() const;
0301 
0302 protected:
0303     void setDocumentSize(const QSize &sz);
0304     QSize documentSize() const;
0305 
0306     void setPreferredCenterFractionX(qreal);
0307     qreal preferredCenterFractionX() const;
0308 
0309     void setPreferredCenterFractionY(qreal);
0310     qreal preferredCenterFractionY() const;
0311 
0312     void setDocumentOffset( QPoint &offset);
0313 
0314 
0315 private:
0316     class Private;
0317     Private * const d;
0318 };
0319 
0320 
0321 /**
0322  * Workaround class for the problem that Qt does not allow two QObject base classes.
0323  * KoCanvasController can be implemented by for instance QWidgets, so it cannot be
0324  * a QObject directly. The interface of this class should be considered public interface
0325  * for KoCanvasController.
0326  */
0327 class FLAKE_EXPORT KoCanvasControllerProxyObject : public QObject
0328 {
0329     Q_OBJECT
0330     Q_DISABLE_COPY(KoCanvasControllerProxyObject)
0331 public:
0332     explicit KoCanvasControllerProxyObject(KoCanvasController *canvasController, QObject *parent = 0);
0333 
0334 public:
0335 
0336     // Convenience methods to invoke the signals from subclasses
0337 
0338     void emitCanvasRemoved(KoCanvasController *canvasController) { emit canvasRemoved(canvasController); }
0339     void emitCanvasSet(KoCanvasController *canvasController) { emit canvasSet(canvasController); }
0340     void emitCanvasOffsetXChanged(int offset) { emit canvasOffsetXChanged(offset); }
0341     void emitCanvasOffsetYChanged(int offset) { emit canvasOffsetYChanged(offset); }
0342     void emitCanvasMousePositionChanged(const QPoint &position) { emit canvasMousePositionChanged(position); }
0343     void emitDocumentMousePositionChanged(const QPointF &position) { emit documentMousePositionChanged(position); }
0344     void emitSizeChanged(const QSize &size) { emit sizeChanged(size); }
0345     void emitMoveDocumentOffset(const QPoint &point) { emit moveDocumentOffset(point); }
0346     void emitZoomRelative(const qreal factor, const QPointF &stillPoint) { emit zoomRelative(factor, stillPoint); }
0347 
0348     // Convenience method to retrieve the canvas controller for who needs to use QPointer
0349     KoCanvasController *canvasController() const { return m_canvasController; }
0350 
0351 Q_SIGNALS:
0352     /**
0353      * Emitted when a previously added canvas is about to be removed.
0354      * @param canvasController this object
0355      */
0356     void canvasRemoved(KoCanvasController *canvasController);
0357 
0358     /**
0359      * Emitted when a canvas is set on this widget
0360      * @param canvasController this object
0361      */
0362     void canvasSet(KoCanvasController *canvasController);
0363 
0364     /**
0365      * Emitted when canvasOffsetX() changes
0366      * @param offset the new canvas offset
0367      */
0368     void canvasOffsetXChanged(int offset);
0369 
0370     /**
0371      * Emitted when canvasOffsetY() changes
0372      * @param offset the new canvas offset
0373      */
0374     void canvasOffsetYChanged(int offset);
0375 
0376     /**
0377      * Emitted when the cursor is moved over the canvas widget.
0378      * @param position the position in view coordinates (pixels).
0379      */
0380     void canvasMousePositionChanged(const QPoint &position);
0381 
0382     /**
0383      * Emitted when the cursor is moved over the canvas widget.
0384      * @param position the position in document coordinates.
0385      *
0386      * Use \ref canvasMousePositionChanged to get the position
0387      * in view coordinates.
0388      */
0389     void documentMousePositionChanged(const QPointF &position);
0390 
0391     /**
0392      * Emitted when the entire controller size changes
0393      * @param size the size in widget pixels.
0394      */
0395     void sizeChanged(const QSize &size);
0396 
0397     /**
0398      * Emitted whenever the document is scrolled.
0399      *
0400      * @param point the new top-left point from which the document should
0401      * be drawn.
0402      */
0403     void moveDocumentOffset(const QPoint &point);
0404 
0405     /**
0406      * Emitted when zoomRelativeToPoint have calculated a factor by which
0407      * the zoom should change and the point which should stand still
0408      * on screen.
0409      * Someone needs to connect to this and take action
0410      *
0411      * @param factor by how much the zoom needs to change.
0412      * @param stillPoint the point which will not change its position
0413      *                   in widget during the zooming. It is measured in
0414      *                   view coordinate system *before* zoom.
0415      */
0416     void zoomRelative(qreal factor, const QPointF &stillPoint);
0417 
0418 public Q_SLOTS:
0419     /**
0420      * Call this slot whenever the size of your document in view coordinates (pixels)
0421      * changes, for instance when zooming.
0422      * @param newSize the new size, in view coordinates (pixels), of the document.
0423      * @param recalculateCenter if true the offset in the document we center on after calling
0424      *      recenterPreferred() will be recalculated for the new document size so the visual offset stays the same.
0425      */
0426     void updateDocumentSize(const QSize &newSize, bool recalculateCenter = true);
0427 
0428 private:
0429     KoCanvasController *m_canvasController;
0430 };
0431 
0432 class FLAKE_EXPORT  KoDummyCanvasController : public KoCanvasController {
0433 
0434 public:
0435 
0436     explicit KoDummyCanvasController(KActionCollection* actionCollection)
0437         : KoCanvasController(actionCollection)
0438     {}
0439 
0440     ~KoDummyCanvasController() override
0441     {}
0442 
0443 
0444     void scrollContentsBy(int /*dx*/, int /*dy*/) override {}
0445     QSize viewportSize() const override { return QSize(); }
0446     void setDrawShadow(bool /*drawShadow*/) override {}
0447     void setCanvas(KoCanvasBase *canvas) override {Q_UNUSED(canvas)}
0448     KoCanvasBase *canvas() const override {return 0;}
0449     int visibleHeight() const override {return 0;}
0450     int visibleWidth() const override {return 0;}
0451     int canvasOffsetX() const override {return 0;}
0452     int canvasOffsetY() const override {return 0;}
0453     void ensureVisible(const QRectF &/*rect*/, bool /*smooth */ = false) override {}
0454     void ensureVisible(KoShape *shape) override {Q_UNUSED(shape)}
0455     void zoomIn(const QPoint &/*center*/) override {}
0456     void zoomOut(const QPoint &/*center*/) override {}
0457     void zoomBy(const QPoint &/*center*/, qreal /*zoom*/) override {}
0458     void zoomTo(const QRect &/*rect*/) override {}
0459     void recenterPreferred() override {}
0460     void setPreferredCenter(const QPointF &/*viewPoint*/) override {}
0461     QPointF preferredCenter() const override {return QPointF();}
0462     void pan(const QPoint &/*distance*/) override {}
0463     QPoint scrollBarValue() const override {return QPoint();}
0464     void setScrollBarValue(const QPoint &/*value*/) override {}
0465     void updateDocumentSize(const QSize &/*sz*/, bool /*recalculateCenter*/) override {}
0466     void setZoomWithWheel(bool /*zoom*/) override {}
0467     void setVastScrolling(qreal /*factor*/) override {}
0468 
0469 };
0470 
0471 #endif