diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 295858c7..7e9a256b 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -13,882 +13,882 @@ * along with this program. If not, see . */ - -#include "UBBoardView.h" - -#include - -#include "UBDrawingController.h" - -#include "frameworks/UBGeometryUtils.h" - -#include "core/UBSettings.h" -#include "core/UBMimeData.h" -#include "core/UBApplication.h" -#include "core/UBSetting.h" -#include "core/UBPersistenceManager.h" - -#include "network/UBHttpGet.h" - -#include "gui/UBStylusPalette.h" -#include "gui/UBRubberBand.h" -#include "gui/UBToolWidget.h" -#include "gui/UBResources.h" -#include "gui/UBMainWindow.h" - -#include "board/UBBoardController.h" - -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBGraphicsPixmapItem.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBItem.h" - -#include "document/UBDocumentProxy.h" -#include "../gui/UBThumbnailWidget.h" - -#include "frameworks/UBPlatformUtils.h" - -#include "core/memcheck.h" - -UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent) -: QGraphicsView (pParent) -, mController (pController) -, mIsCreatingTextZone (false) -, mIsCreatingSceneGrabZone (false) -{ - init (); - - mFilterZIndex = false; -} - -UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent) -: QGraphicsView (pParent) -, mController (pController) -{ - init (); - - mStartLayer = pStartLayer; - mEndLayer = pEndLayer; - - mFilterZIndex = true; -} - -UBBoardView::~UBBoardView () { - //NOOP -} - -void -UBBoardView::init () -{ - connect (UBSettings::settings ()->boardPenPressureSensitive, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - connect (UBSettings::settings ()->boardMarkerPressureSensitive, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - connect (UBSettings::settings ()->boardUseHighResTabletEvent, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - setWindowFlags (Qt::FramelessWindowHint); - setFrameStyle (QFrame::NoFrame); - setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); - setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); - setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); - setAcceptDrops (true); - - setOptimizationFlag (QGraphicsView::IndirectPainting); // enable UBBoardView::drawItems filter - - mTabletStylusIsPressed = false; - mMouseButtonIsPressed = false; - mPendingStylusReleaseEvent = false; - - setCacheMode (QGraphicsView::CacheBackground); - - mUsingTabletEraser = false; - mIsCreatingTextZone = false; - mRubberBand = 0; - - mVirtualKeyboardActive = false; - - settingChanged (QVariant ()); - - unsetCursor(); -} - -UBGraphicsScene* -UBBoardView::scene () -{ - return qobject_cast (QGraphicsView::scene ()); -} - -void -UBBoardView::hideEvent (QHideEvent * event) -{ - Q_UNUSED (event); - emit hidden (); -} - -void -UBBoardView::showEvent (QShowEvent * event) -{ - Q_UNUSED (event); - emit shown (); -} - -void -UBBoardView::keyPressEvent (QKeyEvent *event) -{ - // send to the scene anyway - QApplication::sendEvent (scene (), event); - - if (!event->isAccepted ()) - { - switch (event->key ()) - { - case Qt::Key_Up: - case Qt::Key_PageUp: - case Qt::Key_Left: - { - mController->previousScene (); - break; - } - - case Qt::Key_Down: - case Qt::Key_PageDown: - case Qt::Key_Right: - case Qt::Key_Space: - { - mController->nextScene (); - break; - } - - case Qt::Key_Home: - { - mController->firstScene (); - break; - } - case Qt::Key_End: - { - mController->lastScene (); - break; - } - case Qt::Key_Insert: - { - mController->addScene (); - break; - } - } - - - if (event->modifiers () & Qt::ControlModifier) // keep only ctrl/cmd keys - { - switch (event->key ()) - { - case Qt::Key_Plus: - case Qt::Key_I: - { - mController->zoomIn (); - event->accept (); - break; - } - case Qt::Key_Minus: - case Qt::Key_O: - { - mController->zoomOut (); - event->accept (); - break; - } - case Qt::Key_0: - { - mController->zoomRestore (); - event->accept (); - break; - } - case Qt::Key_Left: - { - mController->handScroll (-100, 0); - event->accept (); - break; - } - case Qt::Key_Right: - { - mController->handScroll (100, 0); - event->accept (); - break; - } - case Qt::Key_Up: - { - mController->handScroll (0, -100); - event->accept (); - break; - } - case Qt::Key_Down: - { - mController->handScroll (0, 100); - event->accept (); - break; - } - default: - { - // NOOP - } - } - } - } -} - -bool -UBBoardView::event (QEvent * e) -{ - if (e->type () == QEvent::Gesture) - { - QGestureEvent *gestureEvent = dynamic_cast (e); - if (gestureEvent) - { - QSwipeGesture* swipe = dynamic_cast (gestureEvent->gesture (Qt::SwipeGesture)); - - if (swipe) - { - if (swipe->horizontalDirection () == QSwipeGesture::Left) - { - mController->previousScene (); - gestureEvent->setAccepted (swipe, true); - } - - if (swipe->horizontalDirection () == QSwipeGesture::Right) - { - mController->nextScene (); - gestureEvent->setAccepted (swipe, true); - } - } - } - } - - return QGraphicsView::event (e); -} - -void -UBBoardView::tabletEvent (QTabletEvent * event) -{ - if (!mUseHighResTabletEvent) - { - event->setAccepted (false); - return; - } - - UBDrawingController *dc = UBDrawingController::drawingController (); - - QPointF tabletPos = UBGeometryUtils::pointConstrainedInRect (event->hiResGlobalPos () - - mapToGlobal (QPoint (0, 0)), rect ()); - - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); - - if (event->type () == QEvent::TabletPress || event->type () == QEvent::TabletEnterProximity) - { - if (event->pointerType () == QTabletEvent::Eraser) - { - dc->setStylusTool (UBStylusTool::Eraser); - mUsingTabletEraser = true; - } - else - { - if (mUsingTabletEraser && currentTool == UBStylusTool::Eraser) - { - dc->setStylusTool (dc->latestDrawingTool ()); - } - - mUsingTabletEraser = false; - } - } - - // if event are not Pen events, we drop the tablet stuff and route everything through mouse event - if (currentTool != UBStylusTool::Pen - && currentTool != UBStylusTool::Line - && currentTool != UBStylusTool::Marker - && !mMarkerPressureSensitive) - { - event->setAccepted (false); - return; - } - - QPointF scenePos = viewportTransform ().inverted ().map (tabletPos); - - qreal pressure = 1.0; - if (((currentTool == UBStylusTool::Pen || currentTool == UBStylusTool::Line) - && mPenPressureSensitive) - || (currentTool == UBStylusTool::Marker && mMarkerPressureSensitive)) - { - pressure = event->pressure (); - } - - bool acceptEvent = true; - - switch (event->type ()) - { - case QEvent::TabletPress: - { - mTabletStylusIsPressed = true; - - scene ()->inputDevicePress (scenePos, pressure); - - break; - } - case QEvent::TabletMove: - { - if (mTabletStylusIsPressed) - { - scene ()->inputDeviceMove (scenePos, pressure); - } - - acceptEvent = false; // rerouted to mouse move - - break; - - } - case QEvent::TabletRelease: - { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); - scene ()->setToolCursor (currentTool); - setToolCursor (currentTool); - - scene ()->inputDeviceRelease (); - - mPendingStylusReleaseEvent = false; - - mTabletStylusIsPressed = false; - mMouseButtonIsPressed = false; - - break; - } - default: - { - //NOOP - avoid compiler warning - } - } - - // ignore mouse press and mouse move tablet event so that it is rerouted to mouse events, - // documented in QTabletEvent Class Reference: - /* The event handler QWidget::tabletEvent() receives all three types of tablet events. - Qt will first send a tabletEvent then, if it is not accepted, it will send a mouse event. */ - // - // This is a workaround to the fact that tablet event are not delivered to child widget (like palettes) - // - - event->setAccepted (acceptEvent); - -} - -void -UBBoardView::mousePressEvent (QMouseEvent *event) -{ - if (isAbsurdPoint (event->pos ())) - { - event->accept (); - return; - } - - mMouseDownPos = event->pos (); - - if (event->button () == Qt::LeftButton && isInteractive ()) - { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - if (!mTabletStylusIsPressed) - mMouseButtonIsPressed = true; - - if (currentTool == UBStylusTool::ZoomIn) - { - mController->zoomIn (mapToScene (event->pos ())); - event->accept (); - } - else if (currentTool == UBStylusTool::ZoomOut) - { - mController->zoomOut (mapToScene (event->pos ())); - event->accept (); - } - else if (currentTool == UBStylusTool::Hand) - { - viewport ()->setCursor (QCursor (Qt::ClosedHandCursor)); - mPreviousPoint = event->posF (); - event->accept (); - } - else if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mousePressEvent (event); - } - else if (currentTool == UBStylusTool::Text) - { - int frameWidth = UBSettings::settings ()->objectFrameWidth; - QRectF fuzzyRect (0, 0, frameWidth * 4, frameWidth * 4); - fuzzyRect.moveCenter (mapToScene (mMouseDownPos)); - - UBGraphicsTextItem* foundTextItem = 0; - QListIterator it (scene ()->items (fuzzyRect)); - - while (it.hasNext () && !foundTextItem) - { - foundTextItem = qgraphicsitem_cast(it.next ()); - } - - if (foundTextItem) - { - mIsCreatingTextZone = false; - QGraphicsView::mousePressEvent (event); - } - else - { - scene ()->deselectAllItems (); - - if (!mRubberBand) - mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); - - mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); - mRubberBand->show (); - mIsCreatingTextZone = true; - - event->accept (); - } - } - else if (currentTool == UBStylusTool::Capture) - { - scene ()->deselectAllItems (); - - if (!mRubberBand) - mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); - - mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); - mRubberBand->show (); - mIsCreatingSceneGrabZone = true; - - event->accept (); - } - else - { - if(UBDrawingController::drawingController()->mActiveRuler==NULL) - { - viewport()->setCursor (QCursor (Qt::BlankCursor)); - } - - if (scene () && !mTabletStylusIsPressed) - { - scene ()->inputDevicePress (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ()))); - } - event->accept (); - } - } -} - -void -UBBoardView::mouseMoveEvent (QMouseEvent *event) -{ - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - if (isAbsurdPoint (event->pos ())) - { - event->accept (); - return; - } - - if (currentTool == UBStylusTool::Hand && (mMouseButtonIsPressed || mTabletStylusIsPressed)) - { - QPointF eventPosition = event->posF (); - qreal dx = eventPosition.x () - mPreviousPoint.x (); - qreal dy = eventPosition.y () - mPreviousPoint.y (); - mController->handScroll (dx, dy); - mPreviousPoint = eventPosition; - event->accept (); - } - else if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mouseMoveEvent (event); - } - else if ((UBDrawingController::drawingController()->isDrawingTool()) - && !mMouseButtonIsPressed) - { - QGraphicsView::mouseMoveEvent (event); - } - else if (currentTool == UBStylusTool::Text || currentTool == UBStylusTool::Capture) - { - if (mRubberBand && (mIsCreatingTextZone || mIsCreatingSceneGrabZone)) - { - mRubberBand->setGeometry (QRect (mMouseDownPos, event->pos ()).normalized ()); - event->accept (); - } - else - { - QGraphicsView::mouseMoveEvent (event); - } - } - else - { - if (!mTabletStylusIsPressed && scene ()) - { - scene ()->inputDeviceMove (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ())), mMouseButtonIsPressed); - } - event->accept (); - } -} - -void -UBBoardView::mouseReleaseEvent (QMouseEvent *event) -{ - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - scene ()->setToolCursor (currentTool); - setToolCursor (currentTool); - - // first propagate device release to the scene - if (scene ()) - scene ()->inputDeviceRelease (); - - if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mouseReleaseEvent (event); - } - else if (currentTool == UBStylusTool::Text) - { - if (mRubberBand) - mRubberBand->hide (); - - if (scene () && mRubberBand && mIsCreatingTextZone) - { - QRect rubberRect = mRubberBand->geometry (); - - UBGraphicsTextItem* textItem = scene ()->addText ("", mapToScene (rubberRect.topLeft ())); - event->accept (); - - UBDrawingController::drawingController ()->setStylusTool (UBStylusTool::Selector); - - textItem->setSelected (true); - } - else - { - QGraphicsView::mouseReleaseEvent (event); - } - - mIsCreatingTextZone = false; - } - else if (currentTool == UBStylusTool::Capture) - { - if (mRubberBand) - mRubberBand->hide (); - - if (scene () && mRubberBand && mIsCreatingSceneGrabZone && mRubberBand->geometry ().width () > 16) - { - QRect rect = mRubberBand->geometry (); - QPointF sceneTopLeft = mapToScene (rect.topLeft ()); - QPointF sceneBottomRight = mapToScene (rect.bottomRight ()); - QRectF sceneRect (sceneTopLeft, sceneBottomRight); - - mController->grabScene (sceneRect); - - event->accept (); - } - else - { - QGraphicsView::mouseReleaseEvent (event); - } - - mIsCreatingSceneGrabZone = false; - } - else - { - if (mPendingStylusReleaseEvent || mMouseButtonIsPressed) - { - event->accept (); - } - } - - mMouseButtonIsPressed = false; - mPendingStylusReleaseEvent = false; - mTabletStylusIsPressed = false; - -} - -void -UBBoardView::forcedTabletRelease () -{ - - if (mMouseButtonIsPressed || mTabletStylusIsPressed || mPendingStylusReleaseEvent) - { - qWarning () << "dirty mouse/tablet state:"; - qWarning () << "mMouseButtonIsPressed =" << mMouseButtonIsPressed; - qWarning () << "mTabletStylusIsPressed = " << mTabletStylusIsPressed; - qWarning () << "mPendingStylusReleaseEvent" << mPendingStylusReleaseEvent; - qWarning () << "forcing device release"; - - scene ()->inputDeviceRelease (); - - mMouseButtonIsPressed = false; - mTabletStylusIsPressed = false; - mPendingStylusReleaseEvent = false; - - } -} - -void -UBBoardView::mouseDoubleClickEvent (QMouseEvent *event) -{ - // We don't want a double click, we want two clicks - mousePressEvent (event); -} - -void -UBBoardView::wheelEvent (QWheelEvent *event) -{ - if (isInteractive () && event->orientation () == Qt::Vertical) - { - // Too many wheelEvent are sent, how should we handle them to "smoothly" zoom ? - // something like zoom( pow(zoomFactor, event->delta() / 120) ) - } - event->accept (); -} - -void -UBBoardView::leaveEvent (QEvent * event) -{ - if (scene ()) - scene ()->leaveEvent (event); - - QGraphicsView::leaveEvent (event); -} - -void -UBBoardView::drawItems (QPainter *painter, int numItems, - QGraphicsItem* items[], - const QStyleOptionGraphicsItem options[]) -{ - if (!mFilterZIndex) - { - QGraphicsView::drawItems (painter, numItems, items, options); - } - else - { - int count = 0; - - QGraphicsItem** itemsFiltered = new QGraphicsItem*[numItems]; - QStyleOptionGraphicsItem *optionsFiltered = new QStyleOptionGraphicsItem[numItems]; - - for (int i = 0; i < numItems; i++) - { - if (shouldDisplayItem (items[i])) - { - itemsFiltered[count] = items[i]; - optionsFiltered[count] = options[i]; - count++; - } - } - - QGraphicsView::drawItems (painter, count, itemsFiltered, optionsFiltered); - - delete[] optionsFiltered; - delete[] itemsFiltered; - } -} - -void -UBBoardView::dragEnterEvent (QDragEnterEvent *event) -{ - // TODO UB 4.x be smarter with drag accept code .... we cannot handle everything ... - event->acceptProposedAction (); -} - -void -UBBoardView::dragMoveEvent (QDragMoveEvent *event) -{ - event->acceptProposedAction (); -} - -void -UBBoardView::dropEvent (QDropEvent *event) -{ - if(!event->source() || dynamic_cast(event->source())) - { - mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); - event->acceptProposedAction (); - } -} - -void -UBBoardView::resizeEvent (QResizeEvent * event) -{ - const qreal maxWidth = width () * 10; - const qreal maxHeight = height () * 10; - - setSceneRect (-(maxWidth / 2), -(maxHeight / 2), maxWidth, maxHeight); - centerOn (0, 0); - - emit resized (event); -} - -void -UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) -{ - if (testAttribute (Qt::WA_TranslucentBackground)) - { - QGraphicsView::drawBackground (painter, rect); - return; - } - - bool darkBackground = scene () && scene ()->isDarkBackground (); - - if (darkBackground) - { - painter->fillRect (rect, QBrush (QColor (Qt::black))); - } - else - { - painter->fillRect (rect, QBrush (QColor (Qt::white))); - } - - if (transform ().m11 () > 0.5) - { - QColor bgCrossColor; - - if (darkBackground) - bgCrossColor = UBSettings::crossDarkBackground; - else - bgCrossColor = UBSettings::crossLightBackground; - - if (transform ().m11 () < 1.0) - { - int alpha = 255 * transform ().m11 () / 2; - bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms - } - - painter->setPen (bgCrossColor); - - if (scene () && scene ()->isCrossedBackground ()) - { - qreal firstY = ((int) (rect.y () / UBSettings::crossSize)) * UBSettings::crossSize; - - for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += UBSettings::crossSize) - { - painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); - } - - qreal firstX = ((int) (rect.x () / UBSettings::crossSize)) * UBSettings::crossSize; - - for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += UBSettings::crossSize) - { - painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); - } - } - } - - if (!mFilterZIndex && scene ()) - { - QSize pageNominalSize = scene ()->nominalSize (); - - if (pageNominalSize.isValid ()) - { - qreal penWidth = 8.0 / transform ().m11 (); - - QRectF pageRect (pageNominalSize.width () / -2, pageNominalSize.height () / -2 - , pageNominalSize.width (), pageNominalSize.height ()); - - pageRect.adjust (-penWidth / 2, -penWidth / 2, penWidth / 2, penWidth / 2); - - QColor docSizeColor; - - if (darkBackground) - docSizeColor = UBSettings::documentSizeMarkColorDarkBackground; - else - docSizeColor = UBSettings::documentSizeMarkColorLightBackground; - - QPen pen (docSizeColor); - pen.setWidth (penWidth); - painter->setPen (pen); - painter->drawRect (pageRect); - } - } -} - -void -UBBoardView::settingChanged (QVariant newValue) -{ - Q_UNUSED (newValue); - - mPenPressureSensitive = UBSettings::settings ()->boardPenPressureSensitive->get ().toBool (); - mMarkerPressureSensitive = UBSettings::settings ()->boardMarkerPressureSensitive->get ().toBool (); - mUseHighResTabletEvent = UBSettings::settings ()->boardUseHighResTabletEvent->get ().toBool (); -} - -void UBBoardView::virtualKeyboardActivated(bool b) -{ - UBPlatformUtils::setWindowNonActivableFlag(this, b); - mVirtualKeyboardActive = b; - setInteractive(!b); -} - - -// Apple remote desktop sends funny events when the transmission is bad - -bool -UBBoardView::isAbsurdPoint (QPoint point) -{ - QDesktopWidget *desktop = qApp->desktop (); - bool isValidPoint = false; - - for (int i = 0; i < desktop->numScreens (); i++) - { - QRect screenRect = desktop->screenGeometry (i); - isValidPoint = isValidPoint || screenRect.contains (point); - } - - return !isValidPoint; -} - -void -UBBoardView::focusOutEvent (QFocusEvent * event) -{ - Q_UNUSED (event); -} - -void -UBBoardView::setToolCursor (int tool) -{ - QWidget *controlViewport = viewport (); - switch (tool) - { - case UBStylusTool::Pen: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - case UBStylusTool::Eraser: - controlViewport->setCursor (UBResources::resources ()->eraserCursor); - break; - case UBStylusTool::Marker: - controlViewport->setCursor (UBResources::resources ()->markerCursor); - break; - case UBStylusTool::Pointer: - controlViewport->setCursor (UBResources::resources ()->pointerCursor); - break; - case UBStylusTool::Hand: - controlViewport->setCursor (UBResources::resources ()->handCursor); - break; - case UBStylusTool::ZoomIn: - controlViewport->setCursor (UBResources::resources ()->zoomInCursor); - break; - case UBStylusTool::ZoomOut: - controlViewport->setCursor (UBResources::resources ()->zoomOutCursor); - break; - case UBStylusTool::Selector: - controlViewport->setCursor (UBResources::resources ()->arrowCursor); - break; - case UBStylusTool::Line: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - case UBStylusTool::Text: - controlViewport->setCursor (UBResources::resources ()->textCursor); - break; - case UBStylusTool::Capture: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - default: - Q_ASSERT (false); - //failsafe - controlViewport->setCursor (UBResources::resources ()->penCursor); - } -} - - + +#include "UBBoardView.h" + +#include + +#include "UBDrawingController.h" + +#include "frameworks/UBGeometryUtils.h" + +#include "core/UBSettings.h" +#include "core/UBMimeData.h" +#include "core/UBApplication.h" +#include "core/UBSetting.h" +#include "core/UBPersistenceManager.h" + +#include "network/UBHttpGet.h" + +#include "gui/UBStylusPalette.h" +#include "gui/UBRubberBand.h" +#include "gui/UBToolWidget.h" +#include "gui/UBResources.h" +#include "gui/UBMainWindow.h" + +#include "board/UBBoardController.h" + +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBItem.h" + +#include "document/UBDocumentProxy.h" +#include "../gui/UBThumbnailWidget.h" + +#include "frameworks/UBPlatformUtils.h" + +#include "core/memcheck.h" + +UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent) +: QGraphicsView (pParent) +, mController (pController) +, mIsCreatingTextZone (false) +, mIsCreatingSceneGrabZone (false) +{ + init (); + + mFilterZIndex = false; +} + +UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent) +: QGraphicsView (pParent) +, mController (pController) +{ + init (); + + mStartLayer = pStartLayer; + mEndLayer = pEndLayer; + + mFilterZIndex = true; +} + +UBBoardView::~UBBoardView () { + //NOOP +} + +void +UBBoardView::init () +{ + connect (UBSettings::settings ()->boardPenPressureSensitive, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + connect (UBSettings::settings ()->boardMarkerPressureSensitive, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + connect (UBSettings::settings ()->boardUseHighResTabletEvent, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + setWindowFlags (Qt::FramelessWindowHint); + setFrameStyle (QFrame::NoFrame); + setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); + setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); + setAcceptDrops (true); + + setOptimizationFlag (QGraphicsView::IndirectPainting); // enable UBBoardView::drawItems filter + + mTabletStylusIsPressed = false; + mMouseButtonIsPressed = false; + mPendingStylusReleaseEvent = false; + + setCacheMode (QGraphicsView::CacheBackground); + + mUsingTabletEraser = false; + mIsCreatingTextZone = false; + mRubberBand = 0; + + mVirtualKeyboardActive = false; + + settingChanged (QVariant ()); + + unsetCursor(); +} + +UBGraphicsScene* +UBBoardView::scene () +{ + return qobject_cast (QGraphicsView::scene ()); +} + +void +UBBoardView::hideEvent (QHideEvent * event) +{ + Q_UNUSED (event); + emit hidden (); +} + +void +UBBoardView::showEvent (QShowEvent * event) +{ + Q_UNUSED (event); + emit shown (); +} + +void +UBBoardView::keyPressEvent (QKeyEvent *event) +{ + // send to the scene anyway + QApplication::sendEvent (scene (), event); + + if (!event->isAccepted ()) + { + switch (event->key ()) + { + case Qt::Key_Up: + case Qt::Key_PageUp: + case Qt::Key_Left: + { + mController->previousScene (); + break; + } + + case Qt::Key_Down: + case Qt::Key_PageDown: + case Qt::Key_Right: + case Qt::Key_Space: + { + mController->nextScene (); + break; + } + + case Qt::Key_Home: + { + mController->firstScene (); + break; + } + case Qt::Key_End: + { + mController->lastScene (); + break; + } + case Qt::Key_Insert: + { + mController->addScene (); + break; + } + } + + + if (event->modifiers () & Qt::ControlModifier) // keep only ctrl/cmd keys + { + switch (event->key ()) + { + case Qt::Key_Plus: + case Qt::Key_I: + { + mController->zoomIn (); + event->accept (); + break; + } + case Qt::Key_Minus: + case Qt::Key_O: + { + mController->zoomOut (); + event->accept (); + break; + } + case Qt::Key_0: + { + mController->zoomRestore (); + event->accept (); + break; + } + case Qt::Key_Left: + { + mController->handScroll (-100, 0); + event->accept (); + break; + } + case Qt::Key_Right: + { + mController->handScroll (100, 0); + event->accept (); + break; + } + case Qt::Key_Up: + { + mController->handScroll (0, -100); + event->accept (); + break; + } + case Qt::Key_Down: + { + mController->handScroll (0, 100); + event->accept (); + break; + } + default: + { + // NOOP + } + } + } + } +} + +bool +UBBoardView::event (QEvent * e) +{ + if (e->type () == QEvent::Gesture) + { + QGestureEvent *gestureEvent = dynamic_cast (e); + if (gestureEvent) + { + QSwipeGesture* swipe = dynamic_cast (gestureEvent->gesture (Qt::SwipeGesture)); + + if (swipe) + { + if (swipe->horizontalDirection () == QSwipeGesture::Left) + { + mController->previousScene (); + gestureEvent->setAccepted (swipe, true); + } + + if (swipe->horizontalDirection () == QSwipeGesture::Right) + { + mController->nextScene (); + gestureEvent->setAccepted (swipe, true); + } + } + } + } + + return QGraphicsView::event (e); +} + +void +UBBoardView::tabletEvent (QTabletEvent * event) +{ + if (!mUseHighResTabletEvent) + { + event->setAccepted (false); + return; + } + + UBDrawingController *dc = UBDrawingController::drawingController (); + + QPointF tabletPos = UBGeometryUtils::pointConstrainedInRect (event->hiResGlobalPos () + - mapToGlobal (QPoint (0, 0)), rect ()); + + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); + + if (event->type () == QEvent::TabletPress || event->type () == QEvent::TabletEnterProximity) + { + if (event->pointerType () == QTabletEvent::Eraser) + { + dc->setStylusTool (UBStylusTool::Eraser); + mUsingTabletEraser = true; + } + else + { + if (mUsingTabletEraser && currentTool == UBStylusTool::Eraser) + { + dc->setStylusTool (dc->latestDrawingTool ()); + } + + mUsingTabletEraser = false; + } + } + + // if event are not Pen events, we drop the tablet stuff and route everything through mouse event + if (currentTool != UBStylusTool::Pen + && currentTool != UBStylusTool::Line + && currentTool != UBStylusTool::Marker + && !mMarkerPressureSensitive) + { + event->setAccepted (false); + return; + } + + QPointF scenePos = viewportTransform ().inverted ().map (tabletPos); + + qreal pressure = 1.0; + if (((currentTool == UBStylusTool::Pen || currentTool == UBStylusTool::Line) + && mPenPressureSensitive) + || (currentTool == UBStylusTool::Marker && mMarkerPressureSensitive)) + { + pressure = event->pressure (); + } + + bool acceptEvent = true; + + switch (event->type ()) + { + case QEvent::TabletPress: + { + mTabletStylusIsPressed = true; + + scene ()->inputDevicePress (scenePos, pressure); + + break; + } + case QEvent::TabletMove: + { + if (mTabletStylusIsPressed) + { + scene ()->inputDeviceMove (scenePos, pressure); + } + + acceptEvent = false; // rerouted to mouse move + + break; + + } + case QEvent::TabletRelease: + { + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); + scene ()->setToolCursor (currentTool); + setToolCursor (currentTool); + + scene ()->inputDeviceRelease (); + + mPendingStylusReleaseEvent = false; + + mTabletStylusIsPressed = false; + mMouseButtonIsPressed = false; + + break; + } + default: + { + //NOOP - avoid compiler warning + } + } + + // ignore mouse press and mouse move tablet event so that it is rerouted to mouse events, + // documented in QTabletEvent Class Reference: + /* The event handler QWidget::tabletEvent() receives all three types of tablet events. + Qt will first send a tabletEvent then, if it is not accepted, it will send a mouse event. */ + // + // This is a workaround to the fact that tablet event are not delivered to child widget (like palettes) + // + + event->setAccepted (acceptEvent); + +} + +void +UBBoardView::mousePressEvent (QMouseEvent *event) +{ + if (isAbsurdPoint (event->pos ())) + { + event->accept (); + return; + } + + mMouseDownPos = event->pos (); + + if (event->button () == Qt::LeftButton && isInteractive ()) + { + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (!mTabletStylusIsPressed) + mMouseButtonIsPressed = true; + + if (currentTool == UBStylusTool::ZoomIn) + { + mController->zoomIn (mapToScene (event->pos ())); + event->accept (); + } + else if (currentTool == UBStylusTool::ZoomOut) + { + mController->zoomOut (mapToScene (event->pos ())); + event->accept (); + } + else if (currentTool == UBStylusTool::Hand) + { + viewport ()->setCursor (QCursor (Qt::ClosedHandCursor)); + mPreviousPoint = event->posF (); + event->accept (); + } + else if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mousePressEvent (event); + } + else if (currentTool == UBStylusTool::Text) + { + int frameWidth = UBSettings::settings ()->objectFrameWidth; + QRectF fuzzyRect (0, 0, frameWidth * 4, frameWidth * 4); + fuzzyRect.moveCenter (mapToScene (mMouseDownPos)); + + UBGraphicsTextItem* foundTextItem = 0; + QListIterator it (scene ()->items (fuzzyRect)); + + while (it.hasNext () && !foundTextItem) + { + foundTextItem = qgraphicsitem_cast(it.next ()); + } + + if (foundTextItem) + { + mIsCreatingTextZone = false; + QGraphicsView::mousePressEvent (event); + } + else + { + scene ()->deselectAllItems (); + + if (!mRubberBand) + mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); + + mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); + mRubberBand->show (); + mIsCreatingTextZone = true; + + event->accept (); + } + } + else if (currentTool == UBStylusTool::Capture) + { + scene ()->deselectAllItems (); + + if (!mRubberBand) + mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); + + mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); + mRubberBand->show (); + mIsCreatingSceneGrabZone = true; + + event->accept (); + } + else + { + if(UBDrawingController::drawingController()->mActiveRuler==NULL) + { + viewport()->setCursor (QCursor (Qt::BlankCursor)); + } + + if (scene () && !mTabletStylusIsPressed) + { + scene ()->inputDevicePress (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ()))); + } + event->accept (); + } + } +} + +void +UBBoardView::mouseMoveEvent (QMouseEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (isAbsurdPoint (event->pos ())) + { + event->accept (); + return; + } + + if (currentTool == UBStylusTool::Hand && (mMouseButtonIsPressed || mTabletStylusIsPressed)) + { + QPointF eventPosition = event->posF (); + qreal dx = eventPosition.x () - mPreviousPoint.x (); + qreal dy = eventPosition.y () - mPreviousPoint.y (); + mController->handScroll (dx, dy); + mPreviousPoint = eventPosition; + event->accept (); + } + else if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mouseMoveEvent (event); + } + else if ((UBDrawingController::drawingController()->isDrawingTool()) + && !mMouseButtonIsPressed) + { + QGraphicsView::mouseMoveEvent (event); + } + else if (currentTool == UBStylusTool::Text || currentTool == UBStylusTool::Capture) + { + if (mRubberBand && (mIsCreatingTextZone || mIsCreatingSceneGrabZone)) + { + mRubberBand->setGeometry (QRect (mMouseDownPos, event->pos ()).normalized ()); + event->accept (); + } + else + { + QGraphicsView::mouseMoveEvent (event); + } + } + else + { + if (!mTabletStylusIsPressed && scene ()) + { + scene ()->inputDeviceMove (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ())), mMouseButtonIsPressed); + } + event->accept (); + } +} + +void +UBBoardView::mouseReleaseEvent (QMouseEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + scene ()->setToolCursor (currentTool); + setToolCursor (currentTool); + + // first propagate device release to the scene + if (scene ()) + scene ()->inputDeviceRelease (); + + if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mouseReleaseEvent (event); + } + else if (currentTool == UBStylusTool::Text) + { + if (mRubberBand) + mRubberBand->hide (); + + if (scene () && mRubberBand && mIsCreatingTextZone) + { + QRect rubberRect = mRubberBand->geometry (); + + UBGraphicsTextItem* textItem = scene ()->addText ("", mapToScene (rubberRect.topLeft ())); + event->accept (); + + UBDrawingController::drawingController ()->setStylusTool (UBStylusTool::Selector); + + textItem->setSelected (true); + } + else + { + QGraphicsView::mouseReleaseEvent (event); + } + + mIsCreatingTextZone = false; + } + else if (currentTool == UBStylusTool::Capture) + { + if (mRubberBand) + mRubberBand->hide (); + + if (scene () && mRubberBand && mIsCreatingSceneGrabZone && mRubberBand->geometry ().width () > 16) + { + QRect rect = mRubberBand->geometry (); + QPointF sceneTopLeft = mapToScene (rect.topLeft ()); + QPointF sceneBottomRight = mapToScene (rect.bottomRight ()); + QRectF sceneRect (sceneTopLeft, sceneBottomRight); + + mController->grabScene (sceneRect); + + event->accept (); + } + else + { + QGraphicsView::mouseReleaseEvent (event); + } + + mIsCreatingSceneGrabZone = false; + } + else + { + if (mPendingStylusReleaseEvent || mMouseButtonIsPressed) + { + event->accept (); + } + } + + mMouseButtonIsPressed = false; + mPendingStylusReleaseEvent = false; + mTabletStylusIsPressed = false; + +} + +void +UBBoardView::forcedTabletRelease () +{ + + if (mMouseButtonIsPressed || mTabletStylusIsPressed || mPendingStylusReleaseEvent) + { + qWarning () << "dirty mouse/tablet state:"; + qWarning () << "mMouseButtonIsPressed =" << mMouseButtonIsPressed; + qWarning () << "mTabletStylusIsPressed = " << mTabletStylusIsPressed; + qWarning () << "mPendingStylusReleaseEvent" << mPendingStylusReleaseEvent; + qWarning () << "forcing device release"; + + scene ()->inputDeviceRelease (); + + mMouseButtonIsPressed = false; + mTabletStylusIsPressed = false; + mPendingStylusReleaseEvent = false; + + } +} + +void +UBBoardView::mouseDoubleClickEvent (QMouseEvent *event) +{ + // We don't want a double click, we want two clicks + mousePressEvent (event); +} + +void +UBBoardView::wheelEvent (QWheelEvent *event) +{ + if (isInteractive () && event->orientation () == Qt::Vertical) + { + // Too many wheelEvent are sent, how should we handle them to "smoothly" zoom ? + // something like zoom( pow(zoomFactor, event->delta() / 120) ) + } + event->accept (); +} + +void +UBBoardView::leaveEvent (QEvent * event) +{ + if (scene ()) + scene ()->leaveEvent (event); + + QGraphicsView::leaveEvent (event); +} + +void +UBBoardView::drawItems (QPainter *painter, int numItems, + QGraphicsItem* items[], + const QStyleOptionGraphicsItem options[]) +{ + if (!mFilterZIndex) + { + QGraphicsView::drawItems (painter, numItems, items, options); + } + else + { + int count = 0; + + QGraphicsItem** itemsFiltered = new QGraphicsItem*[numItems]; + QStyleOptionGraphicsItem *optionsFiltered = new QStyleOptionGraphicsItem[numItems]; + + for (int i = 0; i < numItems; i++) + { + if (shouldDisplayItem (items[i])) + { + itemsFiltered[count] = items[i]; + optionsFiltered[count] = options[i]; + count++; + } + } + + QGraphicsView::drawItems (painter, count, itemsFiltered, optionsFiltered); + + delete[] optionsFiltered; + delete[] itemsFiltered; + } +} + +void +UBBoardView::dragEnterEvent (QDragEnterEvent *event) +{ + // TODO UB 4.x be smarter with drag accept code .... we cannot handle everything ... + event->acceptProposedAction (); +} + +void +UBBoardView::dragMoveEvent (QDragMoveEvent *event) +{ + event->acceptProposedAction (); +} + +void +UBBoardView::dropEvent (QDropEvent *event) +{ + if(!event->source() || dynamic_cast(event->source())) + { + mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); + event->acceptProposedAction (); + } +} + +void +UBBoardView::resizeEvent (QResizeEvent * event) +{ + const qreal maxWidth = width () * 10; + const qreal maxHeight = height () * 10; + + setSceneRect (-(maxWidth / 2), -(maxHeight / 2), maxWidth, maxHeight); + centerOn (0, 0); + + emit resized (event); +} + +void +UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) +{ + if (testAttribute (Qt::WA_TranslucentBackground)) + { + QGraphicsView::drawBackground (painter, rect); + return; + } + + bool darkBackground = scene () && scene ()->isDarkBackground (); + + if (darkBackground) + { + painter->fillRect (rect, QBrush (QColor (Qt::black))); + } + else + { + painter->fillRect (rect, QBrush (QColor (Qt::white))); + } + + if (transform ().m11 () > 0.5) + { + QColor bgCrossColor; + + if (darkBackground) + bgCrossColor = UBSettings::crossDarkBackground; + else + bgCrossColor = UBSettings::crossLightBackground; + + if (transform ().m11 () < 1.0) + { + int alpha = 255 * transform ().m11 () / 2; + bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms + } + + painter->setPen (bgCrossColor); + + if (scene () && scene ()->isCrossedBackground ()) + { + qreal firstY = ((int) (rect.y () / UBSettings::crossSize)) * UBSettings::crossSize; + + for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += UBSettings::crossSize) + { + painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); + } + + qreal firstX = ((int) (rect.x () / UBSettings::crossSize)) * UBSettings::crossSize; + + for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += UBSettings::crossSize) + { + painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); + } + } + } + + if (!mFilterZIndex && scene ()) + { + QSize pageNominalSize = scene ()->nominalSize (); + + if (pageNominalSize.isValid ()) + { + qreal penWidth = 8.0 / transform ().m11 (); + + QRectF pageRect (pageNominalSize.width () / -2, pageNominalSize.height () / -2 + , pageNominalSize.width (), pageNominalSize.height ()); + + pageRect.adjust (-penWidth / 2, -penWidth / 2, penWidth / 2, penWidth / 2); + + QColor docSizeColor; + + if (darkBackground) + docSizeColor = UBSettings::documentSizeMarkColorDarkBackground; + else + docSizeColor = UBSettings::documentSizeMarkColorLightBackground; + + QPen pen (docSizeColor); + pen.setWidth (penWidth); + painter->setPen (pen); + painter->drawRect (pageRect); + } + } +} + +void +UBBoardView::settingChanged (QVariant newValue) +{ + Q_UNUSED (newValue); + + mPenPressureSensitive = UBSettings::settings ()->boardPenPressureSensitive->get ().toBool (); + mMarkerPressureSensitive = UBSettings::settings ()->boardMarkerPressureSensitive->get ().toBool (); + mUseHighResTabletEvent = UBSettings::settings ()->boardUseHighResTabletEvent->get ().toBool (); +} + +void UBBoardView::virtualKeyboardActivated(bool b) +{ + UBPlatformUtils::setWindowNonActivableFlag(this, b); + mVirtualKeyboardActive = b; + setInteractive(!b); +} + + +// Apple remote desktop sends funny events when the transmission is bad + +bool +UBBoardView::isAbsurdPoint (QPoint point) +{ + QDesktopWidget *desktop = qApp->desktop (); + bool isValidPoint = false; + + for (int i = 0; i < desktop->numScreens (); i++) + { + QRect screenRect = desktop->screenGeometry (i); + isValidPoint = isValidPoint || screenRect.contains (point); + } + + return !isValidPoint; +} + +void +UBBoardView::focusOutEvent (QFocusEvent * event) +{ + Q_UNUSED (event); +} + +void +UBBoardView::setToolCursor (int tool) +{ + QWidget *controlViewport = viewport (); + switch (tool) + { + case UBStylusTool::Pen: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + case UBStylusTool::Eraser: + controlViewport->setCursor (UBResources::resources ()->eraserCursor); + break; + case UBStylusTool::Marker: + controlViewport->setCursor (UBResources::resources ()->markerCursor); + break; + case UBStylusTool::Pointer: + controlViewport->setCursor (UBResources::resources ()->pointerCursor); + break; + case UBStylusTool::Hand: + controlViewport->setCursor (UBResources::resources ()->handCursor); + break; + case UBStylusTool::ZoomIn: + controlViewport->setCursor (UBResources::resources ()->zoomInCursor); + break; + case UBStylusTool::ZoomOut: + controlViewport->setCursor (UBResources::resources ()->zoomOutCursor); + break; + case UBStylusTool::Selector: + controlViewport->setCursor (UBResources::resources ()->arrowCursor); + break; + case UBStylusTool::Line: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + case UBStylusTool::Text: + controlViewport->setCursor (UBResources::resources ()->textCursor); + break; + case UBStylusTool::Capture: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + default: + Q_ASSERT (false); + //failsafe + controlViewport->setCursor (UBResources::resources ()->penCursor); + } +} + + diff --git a/src/desktop/UBDesktopAnnotationController.cpp b/src/desktop/UBDesktopAnnotationController.cpp index d7a4a9cd..b78e767c 100644 --- a/src/desktop/UBDesktopAnnotationController.cpp +++ b/src/desktop/UBDesktopAnnotationController.cpp @@ -90,6 +90,7 @@ UBDesktopAnnotationController::UBDesktopAnnotationController(QObject *parent) mKeyboardPalette = UBKeyboardPalette::create(mTransparentDrawingView); mKeyboardPalette->setParent(mTransparentDrawingView); connect(mKeyboardPalette, SIGNAL(keyboardActivated(bool)), mTransparentDrawingView, SLOT(virtualKeyboardActivated(bool))); + connect(mKeyboardPalette, SIGNAL(moved(QPoint)), this, SLOT(refreshMask())); } connect(mDesktopPalette, SIGNAL(uniboardClick()), this, SLOT(goToUniboard())); @@ -143,12 +144,16 @@ UBDesktopAnnotationController::UBDesktopAnnotationController(QObject *parent) connect(&mHoldTimerMarker, SIGNAL(timeout()), this, SLOT(markerActionReleased())); connect(&mHoldTimerEraser, SIGNAL(timeout()), this, SLOT(eraserActionReleased())); + connect(mDesktopPalette, SIGNAL(moving()), this, SLOT(refreshMask())); + connect(mLibPalette, SIGNAL(resized()), this, SLOT(refreshMask())); + onDesktopPaletteMaximized(); } void UBDesktopAnnotationController::showKeyboard(bool show) { mKeyboardPalette->setVisible(show); + updateMask(true); // mDesktopPalette->showVirtualKeyboard(show); } @@ -332,6 +337,10 @@ void UBDesktopAnnotationController::showWindow() UBPlatformUtils::setDesktopMode(true); mDesktopPalette->appear(); + +#ifdef Q_WS_X11 + updateMask(true); +#endif } @@ -343,7 +352,15 @@ void UBDesktopAnnotationController::close() void UBDesktopAnnotationController::stylusToolChanged(int tool) { - Q_UNUSED(tool); + UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; + mDesktopPalette->notifySelectorSelection(UBStylusTool::Selector == eTool); + + if(UBStylusTool::Selector != eTool) + { + UBApplication::mainWindow->actionVirtualKeyboard->setChecked(false); + mKeyboardPalette->setVisible(false); + } + updateBackground(); } @@ -356,6 +373,9 @@ void UBDesktopAnnotationController::updateBackground() || UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) { newBrush = QBrush(Qt::transparent); +#ifdef Q_WS_X11 + updateMask(true); +#endif } else { @@ -363,6 +383,9 @@ void UBDesktopAnnotationController::updateBackground() newBrush = QBrush(QColor(127, 127, 127, 15)); #else newBrush = QBrush(QColor(127, 127, 127, 1)); +#endif +#ifdef Q_WS_X11 + updateMask(false); #endif } @@ -389,6 +412,8 @@ void UBDesktopAnnotationController::goToUniboard() UBPlatformUtils::setDesktopMode(false); + UBApplication::mainWindow->actionVirtualKeyboard->setEnabled(true); + emit restoreUniboard(); } @@ -751,3 +776,83 @@ void UBDesktopAnnotationController::onTransparentWidgetResized() // qDebug() << "mLibPalette (" << mLibPalette->width() << "," << mLibPalette->height() << ")"; mLibPalette->resize(mLibPalette->width(), mTransparentDrawingView->height()); } + +void UBDesktopAnnotationController::updateMask(bool bTransparent) +{ + if(bTransparent) + { + // Here we have to generate a new mask. This method is certainly resource + // consuming but for the moment this is the only solution that I found. + mMask = QPixmap(mTransparentDrawingView->width(), mTransparentDrawingView->height()); + + QPainter p; + + p.begin(&mMask); + + p.setPen(Qt::red); + p.setBrush(QBrush(Qt::red)); + + // Here we draw the widget mask + if(mDesktopPalette->isVisible()) + { + p.drawRect(mDesktopPalette->geometry().x(), mDesktopPalette->geometry().y(), mDesktopPalette->width(), mDesktopPalette->height()); + } + if(mKeyboardPalette->isVisible()) + { + p.drawRect(mKeyboardPalette->geometry().x(), mKeyboardPalette->geometry().y(), mKeyboardPalette->width(), mKeyboardPalette->height()); + } + if(mLibPalette->isVisible()) + { + p.drawRect(mLibPalette->geometry().x(), mLibPalette->geometry().y(), mLibPalette->width(), mLibPalette->height()); + } + + p.end(); + + // Then we add the annotations. We create another painter because we need to + // apply transformations on it for coordinates matching + QPainter annotationPainter; + + QTransform trans; + trans.translate(mTransparentDrawingView->width()/2, mTransparentDrawingView->height()/2); + + annotationPainter.begin(&mMask); + annotationPainter.setPen(Qt::red); + annotationPainter.setBrush(Qt::red); + + annotationPainter.setTransform(trans); + + QList allItems = mTransparentDrawingScene->items(); + + for(int i = 0; i < allItems.size(); i++) + { + QGraphicsItem* pCrntItem = allItems.at(i); + + if(pCrntItem->isVisible()) + { + QPainterPath crntPath = pCrntItem->shape(); + QRectF rect = crntPath.boundingRect(); + + annotationPainter.drawRect(rect); + } + } + + annotationPainter.end(); + + mTransparentDrawingView->setMask(mMask.createMaskFromColor(Qt::black)); + } + else + { + // Remove the mask + QPixmap noMask(mTransparentDrawingView->width(), mTransparentDrawingView->height()); + mTransparentDrawingView->setMask(noMask.mask()); + } +} + +void UBDesktopAnnotationController::refreshMask() +{ + if(mIsFullyTransparent + || UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + updateMask(true); + } +} diff --git a/src/desktop/UBDesktopAnnotationController.h b/src/desktop/UBDesktopAnnotationController.h index d595c04a..469296a7 100644 --- a/src/desktop/UBDesktopAnnotationController.h +++ b/src/desktop/UBDesktopAnnotationController.h @@ -94,10 +94,12 @@ class UBDesktopAnnotationController : public QObject void onDesktopPaletteMaximized(); void onDesktopPaletteMinimize(); void onTransparentWidgetResized(); + void refreshMask(); private: void setAssociatedPalettePosition(UBActionPalette* palette, const QString& actionName); void togglePropertyPalette(UBActionPalette* palette); + void updateMask(bool bTransparent); UBDesktopPalette *mDesktopPalette; UBKeyboardPalette *mKeyboardPalette; @@ -126,6 +128,8 @@ class UBDesktopAnnotationController : public QObject int mBoardStylusTool; int mDesktopStylusTool; + QPixmap mMask; + }; #endif /* UBUNINOTESWINDOWCONTROLLER_H_ */ diff --git a/src/desktop/UBDesktopPalette.cpp b/src/desktop/UBDesktopPalette.cpp index 6ec00c8a..f881f58a 100644 --- a/src/desktop/UBDesktopPalette.cpp +++ b/src/desktop/UBDesktopPalette.cpp @@ -36,9 +36,7 @@ UBDesktopPalette::UBDesktopPalette(QWidget *parent) actions << UBApplication::mainWindow->actionPen; actions << UBApplication::mainWindow->actionEraser; actions << UBApplication::mainWindow->actionMarker; -#ifndef Q_WS_X11 actions << UBApplication::mainWindow->actionSelector; -#endif actions << UBApplication::mainWindow->actionPointer; if (UBPlatformUtils::hasVirtualKeyboard()) @@ -152,9 +150,7 @@ void UBDesktopPalette::maximizeMe() actions << UBApplication::mainWindow->actionPen; actions << UBApplication::mainWindow->actionEraser; actions << UBApplication::mainWindow->actionMarker; -#ifndef Q_WS_X11 actions << UBApplication::mainWindow->actionSelector; -#endif actions << UBApplication::mainWindow->actionPointer; if (UBPlatformUtils::hasVirtualKeyboard()) actions << UBApplication::mainWindow->actionVirtualKeyboard; @@ -221,3 +217,8 @@ QPoint UBDesktopPalette::buttonPos(QAction *action) return p; } + +void UBDesktopPalette::notifySelectorSelection(bool selected) +{ + UBApplication::mainWindow->actionVirtualKeyboard->setEnabled(selected); +} diff --git a/src/desktop/UBDesktopPalette.h b/src/desktop/UBDesktopPalette.h index 83c01eab..17168b85 100644 --- a/src/desktop/UBDesktopPalette.h +++ b/src/desktop/UBDesktopPalette.h @@ -27,6 +27,7 @@ class UBDesktopPalette : public UBActionPalette void disappearForCapture(); void appear(); QPoint buttonPos(QAction* action); + void notifySelectorSelection(bool selected); signals: void uniboardClick(); diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 8a69e4e0..b66f4396 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -249,6 +249,8 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres { if (currentTool == UBStylusTool::Line) { + // TODO: Verify this beautiful implementation and check if + // it is possible to optimize it QLineF radius(mPreviousPoint, position); qreal angle = radius.angle(); angle = qRound(angle / 45) * 45; @@ -257,7 +259,7 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres mPreviousPoint.x() + radiusLength * cos((angle * PI) / 180), mPreviousPoint.y() - radiusLength * sin((angle * PI) / 180)); QLineF chord(position, newPosition); - if (chord.length() < qMin((int)16, (int)(radiusLength / 20))) + if (chord.length() < qMin((int)16, (int)(radiusLength / 20))) position = newPosition; } diff --git a/src/gui/UBFloatingPalette.cpp b/src/gui/UBFloatingPalette.cpp index 83a85261..6be7d5bc 100644 --- a/src/gui/UBFloatingPalette.cpp +++ b/src/gui/UBFloatingPalette.cpp @@ -106,6 +106,7 @@ void UBFloatingPalette::mouseMoveEvent(QMouseEvent *event) { moveInsideParent(event->globalPos() - mDragPosition); event->accept(); + emit moving(); } else { diff --git a/src/gui/UBFloatingPalette.h b/src/gui/UBFloatingPalette.h index a7e63125..0ddc6ade 100644 --- a/src/gui/UBFloatingPalette.h +++ b/src/gui/UBFloatingPalette.h @@ -78,6 +78,7 @@ class UBFloatingPalette : public QWidget void minimizeStart(eMinimizedLocation location); void maximizeStart(); void maximized(); + void moving(); }; diff --git a/src/gui/UBLibPalette.cpp b/src/gui/UBLibPalette.cpp index 656e2276..56ffeef2 100644 --- a/src/gui/UBLibPalette.cpp +++ b/src/gui/UBLibPalette.cpp @@ -34,7 +34,7 @@ UBLibPalette::UBLibPalette(QWidget *parent, const char *name):UBDockPalette(pare mIcon = QPixmap(":images/paletteLibrary.png"); setAcceptDrops(true); - resize(UBSettings::settings()->libPaletteWidth->get().toInt(), height()); + resize(UBSettings::settings()->libPaletteWidth->get().toInt(), parentWidget()->height()); setContentsMargins(border(), 0, 0, 0); mCollapseWidth = 180; mLastWidth = 300; @@ -201,6 +201,7 @@ void UBLibPalette::resizeEvent(QResizeEvent *event) { UBDockPalette::resizeEvent(event); UBSettings::settings()->libPaletteWidth->set(width()); + emit resized(); } // -------------------------------------------------------------------------- diff --git a/src/gui/UBLibPalette.h b/src/gui/UBLibPalette.h index 3733610e..afbe8ff9 100644 --- a/src/gui/UBLibPalette.h +++ b/src/gui/UBLibPalette.h @@ -55,6 +55,9 @@ public: UBLibActionBar* actionBar(){return mActionBar;} +signals: + void resized(); + protected: void updateMaxWidth(); void dragEnterEvent(QDragEnterEvent* pEvent);