From 18028d18a11402690139134dffc27e1a36d2cbcb Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sun, 3 Nov 2019 19:02:07 -0500 Subject: [PATCH] [TD]fix Balloon text positioning --- src/Mod/TechDraw/Gui/QGIViewBalloon.cpp | 205 ++++++++++++++++++++---- src/Mod/TechDraw/Gui/QGIViewBalloon.h | 53 +++++- 2 files changed, 229 insertions(+), 29 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp index 837f7f6451bf..b40c056814ec 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp @@ -38,7 +38,7 @@ # include # include - # include + # include #endif #include @@ -46,13 +46,10 @@ #include #include #include -#include #include #include #include -#include - #include #include #include @@ -72,19 +69,172 @@ #include "MDIViewPage.h" #include "TaskBalloon.h" -#define PI 3.14159 - //TODO: hide the Qt coord system (+y down). using namespace TechDraw; using namespace TechDrawGui; +QGIBalloonLabel::QGIBalloonLabel() +{ + posX = 0; + posY = 0; + + setCacheMode(QGraphicsItem::NoCache); + setFlag(ItemSendsGeometryChanges, true); + setFlag(ItemIsMovable, true); + setFlag(ItemIsSelectable, true); + setAcceptHoverEvents(true); + + m_labelText = new QGCustomText(); + m_labelText->setParentItem(this); + + m_ctrl = false; + hasHover = false; +} + +QVariant QGIBalloonLabel::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemSelectedHasChanged && scene()) { + if(isSelected()) { + Q_EMIT selected(true); + setPrettySel(); + } else { + Q_EMIT selected(false); + setPrettyNormal(); + } + update(); + } else if(change == ItemPositionHasChanged && scene()) { + setLabelCenter(); + Q_EMIT dragging(m_ctrl); + } + + return QGraphicsItem::itemChange(change, value); +} + +void QGIBalloonLabel::mousePressEvent(QGraphicsSceneMouseEvent * event) +{ + if(event->modifiers() & Qt::ControlModifier) { + m_ctrl = true; + } + + if(scene() && this == scene()->mouseGrabberItem()) { + Q_EMIT dragFinished(); + } + QGraphicsItem::mousePressEvent(event); +} + +void QGIBalloonLabel::mouseMoveEvent(QGraphicsSceneMouseEvent * event) +{ + QGraphicsItem::mouseMoveEvent(event); +} + +void QGIBalloonLabel::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) +{ + m_ctrl = false; + if(scene() && this == scene()->mouseGrabberItem()) { + Q_EMIT dragFinished(); + } + + QGraphicsItem::mouseReleaseEvent(event); +} + void QGIBalloonLabel::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event) { Gui::Control().showDialog(new TaskDlgBalloon(parent)); QGraphicsItem::mouseDoubleClickEvent(event); } +void QGIBalloonLabel::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_EMIT hover(true); + hasHover = true; + if (!isSelected()) { + setPrettyPre(); + } + QGraphicsItem::hoverEnterEvent(event); +} + +void QGIBalloonLabel::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + QGIView *view = dynamic_cast (parentItem()); + assert(view != 0); + Q_UNUSED(view); + + Q_EMIT hover(false); + hasHover = false; + if (!isSelected()) { + setPrettyNormal(); + } + QGraphicsItem::hoverLeaveEvent(event); +} + +QRectF QGIBalloonLabel::boundingRect() const +{ + return childrenBoundingRect(); +} + +void QGIBalloonLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + Q_UNUSED(painter); + QStyleOptionGraphicsItem myOption(*option); + myOption.state &= ~QStyle::State_Selected; + + //QGraphicsObject/QGraphicsItem::paint gives link error. +} + +void QGIBalloonLabel::setPosFromCenter(const double &xCenter, const double &yCenter) +{ + //set label's Qt position(top,left) given boundingRect center point + setPos(xCenter - m_labelText->boundingRect().width() / 2., yCenter - m_labelText->boundingRect().height() / 2.); +} + +void QGIBalloonLabel::setLabelCenter() +{ + //save label's bRect center (posX,posY) given Qt position (top,left) + posX = x() + m_labelText->boundingRect().width() / 2.; + posY = y() + m_labelText->boundingRect().height() / 2.; +} + +void QGIBalloonLabel::setFont(QFont f) +{ + m_labelText->setFont(f); +} + +void QGIBalloonLabel::setDimString(QString t) +{ + prepareGeometryChange(); + m_labelText->setPlainText(t); +} + +void QGIBalloonLabel::setDimString(QString t, qreal maxWidth) +{ + prepareGeometryChange(); + m_labelText->setPlainText(t); + m_labelText->setTextWidth(maxWidth); +} + +void QGIBalloonLabel::setPrettySel(void) +{ + m_labelText->setPrettySel(); +} + +void QGIBalloonLabel::setPrettyPre(void) +{ + m_labelText->setPrettyPre(); +} + +void QGIBalloonLabel::setPrettyNormal(void) +{ + m_labelText->setPrettyNormal(); +} + +void QGIBalloonLabel::setColor(QColor c) +{ + m_colNormal = c; + m_labelText->setColor(m_colNormal); +} + //************************************************************** QGIViewBalloon::QGIViewBalloon() : hasHover(false), @@ -173,23 +323,22 @@ void QGIViewBalloon::placeBalloon(QPointF pos) return; } - balloon->OriginX.setValue(mapFromScene(pos).x()); - balloon->OriginY.setValue(mapFromScene(pos).y()); - - int idx = featPage->getNextBalloonIndex(); - QString labelText = QString::number(idx); - balloon->Text.setValue(std::to_string(idx).c_str()); - - QFont font = balloonLabel->getFont(); - font.setPixelSize(calculateFontPixelSize(vp->Fontsize.getValue())); - font.setFamily(QString::fromUtf8(vp->Font.getValue())); - balloonLabel->setFont(font); - prepareGeometryChange(); - - // Default label position - balloonLabel->setPosFromCenter(mapFromScene(pos).x() + 200, mapFromScene(pos).y() -200); - balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); -// } + balloon->OriginX.setValue(mapFromScene(pos).x()); + balloon->OriginY.setValue(mapFromScene(pos).y()); + + int idx = featPage->getNextBalloonIndex(); + QString labelText = QString::number(idx); + balloon->Text.setValue(std::to_string(idx).c_str()); + + QFont font = balloonLabel->getFont(); + font.setPixelSize(calculateFontPixelSize(vp->Fontsize.getValue())); + font.setFamily(QString::fromUtf8(vp->Font.getValue())); + balloonLabel->setFont(font); + prepareGeometryChange(); + + // Default label position + balloonLabel->setPosFromCenter(mapFromScene(pos).x() + 200, mapFromScene(pos).y() -200); + balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); draw(); } @@ -393,13 +542,13 @@ void QGIViewBalloon::draw_modifier(bool modifier) double radius = sqrt(pow((textHeight / 2.0), 2) + pow((textWidth / 2.0), 2)); radius = radius * scale; radius += Rez::guiX(3.0); - offset = (tan(30 * PI / 180) * radius); + offset = (tan(30 * M_PI / 180) * radius); QPolygonF triangle; - double startAngle = -PI / 2; + double startAngle = -M_PI / 2; double angle = startAngle; for (int i = 0; i < 4; i++) { triangle += QPointF(lblCenter.x + (radius * cos(angle)), lblCenter.y + (radius * sin(angle))); - angle += (2 * PI / 3); + angle += (2 * M_PI / 3); } balloonPath.moveTo(lblCenter.x + (radius * cos(startAngle)), lblCenter.y + (radius * sin(startAngle))); balloonPath.addPolygon(triangle); @@ -427,11 +576,11 @@ void QGIViewBalloon::draw_modifier(bool modifier) radius += Rez::guiX(1.0); offset = radius; QPolygonF triangle; - double startAngle = -2 * PI / 3; + double startAngle = -2 * M_PI / 3; double angle = startAngle; for (int i = 0; i < 7; i++) { triangle += QPointF(lblCenter.x + (radius * cos(angle)), lblCenter.y + (radius * sin(angle))); - angle += (2 * PI / 6); + angle += (2 * M_PI / 6); } balloonPath.moveTo(lblCenter.x + (radius * cos(startAngle)), lblCenter.y + (radius * sin(startAngle))); balloonPath.addPolygon(triangle); diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.h b/src/Mod/TechDraw/Gui/QGIViewBalloon.h index c384e8546763..05df23421f05 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.h +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.h @@ -52,18 +52,69 @@ class QGIArrow; class QGIDimLines; class QGIViewBalloon; -class QGIBalloonLabel : public QGIDatumLabel +class QGIBalloonLabel : public QGraphicsObject { Q_OBJECT public: + QGIBalloonLabel(); + virtual ~QGIBalloonLabel() = default; + enum {Type = QGraphicsItem::UserType + 141}; int type() const override { return Type;} + virtual QRectF boundingRect() const override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + virtual void paint( QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget = nullptr ) override; + void setLabelCenter(); + void setPosFromCenter(const double &xCenter, const double &yCenter); + double X() const { return posX; } + double Y() const { return posY; } //minus posY? + + void setFont(QFont f); + QFont getFont(void) { return m_labelText->font(); } + void setDimString(QString t); + void setDimString(QString t, qreal maxWidth); + void setPrettySel(void); + void setPrettyPre(void); + void setPrettyNormal(void); + void setColor(QColor c); + + bool verticalSep; + std::vector seps; + + QGCustomText* getDimText(void) { return m_labelText; } + void setDimText(QGCustomText* newText) { m_labelText = newText; } + + bool hasHover; + QGIViewBalloon *parent; +Q_SIGNALS: + void dragging(bool); + void hover(bool state); + void selected(bool state); + void dragFinished(); + protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; +// virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event) override; + + QGCustomText* m_labelText; + QColor m_colNormal; + bool m_ctrl; + + double posX; + double posY; + +private: }; //*******************************************************************