示例#1
0
void
NodeGraph::mouseMoveEvent(QMouseEvent* e)
{
    QPointF newPos = mapToScene( e->pos() );
    QPointF lastMousePosScene = mapToScene( _imp->_lastMousePos.x(), _imp->_lastMousePos.y() );
    double dx, dy;
    {
        QPointF newPosRoot = _imp->_root->mapFromScene(newPos);
        QPointF lastMousePosRoot = _imp->_root->mapFromScene(lastMousePosScene);
        dx = newPosRoot.x() - lastMousePosRoot.x();
        dy = newPosRoot.y() - lastMousePosRoot.y();
    }

    _imp->_hasMovedOnce = true;

    bool mustUpdate = true;
    boost::shared_ptr<NodeCollection> collection = getGroup();
    NodeGroup* isGroup = dynamic_cast<NodeGroup*>( collection.get() );
    bool isGroupEditable = true;
    bool groupEdited = true;
    if (isGroup) {
        isGroupEditable = isGroup->isSubGraphEditable();
        groupEdited = isGroup->getNode()->hasPyPlugBeenEdited();
    }
    if (!groupEdited && isGroupEditable) {
        ///check if user is nearby unlock
        int iw = _imp->unlockIcon.width();
        int ih = _imp->unlockIcon.height();
        int w = width();
        if ( ( e->x() >= (w - iw - 10 - 15) ) && ( e->x() <= (w - 10 + 15) ) &&
                ( e->y() >= (10 - 15) ) && ( e->y() <= (10 + ih + 15) ) ) {
            assert(isGroup);
            QPoint pos = mapToGlobal( e->pos() );
            QToolTip::showText( pos, GuiUtils::convertFromPlainText(QCoreApplication::translate("NodeGraph", "Clicking the unlock button will convert the PyPlug to a regular group saved in the project and dettach it from the script.\n"
                                "Any modification will not be written to the Python script. Subsequent loading of the project will no longer load this group from the python script."), Qt::WhiteSpaceNormal) );
        }
    }

    QRectF sceneR = visibleSceneRect();
    if ( groupEdited && (_imp->_evtState != eEventStateSelectionRect) && (_imp->_evtState != eEventStateDraggingArrow) ) {
        // Set cursor

        std::set<NodeGui*> visibleNodes;
        getNodesWithinViewportRect(visibleWidgetRect(), &visibleNodes);

        NodeGuiPtr selected;
        Edge* selectedEdge = 0;
        bool optionalInputsAutoHidden = areOptionalInputsAutoHidden();

        for (std::set<NodeGui*>::iterator it = visibleNodes.begin(); it != visibleNodes.end(); ++it) {
            QPointF evpt = (*it)->mapFromScene(newPos);
            QRectF bbox = (*it)->mapToScene( (*it)->boundingRect() ).boundingRect();
            if ( (*it)->isActive() && bbox.intersects(sceneR) ) {
                if ( (*it)->contains(evpt) ) {
                    selected = (*it)->shared_from_this();
                    if (optionalInputsAutoHidden) {
                        (*it)->refreshEdgesVisility(true);
                    } else {
                        break;
                    }
                } else {
                    Edge* edge = (*it)->hasEdgeNearbyPoint(newPos);
                    if (edge) {
                        selectedEdge = edge;
                        if (!optionalInputsAutoHidden) {
                            break;
                        }
                    } else if ( optionalInputsAutoHidden && !(*it)->getIsSelected() ) {
                        (*it)->refreshEdgesVisility(false);
                    }
                }
            }
        }
        if (selected) {
            _imp->cursorSet = true;
            setCursor( QCursor(Qt::OpenHandCursor) );
        } else if (selectedEdge) {
        } else if (!selectedEdge && !selected) {
            if (_imp->cursorSet) {
                _imp->cursorSet = false;
                unsetCursor();
            }
        }
    }

    bool mustUpdateNavigator = false;
    ///Apply actions
    switch (_imp->_evtState) {
    case eEventStateDraggingArrow: {
        QPointF np = _imp->_arrowSelected->mapFromScene(newPos);
        if ( _imp->_arrowSelected->isOutputEdge() ) {
            _imp->_arrowSelected->dragDest(np);
        } else {
            _imp->_arrowSelected->dragSource(np);
        }
        checkAndStartAutoScrollTimer(newPos);
        mustUpdate = true;
        break;
    }
    case eEventStateDraggingNode: {
        mustUpdate = true;
        mustUpdateNavigator = true;
        bool controlDown = modifierHasControl(e);
        bool shiftdown = modifierHasShift(e);
        moveSelectedNodesBy(shiftdown, controlDown, lastMousePosScene, newPos, sceneR, true);
        break;
    }
    case eEventStateMovingArea: {
        mustUpdateNavigator = true;
        moveRootInternal(dx, dy);
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::SizeAllCursor) );
        mustUpdate = true;
        break;
    }
    case eEventStateResizingBackdrop: {
        mustUpdateNavigator = true;
        assert(_imp->_backdropResized);
        QPointF p = _imp->_backdropResized->scenePos();
        int w = newPos.x() - p.x();
        int h = newPos.y() - p.y();
        checkAndStartAutoScrollTimer(newPos);
        mustUpdate = true;
        pushUndoCommand( new ResizeBackdropCommand(_imp->_backdropResized, w, h) );
        break;
    }
    case eEventStateSelectionRect: {
        QPointF startDrag = _imp->_lastSelectionStartPointScene;
        QPointF cur = newPos;
        double xmin = std::min( cur.x(), startDrag.x() );
        double xmax = std::max( cur.x(), startDrag.x() );
        double ymin = std::min( cur.y(), startDrag.y() );
        double ymax = std::max( cur.y(), startDrag.y() );
        checkAndStartAutoScrollTimer(newPos);
        QRectF selRect(xmin, ymin, xmax - xmin, ymax - ymin);
        _imp->_selectionRect = selRect;
        mustUpdate = true;
        break;
    }
    case eEventStateDraggingNavigator: {
        QPointF mousePosSceneCoordinates;
        bool insideNavigator = isNearbyNavigator(e->pos(), mousePosSceneCoordinates);
        if (insideNavigator) {
            _imp->_refreshOverlays = true;
            centerOn(mousePosSceneCoordinates);
            _imp->_lastMousePos = e->pos();
            update();

            return;
        }
        break;
    }
    case eEventStateZoomingArea: {
        int delta = 2 * ( ( e->x() - _imp->_lastMousePos.x() ) - ( e->y() - _imp->_lastMousePos.y() ) );
        setTransformationAnchor(QGraphicsView::AnchorViewCenter);
        wheelEventInternal(modCASIsControl(e), delta);
        setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
        mustUpdate = true;
        break;
    }
    default:
        mustUpdate = false;
        break;
    } // switch


    _imp->_lastMousePos = e->pos();


    if (mustUpdateNavigator) {
        _imp->_refreshOverlays = true;
        mustUpdate = true;
    }

    if (mustUpdate) {
        update();
    }
    QGraphicsView::mouseMoveEvent(e);
} // mouseMoveEvent
示例#2
0
// draw focus background on area in a way typical on platform
void
wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
#if wxUSE_UXTHEME
    wxUxThemeHandle hTheme(this, L"COMBOBOX");
#endif

    wxSize sz = GetClientSize();
    bool isEnabled;
    bool doDrawFocusRect; // also selected

    // For smaller size control (and for disabled background) use less spacing
    int focusSpacingX;
    int focusSpacingY;

    if ( !(flags & wxCONTROL_ISSUBMENU) )
    {
        // Drawing control
        isEnabled = IsThisEnabled();
        doDrawFocusRect = ShouldDrawFocus();

#if wxUSE_UXTHEME
        // Windows-style: for smaller size control (and for disabled background) use less spacing
        if ( hTheme )
        {
            // WinXP  Theme
            focusSpacingX = isEnabled ? 2 : 1;
            focusSpacingY = sz.y > (GetCharHeight()+2) && isEnabled ? 2 : 1;
        }
        else
#endif
        {
            // Classic Theme
            if ( isEnabled )
            {
                focusSpacingX = 1;
                focusSpacingY = 1;
            }
            else
            {
                focusSpacingX = 0;
                focusSpacingY = 0;
            }
        }
    }
    else
    {
        // Drawing a list item
        isEnabled = true; // they are never disabled
        doDrawFocusRect = flags & wxCONTROL_SELECTED ? true : false;

        focusSpacingX = 0;
        focusSpacingY = 0;
    }

    // Set the background sub-rectangle for selection, disabled etc
    wxRect selRect(rect);
    selRect.y += focusSpacingY;
    selRect.height -= (focusSpacingY*2);

    int wcp = 0;

    if ( !(flags & wxCONTROL_ISSUBMENU) )
        wcp += m_widthCustomPaint;

    selRect.x += wcp + focusSpacingX;
    selRect.width -= wcp + (focusSpacingX*2);

    wxColour fgCol;
    wxColour bgCol;
    bool doDrawDottedEdge = false;
    bool doDrawSelRect = true;

    // TODO: doDrawDottedEdge = true when focus has arrived to control via tab.
    //       (and other cases which are not that apparent).

    if ( isEnabled )
    {
        // If popup is hidden and this control is focused,
        // then draw the focus-indicator (selbgcolor background etc.).
        if ( doDrawFocusRect )
        {
            // NB: We can't really use XP visual styles to get TMT_TEXTCOLOR since
            //     it is not properly defined for combo boxes. Instead, they expect
            //     you to use DrawThemeText.
            //
            //    Here is, however, sample code how to get theme colours:
            //
            //    COLORREF cref;
            //    theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_NORMAL,TMT_TEXTCOLOR,&cref);
            //    dc.SetTextForeground( wxRGBToColour(cref) );
            if ( (m_iFlags & wxCC_FULL_BUTTON) && !(flags & wxCONTROL_ISSUBMENU) )
            {
                // Vista style read-only combo
                fgCol = GetForegroundColour();
                bgCol = GetBackgroundColour();
                doDrawSelRect = false;
                doDrawDottedEdge = true;
            }
            else
            {
                fgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
                bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
            }
        }
        else
        {
            fgCol = GetForegroundColour();
            bgCol = GetBackgroundColour();
            doDrawSelRect = false;
        }
    }
    else
    {
        fgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
        bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
    }

    dc.SetTextForeground(fgCol);
    dc.SetBrush(bgCol);
    if ( doDrawSelRect )
    {
        dc.SetPen(bgCol);
        dc.DrawRectangle(selRect);
    }

    if ( doDrawDottedEdge )
        wxMSWDrawFocusRect(dc, selRect);

    // Don't clip exactly to the selection rectangle so we can draw
    // to the non-selected area in front of it.
    wxRect clipRect(rect.x,rect.y,
                    (selRect.x+selRect.width)-rect.x-1,rect.height);
    dc.SetClippingRegion(clipRect);
}
示例#3
0
void
TOSMagnify::DrawSelection()
{
	if (!fParent->SelectionIsShowing())
		return;

	float x, y;
	int32 pixelSize = fParent->PixelSize();
	int32 squareSize = pixelSize - 2;

	fParent->SelectionLoc(&x, &y);
	x *= pixelSize; x++;
	y *= pixelSize; y++;
	BRect selRect(x, y, x+squareSize, y+squareSize);

	short selection = fParent->Selection();

	PushState();
	SetLowColor(ViewColor());
	SetHighColor(kRedColor);
	StrokeRect(selRect);
	if (selection == 0) {
		StrokeLine(BPoint(x,y), BPoint(x+squareSize,y+squareSize));
		StrokeLine(BPoint(x,y+squareSize), BPoint(x+squareSize,y));
	}

	bool ch1Showing, ch2Showing;
	fParent->CrossHairsShowing(&ch1Showing, &ch2Showing);
	if (ch1Showing) {
		SetHighColor(kBlueColor);
		fParent->CrossHair1Loc(&x, &y);
		x *= pixelSize; x++;
		y *= pixelSize; y++;
		selRect.Set(x, y,x+squareSize, y+squareSize);
		StrokeRect(selRect);
		BeginLineArray(4);
		AddLine(BPoint(0, y+(squareSize/2)),
			BPoint(x, y+(squareSize/2)), kBlueColor);					//	left
		AddLine(BPoint(x+squareSize,y+(squareSize/2)),
			BPoint(Bounds().Width(), y+(squareSize/2)), kBlueColor);	// right
		AddLine(BPoint(x+(squareSize/2), 0),
			BPoint(x+(squareSize/2), y), kBlueColor);					// top
		AddLine(BPoint(x+(squareSize/2), y+squareSize),
			BPoint(x+(squareSize/2), Bounds().Height()), kBlueColor);	// bottom
		EndLineArray();
		if (selection == 1) {
			StrokeLine(BPoint(x,y), BPoint(x+squareSize,y+squareSize));
			StrokeLine(BPoint(x,y+squareSize), BPoint(x+squareSize,y));
		}
	}
	if (ch2Showing) {
		SetHighColor(kBlueColor);
		fParent->CrossHair2Loc(&x, &y);
		x *= pixelSize; x++;
		y *= pixelSize; y++;
		selRect.Set(x, y,x+squareSize, y+squareSize);
		StrokeRect(selRect);
		BeginLineArray(4);
		AddLine(BPoint(0, y+(squareSize/2)),
			BPoint(x, y+(squareSize/2)), kBlueColor);					//	left
		AddLine(BPoint(x+squareSize,y+(squareSize/2)),
			BPoint(Bounds().Width(), y+(squareSize/2)), kBlueColor);	// right
		AddLine(BPoint(x+(squareSize/2), 0),
			BPoint(x+(squareSize/2), y), kBlueColor);					// top
		AddLine(BPoint(x+(squareSize/2), y+squareSize),
			BPoint(x+(squareSize/2), Bounds().Height()), kBlueColor);	// bottom
		EndLineArray();
		if (selection == 2) {
			StrokeLine(BPoint(x,y), BPoint(x+squareSize,y+squareSize));
			StrokeLine(BPoint(x,y+squareSize), BPoint(x+squareSize,y));
		}
	}

	PopState();
}
示例#4
0
void CCalendarCtrl::DrawCells(CDC* pDC)
{
	CRect rc;
	GetClientRect(&rc);
	int ncHeight = (rc.Height()-CALENDAR_HEADER_HEIGHT)/CALENDAR_ROWS;
	int ncWidth = rc.Width()/CALENDAR_COLUMNS;

	CPen whitePen(PS_SOLID, 1, RGB(255,255,255));
	CPen blackPen(PS_SOLID, 1, RGB(0,0,0));

	CFont* pOldFont = pDC->SelectObject(&m_DefaultFont);
	CPen* pOldPen = pDC->SelectObject(&blackPen);

	for(int i=0; i<CALENDAR_ROWS ; i++)
	{
		for(int u=0; u<CALENDAR_COLUMNS ; u++)
		{
			CRect rect;
			if(GetRectFromCell(i, u, rect))
			{
				if(u == CALENDAR_COLUMNS-1) rect.right = rc.right;
				if(i == CALENDAR_ROWS-1) rect.bottom = rc.bottom;

				if((m_bMonthIsOdd &&  !(m_dayCells[i][u].date.GetMonth()%2))
					|| (!m_bMonthIsOdd && (m_dayCells[i][u].date.GetMonth()%2)))
				{
					CBrush br;
					br.CreateSolidBrush(CALENDAR_LIGHTGREY);
					pDC->FillRect(&rect ,&br);
				}

				COleDateTime today(time(NULL));
				bool btoday = false;
				if(today.GetDay() == m_dayCells[i][u].date.GetDay()	&& today.GetMonth() == m_dayCells[i][u].date.GetMonth()	&& today.GetYear() == m_dayCells[i][u].date.GetYear())
				{
					// Draw the frame 
					CRect rcLine(rect);
					rcLine.bottom = rcLine.top+15;
					rcLine.top = rcLine.bottom-1;
					for(int c=0; c<15; c++)
					{
						pDC->FillSolidRect(rcLine, GetFadedBlue(c*6));
						rcLine.bottom--;
						rcLine.top = rcLine.bottom-1;
					}
					btoday = true;
				}

				// Draw the selection
				bool bSelected = false;
				time_t tmax = max(m_SelectionRange[0], m_SelectionRange[1]);
				time_t tmin = min(m_SelectionRange[0], m_SelectionRange[1]);			
				time_t tcur = DateToSeconds(m_dayCells[i][u].date);				
				if(m_RandomSelection.GetCount())
				{	
					POSITION pos = m_RandomSelection.GetStartPosition();	 
					while (pos){
						void* p; DWORD date;
						m_RandomSelection.GetNextAssoc(pos, (void*&)date, p);
						if(date == (DWORD)tcur)
						{							
							CBrush br;
							br.CreateSolidBrush(GetFadedBlue(70));
							CRect selRect(rect);
							if(btoday)	selRect.top += 15;
							pDC->FillRect(&selRect, &br);
							bSelected = true;
						}
					}

					if(m_SelectionRange[2] == tcur)
					{
						rect.left+=2;	rect.right -=1;
						rect.top+=2;	rect.bottom -=1;
						pDC->DrawFocusRect(rect);
					}
				}
				else if((tmax >= tcur) && (tcur >= tmin))
				{						
					CRect selRect(rect);
					CBrush br;
					br.CreateSolidBrush(GetFadedBlue(70));
					if(btoday)	selRect.top += 15;
					pDC->FillRect(&selRect, &br);
					bSelected = true;
				}

				// Out of range
				if( (m_dayCells[i][u].date >= m_BoundUp) || 
					(m_dayCells[i][u].date <= m_BoundDown) )	
				{
					CRect selRect(rect);
					CBrush br;
					br.CreateSolidBrush(RGB(255,225,225));
					pDC->FillRect(&selRect, &br);
				}

				if(m_dayCells[i][u].bMark)
				{
					CBrush br;
					br.CreateSolidBrush(RGB(255,104,4));
					CRect rcMark(rect);
					rcMark.DeflateRect(3,3);
					rcMark.right = rcMark.left +6;
					rcMark.bottom = rcMark.top +6;
					pDC->FillRect(&rcMark, &br);
				}

				// draw inside...
				rect.DeflateRect(1,1);		
				CString csDay;
				int nDay = m_dayCells[i][u].date.GetDay();
				if(nDay == 1 || (i==0 && u==0))
				{
					csDay.Format(_T("%s %d"), m_dayCells[i][u].date.Format(_T("%B")), nDay);
					CSize dtSize(pDC->GetTextExtent(csDay));
					if(dtSize.cx>rect.Width())
						csDay.Format(_T("%s %d"), m_dayCells[i][u].date.Format(_T("%b")), nDay);
				}
				else
					csDay.Format(_T("%d"), nDay);

				unsigned long nColor;
				if(bSelected && !btoday)
					nColor = pDC->SetTextColor(RGB(255,104,4));
				else
					nColor = pDC->SetTextColor(RGB(0,0,0));
				pDC->DrawText(csDay, rect, DT_RIGHT|DT_TOP);
				pDC->SetTextColor(nColor);

				// Draw the cell content if possible
				if(rect.Width() >= 15)
				{
					for (int j=0; j<m_dayCells[i][u].csaLines.GetSize(); j++)
					{
						CRect txtRect(rect);
						CRect dotRect(rect);

						txtRect.left += 9; //CALENDAR_LINE_HEIGHT;
						txtRect.right-= 2;
						txtRect.top += (j+1)*CALENDAR_LINE_HEIGHT; 

						dotRect.top += (j+1)*CALENDAR_LINE_HEIGHT+(CALENDAR_LINE_HEIGHT/2-1); 
						dotRect.bottom = dotRect.top + 3;
						dotRect.left += 3;
						dotRect.right = dotRect.left +3;

						m_dayCells[i][u].bPartial = false;
						if(!m_dayCells[i][u].csaLines[j].IsEmpty() && txtRect.Height() > CALENDAR_LINE_HEIGHT)
						{
							pDC->SetTextColor(RGB(0,0,0));
							pDC->DrawText(m_dayCells[i][u].csaLines[j], txtRect, DT_LEFT|DT_TOP);								
							CBrush br;
							br.CreateSolidBrush(RGB(125,175,255));
							pDC->FillRect(&dotRect, &br);
						}
						else if(!m_dayCells[i][u].csaLines[j].IsEmpty())
						{
							CPen dotPen(PS_SOLID, 1, RGB(170,170,170));
							pDC->SelectObject(&dotPen);
							// Draw a little arrow
							static int t[2][7] = {5,5,8,8,8,5,5,4,3,2,1,2,3,4};
							int n = 0;
							for(int r=7; r>0; r--){
								pDC->MoveTo(rect.right-9+r, rect.bottom-t[0][n]);
								pDC->LineTo(rect.right-9+r, rect.bottom-t[1][n]);
								n++;
							}
							m_dayCells[i][u].bPartial = true;
							break;
						}
					}
				}
			}
		}
	}

	pDC->SelectObject(pOldFont);
	pDC->SelectObject(pOldPen);
}
示例#5
0
void
NodeGraph::mouseMoveEvent(QMouseEvent* e)
{
    QPointF newPos = mapToScene( e->pos() );
    QPointF lastMousePosScene = mapToScene( _imp->_lastMousePos.x(), _imp->_lastMousePos.y() );
    double dx, dy;
    {
        QPointF newPosRoot = _imp->_root->mapFromScene(newPos);
        QPointF lastMousePosRoot = _imp->_root->mapFromScene(lastMousePosScene);
        dx = newPosRoot.x() - lastMousePosRoot.x();
        dy = newPosRoot.y() - lastMousePosRoot.y();
    }

    _imp->_hasMovedOnce = true;

    bool mustUpdate = true;
    NodeCollectionPtr collection = getGroup();
    NodeGroupPtr isGroup = toNodeGroup(collection);
    bool isGroupEditable = true;
    bool groupEdited = true;
    if (isGroup) {
        isGroupEditable = isGroup->isSubGraphEditable();
        groupEdited = isGroup->isSubGraphEditedByUser();
    }
    if (!groupEdited && isGroupEditable) {
        ///check if user is nearby unlock
        // see NodeGraph::paintEvent()
        QPoint pixPos = _imp->getPyPlugUnlockPos();
        int pixW = _imp->unlockIcon.width();
        int pixH = _imp->unlockIcon.height();
        QRect pixRect(pixPos.x(), pixPos.y(), pixW, pixH);
        pixRect.adjust(-2, -2, 2, 2);
        QRect selRect = pixRect;
        selRect.adjust(-3, -3, 3, 3);
        if ( selRect.contains( e->pos() ) ) {
            assert(isGroup);
            QPoint pos = mapToGlobal( e->pos() );
            // Unfortunately, the timeout delay for the tooltip is hardcoded in Qt 4, and the last parameter to showText doesn't seem to influence anything
            // Can not fix https://github.com/MrKepzie/Natron/issues/1151 (at least in Qt4)
            QToolTip::showText( pos, NATRON_NAMESPACE::convertFromPlainText(QCoreApplication::translate("NodeGraph", "Clicking the unlock button will convert the PyPlug to a regular group saved in the project and dettach it from the script.\n"
                                                                                                "Any modification will not be written to the Python script. Subsequent loading of the project will no longer load this group from the python script."), NATRON_NAMESPACE::WhiteSpaceNormal),
                               this, selRect);
            e->accept();
            return;
        }
    }

    QRectF sceneR = visibleSceneRect();

    bool mustUpdateNavigator = false;
    ///Apply actions
    switch (_imp->_evtState) {
    case eEventStateDraggingArrow: {
        QPointF np = _imp->_arrowSelected->mapFromScene(newPos);
        if ( _imp->_arrowSelected->isOutputEdge() ) {
            _imp->_arrowSelected->dragDest(np);
        } else {
            _imp->_arrowSelected->dragSource(np);
        }
        checkAndStartAutoScrollTimer(newPos);
        mustUpdate = true;
        if (_imp->cursorSet) {
            _imp->cursorSet = false;
            unsetCursor();
        }
        break;
    }
    case eEventStateDraggingNode: {
        mustUpdate = true;
        mustUpdateNavigator = true;
        bool controlDown = modifierHasControl(e);
        bool shiftdown = modifierHasShift(e);
        moveSelectedNodesBy(shiftdown, controlDown, lastMousePosScene, newPos, sceneR, true);
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::ClosedHandCursor) );
        break;
    }
    case eEventStateMovingArea: {
        mustUpdateNavigator = true;
        moveRootInternal(dx, dy);
        mustUpdate = true;
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::SizeAllCursor) );
        break;
    }
    case eEventStateResizingBackdrop: {
        mustUpdateNavigator = true;
        assert(_imp->_backdropResized.lock());
        QPointF p = _imp->_backdropResized.lock()->scenePos();
        int w = newPos.x() - p.x();
        int h = newPos.y() - p.y();
        checkAndStartAutoScrollTimer(newPos);
        mustUpdate = true;
        pushUndoCommand( new ResizeBackdropCommand(_imp->_backdropResized.lock(), w, h) );
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::SizeFDiagCursor) );
        break;
    }
    case eEventStateSelectionRect: {
        QPointF startDrag = _imp->_lastSelectionStartPointScene;
        QPointF cur = newPos;
        double xmin = std::min( cur.x(), startDrag.x() );
        double xmax = std::max( cur.x(), startDrag.x() );
        double ymin = std::min( cur.y(), startDrag.y() );
        double ymax = std::max( cur.y(), startDrag.y() );
        checkAndStartAutoScrollTimer(newPos);
        QRectF selRect(xmin, ymin, xmax - xmin, ymax - ymin);
        _imp->_selectionRect = selRect;
        mustUpdate = true;
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::CrossCursor) );
        break;
    }
    case eEventStateDraggingNavigator: {
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::ClosedHandCursor) );
        QPointF mousePosSceneCoordinates;
        bool insideNavigator = isNearbyNavigator(e->pos(), mousePosSceneCoordinates);
        if (insideNavigator) {
            _imp->_refreshOverlays = true;
            centerOn(mousePosSceneCoordinates);
            _imp->_lastMousePos = e->pos();
            update();

            return;
        }
        break;
    }
    case eEventStateZoomingArea: {
        int delta = 2 * ( ( e->x() - _imp->_lastMousePos.x() ) - ( e->y() - _imp->_lastMousePos.y() ) );
        setTransformationAnchor(QGraphicsView::AnchorViewCenter);
        wheelEventInternal(modCASIsControl(e), delta);
        setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
        mustUpdate = true;
        _imp->cursorSet = true;
        setCursor( QCursor(Qt::SizeAllCursor) );
        break;
    }
    case eEventStateNone:
    default: {
        mustUpdate = false;
        // Test if mouse is inside the navigator
        QPointF mousePosSceneCoordinates;
        bool insideNavigator = isNearbyNavigator(e->pos(), mousePosSceneCoordinates);
        if (insideNavigator) {
            _imp->cursorSet = true;
            setCursor( QCursor(Qt::OpenHandCursor) );
        } else if (!groupEdited) {
            if (_imp->cursorSet) {
                _imp->cursorSet = false;
                unsetCursor();
            }
        } else {
            // Set cursor
            // The cursor should clearly indicate when will happen if mouse is pressed
            NodeGuiPtr nearbyNode;
            Edge* nearbyEdge = NULL;
            NearbyItemEnum nearbyItemCode = hasItemNearbyMouse(e->pos(), &nearbyNode, &nearbyEdge);

            switch (nearbyItemCode) {
            case eNearbyItemNode:
            case eNearbyItemBackdropFrame:
            case eNearbyItemEdgeBendPoint: {
                _imp->cursorSet = true;
                setCursor( QCursor(Qt::OpenHandCursor) );
                break;
            }
            case eNearbyItemBackdropResizeHandle: {
                _imp->cursorSet = true;
                setCursor( QCursor(Qt::SizeFDiagCursor) );
                break;
            }
            case eNearbyItemNone: {
                _imp->cursorSet = true;
                setCursor( QCursor(Qt::CrossCursor) );
                break;
            }
            case eNearbyItemNodeEdge:
            default: {
                if (_imp->cursorSet) {
                    _imp->cursorSet = false;
                    unsetCursor();
                }
                break;
            }
            }
        }
        break;
    }
    } // switch


    _imp->_lastMousePos = e->pos();


    if (mustUpdateNavigator) {
        _imp->_refreshOverlays = true;
        mustUpdate = true;
    }

    if (mustUpdate) {
        update();
    }

    TabWidget* tab = getParentPane() ;
    if (tab && _imp->_evtState == eEventStateNone) {
        // If the Viewer is in a tab, send the tab widget the event directly
        qApp->sendEvent(tab, e);
    }
    QGraphicsView::mouseMoveEvent(e);
} // mouseMoveEvent