From 79f8d4a7cd22e02620c0f4cc883c59381aae48c5 Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Sun, 19 May 2019 14:19:00 +0200 Subject: [PATCH] [TD] Rewrite balloon placing method When clicking on balloon command, cursor is changing to balloon cursor. It means user is ready to place a balloon (anywhere on the page). Balloon object is not created until user click somewhere. Balloon command can be aborted pressing escape or when page view lost focus (in other words, when user clic somewhere else than the page). --- src/Mod/TechDraw/App/DrawPage.cpp | 1 + src/Mod/TechDraw/App/DrawPage.h | 4 +- src/Mod/TechDraw/App/DrawViewBalloon.h | 1 + src/Mod/TechDraw/Gui/Command.cpp | 25 +---- src/Mod/TechDraw/Gui/QGIViewBalloon.cpp | 74 ++++---------- src/Mod/TechDraw/Gui/QGIViewBalloon.h | 4 +- src/Mod/TechDraw/Gui/QGVPage.cpp | 125 ++++++++++++++++++------ src/Mod/TechDraw/Gui/QGVPage.h | 9 +- 8 files changed, 125 insertions(+), 118 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawPage.cpp b/src/Mod/TechDraw/App/DrawPage.cpp index 0d34b1e44a..47c60adfc0 100644 --- a/src/Mod/TechDraw/App/DrawPage.cpp +++ b/src/Mod/TechDraw/App/DrawPage.cpp @@ -104,6 +104,7 @@ DrawPage::DrawPage(void) Scale.setConstraints(&scaleRange); double defScale = hGrp->GetFloat("DefaultScale",1.0); Scale.setValue(defScale); + balloonPlacing = false; } DrawPage::~DrawPage() diff --git a/src/Mod/TechDraw/App/DrawPage.h b/src/Mod/TechDraw/App/DrawPage.h index 33f0420dc1..140818f5e7 100644 --- a/src/Mod/TechDraw/App/DrawPage.h +++ b/src/Mod/TechDraw/App/DrawPage.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace TechDraw { @@ -89,7 +90,8 @@ public: bool isUnsetting(void) { return nowUnsetting; } void requestPaint(void); std::vector getAllViews(void) ; - + bool balloonPlacing; + DrawViewPart *balloonParent; protected: void onBeforeChange(const App::Property* prop); diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.h b/src/Mod/TechDraw/App/DrawViewBalloon.h index cce389461f..3a2971818b 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.h +++ b/src/Mod/TechDraw/App/DrawViewBalloon.h @@ -61,6 +61,7 @@ public: short mustExecute() const; DrawViewPart* getViewPart() const; + QPointF origin; //virtual PyObject *getPyObject(void); diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 77264fc351..a13c7d618f 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -747,34 +747,17 @@ void CmdTechDrawNewBalloon::activated(int iMsg) if (!result) return; - std::string FeatName = getUniqueObjectName("Balloon"); - std::vector selection = getSelection().getSelectionEx(); auto objFeat( dynamic_cast(selection[0].getObject()) ); if( objFeat == nullptr ) { return; } + TechDraw::DrawPage* page = objFeat->findParentPage(); std::string PageName = page->getNameInDocument(); - TechDraw::DrawViewBalloon *balloon = 0; - - openCommand("Create Balloon"); - doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewBalloon','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); - - balloon = dynamic_cast(getDocument()->getObject(FeatName.c_str())); - if (!balloon) { - throw Base::TypeError("CmdTechDrawNewBalloon - balloon not found\n"); - } - - balloon->sourceView.setValue(objFeat); - - commitCommand(); - balloon->recomputeFeature(); - - //Horrible hack to force Tree update - double x = objFeat->X.getValue(); - objFeat->X.setValue(x); + + page->balloonParent = objFeat; + page->balloonPlacing = true; } diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp index bd423dd551..2fb0c4fbd0 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp @@ -136,30 +136,9 @@ QGIViewBalloon::QGIViewBalloon() : } -void QGIViewBalloon::disconnect(void) +void QGIViewBalloon::placeBalloon(QPointF pos) { - auto bnd = boost::bind(&QGIViewBalloon::parentViewMousePressed, this, _1, _2); - if (m_parent) { - m_parent->signalSelectPoint.disconnect(bnd); - } -} -void QGIViewBalloon::connect(QGIView *parent) -{ - auto bnd = boost::bind(&QGIViewBalloon::parentViewMousePressed, this, _1, _2); - parent->signalSelectPoint.connect(bnd); - m_parent = parent; -} - -void QGIViewBalloon::parentViewMousePressed(QGIView *view, QPointF pos) -{ - //Base::Console().Message("%s::parentViewMousePressed from %s\n", this->getViewName(), view->getViewName()); - onAttachPointPicked(view, pos); -} - -void QGIViewBalloon::onAttachPointPicked(QGIView *view, QPointF pos) -{ - Q_UNUSED(view); auto balloon( dynamic_cast(getViewObject()) ); if( balloon == nullptr ) return; @@ -169,38 +148,26 @@ void QGIViewBalloon::onAttachPointPicked(QGIView *view, QPointF pos) return; } - auto bnd = boost::bind(&QGIViewBalloon::parentViewMousePressed, this, _1, _2); + MDIViewPage* mdi = getMDIViewPage(); + QGVPage* page; + if (mdi != nullptr) { + page = mdi->getQGVPage(); - if (balloon->OriginIsSet.getValue() == false) { - - balloon->OriginX.setValue(pos.x()); - balloon->OriginY.setValue(pos.y()); - balloon->OriginIsSet.setValue(true); + balloon->OriginX.setValue(mapFromScene(pos).x()); + balloon->OriginY.setValue(mapFromScene(pos).y()); - m_parent->signalSelectPoint.disconnect(bnd); + QString labelText = QString::fromUtf8(std::to_string(page->balloonIndex).c_str()); + balloon->Text.setValue(std::to_string(page->balloonIndex++).c_str()); - MDIViewPage* mdi = getMDIViewPage(); - QGVPage* page; - if (mdi != nullptr) { - page = mdi->getQGVPage(); + QFont font = balloonLabel->getFont(); + font.setPointSizeF(Rez::guiX(vp->Fontsize.getValue())); + font.setFamily(QString::fromUtf8(vp->Font.getValue())); + balloonLabel->setFont(font); + prepareGeometryChange(); - page->balloonPlacing(false); - - QString labelText = QString::fromUtf8(std::to_string(page->balloonIndex).c_str()); - balloon->Text.setValue(std::to_string(page->balloonIndex++).c_str()); - - QFont font = balloonLabel->getFont(); - font.setPointSizeF(Rez::guiX(vp->Fontsize.getValue())); - font.setFamily(QString::fromUtf8(vp->Font.getValue())); - balloonLabel->setFont(font); - prepareGeometryChange(); - - // Default label position - balloonLabel->setPosFromCenter(pos.x() + 200, pos.y() -200); - balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); - - QApplication::setOverrideCursor(Qt::ArrowCursor); - } + // Default label position + balloonLabel->setPosFromCenter(mapFromScene(pos).x() + 200, mapFromScene(pos).y() -200); + balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); } draw(); @@ -274,9 +241,6 @@ void QGIViewBalloon::updateBalloon(bool obtuse) return; } - if (balloon->OriginIsSet.getValue() == false) - return; - QFont font = balloonLabel->getFont(); font.setPointSizeF(Rez::guiX(vp->Fontsize.getValue())); font.setFamily(QString::fromUtf8(vp->Font.getValue())); @@ -338,10 +302,6 @@ void QGIViewBalloon::draw_modifier(bool modifier) return; } - if (balloon->OriginIsSet.getValue() == false) { - return; - } - balloonLabel->show(); show(); diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.h b/src/Mod/TechDraw/Gui/QGIViewBalloon.h index 95f04144f9..d5e93faa4c 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.h +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.h @@ -74,9 +74,8 @@ public: QWidget * widget = 0 ) override; virtual QColor getNormalColor(void) override; QString getLabelText(void); - void connect(QGIView *parent); - void disconnect(void); void draw_modifier(bool modifier); + void placeBalloon(QPointF pos); public Q_SLOTS: void balloonLabelDragged(bool ctrl); @@ -89,7 +88,6 @@ protected: void draw() override; virtual QVariant itemChange( GraphicsItemChange change, const QVariant &value ) override; - void onAttachPointPicked(QGIView *view, QPointF pos); virtual void setSvgPens(void); virtual void setPens(void); QString getPrecision(void); diff --git a/src/Mod/TechDraw/Gui/QGVPage.cpp b/src/Mod/TechDraw/Gui/QGVPage.cpp index becd9528a6..8d21b71f80 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.cpp +++ b/src/Mod/TechDraw/Gui/QGVPage.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #endif @@ -51,6 +52,7 @@ #include #include #include +#include #include #include @@ -95,6 +97,8 @@ #include "ViewProviderPage.h" #include "QGVPage.h" +using namespace Gui; +using namespace TechDraw; using namespace TechDrawGui; QGVPage::QGVPage(ViewProviderPage *vp, QGraphicsScene* s, QWidget *parent) @@ -146,7 +150,10 @@ QGVPage::QGVPage(ViewProviderPage *vp, QGraphicsScene* s, QWidget *parent) bkgBrush = new QBrush(getBackgroundColor()); balloonIndex = 1; - balloonPlacing(false); + + balloonCursor = new QLabel(this); + balloonCursor->setPixmap(QPixmap(QString::fromUtf8(":/icons/cursor-balloon.png"))); + balloonCursor->hide(); resetCachedContent(); } @@ -157,6 +164,13 @@ QGVPage::~QGVPage() } +void QGVPage::cancelBalloonPlacing(void) +{ + getDrawPage()->balloonPlacing = false; + balloonCursor->hide(); + QApplication::setOverrideCursor(Qt::ArrowCursor); +} + void QGVPage::drawBackground(QPainter *p, const QRectF &) { //Note: Background is not part of scene() @@ -405,28 +419,26 @@ QGIView * QGVPage::addDrawViewImage(TechDraw::DrawViewImage *view) QGIView * QGVPage::addViewBalloon(TechDraw::DrawViewBalloon *balloon) { - auto balloonGroup( new QGIViewBalloon ); + auto vBalloon( new QGIViewBalloon ); auto ourScene( scene() ); assert(ourScene); - ourScene->addItem(balloonGroup); + ourScene->addItem(vBalloon); - balloonGroup->setViewPartFeature(balloon); + vBalloon->setViewPartFeature(balloon); - // Find if it belongs to a parent QGIView *parent = 0; - parent = findParent(balloonGroup); + parent = findParent(vBalloon); - if(balloon->OriginIsSet.getValue() == false) { - if(parent) { - balloonPlacing(true); - QApplication::setOverrideCursor(QCursor(QPixmap(QString::fromUtf8(":/icons/cursor-balloon.png")),0,32)); - balloonGroup->connect(parent); - addBalloonToParent(balloonGroup,parent); - } + if(parent) + addBalloonToParent(vBalloon,parent); + + if (getDrawPage()->balloonPlacing) { + vBalloon->placeBalloon(balloon->origin); + cancelBalloonPlacing(); } - return balloonGroup; + return vBalloon; } void QGVPage::addBalloonToParent(QGIViewBalloon* balloon, QGIView* parent) @@ -896,6 +908,10 @@ void QGVPage::keyPressEvent(QKeyEvent *event) kbPanScroll(0, -1); break; } + case Qt::Key_Escape: { + cancelBalloonPlacing(); + break; + } default: { break; } @@ -904,6 +920,11 @@ void QGVPage::keyPressEvent(QKeyEvent *event) QGraphicsView::keyPressEvent(event); } +void QGVPage::focusOutEvent(QFocusEvent *event) { + Q_UNUSED(event); + cancelBalloonPlacing(); +} + void QGVPage::kbPanScroll(int xMove, int yMove) { if (xMove != 0) { @@ -925,31 +946,43 @@ void QGVPage::kbPanScroll(int xMove, int yMove) void QGVPage::enterEvent(QEvent *event) { QGraphicsView::enterEvent(event); - setCursor(Qt::ArrowCursor); - viewport()->setCursor(Qt::ArrowCursor); + if(getDrawPage()->balloonPlacing) { + balloonCursor->hide(); + QApplication::setOverrideCursor(QCursor(QPixmap(QString::fromUtf8(":/icons/cursor-balloon.png")),0,32)); + } else { + setCursor(Qt::ArrowCursor); + QApplication::restoreOverrideCursor(); + viewport()->setCursor(Qt::ArrowCursor); + } } void QGVPage::leaveEvent(QEvent * event) { - if(m_balloonPlacing) { + QApplication::setOverrideCursor(Qt::ArrowCursor); + if(getDrawPage()->balloonPlacing) { - // Get the window geometry & cursor position - const QRect &rect = geometry(); - QPoint position = this->mapFromGlobal(QCursor::pos()); - // Check the bounds - qint32 x = qBound(rect.left(), position.x(), rect.right()); - qint32 y = qBound(rect.top(), position.y(), rect.bottom()); + int left_x; + if (balloonCursorPos.x() < 32) + left_x = 0; + else if (balloonCursorPos.x() > (this->contentsRect().right() - 32)) + left_x = this->contentsRect().right() - 32; + else + left_x = balloonCursorPos.x(); - QPoint newPoint(x, y); + int left_y; + if (balloonCursorPos.y() < 32) + left_y = 0; + else if (balloonCursorPos.y() > (this->contentsRect().bottom() - 32)) + left_y = this->contentsRect().bottom() - 32; + else + left_y = balloonCursorPos.y(); - // Adjust the cursor - if (x != position.x() || y != position.y()) - QCursor::setPos(this->mapToGlobal(newPoint)); - - event->accept(); + /* When cursor leave the page, display balloonCursor where it left */ + balloonCursor->setGeometry(left_x ,left_y, 32, 32); + balloonCursor->show(); } - + QGraphicsView::leaveEvent(event); } @@ -961,14 +994,42 @@ void QGVPage::mousePressEvent(QMouseEvent *event) void QGVPage::mouseMoveEvent(QMouseEvent *event) { + balloonCursorPos = event->pos(); QGraphicsView::mouseMoveEvent(event); } void QGVPage::mouseReleaseEvent(QMouseEvent *event) { + if(getDrawPage()->balloonPlacing) { + QApplication::setOverrideCursor(Qt::ArrowCursor); + balloonCursor->hide(); + + std::string FeatName = getDrawPage()->getDocument()->getUniqueObjectName("Balloon"); + std::string PageName = getDrawPage()->getNameInDocument(); + Gui::Command::openCommand("Create Balloon"); + TechDraw::DrawViewBalloon *balloon = 0; + + Gui::Command::openCommand("Create Balloon"); + Command::doCommand(Command::Doc,"App.activeDocument().addObject('TechDraw::DrawViewBalloon','%s')",FeatName.c_str()); + Command::doCommand(Command::Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + + balloon = dynamic_cast(getDrawPage()->getDocument()->getObject(FeatName.c_str())); + if (!balloon) { + throw Base::TypeError("CmdTechDrawNewBalloon - balloon not found\n"); + } + + balloon->sourceView.setValue(getDrawPage()->balloonParent); + balloon->origin = mapToScene(event->pos()); + + Gui::Command::commitCommand(); + balloon->recomputeFeature(); + + //Horrible hack to force Tree update + double x = getDrawPage()->balloonParent->X.getValue(); + getDrawPage()->balloonParent->X.setValue(x); + } + QGraphicsView::mouseReleaseEvent(event); -// setCursor(Qt::ArrowCursor); -// viewport()->setCursor(Qt::ArrowCursor); } TechDraw::DrawPage* QGVPage::getDrawPage() diff --git a/src/Mod/TechDraw/Gui/QGVPage.h b/src/Mod/TechDraw/Gui/QGVPage.h index acefe5df48..4c7606d2e1 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.h +++ b/src/Mod/TechDraw/Gui/QGVPage.h @@ -25,6 +25,7 @@ #include #include +#include class QTemporaryFile; @@ -100,8 +101,6 @@ public: int removeQViewByName(const char* name); void removeQViewFromScene(QGIView *view); - void balloonPlacing(bool val) { m_balloonPlacing = val; }; - //void setViews(const std::vector &view) {views = view; } void setPageTemplate(TechDraw::DrawTemplate *pageTemplate); @@ -131,6 +130,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void kbPanScroll(int xMove = 1, int yMove = 1); @@ -155,9 +155,10 @@ private: double m_zoomIncrement; int m_reversePan; int m_reverseScroll; - bool m_balloonPlacing; - bool m_borderState; + QLabel *balloonCursor; + QPoint balloonCursorPos; + void cancelBalloonPlacing(void); }; } // namespace MDIViewPageGui