mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-05 18:54:14 +02:00
Add an Arc tool and a handle to pull a half arc in or out (#408)
The diagram toolbar gets an "Ajouter un arc" button next to the ellipse. Click one end, then click the other end at the height the arc should reach: the result is a half arc bulging up or down from the line between the two clicks (Shift: a true half circle). It is not filled, since a fill would close it into a half disc. A selected half arc shows one more handle, in the middle of the curve. Dragging it makes the arc deeper or flatter while both ends stay put; dragging it across the line between the ends turns the arc over. The handle is hidden whenever the arc is not a half arc on a horizontal or vertical diameter, because only then is "keep the ends, move the middle" one well-defined change. Nothing new is stored: an arc stays an Ellipse with a start and end angle, exactly as the existing arc handles of an ellipse save it, so files read by older versions are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,10 +34,14 @@
|
||||
Default constructor
|
||||
@param diagram : the diagram where this event must operate
|
||||
@param shape_type : the type of shape to draw
|
||||
@param half_arc : with shape_type Ellipse, draw a half arc instead of
|
||||
a whole ellipse (the Arc tool). It is still an Ellipse with a start
|
||||
and end angle, the same shape the arc handles of an ellipse produce.
|
||||
*/
|
||||
DiagramEventAddShape::DiagramEventAddShape(Diagram *diagram, QetShapeItem::ShapeType shape_type) :
|
||||
DiagramEventAddShape::DiagramEventAddShape(Diagram *diagram, QetShapeItem::ShapeType shape_type, bool half_arc) :
|
||||
DiagramEventInterface(diagram),
|
||||
m_shape_type (shape_type),
|
||||
m_half_arc (half_arc && shape_type == QetShapeItem::Ellipse),
|
||||
m_shape_item (nullptr),
|
||||
m_help_horiz (nullptr),
|
||||
m_help_verti (nullptr)
|
||||
@@ -131,6 +135,23 @@ void DiagramEventAddShape::applyPosition(const QPointF &pos, Qt::KeyboardModifie
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_half_arc)
|
||||
{
|
||||
// The first click is one end of the arc and sets the height of
|
||||
// its chord; the cursor sets the other end and how far the arc
|
||||
// bulges, up or down, from that chord. Shift makes it a true
|
||||
// half circle.
|
||||
const qreal width = qAbs(pos.x() - m_anchor_point.x());
|
||||
qreal height = pos.y() - m_anchor_point.y();
|
||||
if (mods & Qt::ShiftModifier)
|
||||
height = (height < 0 ? -width : width) / 2;
|
||||
const qreal depth = qAbs(height);
|
||||
m_shape_item->setRect(QRectF(qMin(pos.x(), m_anchor_point.x()), m_anchor_point.y() - depth,
|
||||
width, 2 * depth));
|
||||
m_shape_item->setEndAngle(height <= 0 ? 180 : -180);
|
||||
return;
|
||||
}
|
||||
|
||||
m_center_anchored = (mods & Qt::ControlModifier)
|
||||
&& (m_shape_type == QetShapeItem::Rectangle || m_shape_type == QetShapeItem::Ellipse);
|
||||
if (m_center_anchored)
|
||||
@@ -227,15 +248,20 @@ void DiagramEventAddShape::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
// live on every subsequent move, from whatever Ctrl state is
|
||||
// held at the time.
|
||||
m_center_anchored = (event->modifiers() & Qt::ControlModifier)
|
||||
&& !m_half_arc
|
||||
&& (m_shape_type == QetShapeItem::Rectangle || m_shape_type == QetShapeItem::Ellipse);
|
||||
if (m_center_anchored)
|
||||
showCenterMarker(m_anchor_point);
|
||||
if (m_half_arc)
|
||||
m_shape_item->setEndAngle(180);
|
||||
//Start from whatever pen/brush was last applied this
|
||||
//session, rather than always the hardcoded default.
|
||||
//Not the brush for an arc: it is a line, and a fill
|
||||
//would close it into a half disc.
|
||||
if (LastUsedStyle::hasShapePen()) {
|
||||
m_shape_item->setPen(LastUsedStyle::shapePen());
|
||||
}
|
||||
if (LastUsedStyle::hasShapeBrush()) {
|
||||
if (LastUsedStyle::hasShapeBrush() && !m_half_arc) {
|
||||
m_shape_item->setBrush(LastUsedStyle::shapeBrush());
|
||||
}
|
||||
m_diagram->addItem (m_shape_item);
|
||||
@@ -461,6 +487,8 @@ QString DiagramEventAddShape::beforeClickHint() const
|
||||
return tr("Clic gauche : positionner le point de départ (Ctrl = position libre)");
|
||||
case QetShapeItem::Rectangle:
|
||||
case QetShapeItem::Ellipse:
|
||||
if (m_half_arc)
|
||||
return tr("Clic gauche : positionner une extrémité de l'arc (Ctrl = position libre)");
|
||||
return tr("Clic gauche : positionner le premier coin (Ctrl = point central, position libre)");
|
||||
case QetShapeItem::Polygon:
|
||||
return tr("Clic gauche : positionner le premier point (Ctrl = position libre)");
|
||||
@@ -479,6 +507,9 @@ QString DiagramEventAddShape::afterClickHint() const
|
||||
return tr("Clic gauche : positionner le coin opposé (Maj = carré, "
|
||||
"Ctrl = depuis le centre + position libre, Ctrl+Maj = carré centré) ; clic droit : annuler");
|
||||
case QetShapeItem::Ellipse:
|
||||
if (m_half_arc)
|
||||
return tr("Clic gauche : positionner l'autre extrémité et la hauteur de l'arc "
|
||||
"(Maj = demi-cercle, Ctrl = position libre) ; clic droit : annuler");
|
||||
return tr("Clic gauche : positionner le coin opposé (Maj = cercle, "
|
||||
"Ctrl = depuis le centre + position libre, Ctrl+Maj = cercle centré) ; clic droit : annuler");
|
||||
case QetShapeItem::Polygon:
|
||||
|
||||
Reference in New Issue
Block a user