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