1 #pragma once 2 3 #ifndef SCREENBOARD_H 4 #define SCREENBOARD_H 5 6 #include "tcommon.h" 7 8 #include <QWidget> 9 #include <QList> 10 11 #undef DVAPI 12 #undef DVVAR 13 #ifdef TOONZQT_EXPORTS 14 #define DVAPI DV_EXPORT_API 15 #define DVVAR DV_EXPORT_VAR 16 #else 17 #define DVAPI DV_IMPORT_API 18 #define DVVAR DV_IMPORT_VAR 19 #endif 20 21 namespace DVGui { 22 23 //**************************************************************************** 24 // ScreenBoard class 25 //**************************************************************************** 26 27 //! The ScreenBoard is a singleton class that allows self-drawing objects to 28 //! be rendered on the whole desktop surface. 29 30 /*! The Qt Framework does not provide a standard way to draw directly on the 31 desktop. 32 \n\n 33 Typically, users have to allocate a QWidget to host any drawing command 34 to be rendered - but the rendering surface only covers the entirety of the 35 widget geometry, and nothing more. 36 37 Plus, the maximal drawing geometry should be known in advance when using a 38 host widget, or else heavy flickering will result from attempts to move 39 \a and resize the widget to cover new portions of the desktop. 40 \n\n 41 Another important use for the ScreenBoard is that of allowing dektop-wide 42 mouse 43 grabbing through the grabMouse() and releaseMouse() functions. 44 \n\n 45 The ScreenBoard stores a private collection of static, inert and transparent 46 <I> screen widgets <\I>, each overlapping a desktop screen, to be used as 47 drawable surfaces for self-drawing objects (ScreenBoard::Drawing instances) 48 that are added to the board. 49 \n\n 50 Drawings can be added to the board by direct manipulation of the drawings() 51 container list. 52 53 Use the update() method to refresh the screen after drawing insertions or 54 removals. 55 \n\n 56 Screen widgets redirect any event they receive to drawings that accept 57 redirection 58 through the Drawings::accpetScreenEvents() method. 59 60 The drawings() list sorting affects the order in which events from screen 61 widgets 62 are delivered to drawings. 63 64 In particular, drawings' <I> stacking order <\I> is \b inverse to the their 65 list 66 ordering - so, paint events are received in \b reverse with respect to other 67 events. Event acceptance is ignored to determine event delivery to drawings. 68 \n\n 69 Observe that upon every update() invocation, the screen widgets pool will 70 be refreshed to keep it to a minimum. 71 */ 72 73 class DVAPI ScreenBoard final : public QObject { 74 Q_OBJECT 75 76 public: 77 class Drawing; 78 79 private: 80 class ScreenWidget; 81 82 QVector<ScreenWidget *> m_screenWidgets; 83 QList<Drawing *> m_drawings; 84 85 QCursor m_cursor; 86 87 bool m_grabbing; 88 bool m_mouseOnAScreen; 89 bool m_updated; 90 91 public: 92 static ScreenBoard *instance(); 93 drawings()94 const QList<Drawing *> &drawings() const { return m_drawings; } drawings()95 QList<Drawing *> &drawings() { return m_drawings; } 96 97 void grabMouse( 98 const QCursor &cursor); //!< Grabs mouse inputs across the whole desktop. 99 void releaseMouse(); //!< Releases the mouse grab after grabMouse(). 100 grabbingMouse()101 bool grabbingMouse() const { 102 return m_grabbing; 103 } //!< Whether mouse grabbing is on. 104 105 private: 106 ScreenBoard(); 107 108 void reallocScreenWidgets(); 109 void ensureMouseOnAScreen(); 110 111 public slots: 112 113 void update(); //!< Refreshes the screen widgets pool and updates them. 114 115 private slots: 116 117 friend class ScreenWidget; 118 119 void trackCursor(); 120 void doUpdate(); 121 }; 122 123 //**************************************************************************** 124 // ScreenBoard::Drawing class 125 //**************************************************************************** 126 127 //! ScreenDrawing is the base class for objects that can be painted directly 128 //! in screen coordinates through the ScreenBoard. 129 class ScreenBoard::Drawing { 130 public: 131 //! Generic event handler for drawings. 132 /*! Reimplement it to receive events from screen widgets other than paint 133 events. 134 Paint events are \b not received in this handler, since they must be delivered 135 in reverse order. 136 */ event(QWidget * widget,QEvent * e)137 virtual void event(QWidget *widget, QEvent *e) {} 138 139 //! Paints the drawing on the specified screen widget. Use the widget's 140 //! mapFromGlobal() function to match desktop coordinates to screen 141 //! coordinates. 142 virtual void paintEvent(QWidget *widget, QPaintEvent *pe) = 0; 143 144 //! Returns whether the drawing is interested in events from the passed screen 145 //! geometry. 146 //! Accepting a screen causes a screen widget to be allocated in order to 147 //! receive events. 148 virtual bool acceptScreenEvents(const QRect &screenRect) const = 0; 149 }; 150 151 } // namespace DVGui 152 153 #endif // SCREENBOARD_H 154