TechDraw: Fix dimension alignment issue.
Fixes issue #19121 "dimension numbers placed lower than normal". Problem: QGCustomText has a new method `alignmentRect` which can optionally return a `tightBoundingRect` instead of the regular `boundingRect`. The `alignmentRect` is used for laying out the `QGIDatumLabel`, however QGraphicsItemGroup's `childrenBoundingRect` use the childrens' `boundingRect` and knows nothing of `alignmentRect`. The result is an improperly sized label and frame and miss alignment. Additionally `childrenBoundingRect` calculations includes hidden views, so even though the `m_tolTextOver` and `m_tolTextUnder` are hidden they still affect the bounding rect size. Solution: 1. Implement new method `QGIDatumLabel::tightBoundingRect` this calculates the bounding rect using the subview's `aligmentRect` if there is text in the custom text. 2. Use `tightBoundingRect` in place of `boundingRect` to for the drawing of arrows and the exact dim frames. 3. This PR acknowledges that there are some edge case fonts that while not clipped may not interface perfectly with arrows and the exact dimension frame. 4. Fix vertical alignment of `m_tolTextOver` / `m_tolTextUnder` 5. Incorporate PR Review comments
This commit is contained in:
committed by
Max Wilfinger
parent
11125be89d
commit
9990408035
@@ -178,7 +178,7 @@ void QGCustomText::paint ( QPainter * painter, const QStyleOptionGraphicsItem *
|
||||
myOption.state &= ~QStyle::State_Selected;
|
||||
|
||||
// painter->setPen(Qt::green);
|
||||
// painter->drawRect(boundingRect()); //good for debugging
|
||||
// painter->drawRect(alignmentRect()); //good for debugging
|
||||
|
||||
QGraphicsTextItem::paint (painter, &myOption, widget);
|
||||
}
|
||||
|
||||
@@ -354,18 +354,29 @@ QRectF QGIDatumLabel::boundingRect() const
|
||||
return childrenBoundingRect();
|
||||
}
|
||||
|
||||
QRectF QGIDatumLabel::tightBoundingRect() const
|
||||
{
|
||||
QRectF totalRect;
|
||||
for (QGraphicsItem* item : m_textItems->childItems()) {
|
||||
auto* customText = dynamic_cast<QGCustomText*>(item);
|
||||
if (customText && !customText->toPlainText().isEmpty()) {
|
||||
QRectF itemRect = customText->alignmentRect();
|
||||
QPointF pos = customText->pos();
|
||||
itemRect.translate(pos.x(), pos.y());
|
||||
totalRect = totalRect.isNull() ? itemRect : totalRect.united(itemRect);
|
||||
}
|
||||
}
|
||||
int fontSize = m_dimText->font().pixelSize();
|
||||
int paddingLeft = fontSize * 0.2;
|
||||
int paddingTop = fontSize * 0.1;
|
||||
int paddingRight = fontSize * 0.2;
|
||||
int paddingBottom = fontSize * 0.1;
|
||||
return totalRect.adjusted(-paddingLeft, -paddingTop, paddingRight, paddingBottom);
|
||||
}
|
||||
|
||||
void QGIDatumLabel::updateFrameRect() {
|
||||
prepareGeometryChange();
|
||||
int fontSize = m_dimText->font().pixelSize();
|
||||
int paddingLeft = fontSize * 0.3;
|
||||
int paddingTop = fontSize * 0.1;
|
||||
int paddingRight = fontSize * 0.3;
|
||||
int paddingBottom = fontSize * 0.125;
|
||||
// Why top and bottom padding different?
|
||||
// Because the m_dimText bounding box isn't relative to X height :(
|
||||
// And we want padding to be relative to X height
|
||||
// TODO: make QGCustomLabel::boundingBoxXHeight
|
||||
m_frame->setRect(m_textItems->childrenBoundingRect().adjusted(-paddingLeft, -paddingTop, paddingRight, paddingBottom)); // Update bounding rect
|
||||
m_frame->setRect(tightBoundingRect());
|
||||
}
|
||||
|
||||
void QGIDatumLabel::setLineWidth(double lineWidth)
|
||||
@@ -420,9 +431,7 @@ void QGIDatumLabel::setPosFromCenter(const double& xCenter, const double& yCente
|
||||
|
||||
QRectF labelBox = m_dimText->alignmentRect();
|
||||
double right = labelBox.right();
|
||||
double top = labelBox.top();
|
||||
double bottom = labelBox.bottom();
|
||||
double middle = (top + bottom) / 2.0;
|
||||
double middle = labelBox.center().y();
|
||||
|
||||
//set unit position
|
||||
QRectF unitBox = m_unitText->alignmentRect();
|
||||
@@ -437,10 +446,9 @@ void QGIDatumLabel::setPosFromCenter(const double& xCenter, const double& yCente
|
||||
|
||||
// Adjust for difference in tight and original bounding box sizes, note the y-coord down system
|
||||
QPointF tol_adj = m_tolTextOver->tightBoundingAdjust();
|
||||
m_tolTextOver->justifyLeftAt(tolLeft + tol_adj.x(), middle - tol_adj.y(), false);
|
||||
m_tolTextOver->justifyLeftAt(tolLeft + tol_adj.x(), middle + tol_adj.y()/2.0, false);
|
||||
tol_adj = m_tolTextUnder->tightBoundingAdjust();
|
||||
m_tolTextUnder->justifyLeftAt(tolLeft + tol_adj.x(), middle + overBox.height() - tol_adj.y(),
|
||||
false);
|
||||
m_tolTextUnder->justifyLeftAt(tolLeft + tol_adj.x(), middle + overBox.height() + tol_adj.y()/2.0, false);
|
||||
}
|
||||
|
||||
void QGIDatumLabel::setLabelCenter()
|
||||
@@ -453,7 +461,7 @@ void QGIDatumLabel::setLabelCenter()
|
||||
|
||||
Base::Vector2d QGIDatumLabel::getPosToCenterVec()
|
||||
{
|
||||
QPointF center = boundingRect().center();
|
||||
QPointF center = tightBoundingRect().center();
|
||||
|
||||
return Base::Vector2d(center.x(), center.y());
|
||||
}
|
||||
@@ -2350,7 +2358,7 @@ void QGIViewDimension::drawDistance(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->tightBoundingRect())));
|
||||
|
||||
pointPair linePoints = dimension->getLinearPoints();
|
||||
const char* dimensionType = dimension->Type.getValueAsString();
|
||||
@@ -2387,7 +2395,7 @@ void QGIViewDimension::drawRadius(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->tightBoundingRect())));
|
||||
arcPoints curvePoints = dimension->getArcPoints();
|
||||
|
||||
double endAngle;
|
||||
@@ -2418,7 +2426,7 @@ void QGIViewDimension::drawDiameter(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->tightBoundingRect())));
|
||||
Base::Vector2d labelCenter(labelRectangle.GetCenter());
|
||||
|
||||
arcPoints curvePoints = dimension->getArcPoints();
|
||||
@@ -2585,7 +2593,7 @@ void QGIViewDimension::drawAngle(TechDraw::DrawViewDimension* dimension,
|
||||
QPainterPath anglePath;
|
||||
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->tightBoundingRect())));
|
||||
Base::Vector2d labelCenter(labelRectangle.GetCenter());
|
||||
double labelAngle = 0.0;
|
||||
|
||||
@@ -2775,7 +2783,7 @@ void QGIViewDimension::drawArea(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->tightBoundingRect())));
|
||||
areaPoint areaPoint = dimension->getAreaPoint();
|
||||
|
||||
drawAreaExecutive(
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
int type() const override { return Type;}
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
QRectF tightBoundingRect() const;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void paint( QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
|
||||
Reference in New Issue
Block a user