| |
| |
| #include <QPaintEvent> |
| #include <QDesktopWidget> |
| #include <QApplication> |
| #include <QMetaObject> |
| #include <QCursor> |
| #include <QPainter> |
| |
| #include "toonzqt/screenboard.h" |
| |
| using namespace DVGui; |
| |
| #include <QPalette> |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| class MouseTrackerDrawing : public ScreenBoard::Drawing |
| { |
| public: |
| bool acceptScreenEvents(const QRect &rect) const |
| { |
| return rect.contains(QCursor::pos()); |
| } |
| void paintEvent(QWidget *widget, QPaintEvent *pe) |
| { |
| |
| |
| |
| |
| |
| |
| #ifdef MACOSX |
| #define MIN_ALPHA 13 |
| #else |
| #define MIN_ALPHA 1 |
| #endif |
| |
| QPainter painter(widget); |
| painter.fillRect(0, 0, widget->width(), widget->height(), QColor(0, 0, 0, MIN_ALPHA)); |
| } |
| |
| } tracker; |
| |
| } |
| |
| |
| |
| |
| |
| class ScreenBoard::ScreenWidget : public QWidget |
| { |
| QList<ScreenBoard::Drawing *> m_drawings; |
| bool m_mouseOnScreen; |
| |
| public: |
| ScreenWidget(QWidget *parent = 0, bool grabbing = false) |
| : QWidget(parent, Qt::Tool | |
| Qt::FramelessWindowHint | |
| Qt::WindowStaysOnTopHint) |
| { |
| setAttribute(Qt::WA_TransparentForMouseEvents, !grabbing); |
| setAttribute(Qt::WA_TranslucentBackground); |
| setFocusPolicy(Qt::NoFocus); |
| |
| setMouseTracking(true); |
| } |
| |
| const QList<Drawing *> &drawings() const { return m_drawings; } |
| QList<Drawing *> &drawings() { return m_drawings; } |
| |
| bool mouseOnScreen() const { return m_mouseOnScreen; } |
| |
| protected: |
| bool event(QEvent *e) |
| { |
| int i, size = m_drawings.size(); |
| if (e->type() == QEvent::Paint) { |
| |
| for (i = size - 1; i >= 0; --i) |
| m_drawings[i]->paintEvent(this, static_cast<QPaintEvent *>(e)); |
| } |
| |
| |
| for (i = 0; i < size; ++i) |
| m_drawings[i]->event(this, e); |
| |
| return QWidget::event(e); |
| } |
| |
| void leaveEvent(QEvent *e) |
| { |
| m_mouseOnScreen = false; |
| |
| ScreenBoard *screenBoard = ScreenBoard::instance(); |
| if (screenBoard->m_grabbing) |
| screenBoard->ensureMouseOnAScreen(); |
| } |
| |
| void enterEvent(QEvent *e) |
| { |
| m_mouseOnScreen = true; |
| ScreenBoard::instance()->m_mouseOnAScreen = true; |
| } |
| }; |
| |
| |
| |
| |
| |
| ScreenBoard::ScreenBoard() |
| : m_grabbing(false) |
| { |
| } |
| |
| |
| |
| ScreenBoard *ScreenBoard::instance() |
| { |
| static ScreenBoard theInstance; |
| return &theInstance; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| void ScreenBoard::grabMouse(const QCursor &cursor) |
| { |
| m_grabbing = true; |
| m_cursor = cursor; |
| |
| |
| m_drawings.push_back(&::tracker); |
| |
| |
| int i, size = m_screenWidgets.size(); |
| for (i = 0; i < size; ++i) { |
| QWidget *screenWidget = m_screenWidgets[i]; |
| if (screenWidget) { |
| screenWidget->setAttribute(Qt::WA_TransparentForMouseEvents, false); |
| screenWidget->setCursor(m_cursor); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| void ScreenBoard::releaseMouse() |
| { |
| |
| int i, size = m_screenWidgets.size(); |
| for (i = 0; i < size; ++i) { |
| QWidget *screenWidget = m_screenWidgets[i]; |
| if (screenWidget) { |
| screenWidget->setAttribute(Qt::WA_TransparentForMouseEvents, true); |
| screenWidget->unsetCursor(); |
| } |
| } |
| |
| |
| m_drawings.removeAt(m_drawings.indexOf(&::tracker)); |
| |
| m_cursor = QCursor(); |
| m_grabbing = false; |
| } |
| |
| |
| |
| |
| void ScreenBoard::reallocScreenWidgets() |
| { |
| QDesktopWidget *desktop = QApplication::desktop(); |
| |
| int i, screensCount = desktop->numScreens(); |
| |
| |
| for (i = screensCount; i < m_screenWidgets.size(); ++i) { |
| m_screenWidgets[i]->hide(); |
| m_screenWidgets[i]->deleteLater(); |
| |
| } |
| |
| m_screenWidgets.resize(desktop->numScreens()); |
| |
| |
| for (i = 0; i < screensCount; ++i) { |
| ScreenWidget *screenWidget = m_screenWidgets[i]; |
| if (screenWidget) |
| screenWidget->drawings().clear(); |
| } |
| |
| |
| int j, drawingsCount = m_drawings.size(); |
| for (i = 0; i < screensCount; ++i) { |
| ScreenWidget *screenWidget = m_screenWidgets[i]; |
| const QRect &screenGeom = desktop->screenGeometry(i); |
| |
| for (j = 0; j < drawingsCount; ++j) { |
| Drawing *drawing = m_drawings[j]; |
| if (drawing->acceptScreenEvents(screenGeom)) { |
| |
| if (!screenWidget) { |
| m_screenWidgets[i] = screenWidget = new ScreenWidget(0, m_grabbing); |
| if (m_grabbing) |
| screenWidget->setCursor(m_cursor); |
| |
| screenWidget->setGeometry(screenGeom); |
| screenWidget->show(); |
| } |
| |
| |
| screenWidget->drawings().push_back(drawing); |
| } |
| } |
| } |
| |
| |
| for (i = 0; i < screensCount; ++i) { |
| ScreenWidget *screenWidget = m_screenWidgets[i]; |
| if (screenWidget && screenWidget->drawings().empty()) { |
| screenWidget->hide(); |
| screenWidget->deleteLater(); |
| m_screenWidgets[i] = 0; |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void ScreenBoard::update() |
| { |
| m_updated = false; |
| QMetaObject::invokeMethod(this, "doUpdate", Qt::QueuedConnection); |
| } |
| |
| |
| |
| void ScreenBoard::doUpdate() |
| { |
| if (m_updated) |
| return; |
| |
| m_updated = true; |
| |
| reallocScreenWidgets(); |
| |
| |
| int i, size = m_screenWidgets.size(); |
| for (i = 0; i < size; ++i) |
| if (m_screenWidgets[i]) |
| m_screenWidgets[i]->update(); |
| } |
| |
| |
| |
| void ScreenBoard::ensureMouseOnAScreen() |
| { |
| |
| m_mouseOnAScreen = false; |
| |
| int i, size = m_screenWidgets.size(); |
| for (i = 0; i < size; ++i) { |
| ScreenWidget *screenWidget = m_screenWidgets[i]; |
| if (screenWidget) |
| m_mouseOnAScreen |= screenWidget->mouseOnScreen(); |
| } |
| |
| if (!m_mouseOnAScreen) |
| |
| |
| QMetaObject::invokeMethod(this, "trackCursor", Qt::QueuedConnection); |
| } |
| |
| |
| |
| void ScreenBoard::trackCursor() |
| { |
| while (!m_mouseOnAScreen) { |
| update(); |
| QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); |
| } |
| } |
| |