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 ¢er) = 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 ¢er) = 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 ¢er, 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