2016-05-17 03:04:11 +12:00
|
|
|
#pragma once
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#ifndef SCREENBOARD_H
|
|
|
|
#define SCREENBOARD_H
|
|
|
|
|
|
|
|
#include "tcommon.h"
|
|
|
|
|
|
|
|
#include <QWidget>
|
|
|
|
#include <QList>
|
|
|
|
|
|
|
|
#undef DVAPI
|
|
|
|
#undef DVVAR
|
|
|
|
#ifdef TOONZQT_EXPORTS
|
|
|
|
#define DVAPI DV_EXPORT_API
|
|
|
|
#define DVVAR DV_EXPORT_VAR
|
|
|
|
#else
|
|
|
|
#define DVAPI DV_IMPORT_API
|
|
|
|
#define DVVAR DV_IMPORT_VAR
|
|
|
|
#endif
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace DVGui {
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//****************************************************************************
|
|
|
|
// ScreenBoard class
|
|
|
|
//****************************************************************************
|
|
|
|
|
|
|
|
//! The ScreenBoard is a singleton class that allows self-drawing objects to
|
|
|
|
//! be rendered on the whole desktop surface.
|
|
|
|
|
|
|
|
/*! The Qt Framework does not provide a standard way to draw directly on the
|
|
|
|
desktop.
|
|
|
|
\n\n
|
|
|
|
Typically, users have to allocate a QWidget to host any drawing command
|
|
|
|
to be rendered - but the rendering surface only covers the entirety of the
|
|
|
|
widget geometry, and nothing more.
|
|
|
|
|
|
|
|
Plus, the maximal drawing geometry should be known in advance when using a
|
|
|
|
host widget, or else heavy flickering will result from attempts to move
|
|
|
|
\a and resize the widget to cover new portions of the desktop.
|
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
Another important use for the ScreenBoard is that of allowing dektop-wide
|
|
|
|
mouse
|
2016-03-19 06:57:51 +13:00
|
|
|
grabbing through the grabMouse() and releaseMouse() functions.
|
|
|
|
\n\n
|
|
|
|
The ScreenBoard stores a private collection of static, inert and transparent
|
|
|
|
<I> screen widgets <\I>, each overlapping a desktop screen, to be used as
|
|
|
|
drawable surfaces for self-drawing objects (ScreenBoard::Drawing instances)
|
|
|
|
that are added to the board.
|
|
|
|
\n\n
|
|
|
|
Drawings can be added to the board by direct manipulation of the drawings()
|
|
|
|
container list.
|
|
|
|
|
|
|
|
Use the update() method to refresh the screen after drawing insertions or
|
|
|
|
removals.
|
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
Screen widgets redirect any event they receive to drawings that accept
|
|
|
|
redirection
|
2016-03-19 06:57:51 +13:00
|
|
|
through the Drawings::accpetScreenEvents() method.
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
The drawings() list sorting affects the order in which events from screen
|
|
|
|
widgets
|
2016-03-19 06:57:51 +13:00
|
|
|
are delivered to drawings.
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
In particular, drawings' <I> stacking order <\I> is \b inverse to the their
|
|
|
|
list
|
2016-03-19 06:57:51 +13:00
|
|
|
ordering - so, paint events are received in \b reverse with respect to other
|
|
|
|
events. Event acceptance is ignored to determine event delivery to drawings.
|
|
|
|
\n\n
|
|
|
|
Observe that upon every update() invocation, the screen widgets pool will
|
|
|
|
be refreshed to keep it to a minimum.
|
|
|
|
*/
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI ScreenBoard : public QObject {
|
|
|
|
Q_OBJECT
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
class Drawing;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
class ScreenWidget;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
QVector<ScreenWidget *> m_screenWidgets;
|
|
|
|
QList<Drawing *> m_drawings;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
QCursor m_cursor;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
bool m_grabbing;
|
|
|
|
bool m_mouseOnAScreen;
|
|
|
|
bool m_updated;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
static ScreenBoard *instance();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
const QList<Drawing *> &drawings() const { return m_drawings; }
|
|
|
|
QList<Drawing *> &drawings() { return m_drawings; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void grabMouse(
|
|
|
|
const QCursor &cursor); //!< Grabs mouse inputs across the whole desktop.
|
|
|
|
void releaseMouse(); //!< Releases the mouse grab after grabMouse().
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
bool grabbingMouse() const {
|
|
|
|
return m_grabbing;
|
|
|
|
} //!< Whether mouse grabbing is on.
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
ScreenBoard();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void reallocScreenWidgets();
|
|
|
|
void ensureMouseOnAScreen();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void update(); //!< Refreshes the screen widgets pool and updates them.
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
friend class ScreenWidget;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void trackCursor();
|
|
|
|
void doUpdate();
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//****************************************************************************
|
|
|
|
// ScreenBoard::Drawing class
|
|
|
|
//****************************************************************************
|
|
|
|
|
|
|
|
//! ScreenDrawing is the base class for objects that can be painted directly
|
|
|
|
//! in screen coordinates through the ScreenBoard.
|
2016-06-15 18:43:10 +12:00
|
|
|
class ScreenBoard::Drawing {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Generic event handler for drawings.
|
|
|
|
/*! Reimplement it to receive events from screen widgets other than paint
|
|
|
|
events.
|
|
|
|
Paint events are \b not received in this handler, since they must be delivered
|
|
|
|
in reverse order.
|
|
|
|
*/
|
|
|
|
virtual void event(QWidget *widget, QEvent *e) {}
|
|
|
|
|
|
|
|
//! Paints the drawing on the specified screen widget. Use the widget's
|
|
|
|
//! mapFromGlobal() function to match desktop coordinates to screen
|
|
|
|
//! coordinates.
|
|
|
|
virtual void paintEvent(QWidget *widget, QPaintEvent *pe) = 0;
|
|
|
|
|
|
|
|
//! Returns whether the drawing is interested in events from the passed screen
|
|
|
|
//! geometry.
|
|
|
|
//! Accepting a screen causes a screen widget to be allocated in order to
|
|
|
|
//! receive events.
|
|
|
|
virtual bool acceptScreenEvents(const QRect &screenRect) const = 0;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
} // namespace DVGui
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
#endif // SCREENBOARD_H
|