[qet] [3694] Element editor : hover a primitve will highlight it with a blue halo |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/qet Archives
]
Revision: 3694
Author: blacksun
Date: 2015-02-09 09:57:40 +0100 (Mon, 09 Feb 2015)
Log Message:
-----------
Element editor : hover a primitve will highlight it with a blue halo
Modified Paths:
--------------
trunk/sources/editor/arceditor.cpp
trunk/sources/editor/editorcommands.cpp
trunk/sources/editor/elementscene.cpp
trunk/sources/editor/ellipseeditor.cpp
trunk/sources/editor/esevent/eseventaddarc.cpp
trunk/sources/editor/esevent/eseventaddellipse.cpp
trunk/sources/editor/esevent/eseventaddellipse.h
trunk/sources/editor/esevent/eseventaddline.cpp
trunk/sources/editor/esevent/eseventaddpolygon.cpp
trunk/sources/editor/esevent/eseventaddrect.cpp
trunk/sources/editor/esevent/eseventaddrect.h
trunk/sources/editor/esevent/eseventaddterminal.cpp
trunk/sources/editor/graphicspart/customelementgraphicpart.cpp
trunk/sources/editor/graphicspart/customelementgraphicpart.h
trunk/sources/editor/graphicspart/partarc.cpp
trunk/sources/editor/graphicspart/partarc.h
trunk/sources/editor/graphicspart/partellipse.cpp
trunk/sources/editor/graphicspart/partellipse.h
trunk/sources/editor/graphicspart/partline.cpp
trunk/sources/editor/graphicspart/partline.h
trunk/sources/editor/graphicspart/partpolygon.cpp
trunk/sources/editor/graphicspart/partpolygon.h
trunk/sources/editor/graphicspart/partrectangle.cpp
trunk/sources/editor/graphicspart/partrectangle.h
trunk/sources/editor/graphicspart/partterminal.cpp
trunk/sources/editor/graphicspart/partterminal.h
trunk/sources/editor/lineeditor.cpp
trunk/sources/editor/lineeditor.h
trunk/sources/editor/rectangleeditor.cpp
trunk/sources/editor/rectangleeditor.h
Added Paths:
-----------
trunk/sources/editor/graphicspart/abstractpartellipse.cpp
trunk/sources/editor/graphicspart/abstractpartellipse.h
Modified: trunk/sources/editor/arceditor.cpp
===================================================================
--- trunk/sources/editor/arceditor.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/arceditor.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -110,26 +110,26 @@
*/
void ArcEditor::updateArc() {
if (!part) return;
- part -> setProperty("x", x -> value());
- part -> setProperty("y", y -> value());
- part -> setProperty("diameter_h", h -> value());
- part -> setProperty("diameter_v", v -> value());
- part -> setProperty("start_angle", -start_angle -> value() + 90);
- part -> setProperty("angle", -angle -> value());
+ part -> setProperty("centerX", x -> value());
+ part -> setProperty("centerY", y -> value());
+ part -> setProperty("diameter_h", h -> value());
+ part -> setProperty("diameter_v", v -> value());
+ part -> setProperty("startAngle", ((start_angle -> value() * -1) + 90) * 16);
+ part -> setProperty("spanAngle", angle -> value() * -16);
}
/// Met a jour l'abscisse du centre de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcX() { addChangePartCommand(tr("abscisse"), part, "x", x -> value()); }
+void ArcEditor::updateArcX() { addChangePartCommand(tr("abscisse"), part, "centerX", x -> value()); }
/// Met a jour l'ordonnee du centre de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> value()); }
+void ArcEditor::updateArcY() { addChangePartCommand(tr("ordonn\351e"), part, "centerY", y -> value()); }
/// Met a jour le diametre horizontal de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h", h -> value()); }
+void ArcEditor::updateArcH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h", h -> value()); }
/// Met a jour le diametre vertical de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcV() { addChangePartCommand(tr("diam\350tre vertical"), part, "diameter_v", v -> value()); }
+void ArcEditor::updateArcV() { addChangePartCommand(tr("diam\350tre vertical"), part, "diameter_v", v -> value()); }
/// Met a jour l'angle de depart de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcS() { addChangePartCommand(tr("angle de d\351part"), part, "start_angle", -start_angle -> value() + 90); }
+void ArcEditor::updateArcS() { addChangePartCommand(tr("angle de d\351part"), part, "startAngle", ((start_angle -> value() * -1) + 90) * 16); }
/// Met a jour l'etendue de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"), part, "angle", -angle -> value()); }
+void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"), part, "spanAngle", angle -> value() * -16); }
/**
Met a jour le formulaire d'edition
@@ -141,8 +141,8 @@
y->setValue(part->property("y").toReal());
h->setValue(part->property("diameter_h").toReal());
v->setValue(part->property("diameter_v").toReal());
- start_angle -> setValue(-part -> startAngle() + 90);
- angle -> setValue(-part -> angle());
+ start_angle -> setValue(((part->property("startAngle").toInt() / 16) - 90) * -1);
+ angle -> setValue(part->property("spanAngle").toInt() / -16);
activeConnections(true);
}
Modified: trunk/sources/editor/editorcommands.cpp
===================================================================
--- trunk/sources/editor/editorcommands.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/editorcommands.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -567,8 +567,7 @@
ScalePartsCommand::ScalePartsCommand(ElementScene *scene, QUndoCommand * parent) :
ElementEditionCommand(scene, 0, parent),
first_redo(true)
-{
-}
+{}
/**
Destructor
Modified: trunk/sources/editor/elementscene.cpp
===================================================================
--- trunk/sources/editor/elementscene.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/elementscene.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -849,15 +849,15 @@
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
CustomElementPart *cep;
- if (qde.tagName() == "line") cep = new PartLine (element_editor, 0, 0);
- else if (qde.tagName() == "rect") cep = new PartRectangle(element_editor, 0, 0);
- else if (qde.tagName() == "ellipse") cep = new PartEllipse (element_editor, 0, 0);
- else if (qde.tagName() == "circle") cep = new PartEllipse (element_editor, 0, 0);
- else if (qde.tagName() == "polygon") cep = new PartPolygon (element_editor, 0, 0);
- else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor, 0, 0);
- else if (qde.tagName() == "text") cep = new PartText (element_editor, 0, 0);
- else if (qde.tagName() == "input") cep = new PartTextField(element_editor, 0, 0);
- else if (qde.tagName() == "arc") cep = new PartArc (element_editor, 0, 0);
+ if (qde.tagName() == "line") cep = new PartLine (element_editor);
+ else if (qde.tagName() == "rect") cep = new PartRectangle(element_editor);
+ else if (qde.tagName() == "ellipse") cep = new PartEllipse (element_editor);
+ else if (qde.tagName() == "circle") cep = new PartEllipse (element_editor);
+ else if (qde.tagName() == "polygon") cep = new PartPolygon (element_editor);
+ else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor);
+ else if (qde.tagName() == "text") cep = new PartText (element_editor);
+ else if (qde.tagName() == "input") cep = new PartTextField(element_editor);
+ else if (qde.tagName() == "arc") cep = new PartArc (element_editor);
else continue;
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) {
if (!qgi -> zValue()) qgi -> setZValue(z++);
Modified: trunk/sources/editor/ellipseeditor.cpp
===================================================================
--- trunk/sources/editor/ellipseeditor.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/ellipseeditor.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -102,16 +102,16 @@
*/
void EllipseEditor::updateEllipse() {
if (!part) return;
- part -> setProperty("x", x -> value());
- part -> setProperty("y", y -> value());
+ part -> setProperty("centerX", x -> value());
+ part -> setProperty("centerY", y -> value());
part -> setProperty("diameter_h", h -> value());
part -> setProperty("diameter_v", v -> value());
}
/// Met a jour l'abscisse du centre de l'ellipse et cree un objet d'annulation
-void EllipseEditor::updateEllipseX() { addChangePartCommand(tr("abscisse"), part, "x", x -> value()); }
+void EllipseEditor::updateEllipseX() { addChangePartCommand(tr("abscisse"), part, "centerX", x -> value()); }
/// Met a jour l'ordonnee du centre de l'ellipse et cree un objet d'annulation
-void EllipseEditor::updateEllipseY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> value()); }
+void EllipseEditor::updateEllipseY() { addChangePartCommand(tr("ordonn\351e"), part, "centerY", y -> value()); }
/// Met a jour le diametre horizontal de l'ellipse et cree un objet d'annulation
void EllipseEditor::updateEllipseH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h", h -> value()); }
/// Met a jour le diametre vertical de l'ellipse et cree un objet d'annulation
@@ -123,8 +123,8 @@
void EllipseEditor::updateForm() {
if (!part) return;
activeConnections(false);
- x->setValue(part->property("x").toReal());
- y->setValue(part->property("y").toReal());
+ x->setValue(part->property("centerX").toReal());
+ y->setValue(part->property("centerY").toReal());
h->setValue(part->property("diameter_h").toReal());
v->setValue(part->property("diameter_v").toReal());
activeConnections(true);
Modified: trunk/sources/editor/esevent/eseventaddarc.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddarc.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddarc.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -45,30 +45,36 @@
* @param event
* @return
*/
-bool ESEventAddArc::mousePressEvent(QGraphicsSceneMouseEvent *event) {
- if (event -> button() == Qt::LeftButton) {
+bool ESEventAddArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event -> button() == Qt::LeftButton)
+ {
if(!m_running) m_running = true;
QPointF pos = m_scene->snapToGrid(event -> scenePos());
- //create new arc
- if (!m_arc) {
- m_arc = new PartArc(m_editor, 0, m_scene);
- m_arc -> setRect(QRectF(pos, pos));
- m_arc -> setAngle(90);
+ //create new arc
+ if (!m_arc)
+ {
+ m_arc = new PartArc(m_editor);
+ m_scene -> addItem(m_arc);
+ m_arc -> setPos(pos);
+ m_arc -> setProperty("startAngle", 0);
+ m_arc -> setProperty("spanAngle", 1440);
m_arc -> setProperty("antialias", true);
m_origin = pos;
return true;
}
- //Add arc to scene
+ //At this point, m_arc is finish, we add it with an undo command
m_arc -> setRect(m_arc->rect().normalized());
m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Arc"), m_scene, m_arc));
- //Set m_arc to nullptr for create new ellipse at next mouse press
+ //Set m_arc to nullptr for create new ellipse at next mouse press
m_arc = nullptr;
return true;
}
+
return false;
}
@@ -120,67 +126,78 @@
* @brief ESEventAddArc::updateArc
* Redraw the arc with curent value
*/
-void ESEventAddArc::updateArc() {
-
+void ESEventAddArc::updateArc()
+{
qreal width = (m_mouse_pos.x() - m_origin.x())*2;
if (width < 0) width *= -1;
qreal height = (m_mouse_pos.y() - m_origin.y())*2;
if (height < 0) height *= -1;
- QPointF pos_ = m_origin;
+ QPointF pos_ = m_arc -> mapFromScene(m_origin);
//Draw arc inverted
- if (m_inverted) {
+ if (m_inverted)
+ {
//Adjust the start angle to be snapped at the origin point of draw
- if (m_mouse_pos.y() > m_origin.y()) {
-
- if (m_mouse_pos.x() > m_origin.x()) {
+ if (m_mouse_pos.y() > m_origin.y())
+ {
+ if (m_mouse_pos.x() > m_origin.x())
+ {
pos_.ry() -= height/2;
- m_arc->setStartAngle(180);
+ m_arc->setStartAngle(2880);
}
- else {
+ else
+ {
pos_.rx() -= width/2;
- m_arc->setStartAngle(90);
+ m_arc->setStartAngle(1440);
}
}
- else {
- if (m_mouse_pos.x() > m_origin.x()) {
+ else
+ {
+ if (m_mouse_pos.x() > m_origin.x())
+ {
pos_.ry() -= height;
pos_.rx() -= width/2;
- m_arc->setStartAngle(270);
+ m_arc->setStartAngle(4320);
}
- else {
+ else
+ {
pos_.rx() -= width;
pos_.ry() -= height/2;
m_arc->setStartAngle(0);
}
}
}
-
- //Draw arc non inverted
- else {
- //Adjust the start angle to be snapped at the origin point of draw
- if (m_mouse_pos.y() > m_origin.y()) {
-
- if (m_mouse_pos.x() > m_origin.x()) {
+ //Draw arc non inverted
+ else
+ {
+ //Adjust the start angle to be snapped at the origin point of draw
+ if (m_mouse_pos.y() > m_origin.y())
+ {
+ if (m_mouse_pos.x() > m_origin.x())
+ {
pos_.rx() -= width/2;
m_arc->setStartAngle(0);
}
- else {
+ else
+ {
pos_.rx() -= width;
pos_.ry() -= height/2;
- m_arc->setStartAngle(270);
+ m_arc->setStartAngle(4320);
}
}
- else {
- if (m_mouse_pos.x() > m_origin.x()) {
+ else
+ {
+ if (m_mouse_pos.x() > m_origin.x())
+ {
pos_.ry() -= height/2;
- m_arc->setStartAngle(90);
+ m_arc->setStartAngle(1440);
}
- else {
+ else
+ {
pos_.rx() -= width/2;
pos_.ry() -= height;
- m_arc->setStartAngle(180);
+ m_arc->setStartAngle(2880);
}
}
}
Modified: trunk/sources/editor/esevent/eseventaddellipse.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddellipse.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddellipse.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -50,19 +50,20 @@
if(!m_running) m_running = true;
QPointF pos = m_scene->snapToGrid(event -> scenePos());
- //create new ellpise
+ //create new ellpise
if (!m_ellipse) {
- m_ellipse = new PartEllipse(m_editor, 0, m_scene);
- m_ellipse -> setRect(QRectF(pos, pos));
- m_origin = pos;
+ m_ellipse = new PartEllipse(m_editor);
+ m_scene -> addItem(m_ellipse);
+ m_ellipse -> setPos(pos);
+ m_origin = m_new_pos = pos;
return true;
}
- //Add ellipse to scene
- m_ellipse -> setRect(m_ellipse -> rect().normalized());
+ //Add ellipse to scene
+ m_ellipse -> setRect(m_ellipse -> rect().normalized());
m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Ellipse"), m_scene, m_ellipse));
- //Set m_ellipse to nullptr for create new ellipse at next mouse press
+ //Set m_ellipse to nullptr for create new ellipse at next mouse press
m_ellipse = nullptr;
return true;
@@ -79,15 +80,16 @@
updateHelpCross(event -> scenePos());
if (!m_ellipse) return false;
- QPointF mouse_pos = m_scene -> snapToGrid(event -> scenePos());
+ QPointF pos = m_scene -> snapToGrid(event -> scenePos());
+ if (pos == m_new_pos) return true;
+ m_new_pos = pos;
- qreal width = (mouse_pos.x() - m_origin.x())*2;
- qreal height = (mouse_pos.y() - m_origin.y())*2;
+ qreal width = (m_new_pos.x() - m_origin.x())*2;
+ qreal height = (m_new_pos.y() - m_origin.y())*2;
+ //calculates the position of the rectangle so that its center is at position (0,0) of m_ellipse
+ QPointF center(-width/2, -height/2);
- QPointF pos(m_origin.x() - width/2,
- m_origin.y() - height/2);
-
- m_ellipse -> setRect(QRectF(pos, QSizeF(width, height)));
+ m_ellipse -> setRect(QRectF(center, QSizeF(width, height)));
return true;
}
Modified: trunk/sources/editor/esevent/eseventaddellipse.h
===================================================================
--- trunk/sources/editor/esevent/eseventaddellipse.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddellipse.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -41,7 +41,7 @@
private:
PartEllipse *m_ellipse;
- QPointF m_origin;
+ QPointF m_origin, m_new_pos;
};
#endif // ESEVENTADDELLIPSE_H
Modified: trunk/sources/editor/esevent/eseventaddline.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddline.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddline.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -57,8 +57,10 @@
//Create new line
if (!m_line) {
- m_line = new PartLine(m_editor, 0, m_scene);
- m_line -> setLine(QLineF(pos, pos));
+ m_line = new PartLine(m_editor);
+ m_scene -> addItem(m_line);
+ m_line -> setP1(pos);
+ m_line -> setP2(pos);
return true;
}
Modified: trunk/sources/editor/esevent/eseventaddpolygon.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddpolygon.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddpolygon.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -51,7 +51,8 @@
//create new polygon
if (!m_polygon) {
- m_polygon = new PartPolygon(m_editor, 0, m_scene);
+ m_polygon = new PartPolygon(m_editor);
+ m_scene -> addItem(m_polygon);
m_polygon -> addPoint(pos);
}
Modified: trunk/sources/editor/esevent/eseventaddrect.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddrect.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddrect.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -44,23 +44,29 @@
* @param event
* @return
*/
-bool ESEventAddRect::mousePressEvent(QGraphicsSceneMouseEvent *event) {
- if (event -> button() == Qt::LeftButton) {
+bool ESEventAddRect::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event -> button() == Qt::LeftButton)
+ {
if(!m_running) m_running = true;
QPointF pos = m_scene->snapToGrid(event -> scenePos());
- //create new rectangle
- if (!m_rect) {
- m_rect = new PartRectangle(m_editor, 0, m_scene);
+ //create new rectangle, pos isn't define,
+ //so m_rect.pos = 0,0 , that mean event.scenePos is in same coordinate of item
+ //we don't need to map point for m_rect
+ if (!m_rect)
+ {
+ m_rect = new PartRectangle(m_editor);
+ m_scene -> addItem(m_rect);
m_rect -> setRect(QRectF(pos, pos));
return true;
}
- //Add rectangle to scene
+ //Add rectangle to scene
m_rect -> setRect(m_rect -> rect().normalized());
m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Rectangle"), m_scene, m_rect));
- //Set m_rect to nullptr for create new rectangle at next mouse press
+ //Set m_rect to nullptr for create new rectangle at next mouse press
m_rect = nullptr;
return true;
@@ -77,7 +83,7 @@
updateHelpCross(event -> scenePos());
if (!m_rect) return false;
- QRectF rect(m_rect -> rect().topLeft(), m_scene->snapToGrid(event -> scenePos()));
+ QRectF rect(m_rect->rectTopLeft(), m_scene->snapToGrid(event -> scenePos()));
m_rect -> setRect(rect);
return true;
}
Modified: trunk/sources/editor/esevent/eseventaddrect.h
===================================================================
--- trunk/sources/editor/esevent/eseventaddrect.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddrect.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -19,6 +19,7 @@
#define ESEVENTADDRECT_H
#include "eseventinterface.h"
+#include <QPointF>
class ElementScene;
class PartRectangle;
Modified: trunk/sources/editor/esevent/eseventaddterminal.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddterminal.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddterminal.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -29,7 +29,8 @@
ESEventAddTerminal::ESEventAddTerminal(ElementScene *scene) :
ESEventInterface(scene)
{
- m_terminal = new PartTerminal(m_editor, 0, m_scene);
+ m_terminal = new PartTerminal(m_editor);
+ m_scene -> addItem(m_terminal);
m_running = true;
}
@@ -63,7 +64,8 @@
//Set new terminal with same rotation
Qet::Orientation ori = m_terminal -> orientation();
- m_terminal = new PartTerminal(m_editor, 0, m_scene);
+ m_terminal = new PartTerminal(m_editor);
+ m_scene -> addItem(m_terminal);
m_terminal -> setOrientation(ori);
m_terminal -> setPos(m_scene -> snapToGrid(event -> scenePos()));
Added: trunk/sources/editor/graphicspart/abstractpartellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.cpp (rev 0)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -0,0 +1,229 @@
+/*
+ Copyright 2006-2015 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "abstractpartellipse.h"
+
+/**
+ * @brief AbstractPartEllipse::AbstractPartEllipse
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+AbstractPartEllipse::AbstractPartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
+ CustomElementGraphicPart(editor, parent),
+ m_rect (QRectF(0, 0, 0, 0)),
+ m_start_angle (0),
+ m_span_angle (5760)
+{}
+
+/**
+ * @brief AbstractPartEllipse::~AbstractPartEllipse
+ * Destructor
+ */
+AbstractPartEllipse::~AbstractPartEllipse() {}
+
+/**
+ * @brief AbstractPartEllipse::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void AbstractPartEllipse::startUserTransformation(const QRectF &initial_selection_rect)
+{
+ Q_UNUSED(initial_selection_rect)
+ // we keep track of our own rectangle at the moment in scene coordinates too
+ saved_points_.clear();
+ saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
+}
+
+/**
+ * @brief AbstractPartEllipse::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void AbstractPartEllipse::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
+ QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
+ setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
+}
+
+/**
+ * @brief AbstractPartEllipse::boundingRect
+ * Bounding rectangle this part can fit into
+ * @return
+ */
+QRectF AbstractPartEllipse::boundingRect() const
+{
+ qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+ //We add 0.5 because CustomElementGraphicPart::drawShadowShape
+ //draw a shape bigger of 0.5 when pen weight is to 0.
+ if (penWeight() == 0) adjust += 0.5;
+ QRectF r(m_rect.normalized());
+ r.adjust(-adjust, -adjust, adjust, adjust);
+ return(r);
+}
+
+/**
+ * @brief AbstractPartEllipse::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into in scene coordinates.
+ * It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
+QRectF AbstractPartEllipse::sceneGeometricRect() const {
+ return(mapToScene(rect()).boundingRect());
+}
+
+/**
+ * @brief AbstractPartEllipse::sceneTopLeft
+ * @return return the top left of rectangle, in scene coordinate
+ */
+QPointF AbstractPartEllipse::sceneTopLeft() const {
+ return(mapToScene(rect().topLeft()));
+}
+
+/**
+ * @brief AbstractPartEllipse::rect
+ * Returns the item's ellipse geometry as a QRectF.
+ */
+QRectF AbstractPartEllipse::rect() const {
+ return m_rect;
+}
+
+/**
+ * @brief AbstractPartEllipse::setRect
+ * Sets the item's ellipse geometry to rect.
+ * The rectangle's left edge defines the left edge of the ellipse,
+ * and the rectangle's top edge describes the top of the ellipse
+ * The height and width of the rectangle describe the height and width of the ellipse.
+ * @param rect
+ */
+void AbstractPartEllipse::setRect(const QRectF &rect)
+{
+ if (rect == m_rect) return;
+ prepareGeometryChange();
+ m_rect = rect;
+}
+
+/**
+ * @brief AbstractPartEllipse::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * An ellipse is relevant when is rect is not null.
+ */
+bool AbstractPartEllipse::isUseless() const {
+ return(rect().isNull());
+}
+
+/**
+ * @brief AbstractPartEllipse::setStartAngle
+ * Sets the start angle for an ellipse segment to angle, which is in 16ths of a degree.
+ * This angle is used together with spanAngle() for representing an ellipse segment (a pie).
+ * By default, the start angle is 0.
+ * @param start_angle
+ */
+void AbstractPartEllipse::setStartAngle(const int &start_angle)
+{
+ if (m_start_angle == start_angle) return;
+ m_start_angle = start_angle;
+ update();
+}
+
+/**
+ * @brief AbstractPartEllipse::setSpanAngle
+ * Returns the span angle of an ellipse segment in 16ths of a degree.
+ * This angle is used together with startAngle() for representing an ellipse segment (a pie).
+ * By default, this function returns 5760 (360 * 16, a full ellipse).
+ * @param span_angle
+ */
+void AbstractPartEllipse::setSpanAngle(const int &span_angle)
+{
+ if (m_span_angle == span_angle) return;
+ m_span_angle = span_angle;
+ update();
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenterX
+ * Like setCenter but Y keep unchanged
+ * See setCenter(const QPointF ¢er)
+ * @param x
+ */
+void AbstractPartEllipse::setCenterX(const qreal x)
+{
+ QPointF pos = mapToParent(m_rect.center());
+ pos.setX(x);
+ setCenter(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenterY
+ * Like setCenter but X keep unchanged
+ * See setCenter(const QPointF ¢er)
+ * @param y
+ */
+void AbstractPartEllipse::setCenterY(const qreal y)
+{
+ QPointF pos = mapToParent(m_rect.center());
+ pos.setY(y);
+ setCenter(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenter
+ * This is a convenience method to setPos().
+ * Adjust the position of this item,
+ * so that the center of the rectangle is at the given position(position in parent coordinates).
+ * @param center
+ */
+void AbstractPartEllipse::setCenter(const QPointF ¢er)
+{
+ QPointF pos = center - m_rect.center();
+ setPos(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setWidth
+ * Set new width for rectangle.
+ * The center of rectangle is unchanged,
+ * The coordinates of the left side and right side of the rectangle change
+ * @param w
+ */
+void AbstractPartEllipse::setWidth(const qreal w)
+{
+ qreal new_width = qAbs(w);
+ QRectF current_rect = rect();
+ current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
+ current_rect.setWidth(new_width);
+ setRect(current_rect);
+}
+
+/**
+ * @brief AbstractPartEllipse::setHeight
+ * Set new height for rectangle
+ * The center of rectangle is unchanged
+ * The coordinates of the top side and bottom side of the rectangle change
+ * @param h
+ */
+void AbstractPartEllipse::setHeight(const qreal h)
+{
+ qreal new_height = qAbs(h);
+ QRectF current_rect = rect();
+ current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
+ current_rect.setHeight(new_height);
+ setRect(current_rect);
+}
Added: trunk/sources/editor/graphicspart/abstractpartellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.h (rev 0)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -0,0 +1,92 @@
+/*
+ Copyright 2006-2015 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef ABSTRACTPARTELLIPSE_H
+#define ABSTRACTPARTELLIPSE_H
+
+#include "customelementgraphicpart.h"
+
+/**
+ * @brief The AbstractPartEllipse class
+ * This is the base class for all ellipse based item like ellipse, circle, arc.
+ * This class only provide common method for edit the ellipse like rect that contain the ellipse.
+ * All coordinates is in item coordinate, except pos(), center(), centerX() and centerY()
+ * which are in parent coordinate (or scene if no parent).
+ *
+ * In several points, this class is a copy of QGraphicsEllipseItem with some change,
+ * (the use of Q_PROPERTY) to be easily used with Element editor.
+ */
+class AbstractPartEllipse : public CustomElementGraphicPart
+{
+ Q_OBJECT
+ Q_PROPERTY(int startAngle READ startAngle WRITE setStartAngle)
+ Q_PROPERTY(int spanAngle READ spanAngle WRITE setSpanAngle)
+ Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX)
+ Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY)
+ Q_PROPERTY(qreal diameter_h READ width WRITE setWidth)
+ Q_PROPERTY(qreal diameter_v READ height WRITE setHeight)
+
+ // constructors, destructor
+ public:
+ AbstractPartEllipse(QETElementEditor *editor, QGraphicsItem * parent = 0);
+ virtual ~AbstractPartEllipse();
+
+ private:
+ AbstractPartEllipse(const AbstractPartEllipse &);
+
+ // methods
+ public:
+ virtual void startUserTransformation (const QRectF &);
+ virtual void handleUserTransformation (const QRectF &, const QRectF &);
+
+ //Coordinates
+ virtual QRectF boundingRect() const;
+ virtual QRectF sceneGeometricRect() const;
+ virtual QPointF sceneTopLeft() const;
+
+ QRectF rect() const;
+ void setRect (const QRectF &rect);
+ virtual bool isUseless() const;
+
+ int startAngle() const {return m_start_angle;}
+ void setStartAngle (const int &start_angle);
+
+ int spanAngle () const {return m_span_angle;}
+ void setSpanAngle (const int &span_angle);
+
+ qreal centerX() const {return mapToScene(rect().center()).x() ;}
+ void setCenterX(const qreal x);
+
+ qreal centerY() const {return mapToScene(rect().center()).y();}
+ void setCenterY(const qreal y);
+
+ void setCenter (const QPointF ¢er);
+
+ qreal width() const {return rect().width();}
+ void setWidth(const qreal w);
+
+ qreal height() const {return rect().height();}
+ void setHeight (const qreal h);
+
+ protected:
+ QList<QPointF> saved_points_;
+ QRectF m_rect;
+ int m_start_angle;
+ int m_span_angle;
+};
+
+#endif // ABSTRACTPARTELLIPSE_H
Modified: trunk/sources/editor/graphicspart/customelementgraphicpart.cpp
===================================================================
--- trunk/sources/editor/graphicspart/customelementgraphicpart.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/customelementgraphicpart.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -20,16 +20,27 @@
/**
* @brief CustomElementGraphicPart::CustomElementGraphicPart
* Default constructor.
+ * By default, item is selectable, send geometry change (Qt > 4.6),
+ * accept mouse left button and accept hover event
* @param editor QETElement editor that belong this.
*/
-CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor) :
+CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor, QGraphicsItem *parent) :
+ QGraphicsObject (parent),
CustomElementPart(editor),
+ m_hovered (false),
_linestyle(NormalStyle),
_lineweight(NormalWeight),
_filling(NoneFilling),
_color(BlackColor),
_antialiased(false)
-{}
+{
+ setFlags(QGraphicsItem::ItemIsSelectable);
+#if QT_VERSION >= 0x040600
+ setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptHoverEvents(true);
+}
/**
* @brief CustomElementGraphicPart::~CustomElementGraphicPart
@@ -38,6 +49,36 @@
CustomElementGraphicPart::~CustomElementGraphicPart() {}
/**
+ * @brief CustomElementGraphicPart::drawCross
+ * Draw a cross at pos center
+ * @param center : center of cross
+ * @param painter : painter to use for draw cross,
+ * the painter state is restored at end of this method.
+ */
+void CustomElementGraphicPart::drawCross(const QPointF ¢er, QPainter *painter)
+{
+ painter -> save();
+ painter -> setRenderHint(QPainter::Antialiasing, false);
+ painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
+ painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
+ painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
+ painter -> restore();
+}
+
+/**
+ * @brief CustomElementGraphicPart::penWeight
+ * @return the weight of pen
+ */
+qreal CustomElementGraphicPart::penWeight() const
+{
+ if (_lineweight == NoneWeight || _lineweight == ThinWeight) return 0;
+ else if (_lineweight == NormalWeight) return 1;
+ else if (_lineweight == UltraWeight) return 2;
+ else if (_lineweight == BigWeight) return 5;
+ return 1;
+}
+
+/**
* @brief CustomElementGraphicPart::stylesToXml
* Write the curent style to xml element.
* The style are stored like this:
@@ -206,3 +247,69 @@
painter.setPen(pen);
painter.setBrush(brush);
}
+
+/**
+ * @brief CustomElementGraphicPart::drawShadowShape
+ * Draw a transparent blue shadow arround the shape of this item.
+ * The QPainterPathStroker used to draw shadows have a width of SHADOWS_HEIGHT
+ * Be carefull if penWeight of this item is to 0 the outline of strock is bigger of 0.5
+ * @param painter : painter to use for draw this shadows
+ */
+void CustomElementGraphicPart::drawShadowShape(QPainter *painter)
+{
+ //@FIXME if pen weight is 0, the strock outline is SHADOWS_HEIGHT/2 + 0.5
+ //may be because shape have no line weight
+ QPainterPathStroker strock;
+ strock.setWidth(SHADOWS_HEIGHT);
+ strock.setJoinStyle(Qt::RoundJoin);
+
+ painter->save();
+ QColor color(Qt::darkBlue);
+ color.setAlpha(50);
+ painter -> setBrush (QBrush (color));
+ painter -> setPen (Qt::NoPen);
+ painter -> drawPath (strock.createStroke(shape()));
+ painter -> restore ();
+}
+
+/**
+ * @brief CustomElementGraphicPart::itemChange
+ * Reimplemented from QGraphicsObject.
+ * If the item position change call updateCurrentPartEditor()
+ * the change is always send to QGraphicsObject
+ * @param change
+ * @param value
+ * @return the returned value of QGraphicsObject::itemChange
+ */
+QVariant CustomElementGraphicPart::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (scene())
+ if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged)
+ updateCurrentPartEditor();
+
+ return(QGraphicsObject::itemChange(change, value));
+}
+
+/**
+ * @brief CustomElementGraphicPart::hoverEnterEvent
+ * Reimplemented from QGraphicsObject.
+ * Set m_hovered to true
+ * @param event
+ */
+void CustomElementGraphicPart::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ m_hovered = true;
+ QGraphicsObject::hoverEnterEvent(event);
+}
+
+/**
+ * @brief CustomElementGraphicPart::hoverLeaveEvent
+ * Reimplemented from QGraphicsObject.
+ * Set m_hovered to false
+ * @param event
+ */
+void CustomElementGraphicPart::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ m_hovered = false;
+ QGraphicsObject::hoverLeaveEvent(event);
+}
Modified: trunk/sources/editor/graphicspart/customelementgraphicpart.h
===================================================================
--- trunk/sources/editor/graphicspart/customelementgraphicpart.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/customelementgraphicpart.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,19 +18,22 @@
#ifndef CUSTOM_ELEMENT_GRAPHIC_PART_H
#define CUSTOM_ELEMENT_GRAPHIC_PART_H
-#include <QObject>
+#include <QGraphicsObject>
#include "customelementpart.h"
class QETElementEditor;
class QPainter;
+
/**
* @brief The CustomElementGraphicPart class
* This class is the base for all home-made primitive like line, rectangle, ellipse etc....
* It provides methods and enums to manage style attributes available for primitive (color, pen style, etc...)
*/
-class CustomElementGraphicPart : public QObject, public CustomElementPart
+class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPart
{
+ #define SHADOWS_HEIGHT 4.0
+
Q_OBJECT
//Made this Q_ENUMS to be used by the Q_PROPERTY system.
@@ -62,15 +65,18 @@
// constructors, destructor
public:
- CustomElementGraphicPart(QETElementEditor *editor);
+ CustomElementGraphicPart(QETElementEditor *editor, QGraphicsItem *parent = 0);
virtual ~CustomElementGraphicPart();
+ static void drawCross (const QPointF ¢er, QPainter *painter);
+
//Getter and setter
LineStyle lineStyle () const {return _linestyle;}
void setLineStyle (const LineStyle ls) {_linestyle = ls;}
LineWeight lineWeight () const {return _lineweight;}
void setLineWeight (const LineWeight lw) {_lineweight = lw;}
+ qreal penWeight () const;
Filling filling () const {return _filling;}
void setFilling(const Filling f) {_filling = f;}
@@ -92,8 +98,14 @@
void stylesFromXml(const QDomElement &);
void resetStyles ();
void applyStylesToQPainter(QPainter &) const;
-
+ void drawShadowShape (QPainter *painter);
+
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
// attributes
+ bool m_hovered;
private:
LineStyle _linestyle;
LineWeight _lineweight;
Modified: trunk/sources/editor/graphicspart/partarc.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partarc.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partarc.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,68 +18,68 @@
#include "partarc.h"
/**
- Constructeur
- @param editor L'editeur d'element concerne
- @param parent Le QGraphicsItem parent de cet arc
- @param scene La scene sur laquelle figure cet arc
-*/
-PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
- CustomElementGraphicPart(editor),
- QGraphicsEllipseItem(parent, scene),
- _angle(-90),
- start_angle(0)
+ * @brief PartArc::PartArc
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) :
+ AbstractPartEllipse(editor, parent)
{
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
- setAcceptedMouseButtons(Qt::LeftButton);
+ m_start_angle = 0;
+ m_span_angle = -1440;
}
-/// Destructeur
-PartArc::~PartArc() {
-}
+/**
+ * @brief PartArc::~PartArc
+ * Destructor
+ */
+PartArc::~PartArc() {}
/**
- Dessine l'arc de cercle
- @param painter QPainter a utiliser pour rendre le dessin
- @param options Options pour affiner le rendu
- @param widget Widget sur lequel le rendu est effectue
-*/
-void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartArc::paint
+ * Draw this arc
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
Q_UNUSED(widget);
+
applyStylesToQPainter(*painter);
- // enleve systematiquement la couleur de fond
+
+ //Always remove the brush
painter -> setBrush(Qt::NoBrush);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
painter -> setPen(t);
- if (isSelected()) {
- // dessine l'ellipse en noir
+ if (isSelected())
+ {
+ //Draw the ellipse in black
painter -> drawEllipse(rect());
-
- // dessine l'arc en rouge
+
+ //Draw the arc in red
t.setColor(Qt::red);
painter -> setPen(t);
}
- painter -> drawArc(rect(), start_angle * 16, _angle * 16);
- if (isSelected()) {
- // dessine la croix au centre de l'ellipse
- painter -> setRenderHint(QPainter::Antialiasing, false);
- painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
- QPointF center = rect().center();
- painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
- painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
- }
+ painter -> drawArc(m_rect, m_start_angle, m_span_angle);
+
+ if (m_hovered)
+ drawShadowShape(painter);
+
+ if (isSelected())
+ drawCross(m_rect.center(), painter);
}
/**
- Exporte l'arc de cercle en XML
- @param xml_document Document XML a utiliser pour creer l'element XML
- @return un element XML decrivant l'arc de cercle
-*/
+ * @brief PartArc::toXml
+ * Export this arc in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return : an xml element that describe this arc
+ */
const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("arc");
QPointF top_left(sceneTopLeft());
@@ -87,144 +87,41 @@
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
xml_element.setAttribute("width", QString("%1").arg(rect().width()));
xml_element.setAttribute("height", QString("%1").arg(rect().height()));
- xml_element.setAttribute("start", QString("%1").arg(start_angle));
- xml_element.setAttribute("angle", QString("%1").arg(_angle));
+ //to maintain compatibility with the previous version, we write the angle in degrees.
+ xml_element.setAttribute("start", QString("%1").arg(m_start_angle / 16));
+ xml_element.setAttribute("angle", QString("%1").arg(m_span_angle / 16));
stylesToXml(xml_element);
return(xml_element);
}
/**
- Importe les proprietes d'un arc de cercle depuis un element XML
- @param qde Element XML a lire
-*/
+ * @brief PartArc::fromXml
+ * Import the properties of this arc from a xml element.
+ * @param qde : Xml document to use.
+ */
void PartArc::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
- setRect(
- QRectF(
- mapFromScene(
- qde.attribute("x", "0").toDouble(),
- qde.attribute("y", "0").toDouble()
- ),
- QSizeF(
- qde.attribute("width", "0").toDouble(),
- qde.attribute("height", "0").toDouble()
- )
- )
- );
- setStartAngle(qde.attribute("start", "0").toInt());
- setAngle(qde.attribute("angle", "-90").toInt());
-}
+ m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+ qde.attribute("y", "0").toDouble()),
+ QSizeF(qde.attribute("width", "0").toDouble(),
+ qde.attribute("height", "0").toDouble()) );
-/**
- @return le coin superieur gauche du rectangle dans lequel s'inscrit
- l'ellipse dont fait partie cet arc, dans les coordonnees de la scene.
-*/
-QPointF PartArc::sceneTopLeft() const {
- return(mapToScene(rect().topLeft()));
+ m_start_angle = qde.attribute("start", "0").toInt() * 16;
+ m_span_angle = qde.attribute("angle", "-1440").toInt() * 16;
}
/**
- * @brief PartArc::setX
- * @param x is the center of the rect bounding this ellipse
+ * @brief PartArc::shape
+ * @return the shape of this item
*/
-void PartArc::setX(const qreal x) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.center());
- setRect(current_rect.translated(x - current_pos.x(), 0.0));
-}
+QPainterPath PartArc::shape() const
+{
+ QPainterPath shape;
+ shape.arcMoveTo(m_rect, m_start_angle/16);
+ shape.arcTo(m_rect, m_start_angle/16, m_span_angle/16);
-/**
- * @brief PartArc::setY
- * @param y is the center of the rect bounding this ellipse
- */
-void PartArc::setY(const qreal y) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.center());
- setRect(current_rect.translated(0.0, y - current_pos.y()));
-}
+ QPainterPathStroker pps;
+ pps.setWidth(penWeight());
-/**
- * @brief PartArc::setWidth
- * @param w is the width of the rect bounding this ellipse
- */
-void PartArc::setWidth(const qreal w) {
- qreal new_width = qAbs(w);
- QRectF current_rect = rect();
- current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
- current_rect.setWidth(new_width);
- setRect(current_rect);
+ return (pps.createStroke(shape));
}
-
-/**
- * @brief PartArc::setHeight
- * @param h is the heigth of the rect bounding this ellipse
- */
-void PartArc::setHeight(const qreal h) {
- qreal new_height = qAbs(h);
- QRectF current_rect = rect();
- current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
- current_rect.setHeight(new_height);
- setRect(current_rect);
-}
-
-/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartArc::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsEllipseItem::itemChange(change, value));
-}
-
-/**
- @return true si cette partie n'est pas pertinente et ne merite pas d'etre
- conservee / enregistree.
- Un arc est pertinent des lors que ses dimensions et son etendue ne sont
- pas nulles.
-*/
-bool PartArc::isUseless() const {
- return(rect().isNull() || !angle());
-}
-
-/**
- @return the minimum, margin-less rectangle this part can fit into, in scene
- coordinates. It is different from boundingRect() because it is not supposed
- to imply any margin, and it is different from shape because it is a regular
- rectangle, not a complex shape.
-*/
-QRectF PartArc::sceneGeometricRect() const {
- return(mapToScene(rect()).boundingRect());
-}
-
-/**
- Start the user-induced transformation, provided this primitive is contained
- within the \a initial_selection_rect bounding rectangle.
-*/
-void PartArc::startUserTransformation(const QRectF &initial_selection_rect) {
- Q_UNUSED(initial_selection_rect)
- saved_points_.clear();
- saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
-}
-
-/**
- Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartArc::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
- QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
- setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
-}
-
-/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartArc::boundingRect() const {
- qreal adjust = 1.5;
- QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
- r.adjust(-adjust, -adjust, adjust, adjust);
- return(r);
-}
Modified: trunk/sources/editor/graphicspart/partarc.h
===================================================================
--- trunk/sources/editor/graphicspart/partarc.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partarc.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,79 +17,41 @@
*/
#ifndef PART_ARC_H
#define PART_ARC_H
-#include <QtGui>
-#include "customelementgraphicpart.h"
+
+#include "abstractpartellipse.h"
+
/**
- This class represents an elliptical arc primitive which may be used to
- compose the drawing of an electrical element within the element editor.
-*/
-class PartArc : public CustomElementGraphicPart, public QGraphicsEllipseItem {
- Q_OBJECT
- // constructors, destructor
+ * @brief The PartArc class
+ * This class represents an elliptical arc primitive which may be used to
+ * compose the drawing of an electrical element within the element editor.
+ */
+class PartArc : public AbstractPartEllipse
+{
+ Q_OBJECT
+
public:
- PartArc(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
- virtual ~PartArc();
+ PartArc(QETElementEditor *editor, QGraphicsItem *parent = 0);
+ virtual ~PartArc();
private:
- PartArc(const PartArc &);
-
- // attributes
- private:
- int _angle;
- int start_angle;
-
- // methods
+ PartArc(const PartArc &);
+
+ // methods
public:
- enum { Type = UserType + 1101 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartArc.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- virtual QString name() const { return(QObject::tr("arc", "element part name")); }
- virtual QString xmlName() const { return(QString("arc")); }
- virtual const QDomElement toXml(QDomDocument &) const;
- virtual void fromXml(const QDomElement &);
- virtual QPointF sceneTopLeft() const;
- virtual QRectF boundingRect() const;
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ enum { Type = UserType + 1101 };
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartArc.
+ * @return the QGraphicsItem type
+ */
+ virtual int type() const { return Type; }
+ virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- ///PROPERT
- // X value
- Q_PROPERTY(qreal x READ x WRITE setX)
- qreal x() const {return mapToScene(rect().center()).x() ;}
- void setX(const qreal x);
- //Y value
- Q_PROPERTY(qreal y READ y WRITE setY)
- qreal y() const {return mapToScene(rect().center()).y();}
- void setY(const qreal y);
- // horizontal diameter
- Q_PROPERTY(qreal diameter_h READ width WRITE setWidth)
- qreal width() const {return rect().width();}
- void setWidth(const qreal w);
- // vertical diameter
- Q_PROPERTY(qreal diameter_v READ height WRITE setHeight)
- qreal height() const {return rect().height();}
- void setHeight (const qreal h);
- // start angle
- Q_PROPERTY(int start_angle READ startAngle WRITE setStartAngle)
- int startAngle() const {return start_angle;}
- void setStartAngle(const int sa){start_angle = sa;}
- // angle value
- Q_PROPERTY(int angle READ angle WRITE setAngle)
- int angle() const {return _angle;}
- void setAngle(const int a) {_angle = a;}
+ //Name and XML
+ virtual QString name() const { return(QObject::tr("arc", "element part name")); }
+ virtual QString xmlName() const { return(QString("arc")); }
+ virtual const QDomElement toXml (QDomDocument &) const;
+ virtual void fromXml (const QDomElement &);
-
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
-
- private:
- QList<QPointF> saved_points_;
+ virtual QPainterPath shape() const;
};
#endif
Modified: trunk/sources/editor/graphicspart/partellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partellipse.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,188 +18,113 @@
#include "partellipse.h"
/**
- Constructeur
- @param editor L'editeur d'element concerne
- @param parent Le QGraphicsItem parent de cette ellipse
- @param scene La scene sur laquelle figure cette ellipse
-*/
-PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : CustomElementGraphicPart(editor), QGraphicsEllipseItem(parent, scene) {
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
- setAcceptedMouseButtons(Qt::LeftButton);
-}
+ * @brief PartEllipse::PartEllipse
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
+ AbstractPartEllipse(editor, parent)
+{}
-/// Destructeur
-PartEllipse::~PartEllipse() {
-}
+/**
+ * @brief PartEllipse::~PartEllipse
+ * Destructor
+ */
+PartEllipse::~PartEllipse() {}
/**
- Dessine l'ellipse
- @param painter QPainter a utiliser pour rendre le dessin
- @param options Options pour affiner le rendu
- @param widget Widget sur lequel le rendu est effectue
-*/
-void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartEllipse::paint
+ * Draw this ellpise
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
Q_UNUSED(widget);
applyStylesToQPainter(*painter);
+
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
- if (isSelected()) {
+
+ if (isSelected())
t.setColor(Qt::red);
- }
+
painter -> setPen(t);
painter -> drawEllipse(rect());
- if (isSelected()) {
- painter -> setRenderHint(QPainter::Antialiasing, false);
- painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
- QPointF center = rect().center();
- painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
- painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
- }
+
+ if (m_hovered)
+ drawShadowShape(painter);
+
+ if (isSelected())
+ drawCross(m_rect.center(), painter);
}
/**
- Exporte l'ellipse en XML
- @param xml_document Document XML a utiliser pour creer l'element XML
- @return un element XML decrivant l'ellipse
-*/
-const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
+ * @brief PartEllipse::toXml
+ * Export this ellipse in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return : an xml element that describe this ellipse
+ */
+const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const
+{
QDomElement xml_element;
- if (qFuzzyCompare(rect().width(), rect().height())) {
+ if (qFuzzyCompare(rect().width(), rect().height()))
+ {
xml_element = xml_document.createElement("circle");
xml_element.setAttribute("diameter", QString("%1").arg(rect().width()));
- } else {
+ }
+ else
+ {
xml_element = xml_document.createElement("ellipse");
xml_element.setAttribute("width", QString("%1").arg(rect().width()));
xml_element.setAttribute("height", QString("%1").arg(rect().height()));
}
+
QPointF top_left(sceneTopLeft());
xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
+
stylesToXml(xml_element);
+
return(xml_element);
}
/**
- Importe les proprietes d'une ellipse depuis un element XML
- @param qde Element XML a lire
-*/
-void PartEllipse::fromXml(const QDomElement &qde) {
+ * @brief PartEllipse::fromXml
+ * Import the properties of this ellipse from a xml element.
+ * @param qde : Xml document to use.
+ */
+void PartEllipse::fromXml(const QDomElement &qde)
+{
stylesFromXml(qde);
qreal width, height;
- if (qde.tagName() == "ellipse") {
+
+ if (qde.tagName() == "ellipse")
+ {
width = qde.attribute("width", "0").toDouble();
height = qde.attribute("height", "0").toDouble();
- } else {
- width = height = qde.attribute("diameter", "0").toDouble();
}
- setRect(
- QRectF(
- mapFromScene(
- qde.attribute("x", "0").toDouble(),
- qde.attribute("y", "0").toDouble()
- ),
- QSizeF(width, height)
- )
- );
-}
+ else
+ width = height = qde.attribute("diameter", "0").toDouble();
-void PartEllipse::setX(const qreal x) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.center());
- setRect(current_rect.translated(x - current_pos.x(), 0.0));
+ m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+ qde.attribute("y", "0").toDouble()),
+ QSizeF(width, height));
}
-void PartEllipse::setY(const qreal y) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.center());
- setRect(current_rect.translated(0.0, y - current_pos.y()));
-}
-
-void PartEllipse::setWidth(const qreal w) {
- qreal new_width = qAbs(w);
- QRectF current_rect = rect();
- current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
- current_rect.setWidth(new_width);
- setRect(current_rect);
-}
-
-void PartEllipse::setHeight(const qreal h) {
- qreal new_height = qAbs(h);
- QRectF current_rect = rect();
- current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
- current_rect.setHeight(new_height);
- setRect(current_rect);
-}
-
/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsEllipseItem::itemChange(change, value));
-}
+ * @brief PartEllipse::shape
+ * @return the shape of this item
+ */
+QPainterPath PartEllipse::shape() const
+{
+ QPainterPath shape;
+ shape.addEllipse(m_rect);
-/**
- @return le coin superieur gauche du rectangle dans lequel s'inscrit
- l'ellipse, dans les coordonnees de la scene.
-*/
-QPointF PartEllipse::sceneTopLeft() const {
- return(mapToScene(rect().topLeft()));
-}
+ QPainterPathStroker pps;
+ pps.setWidth(penWeight());
-/**
- @return true si cette partie n'est pas pertinente et ne merite pas d'etre
- conservee / enregistree.
- Une ellipse est pertinente des lors que ses dimensions ne sont pas nulles
-*/
-bool PartEllipse::isUseless() const {
- return(rect().isNull());
+ return (pps.createStroke(shape));
}
-
-/**
- @return the minimum, margin-less rectangle this part can fit into, in scene
- coordinates. It is different from boundingRect() because it is not supposed
- to imply any margin, and it is different from shape because it is a regular
- rectangle, not a complex shape.
-*/
-QRectF PartEllipse::sceneGeometricRect() const {
- return(mapToScene(rect()).boundingRect());
-}
-
-/**
- Start the user-induced transformation, provided this primitive is contained
- within the \a initial_selection_rect bounding rectangle.
-*/
-void PartEllipse::startUserTransformation(const QRectF &initial_selection_rect) {
- Q_UNUSED(initial_selection_rect)
- // we keep track of our own rectangle at the moment in scene coordinates too
- saved_points_.clear();
- saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
-}
-
-/**
- Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartEllipse::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
- QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
- setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
-}
-
-/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartEllipse::boundingRect() const {
- qreal adjust = 1.5;
- QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
- r.adjust(-adjust, -adjust, adjust, adjust);
- return(r);
-}
Modified: trunk/sources/editor/graphicspart/partellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partellipse.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,65 +17,42 @@
*/
#ifndef PART_ELLIPSE_H
#define PART_ELLIPSE_H
-#include <QtGui>
-#include "customelementgraphicpart.h"
+
+#include "abstractpartellipse.h"
+
/**
- This class represents an ellipse primitive which may be used to compose the
- drawing of an electrical element within the element editor.
-*/
-class PartEllipse : public CustomElementGraphicPart, public QGraphicsEllipseItem {
- Q_OBJECT
- // constructors, destructor
+ * @brief The PartEllipse class
+ * This class represents an ellipse primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ */
+class PartEllipse : public AbstractPartEllipse
+{
+ Q_OBJECT
+
+ // constructors, destructor
public:
- PartEllipse(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
- virtual ~PartEllipse();
+ PartEllipse(QETElementEditor *editor, QGraphicsItem * parent = 0);
+ virtual ~PartEllipse();
private:
- PartEllipse(const PartEllipse &);
+ PartEllipse(const PartEllipse &);
- // methods
+ // methods
public:
- enum { Type = UserType + 1103 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartEllipse.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- virtual QString name() const { return(QObject::tr("ellipse", "element part name")); }
- virtual QString xmlName() const { return(QString("ellipse")); }
- virtual const QDomElement toXml(QDomDocument &) const;
- virtual void fromXml(const QDomElement &);
- virtual QPointF sceneTopLeft() const;
- virtual QRectF boundingRect() const;
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ enum { Type = UserType + 1103 };
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartEllipse.
+ * @return the QGraphicsItem type
+ */
+ virtual int type() const { return Type; }
+ virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- ///PROPERTY
- // X value
- Q_PROPERTY(qreal x READ x WRITE setX)
- qreal x() const {return mapToScene(rect().center()).x() ;}
- void setX(const qreal x);
- // Y value
- Q_PROPERTY(qreal y READ y WRITE setY)
- qreal y() const {return mapToScene(rect().center()).y();}
- void setY(const qreal y);
- // horizontal diameter
- Q_PROPERTY(qreal diameter_h READ width WRITE setWidth)
- qreal width() const {return rect().width();}
- void setWidth(const qreal w);
- // vertical diameter
- Q_PROPERTY(qreal diameter_v READ height WRITE setHeight)
- qreal height() const {return rect().height();}
- void setHeight (const qreal h);
-
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
-
- private:
- QList<QPointF> saved_points_;
+ //Name and XML
+ virtual QString name() const { return(QObject::tr("ellipse", "element part name")); }
+ virtual QString xmlName() const { return(QString("ellipse")); }
+ virtual const QDomElement toXml (QDomDocument &) const;
+ virtual void fromXml (const QDomElement &);
+
+ virtual QPainterPath shape() const;
};
#endif
Modified: trunk/sources/editor/graphicspart/partline.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partline.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partline.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,148 +18,80 @@
#include "partline.h"
#include <cmath>
+
/**
- Constructeur
- @param editor L'editeur d'element concerne
- @param parent Le QGraphicsItem parent de cette ligne
- @param scene La scene sur laquelle figure cette ligne
-*/
-PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
- CustomElementGraphicPart(editor),
- QGraphicsLineItem(parent, scene),
+ * @brief PartLine::PartLine
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) :
+ CustomElementGraphicPart(editor, parent),
first_end(Qet::None),
first_length(1.5),
second_end(Qet::None),
second_length(1.5)
-{
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
- setAcceptedMouseButtons(Qt::LeftButton);
-}
+{}
/// Destructeur
-PartLine::~PartLine() {
-}
+PartLine::~PartLine() {}
/**
- @param end_type Type d'extremite
- @return Le nombre de "longueurs" requises pour dessiner une extremite de type end_type
-*/
-uint PartLine::requiredLengthForEndType(const Qet::EndType &end_type) {
+ * @brief PartLine::requiredLengthForEndType
+ * @param end_type
+ * @return the number of "length" needed to draw a extremity of type Qet::EndType.
+ */
+uint PartLine::requiredLengthForEndType(const Qet::EndType &end_type)
+{
uint length_count_required = 0;
- if (end_type == Qet::Circle || end_type == Qet::Diamond) {
+
+ if (end_type == Qet::Circle || end_type == Qet::Diamond)
length_count_required = 2;
- } else if (end_type == Qet::Simple || end_type == Qet::Triangle) {
+ else if (end_type == Qet::Simple || end_type == Qet::Triangle)
length_count_required = 1;
- }
+
return(length_count_required);
}
/**
- Dessine la ligne
- @param painter QPainter a utiliser pour rendre le dessin
- @param options Options pour affiner le rendu
- @param widget Widget sur lequel le rendu est effectue
-*/
-void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartLine::paint
+ * Draw this line
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
Q_UNUSED(widget);
- // inutile de dessiner une ligne nulle
- if (line().p1() == line().p2()) return;
+ if (isUseless()) return;
+
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setJoinStyle(Qt::MiterJoin);
t.setCosmetic(options && options -> levelOfDetail < 1.0);
- if (isSelected()) {
+
+ if (isSelected())
t.setColor(Qt::red);
- }
+
painter -> setPen(t);
- QPointF point1(line().p1());
- QPointF point2(line().p2());
-
- qreal line_length(line().length());
- qreal pen_width = painter -> pen().widthF();
-
- qreal length1 = first_length;
- qreal length2 = second_length;
-
- //debugPaint(painter);
-
- // determine s'il faut dessiner les extremites
- bool draw_1st_end, draw_2nd_end;
- qreal reduced_line_length = line_length - (length1 * requiredLengthForEndType(first_end));
- draw_1st_end = first_end && reduced_line_length >= 0;
- if (draw_1st_end) {
- reduced_line_length -= (length2 * requiredLengthForEndType(second_end));
- } else {
- reduced_line_length = line_length - (length2 * requiredLengthForEndType(second_end));
- }
- draw_2nd_end = second_end && reduced_line_length >= 0;
-
- // dessine la premiere extremite
- QPointF start_point, stop_point;
- if (draw_1st_end) {
- QList<QPointF> four_points1(fourEndPoints(point1, point2, length1));
- if (first_end == Qet::Circle) {
- painter -> drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
- start_point = four_points1[1];
- } else if (first_end == Qet::Diamond) {
- painter -> drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
- start_point = four_points1[1];
- } else if (first_end == Qet::Simple) {
- painter -> drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
- start_point = point1;
-
- } else if (first_end == Qet::Triangle) {
- painter -> drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
- start_point = four_points1[0];
- }
-
- // ajuste le depart selon l'epaisseur du trait
- if (pen_width && (first_end == Qet::Simple || first_end == Qet::Circle)) {
- start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
- }
- } else {
- start_point = point1;
- }
-
- // dessine la seconde extremite
- if (draw_2nd_end) {
- QList<QPointF> four_points2(fourEndPoints(point2, point1, length2));
- if (second_end == Qet::Circle) {
- painter -> drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
- stop_point = four_points2[1];
- } else if (second_end == Qet::Diamond) {
- painter -> drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
- stop_point = four_points2[1];
- } else if (second_end == Qet::Simple) {
- painter -> drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
- stop_point = point2;
- } else if (second_end == Qet::Triangle) {
- painter -> drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
- stop_point = four_points2[0];
- }
-
- // ajuste l'arrivee selon l'epaisseur du trait
- if (pen_width && (second_end == Qet::Simple || second_end == Qet::Circle)) {
- stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
- }
- } else {
- stop_point = point2;
- }
-
- painter -> drawLine(start_point, stop_point);
+ if (first_end || second_end)
+ painter -> drawPath(path());
+ else
+ painter -> drawLine(m_line);
+
+ if (m_hovered)
+ drawShadowShape(painter);
}
/**
- Exporte la ligne en XML
- @param xml_document Document XML a utiliser pour creer l'element XML
- @return un element XML decrivant la ligne
-*/
-const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
-
+ * @brief PartLine::toXml
+ * Export this line in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return an xml element that describe this line
+ */
+const QDomElement PartLine::toXml(QDomDocument &xml_document) const
+{
QPointF p1(sceneP1());
QPointF p2(sceneP2());
@@ -178,186 +110,141 @@
}
/**
- Importe les proprietes d'une ligne depuis un element XML
- @param qde Element XML a lire
-*/
+ * @brief PartLine::fromXml
+ * Import the properties of this line from a xml element.
+ * @param qde : Xml document to use
+ */
void PartLine::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
- setLine(
- QLineF(
- mapFromScene(
- qde.attribute("x1", "0").toDouble(),
- qde.attribute("y1", "0").toDouble()
- ),
- mapFromScene(
- qde.attribute("x2", "0").toDouble(),
- qde.attribute("y2", "0").toDouble()
- )
- )
- );
- first_end = Qet::endTypeFromString(qde.attribute("end1"));
- first_length = qde.attribute("length1", "1.5").toDouble();
- second_end = Qet::endTypeFromString(qde.attribute("end2"));
+ m_line = QLineF(mapFromScene(qde.attribute("x1", "0").toDouble(),
+ qde.attribute("y1", "0").toDouble()),
+ mapFromScene(qde.attribute("x2", "0").toDouble(),
+ qde.attribute("y2", "0").toDouble()));
+
+ first_end = Qet::endTypeFromString(qde.attribute("end1"));
+ first_length = qde.attribute("length1", "1.5").toDouble();
+ second_end = Qet::endTypeFromString(qde.attribute("end2"));
second_length = qde.attribute("length2", "1.5").toDouble();
}
/**
- * @brief PartLine::setX1
- * set X of P1
- * @param x1
+ * @brief PartLine::p1
+ * @return the point p1 of line.
*/
-void PartLine::setX1(qreal x1) {
- QPointF p = line().p1();
- p.setX(x1);
- setLine(QLineF(p, line().p2()));
+QPointF PartLine::p1() const {
+ return m_line.p1();
}
/**
- * @brief PartLine::setY1
- * set y of P1
- * @param y1
- */
-void PartLine::setY1(qreal y1) {
- QPointF p = line().p1();
- p.setY(y1);
- setLine(QLineF(p, line().p2()));
-}
-
-/**
* @brief PartLine::setP1
* set first point to P1
* @param p1
*/
-void PartLine::setP1(QPointF p1) {
- setLine(QLineF(p1, line().p2()));
+void PartLine::setP1(const QPointF &p1)
+{
+ if (p1 == m_line.p1()) return;
+ prepareGeometryChange();
+ m_line.setP1(p1);
}
/**
- * @brief PartLine::setX2
- * set x of P2
- * @param x2
+ * @brief PartLine::p2
+ * @return the point p2 of line
*/
-void PartLine::setX2(qreal x2) {
- QPointF p = line().p2();
- p.setX(x2);
- setLine(QLineF(line().p1(), p));
+QPointF PartLine::p2() const {
+ return m_line.p2();
}
/**
- * @brief PartLine::setY2
- * set y of P2
- * @param y2
- */
-void PartLine::setY2(qreal y2) {
- QPointF p = line().p2();
- p.setY(y2);
- setLine(QLineF(line().p1(), p));
-}
-
-/**
* @brief PartLine::setP2
* set second point to P2
* @param p2
*/
-void PartLine::setP2(QPointF p2) {
- setLine(QLineF(line().p1(), p2));
+void PartLine::setP2(const QPointF &p2)
+{
+ if (p2 == m_line.p2()) return;
+ prepareGeometryChange();
+ m_line.setP2(p2);
}
/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartLine::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsLineItem::itemChange(change, value));
-}
-
-/**
- @return le premier point, dans les coordonnees de la scene.
-*/
+ * @brief PartLine::sceneP1
+ * @return the point p1 in scene coordinate
+ */
QPointF PartLine::sceneP1() const {
- return(mapToScene(line().p1()));
+ return(mapToScene(p1()));
}
/**
- @return le second point, dans les coordonnees de la scene.
-*/
+ * @brief PartLine::sceneP2
+ * @return the point p2 in scen coordinate
+ */
QPointF PartLine::sceneP2() const {
- return(mapToScene(line().p2()));
+ return(mapToScene(p2()));
}
/**
- @return la forme selectionnable de la ligne
-*/
-QPainterPath PartLine::shape() const {
- QList<QPointF> points = fourShapePoints();
- QPainterPath t;
- t.setFillRule(Qt::WindingFill);
- t.moveTo(points.at(0));
- t.lineTo(points.at(1));
- t.lineTo(points.at(2));
- t.lineTo(points.at(3));
- t.lineTo(points.at(0));
-
- // n'en fait pas plus si la ligne se ramene a un point
- if (line().p1() == line().p2()) return(t);
-
- // ajoute un cercle pour l'extremite 1 si besoin
- if (first_end) {
- QPainterPath t2;
- t2.addEllipse(firstEndCircleRect());
- t.addPath(t2.subtracted(t));
+ * @brief PartLine::shape
+ * @return the shape of this item
+ */
+QPainterPath PartLine::shape() const
+{
+ QPainterPath shape;
+
+ //We calcul path only if there is an end type
+ //Else we just draw a line
+ if (first_end || second_end)
+ shape.addPath(path());
+ else
+ {
+ shape.moveTo(m_line.p1());
+ shape.lineTo(m_line.p2());
}
-
- // ajoute un cercle pour l'extremite 2 si besoin
- if (second_end) {
- QPainterPath t2;
- t2.addEllipse(secondEndCircleRect());
- t.addPath(t2.subtracted(t));
- }
-
- return(t);
+
+ QPainterPathStroker pps;
+ pps.setWidth(penWeight());
+
+ return (pps.createStroke(shape));
}
/**
- @return une liste contenant les deux points de la droite + les 4 points entourant ces deux points
-*/
-QList<QPointF> PartLine::fourShapePoints() const {
+ * @brief PartLine::fourShapePoints
+ * @return a list with the two points that delimite the line
+ * + the four points surrounding these two points
+ */
+QList<QPointF> PartLine::fourShapePoints() const
+{
const qreal marge = 2.0;
- // on a donc A(xa , ya) et B(xb, yb)
- QPointF a = line().p1();
- QPointF b = line().p2();
+
+ QPointF a = m_line.p1();
+ QPointF b = m_line.p2();
QList<QPointF> result;
- // cas particulier : la droite se ramene a un point
- if (a == b) {
+ //Special case, the line is defined by one point
+ if (a == b)
+ {
result << QPointF(a.x() - marge, a.y() - marge);
result << QPointF(a.x() - marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() - marge);
- } else {
-
- // on calcule le vecteur AB : (xb-xa, yb-ya)
+ }
+ else
+ {
+ //We calcule the vector AB : (xb-xa, yb-ya)
QPointF v_ab = b - a;
- // et la distance AB : racine des coordonnees du vecteur au carre
+ //And the distance AB: root of the coordinates of the vector squared
qreal ab = sqrt(pow(v_ab.x(), 2) + pow(v_ab.y(), 2));
- // ensuite on definit le vecteur u(a, b) qui est egal au vecteur AB divise
- // par sa longueur et multiplie par la longueur de la marge que tu veux
- // laisser
+ //Next, we define the vector u(a, b) wich is equal to the vector AB divided
+ //by is length and multiplied by the length of marge.
QPointF u = v_ab / ab * marge;
- // on definit le vecteur v(-b , a) qui est perpendiculaire a AB
+ //We define the vector v(-b, a) wich is perpendicular to AB
QPointF v(-u.y(), u.x());
- QPointF m = -u + v; // on a le vecteur M = -u + v
- QPointF n = -u - v; // et le vecteur N=-u-v
+ QPointF m = -u + v; // we have vector M = -u + v
+ QPointF n = -u - v; // and vector N=-u-v
QPointF h = a + m; // H = A + M
QPointF k = a + n; // K = A + N
QPointF i = b - n; // I = B - N
@@ -369,14 +256,14 @@
}
/**
- @return le rectangle encadrant l'integralite de la premiere extremite
-*/
-QRectF PartLine::firstEndCircleRect() const {
- QList<QPointF> interesting_points = fourEndPoints(
- line().p1(),
- line().p2(),
- first_length
- );
+ * @brief PartLine::firstEndCircleRect
+ * @return the rectangle bordering the entirety of the first extremity
+ */
+QRectF PartLine::firstEndCircleRect() const
+{
+ QList<QPointF> interesting_points = fourEndPoints(m_line.p1(),
+ m_line.p2(),
+ first_length);
QRectF end_rect(
interesting_points[0] - QPointF(first_length, first_length),
@@ -387,14 +274,13 @@
}
/**
- @return le rectangle encadrant l'integralite de la seconde extremite
-*/
+ * @brief PartLine::secondEndCircleRect
+ * @return the rectangle bordering the entirety of the second extremity
+ */
QRectF PartLine::secondEndCircleRect() const {
- QList<QPointF> interesting_points = fourEndPoints(
- line().p2(),
- line().p1(),
- second_length
- );
+ QList<QPointF> interesting_points = fourEndPoints(m_line.p2(),
+ m_line.p1(),
+ second_length);
QRectF end_rect(
interesting_points[0] - QPointF(second_length, second_length),
@@ -405,13 +291,15 @@
}
/**
- Affiche differentes composantes du dessin :
- - le boundingRect
- - les point speciaux a chaque extremite
- - la quadrature du cercle a chaque extremite, meme si celle-ci est d'un
- autre type
-*/
-void PartLine::debugPaint(QPainter *painter) {
+ * @brief PartLine::debugPaint
+ * Display several composante of the drawing
+ * -the bounding rect
+ * -special points at each extremity
+ * -the quadrature of the circle at each extremity, even if itself is an other type
+ * @param painter
+ */
+void PartLine::debugPaint(QPainter *painter)
+{
painter -> save();
painter -> setPen(Qt::gray);
painter -> drawRect(boundingRect());
@@ -421,99 +309,109 @@
painter -> drawRect(secondEndCircleRect());
painter -> setPen(Qt::red);
- foreach(QPointF pointy, fourEndPoints(line().p1(), line().p2(), first_length)) {
+
+ foreach(QPointF pointy, fourEndPoints(p1(), p2(), first_length))
painter -> drawEllipse(pointy, 0.1, 0.1);
- }
- foreach(QPointF pointy, fourEndPoints(line().p2(), line().p1(), second_length)) {
+
+ foreach(QPointF pointy, fourEndPoints(p2(), p1(), second_length))
painter -> drawEllipse(pointy, 0.1, 0.1);
- }
painter -> restore();
}
/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartLine::boundingRect() const {
- QRectF r(QGraphicsLineItem::boundingRect());
-
- // le rectangle ainsi obtenu ne doit pas avoir une dimension nulle
- r.adjust(0.0, 0.0, 0.1, 0.1);
-
- // cas special : les embouts sortent largement du bounding rect originel
- if (first_end != Qet::None) {
- r = r.united(firstEndCircleRect());
- }
-
- if (second_end != Qet::None) {
- r = r.united(secondEndCircleRect());
- }
-
- // la taille du bounding rect est ajustee avec une certaine marge
- qreal adjust = 1.2;
- r.adjust(-adjust, -adjust, adjust, adjust);
- return(r);
+ * @brief PartLine::boundingRect
+ * @return the bounding rect of this part
+ */
+QRectF PartLine::boundingRect() const
+{
+ QRectF bound;
+ if (first_end || second_end)
+ bound = path().boundingRect();
+ else
+ bound = QRectF (m_line.p1(), m_line.p2());
+
+ qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+ //We add 0.5 because CustomElementGraphicPart::drawShadowShape
+ //draw a shape bigger of 0.5 when pen weight is to 0.
+ if (penWeight() == 0) adjust += 0.5;
+
+ bound = bound.normalized();
+ bound.adjust(-adjust, -adjust, adjust, adjust);
+ return bound;
}
/**
- @return true si cette partie n'est pas pertinente et ne merite pas d'etre
- conservee / enregistree.
- Une ligne est pertinente des lors que ses deux points sont differents
-*/
+ * @brief PartLine::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * A line is relevant when is two point is different
+ */
bool PartLine::isUseless() const {
- return(sceneP1() == sceneP2());
+ return(m_line.p1() == m_line.p2());
}
/**
- @return the minimum, margin-less rectangle this part can fit into, in scene
- coordinates. It is different from boundingRect() because it is not supposed
- to imply any margin, and it is different from shape because it is a regular
- rectangle, not a complex shape.
-*/
+ * @brief PartLine::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
QRectF PartLine::sceneGeometricRect() const {
return(QRectF(sceneP1(), sceneP2()));
}
/**
- Start the user-induced transformation, provided this primitive is contained
- within the \a initial_selection_rect bounding rectangle.
-*/
-void PartLine::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartLine::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the \a initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartLine::startUserTransformation(const QRectF &initial_selection_rect)
+{
Q_UNUSED(initial_selection_rect)
saved_points_.clear();
saved_points_ << sceneP1() << sceneP2();
}
/**
- Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartLine::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartLine::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartLine::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
- setLine(QLineF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
+ prepareGeometryChange();
+ m_line = QLineF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1)));
}
/**
- @return Les quatre points interessants a l'extremite d'une droite
- Ces points sont, dans l'ordre :
- * O : point sur la ligne, a une distance length de l'extremite
- * A : point sur la ligne a une distance 2 x length de l'extremite
- * B : point a une distance length de O - O est le projete de B sur la droite
- * C : point a une distance length de O - O est le projete de C sur la droite
- B et C sont situes de part et d'autre de la ligne
- @param end_point Extremite concernee
- @param other_point Autre point permettant de definir une ligne
- @param length Longueur a utiliser entre l'extremite et le point O
-*/
-QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &other_point, const qreal &length) {
- // vecteur et longueur de la ligne
+ * @brief PartLine::fourEndPoints
+ * Return the four interesting point needed to draw the shape
+ * at extremity of line (circle, diamond, arrow, triangle)
+ * This points are in order :
+ * O : point on the line, at a distance 'length' of the extremity
+ * A : point on the line at a 'length' of 2x the extremity length
+ * B : point at a distance of length O - O is the projection of B on the line
+ * C : point at a distance of length O - O is the projection of C on the line
+ * @param end_point : The concerned extremity
+ * @param other_point : other needed point to define the line
+ * @param length : length to use between the extremity and the point O
+ * @return
+ */
+QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &other_point, const qreal &length)
+{
+ //Vector and length of the line
QPointF line_vector = end_point - other_point;
qreal line_length = sqrt(pow(line_vector.x(), 2) + pow(line_vector.y(), 2));
-
- // vecteur unitaire et vecteur perpendiculaire
+
+ //Unitary vector and perpendicular vector
QPointF u(line_vector / line_length * length);
QPointF v(-u.y(), u.x());
- // points O, A, B et C
+ // points O, A, B, C
QPointF o(end_point - u);
QPointF a(o - u);
QPointF b(o + v);
@@ -521,3 +419,119 @@
return(QList<QPointF>() << o << a << b << c);
}
+
+/**
+ * @brief PartLine::path
+ * @return this line has a QPainterPath.
+ * It's notably use when this line have an end type (circle, triangle etc....),
+ * because return a QPainterPath with end already draw.
+ * Else if there isn't an end type get P1 and P2 of line is better (faster).
+ */
+QPainterPath PartLine::path() const
+{
+ QPainterPath path;
+
+ QPointF point1(m_line.p1());
+ QPointF point2(m_line.p2());
+
+ qreal line_length(m_line.length());
+ qreal pen_width = penWeight();
+
+ qreal length1 = first_length;
+ qreal length2 = second_length;
+
+ //debugPaint(painter);
+
+ //Determine if we must to draw extremity
+ qreal reduced_line_length = line_length - (length1 * requiredLengthForEndType(first_end));
+ bool draw_1st_end = first_end && reduced_line_length >= 0;
+
+ if (draw_1st_end)
+ reduced_line_length -= (length2 * requiredLengthForEndType(second_end));
+ else
+ reduced_line_length = line_length - (length2 * requiredLengthForEndType(second_end));
+
+
+ //Draw the first extremity
+ QPointF start_point;
+ if (draw_1st_end)
+ {
+ QList<QPointF> four_points1(fourEndPoints(point1, point2, length1));
+
+ if (first_end == Qet::Circle)
+ {
+ path.addEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
+ start_point = four_points1[1];
+ }
+ else if (first_end == Qet::Diamond)
+ {
+ path.addPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3] << four_points1[1]);
+ start_point = four_points1[1];
+ }
+ else if (first_end == Qet::Simple)
+ {
+ path.addPolygon(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
+ start_point = point1;
+
+ }
+ else if (first_end == Qet::Triangle)
+ {
+ path.addPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3] << four_points1[0]);
+ start_point = four_points1[0];
+ }
+
+ //Adjust the start point according to the pen width
+ if (pen_width && (first_end == Qet::Simple || first_end == Qet::Circle))
+ start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
+ }
+ else
+ {
+ start_point = point1;
+ }
+
+ //Draw the second extremity
+ QPointF stop_point;
+ bool draw_2nd_end = second_end && reduced_line_length >= 0;
+ if (draw_2nd_end)
+ {
+ QList<QPointF> four_points2(fourEndPoints(point2, point1, length2));
+
+ if (second_end == Qet::Circle)
+ {
+ path.addEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
+ stop_point = four_points2[1];
+ }
+ else if (second_end == Qet::Diamond)
+ {
+ path.addPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1] << four_points2[2]);
+ stop_point = four_points2[1];
+ }
+ else if (second_end == Qet::Simple)
+ {
+ path.addPolygon(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
+ stop_point = point2;
+ }
+ else if (second_end == Qet::Triangle)
+ {/**
+ @return true si cette partie n'est pas pertinente et ne merite pas d'etre
+ conservee / enregistree.
+ Une ligne est pertinente des lors que ses deux points sont differents
+*/
+ path.addPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
+ stop_point = four_points2[0];
+ }
+
+ //Adjust the end point accordint to the pen width
+ if (pen_width && (second_end == Qet::Simple || second_end == Qet::Circle))
+ stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
+ }
+ else
+ {
+ stop_point = point2;
+ }
+
+ path.moveTo(start_point);
+ path.lineTo(stop_point);
+
+ return path;
+}
Modified: trunk/sources/editor/graphicspart/partline.h
===================================================================
--- trunk/sources/editor/graphicspart/partline.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partline.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,7 +17,7 @@
*/
#ifndef PART_LINE_H
#define PART_LINE_H
-#include <QtGui>
+
#include "customelementgraphicpart.h"
#include "qet.h"
/**
@@ -29,11 +29,20 @@
drawn if the required length for their drawing is longer than the line itself.
In case there is room for a single end only, the first one get priority.
*/
-class PartLine : public CustomElementGraphicPart, public QGraphicsLineItem {
- Q_OBJECT
+class PartLine : public CustomElementGraphicPart
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPointF p1 READ p1 WRITE setP1)
+ Q_PROPERTY(QPointF p2 READ p2 WRITE setP2)
+ Q_PROPERTY(Qet::EndType end1 READ firstEndType WRITE setFirstEndType)
+ Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType)
+ Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength)
+ Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength)
+
// constructors, destructor
public:
- PartLine(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
+ PartLine(QETElementEditor *, QGraphicsItem * = 0);
virtual ~PartLine();
private:
@@ -41,95 +50,60 @@
// attributes
private:
- Qet::EndType first_end;
- qreal first_length;
- Qet::EndType second_end;
- qreal second_length;
- QList<QPointF> saved_points_;
+
// methods
public:
- enum { Type = UserType + 1104 };
+ enum { Type = UserType + 1104 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartLine.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- virtual QString name() const { return(QObject::tr("ligne", "element part name")); }
- virtual QString xmlName() const { return(QString("line")); }
- virtual const QDomElement toXml(QDomDocument &) const;
- virtual void fromXml(const QDomElement &);
- virtual QPointF sceneP1() const;
- virtual QPointF sceneP2() const;
- virtual QPainterPath shape() const;
- virtual QRectF boundingRect() const;
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
- static uint requiredLengthForEndType(const Qet::EndType &);
- static QList<QPointF> fourEndPoints(const QPointF &, const QPointF &, const qreal &);
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartLine.
+ * @return the QGraphicsItem type
+ */
+ virtual int type() const { return Type; }
+ virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+ virtual QString name() const { return(QObject::tr("ligne", "element part name")); }
+ virtual QString xmlName() const { return(QString("line")); }
+ virtual const QDomElement toXml(QDomDocument &) const;
+ virtual void fromXml(const QDomElement &);
+ virtual QPointF sceneP1() const;
+ virtual QPointF sceneP2() const;
+ virtual QPainterPath shape() const;
+ virtual QRectF boundingRect() const;
+ virtual bool isUseless() const;
+ virtual QRectF sceneGeometricRect() const;
+ virtual void startUserTransformation(const QRectF &);
+ virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ static uint requiredLengthForEndType(const Qet::EndType &);
+ static QList<QPointF> fourEndPoints(const QPointF &, const QPointF &, const qreal &);
- ///PROPERTY
- // X value of the first point
- Q_PROPERTY(qreal x1 READ x1 WRITE setX1)
- qreal x1() const {return sceneP1().x();}
- void setX1(qreal x1);
-
- // Y value of the first point
- Q_PROPERTY(qreal y1 READ y1 WRITE setY1)
- qreal y1() const {return sceneP1().y();}
- void setY1(qreal y1);
-
- //pos of firts point
- Q_PROPERTY(QPointF p1 READ sceneP1 WRITE setP1)
- void setP1 (QPointF p1);
-
- // X value of the second point
- Q_PROPERTY(qreal x2 READ x2 WRITE setX2)
- qreal x2() const {return sceneP2().x();}
- void setX2(qreal x2);
-
- // Y value of the second point
- Q_PROPERTY(qreal y2 READ y2 WRITE setY2)
- qreal y2() const {return sceneP2().y();}
- void setY2(qreal y2);
-
- //pos of second point
- Q_PROPERTY(QPointF p2 READ sceneP2 WRITE setP2)
- void setP2 (QPointF p2);
-
- // End type of the first point
- Q_PROPERTY(Qet::EndType end1 READ firstEndType WRITE setFirstEndType)
+ QPointF p1() const;
+ void setP1 (const QPointF &p1);
+ QPointF p2 () const;
+ void setP2 (const QPointF &p2);
Qet::EndType firstEndType() const {return first_end;}
void setFirstEndType(const Qet::EndType &et) {first_end = et;}
-
- // End type of the second point
- Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType)
Qet::EndType secondEndType() const {return second_end;}
void setSecondEndType(const Qet::EndType &et) {second_end = et;}
-
- // Size of end type of first point
- Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength)
qreal firstEndLength() const {return first_length;}
- void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), line().length());}
-
- // Size of end type of the second point
- Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength)
+ void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), m_line.length());}
qreal secondEndLength() const {return second_length;}
- void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), line().length());}
-
-
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
+ void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), m_line.length());}
private:
- QList<QPointF> fourShapePoints() const;
- QRectF firstEndCircleRect() const;
- QRectF secondEndCircleRect() const;
- void debugPaint(QPainter *);
+ QPainterPath path() const;
+
+ QList<QPointF> fourShapePoints() const;
+ QRectF firstEndCircleRect() const;
+ QRectF secondEndCircleRect() const;
+ void debugPaint(QPainter *);
+
+ Qet::EndType first_end;
+ qreal first_length;
+
+ Qet::EndType second_end;
+ qreal second_length;
+ QList<QPointF> saved_points_;
+ QLineF m_line;
};
#endif
Modified: trunk/sources/editor/graphicspart/partpolygon.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partpolygon.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -16,66 +16,89 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "partpolygon.h"
-#include "qet.h"
/**
- Constructeur
- @param editor L'editeur d'element concerne
- @param parent Le QGraphicsItem parent de ce polygone
- @param scene La scene sur laquelle figure ce polygone
-*/
-PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
- CustomElementGraphicPart(editor),
- QGraphicsPolygonItem(parent, scene),
+ * @brief PartPolygon::PartPolygon
+ * Constructor
+ * @param editor : editor of this item
+ * @param parent : parent item
+ */
+PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) :
+ CustomElementGraphicPart(editor, parent),
m_closed(false)
+{}
+
+/**
+ * @brief PartPolygon::~PartPolygon
+ */
+PartPolygon::~PartPolygon() {}
+
+/**
+ * @brief PartPolygon::paint
+ * Draw this polygon
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
{
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
- setAcceptedMouseButtons(Qt::LeftButton);
-}
+ Q_UNUSED(widget);
-/// Destructeur
-PartPolygon::~PartPolygon() {
+ applyStylesToQPainter(*painter);
+
+ QPen t = painter -> pen();
+ t.setCosmetic(options && options -> levelOfDetail < 1.0);
+ if (isSelected()) t.setColor(Qt::red);
+ painter -> setPen(t);
+
+ m_closed ? painter -> drawPolygon (m_polygon) :
+ painter -> drawPolyline(m_polygon);
+
+ if (m_hovered)
+ drawShadowShape(painter);
}
/**
- Importe les proprietes d'un polygone depuis un element XML
- @param qde Element XML a lire
-*/
-void PartPolygon::fromXml(const QDomElement &qde) {
+ * @brief PartPolygon::fromXml
+ * Import the properties of this polygon from a xml element
+ * @param qde : Xml document to use
+ */
+void PartPolygon::fromXml(const QDomElement &qde)
+{
stylesFromXml(qde);
+
int i = 1;
- while(true) {
- if (
- QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
- QET::attributeIsAReal(qde, QString("y%1").arg(i))
- ) ++ i;
+ while(true)
+ {
+ if (QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
+ QET::attributeIsAReal(qde, QString("y%1").arg(i)))
+ ++ i;
+
else break;
}
QPolygonF temp_polygon;
- for (int j = 1 ; j < i ; ++ j) {
- temp_polygon << QPointF(
- qde.attribute(QString("x%1").arg(j)).toDouble(),
- qde.attribute(QString("y%1").arg(j)).toDouble()
- );
+ for (int j = 1 ; j < i ; ++ j)
+ {
+ temp_polygon << QPointF(qde.attribute(QString("x%1").arg(j)).toDouble(),
+ qde.attribute(QString("y%1").arg(j)).toDouble());
}
- setPolygon(temp_polygon);
+ m_polygon = temp_polygon;
m_closed = qde.attribute("closed") != "false";
}
/**
- Exporte le polygone en XML
- @param xml_document Document XML a utiliser pour creer l'element XML
- @return un element XML decrivant le polygone
-*/
-const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
+ * @brief PartPolygon::toXml
+ * Export this polygin in xml
+ * @param xml_document : Xml document to use for create the xml element
+ * @return an xml element that describe this polygon
+ */
+const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const
+{
QDomElement xml_element = xml_document.createElement("polygon");
int i = 1;
- foreach(QPointF point, polygon()) {
+ foreach(QPointF point, m_polygon) {
point = mapToScene(point);
xml_element.setAttribute(QString("x%1").arg(i), QString("%1").arg(point.x()));
xml_element.setAttribute(QString("y%1").arg(i), QString("%1").arg(point.y()));
@@ -87,101 +110,95 @@
}
/**
- Dessine le polygone
- @param painter QPainter a utiliser pour rendre le dessin
- @param options Options pour affiner le rendu
- @param widget Widget sur lequel le rendu est effectue
-*/
-void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
- Q_UNUSED(widget);
- applyStylesToQPainter(*painter);
- QPen t = painter -> pen();
- t.setCosmetic(options && options -> levelOfDetail < 1.0);
- if (isSelected()) t.setColor(Qt::red);
- painter -> setPen(t);
- if (m_closed) painter -> drawPolygon(polygon());
- else painter -> drawPolyline(polygon());
-}
+ * @brief PartPolygon::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * A polygon is relevant when he have 2 differents points
+ */
+bool PartPolygon::isUseless() const
+{
+ if (m_polygon.count() < 2) return(true);
-/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsPolygonItem::itemChange(change, value));
-}
+ for (int i = 1 ; i < m_polygon.count() ; ++ i)
+ if (m_polygon[i] != m_polygon[i-1]) return(false);
-/**
- @return true si cette partie n'est pas pertinente et ne merite pas d'etre
- conservee / enregistree.
- Un polygone est pertinent des lors qu'il possede deux points differents.
-*/
-bool PartPolygon::isUseless() const {
- QPolygonF poly(polygon());
-
- if (polygon().count() < 2) return(true);
-
- QPointF previous_point;
- for (int i = 1 ; i < poly.count() ; ++ i) {
- if (poly[i] != poly[i-1]) return(false);
- }
-
return(true);
}
/**
- @return the minimum, margin-less rectangle this part can fit into, in scene
- coordinates. It is different from boundingRect() because it is not supposed
- to imply any margin, and it is different from shape because it is a regular
- rectangle, not a complex shape.
-*/
+ * @brief PartPolygon::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
QRectF PartPolygon::sceneGeometricRect() const {
- return(mapToScene(polygon().boundingRect()).boundingRect());
+ return(mapToScene(m_polygon.boundingRect()).boundingRect());
}
/**
- Start the user-induced transformation, provided this primitive is contained
- within the \a initial_selection_rect bounding rectangle.
-*/
-void PartPolygon::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartPolygon::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartPolygon::startUserTransformation(const QRectF &initial_selection_rect)
+{
Q_UNUSED(initial_selection_rect)
- saved_points_ = mapToScene(polygon()).toList();
+ saved_points_ = mapToScene(m_polygon).toList();
}
/**
- Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartPolygon::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartPolygon::handleUserTransformation
+ * Handle the user-induced transformation from initial_selection_rect to new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartPolygon::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
- setPolygon(mapFromScene(QPolygonF(mapped_points.toVector())));
+ m_polygon = (mapFromScene(QPolygonF(mapped_points.toVector())));
}
/**
- @reimp CustomElementPart::preferredScalingMethod
- This method is called by the decorator when it needs to determine the best
- way to interactively scale a primitive. It is typically called when only a
- single primitive is being scaled.
- This reimplementation systematically returns QET::RoundScaleRatios.
-*/
+ * @brief PartPolygon::preferredScalingMethod
+ * This method is called by the decorator when it needs to determine the best
+ * way to interactively scale a primitive. It is typically called when only a
+ * single primitive is being scaled.
+ * @return : This reimplementation systematically returns QET::RoundScaleRatios.
+ */
QET::ScalingMethod PartPolygon::preferredScalingMethod() const {
return(QET::RoundScaleRatios);
}
/**
+ * @brief PartPolygon::polygon
+ * @return the item's polygon, or an empty polygon if no polygon has been set.
+ */
+QPolygonF PartPolygon::polygon() const {
+ return m_polygon;
+}
+
+/**
+ * @brief PartPolygon::setPolygon
+ * Sets the item's polygon to be the given polygon.
+ * @param polygon
+ */
+void PartPolygon::setPolygon(const QPolygonF &polygon)
+{
+ if (m_polygon == polygon) return;
+ prepareGeometryChange();
+ m_polygon = polygon;
+}
+
+/**
* @brief PartPolygon::addPoint
* Add new point to polygon
* @param point
*/
-void PartPolygon::addPoint(const QPointF &point) {
- QPolygonF poly = polygon();
- poly << point;
- setPolygon(poly);
+void PartPolygon::addPoint(const QPointF &point)
+{
+ prepareGeometryChange();
+ m_polygon << point;
}
/**
@@ -189,35 +206,59 @@
* Set the last point of polygon to @point
* @param point
*/
-void PartPolygon::setLastPoint(const QPointF &point) {
- QPolygonF poly = polygon();
+void PartPolygon::setLastPoint(const QPointF &point)
+{
+ if (m_polygon.size())
+ m_polygon.pop_back();
- if (poly.size())
- poly.pop_back();
-
- poly << point;
- setPolygon(poly);
+ prepareGeometryChange();
+ m_polygon << point;
}
/**
* @brief PartPolygon::removeLastPoint
* Remove the last point of polygon
*/
-void PartPolygon::removeLastPoint() {
- QPolygonF poly = polygon();
+void PartPolygon::removeLastPoint()
+{
+ if (m_polygon.size())
+ {
+ prepareGeometryChange();
+ m_polygon.pop_back();
+ }
+}
- if (poly.size())
- poly.pop_back();
+/**
+ * @brief PartPolygon::shape
+ * @return the shape of this item
+ */
+QPainterPath PartPolygon::shape() const
+{
+ QPainterPath shape;
+ shape.addPolygon(m_polygon);
- setPolygon(poly);
+ if (m_closed)
+ shape.lineTo(m_polygon.first());
+
+ QPainterPathStroker pps;
+ pps.setWidth(penWeight());
+
+ return (pps.createStroke(shape));
}
/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartPolygon::boundingRect() const {
- qreal adjust = 1.5;
- QRectF r(QGraphicsPolygonItem::boundingRect());
+ * @brief PartPolygon::boundingRect
+ * @return the bounding rect of this item
+ */
+QRectF PartPolygon::boundingRect() const
+{
+ QRectF r = m_polygon.boundingRect();
+
+ qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+ //We add 0.5 because CustomElementGraphicPart::drawShadowShape
+ //draw a shape bigger of 0.5 when pen weight is to 0.
+ if (penWeight() == 0) adjust += 0.5;
+
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
Modified: trunk/sources/editor/graphicspart/partpolygon.h
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partpolygon.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,63 +17,66 @@
*/
#ifndef PART_POLYGON_H
#define PART_POLYGON_H
-#include <QtGui>
+
+#include <QPolygonF>
#include "customelementgraphicpart.h"
+
/**
- This class represents a polygon primitive which may be used to compose the
- drawing of an electrical element within the element editor.
-*/
-class PartPolygon : public CustomElementGraphicPart, public QGraphicsPolygonItem {
- Q_OBJECT
- // constructors, destructor
+ * @brief The PartPolygon class
+ * This class represents a polygon primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ */
+class PartPolygon : public CustomElementGraphicPart
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool closed READ isClosed WRITE setClosed)
+
+ // constructors, destructor
public:
- PartPolygon(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
- virtual ~PartPolygon();
+ PartPolygon(QETElementEditor *editor, QGraphicsItem *parent = 0);
+ virtual ~PartPolygon();
private:
- PartPolygon(const PartPolygon &);
-
- // attributes
- private:
- bool m_closed;
-
- // methods
+ PartPolygon(const PartPolygon &);
+
+ // methods
public:
- enum { Type = UserType + 1105 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartPolygon.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual QString name() const { return(QObject::tr("polygone", "element part name")); }
- virtual QString xmlName() const { return(QString("polygon")); }
- void fromXml(const QDomElement &);
- const QDomElement toXml(QDomDocument &) const;
- virtual QRectF boundingRect() const;
- void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
- virtual QET::ScalingMethod preferredScalingMethod() const;
+ enum { Type = UserType + 1105 };
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartPolygon.
+ * @return the QGraphicsItem type
+ */
+ virtual int type() const { return Type; }
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+ virtual QString name() const { return(QObject::tr("polygone", "element part name")); }
+ virtual QString xmlName() const { return(QString("polygon")); }
+ void fromXml(const QDomElement &);
+ const QDomElement toXml(QDomDocument &) const;
+
+ virtual QPainterPath shape () const;
+ virtual QRectF boundingRect() const;
+ virtual bool isUseless() const;
+ virtual QRectF sceneGeometricRect() const;
+
+ virtual void startUserTransformation(const QRectF &);
+ virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ virtual QET::ScalingMethod preferredScalingMethod() const;
+
+ QPolygonF polygon () const;
+ void setPolygon (const QPolygonF &polygon);
+
void addPoint (const QPointF &point);
void setLastPoint (const QPointF &point);
- void removeLastPoint ();
+ void removeLastPoint ();
- ///PROPERTY
- // Closed (join the first and last point by a line)
- Q_PROPERTY(bool closed READ isClosed WRITE setClosed)
- bool isClosed() const {return m_closed;}
- void setClosed(bool c) {m_closed = c;}
-
-
+ bool isClosed () const {return m_closed;}
+ void setClosed (bool c) {m_closed = c;}
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
-
private:
- QList<QPointF> saved_points_;
+ bool m_closed;
+ QList<QPointF> saved_points_;
+ QPolygonF m_polygon;
};
#endif
Modified: trunk/sources/editor/graphicspart/partrectangle.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partrectangle.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,201 +18,227 @@
#include "partrectangle.h"
/**
- Constructeur
- @param editor L'editeur d'element concerne
- @param parent Le QGraphicsItem parent de ce rectangle
- @param scene La scene sur laquelle figure ce rectangle
-*/
-PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : CustomElementGraphicPart(editor), QGraphicsRectItem(parent, scene) {
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
- setAcceptedMouseButtons(Qt::LeftButton);
-}
+ * @brief PartRectangle::PartRectangle
+ * Constructor
+ * @param editor the QETElementEditor of this item
+ * @param parent parent item
+ */
+PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
+ CustomElementGraphicPart(editor, parent)
+{}
-/// Destructeur
-PartRectangle::~PartRectangle() {
-}
+/**
+ * @brief PartRectangle::~PartRectangle
+ */
+PartRectangle::~PartRectangle() {}
/**
- Dessine le rectangle
- @param painter QPainter a utiliser pour rendre le dessin
- @param options Options pour affiner le rendu
- @param widget Widget sur lequel le rendu est effectue
-*/
-void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartRectangle::paint
+ * Draw this Rectangle
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
Q_UNUSED(widget);
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
- if (isSelected()) {
+
+ if (isSelected())
t.setColor(Qt::red);
- }
-
- // force le type de jointures pour les rectangles
+
t.setJoinStyle(Qt::MiterJoin);
- // force le dessin avec un trait fin si l'une des dimensions du rectangle est nulle
- if (!rect().width() || !rect().height()) {
+ //Force the pen to width 0 if one of dimension is null
+ if (!rect().width() || !rect().height())
t.setWidth(0);
- }
painter -> setPen(t);
painter -> drawRect(rect());
- if (isSelected()) {
- painter -> setRenderHint(QPainter::Antialiasing, false);
- painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
- QPointF center = rect().center();
- painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
- painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
- }
+
+ if (m_hovered)
+ drawShadowShape(painter);
+
+ if (isSelected())
+ drawCross(m_rect.center(), painter);
}
/**
- Exporte le rectangle en XML
- @param xml_document Document XML a utiliser pour creer l'element XML
- @return un element XML decrivant le rectangle
-*/
-const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const {
+ * @brief PartRectangle::toXml
+ * Export this rectangle in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return an xml element that describe this ellipse
+ */
+const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const
+{
QDomElement xml_element = xml_document.createElement("rect");
QPointF top_left(sceneTopLeft());
xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
- xml_element.setAttribute("width", QString("%1").arg(rect().width()));
- xml_element.setAttribute("height", QString("%1").arg(rect().height()));
+ xml_element.setAttribute("width", QString("%1").arg(m_rect.width()));
+ xml_element.setAttribute("height", QString("%1").arg(m_rect.height()));
stylesToXml(xml_element);
return(xml_element);
}
/**
- Importe les proprietes d'une rectangle depuis un element XML
- @param qde Element XML a lire
-*/
-void PartRectangle::fromXml(const QDomElement &qde) {
+ * @brief PartRectangle::fromXml
+ * Import the properties of this rectangle from a xml element.
+ * @param qde : Xml document to use.
+ */
+void PartRectangle::fromXml(const QDomElement &qde)
+{
stylesFromXml(qde);
- setRect(
- QRectF(
- mapFromScene(
- qde.attribute("x", "0").toDouble(),
- qde.attribute("y", "0").toDouble()
- ),
- QSizeF(
- qde.attribute("width", "0").toDouble(),
- qde.attribute("height", "0").toDouble()
- )
- )
- );
+ setRect(QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+ qde.attribute("y", "0").toDouble()),
+ QSizeF(qde.attribute("width", "0").toDouble(),
+ qde.attribute("height", "0").toDouble())));
}
/**
- * @brief PartRectangle::setX
- * @param x new value
+ * @brief PartRectangle::rect
+ * @return : Returns the item's rectangle.
*/
-void PartRectangle::setX(qreal x) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.topLeft());
- setRect(current_rect.translated(x - current_pos.x(), 0.0));
+QRectF PartRectangle::rect() const {
+ return m_rect;
}
/**
- * @brief PartRectangle::setY
- * @param y new value
+ * @brief PartRectangle::setRect
+ * Sets the item's rectangle to be the given rectangle.
+ * @param rect
*/
-void PartRectangle::setY(qreal y) {
- QRectF current_rect = rect();
- QPointF current_pos = mapToScene(current_rect.topLeft());
- setRect(current_rect.translated(0.0, y - current_pos.y()));
+void PartRectangle::setRect(const QRectF &rect)
+{
+ if (rect == m_rect) return;
+ prepareGeometryChange();
+ m_rect = rect;
}
/**
+ * @brief PartRectangle::rectTopLeft
+ * @return the rectangle top left in item coordinate
+ */
+QPointF PartRectangle::rectTopLeft() const {
+ return m_rect.topLeft();
+}
+
+/**
+ * @brief PartRectangle::setRectTopLeft
+ * @param point, set the rectangle top left in item coordinate.
+ * The rectangle size is unchanged
+ */
+void PartRectangle::setRectTopLeft(const QPointF &point) {
+ m_rect.moveTopLeft(point);
+}
+
+/**
* @brief PartRectangle::setWidth
+ * Sets the width of the rectangle to the given width.
+ * The right edge is changed, but not the left one.
* @param w new value
*/
-void PartRectangle::setWidth(qreal w) {
- qreal new_width = qAbs(w);
- QRectF current_rect = rect();
- current_rect.setWidth(new_width);
- setRect(current_rect);
+void PartRectangle::setWidth(qreal w)
+{
+ prepareGeometryChange();
+ m_rect.setWidth(qAbs(w));
}
/**
* @brief PartRectangle::setHeight
+ * Sets the height of the rectangle to the given height.
+ * The bottom edge is changed, but not the top one.
* @param h new value
*/
-void PartRectangle::setHeight(qreal h) {
- qreal new_height = qAbs(h);
- QRectF current_rect = rect();
- current_rect.setHeight(new_height);
- setRect(current_rect);
+void PartRectangle::setHeight(qreal h)
+{
+ prepareGeometryChange();
+ m_rect.setHeight(qAbs(h));
}
/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartRectangle::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsRectItem::itemChange(change, value));
+ * @brief PartRectangle::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
+QRectF PartRectangle::sceneGeometricRect() const {
+ return(mapToScene(rect()).boundingRect());
}
/**
- @return le coin superieur gauche du rectangle, dans les coordonnees de la
- scene.
-*/
+ * @brief PartRectangle::sceneTopLeft
+ * @return the top left of rectangle, in scene coordinate
+ */
QPointF PartRectangle::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
- @return true si cette partie n'est pas pertinente et ne merite pas d'etre
- conservee / enregistree.
- Un rectangle est pertinent des lors que ses dimensions ne sont pas nulles.
-*/
-bool PartRectangle::isUseless() const {
- return(rect().isNull());
+ * @brief PartRectangle::shape
+ * @return the shape of this item
+ */
+QPainterPath PartRectangle::shape() const
+{
+ QPainterPath shape;
+ shape.addRect(m_rect);
+
+ QPainterPathStroker pps;
+ pps.setWidth(penWeight());
+
+ return (pps.createStroke(shape));
}
/**
- @return the minimum, margin-less rectangle this part can fit into, in scene
- coordinates. It is different from boundingRect() because it is not supposed
- to imply any margin, and it is different from shape because it is a regular
- rectangle, not a complex shape.
-*/
-QRectF PartRectangle::sceneGeometricRect() const {
- return(mapToScene(rect()).boundingRect());
+ * @brief PartRectangle::boundingRect
+ * @return Bounding rectangle this part can fit into
+ */
+QRectF PartRectangle::boundingRect() const
+{
+ qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+ //We add 0.5 because CustomElementGraphicPart::drawShadowShape
+ //draw a shape bigger of 0.5 when pen weight is to 0.
+ if (penWeight() == 0) adjust += 0.5;
+
+ QRectF r = m_rect.normalized();
+ r.adjust(-adjust, -adjust, adjust, adjust);
+ return(r);
}
/**
- Start the user-induced transformation, provided this primitive is contained
- within the \a initial_selection_rect bounding rectangle.
-*/
-void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartRectangle::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * An rectangle is relevant when he's not null.
+ */
+bool PartRectangle::isUseless() const {
+ return(rect().isNull());
+}
+
+/**
+ * @brief PartRectangle::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect)
+{
Q_UNUSED(initial_selection_rect)
- // we keep track of our own rectangle at the moment in scene coordinates too
+ // we keep track of our own rectangle at the moment in scene coordinates too
saved_points_.clear();
saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
}
/**
- Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartRectangle::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
}
-
-/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartRectangle::boundingRect() const {
- qreal adjust = 1.5;
- QRectF r(QGraphicsRectItem::boundingRect().normalized());
- r.adjust(-adjust, -adjust, adjust, adjust);
- return(r);
-}
Modified: trunk/sources/editor/graphicspart/partrectangle.h
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partrectangle.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,65 +17,69 @@
*/
#ifndef PART_RECTANGLE_H
#define PART_RECTANGLE_H
-#include <QtGui>
+
#include "customelementgraphicpart.h"
+
/**
- This class represents a rectangle primitive which may be used to compose the
- drawing of an electrical element within the element editor.
+ * This class represents a rectangle primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ * All coordinates is in item coordinate, except pos()
*/
-class PartRectangle : public CustomElementGraphicPart, public QGraphicsRectItem {
- Q_OBJECT
- // constructors, destructor
+class PartRectangle : public CustomElementGraphicPart
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPointF rectTopLeft READ rectTopLeft WRITE setRectTopLeft)
+ Q_PROPERTY(qreal width READ width WRITE setWidth)
+ Q_PROPERTY(qreal height READ height WRITE setHeight)
+
+ // constructors, destructor
public:
- PartRectangle(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
- virtual ~PartRectangle();
+ PartRectangle(QETElementEditor *, QGraphicsItem *parent = 0);
+ virtual ~PartRectangle();
private:
- PartRectangle(const PartRectangle &);
+ PartRectangle(const PartRectangle &);
- // methods
+ // methods
public:
- enum { Type = UserType + 1109 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartRectangle.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- virtual QString name() const { return(QObject::tr("rectangle", "element part name")); }
- virtual QString xmlName() const { return(QString("rect")); }
- virtual const QDomElement toXml(QDomDocument &) const;
- virtual void fromXml(const QDomElement &);
- virtual QPointF sceneTopLeft() const;
- virtual QRectF boundingRect() const;
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ enum { Type = UserType + 1109 };
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartRectangle.
+ * @return the QGraphicsItem type
+ */
+ virtual int type () const { return Type; }
+ virtual void paint (QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+ virtual QString name () const { return(QObject::tr("rectangle", "element part name")); }
- ///PROPERTY
- // X value
- Q_PROPERTY(qreal x READ x WRITE setX)
- qreal x() const {return mapToScene(rect().topLeft()).x();}
- void setX(qreal x);
- // Y value
- Q_PROPERTY(qreal y READ y WRITE setY)
- qreal y() const {return mapToScene(rect().topLeft()).y();}
- void setY(qreal y);
- // Width value
- Q_PROPERTY(qreal width READ width WRITE setWidth)
- qreal width() const {return rect().width();}
- void setWidth(qreal w);
- // Height value
- Q_PROPERTY(qreal height READ height WRITE setHeight)
- qreal height() const { return rect().height();}
- void setHeight(qreal h);
+ virtual QString xmlName () const { return(QString("rect")); }
+ virtual const QDomElement toXml (QDomDocument &) const;
+ virtual void fromXml (const QDomElement &);
+
+ QRectF rect() const;
+ void setRect(const QRectF &rect);
+
+ QPointF rectTopLeft () const;
+ void setRectTopLeft (const QPointF &point);
+
+ qreal width () const {return rect().width();}
+ void setWidth (qreal w);
+
+ qreal height () const { return rect().height();}
+ void setHeight (qreal h);
+
+ virtual QRectF sceneGeometricRect() const;
+ virtual QPointF sceneTopLeft() const;
+
+ virtual QPainterPath shape () const;
+ virtual QRectF boundingRect() const;
+ virtual bool isUseless() const;
+
+ virtual void startUserTransformation(const QRectF &);
+ virtual void handleUserTransformation(const QRectF &, const QRectF &);
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
-
private:
- QList<QPointF> saved_points_;
+ QRectF m_rect;
+ QList<QPointF> saved_points_;
};
#endif
Modified: trunk/sources/editor/graphicspart/partterminal.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partterminal.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partterminal.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -24,16 +24,11 @@
@param parent Le QGraphicsItem parent de cette borne
@param scene La scene sur laquelle figure cette borne
*/
-PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
- CustomElementGraphicPart(editor),
- QGraphicsItem(parent, scene),
+PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent) :
+ CustomElementGraphicPart(editor, parent),
m_orientation(Qet::North)
{
updateSecondPoint();
- setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
setZValue(100000);
}
@@ -107,23 +102,37 @@
p -> setBrush(Terminal::neutralColor);
p -> drawPoint(QPointF(0.0, 0.0));
p -> restore();
+
+ if (m_hovered)
+ drawShadowShape(p);
}
/**
- @return le rectangle delimitant cette partie.
-*/
-QRectF PartTerminal::boundingRect() const {
- QPointF p1, p2;
- if (second_point.x() <= 0.0 && second_point.y() <= 0.0) {
- p1 = second_point;
- p2 = QPointF(0.0, 0.0);
- } else {
- p1 = QPointF(0.0, 0.0);
- p2 = second_point;
- }
- QRectF br;
- br.setTopLeft (p1 - QPointF(2.0, 2.0));
- br.setBottomRight(p2 + QPointF(2.0, 2.0));
+ * @brief PartTerminal::shape
+ * @return the shape of this item
+ */
+QPainterPath PartTerminal::shape() const
+{
+ QPainterPath shape;
+ shape.lineTo(second_point);
+
+ QPainterPathStroker pps;
+ pps.setWidth(1);
+
+ return (pps.createStroke(shape));
+}
+
+/**
+ * @brief PartTerminal::boundingRect
+ * @return the bounding rect of this item
+ */
+QRectF PartTerminal::boundingRect() const
+{
+ QRectF br(QPointF(0, 0), second_point);
+ br = br.normalized();
+
+ qreal adjust = (SHADOWS_HEIGHT + 1) / 2;
+ br.adjust(-adjust, -adjust, adjust, adjust);
return(br);
}
@@ -138,20 +147,6 @@
}
/**
- Gere les changements intervenant sur cette partie
- @param change Type de changement
- @param value Valeur numerique relative au changement
-*/
-QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (scene()) {
- if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
- updateCurrentPartEditor();
- }
- }
- return(QGraphicsItem::itemChange(change, value));
-}
-
-/**
Met a jour la position du second point en fonction de la position et de
l'orientation de la borne.
*/
Modified: trunk/sources/editor/graphicspart/partterminal.h
===================================================================
--- trunk/sources/editor/graphicspart/partterminal.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partterminal.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,67 +17,59 @@
*/
#ifndef PART_TERMINAL_H
#define PART_TERMINAL_H
+
#include "customelementgraphicpart.h"
-#include "qet.h"
-#include <QtGui>
+
/**
This class represents a terminal which may be used to compose the drawing of
an electrical element within the element editor.
*/
-class PartTerminal : public CustomElementGraphicPart, public QGraphicsItem {
- Q_OBJECT
+class PartTerminal : public CustomElementGraphicPart
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
+
public:
- // constructors, destructor
- PartTerminal(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
- virtual ~PartTerminal();
+ // constructors, destructor
+ PartTerminal(QETElementEditor *editor, QGraphicsItem *parent = 0);
+ virtual ~PartTerminal();
private:
- PartTerminal(const PartTerminal &);
+ PartTerminal(const PartTerminal &);
- // attributes
+ // attributes
private:
- Qet::Orientation m_orientation;
- QPointF second_point;
+ Qet::Orientation m_orientation;
+ QPointF second_point;
- // methods
+ // methods
public:
- enum { Type = UserType + 1106 };
- /**
- Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
- PartTerminal.
- @return the QGraphicsItem type
- */
- virtual int type() const { return Type; }
- virtual QString name() const { return(QObject::tr("borne", "element part name")); }
- virtual QString xmlName() const { return(QString("terminal")); }
- virtual void fromXml(const QDomElement &);
- virtual const QDomElement toXml(QDomDocument &) const;
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
- virtual QRectF boundingRect() const;
-
- /*virtual void setProperty(const QString &, const QVariant &);
- virtual QVariant property(const QString &);*/
- virtual bool isUseless() const;
- virtual QRectF sceneGeometricRect() const;
- virtual void startUserTransformation(const QRectF &);
- virtual void handleUserTransformation(const QRectF &, const QRectF &);
+ enum { Type = UserType + 1106 };
+ /**
+ * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartTerminal.
+ * @return the QGraphicsItem type
+ */
+ virtual int type() const { return Type; }
+ virtual QString name() const { return(QObject::tr("borne", "element part name")); }
+ virtual QString xmlName() const { return(QString("terminal")); }
+ virtual void fromXml(const QDomElement &);
+ virtual const QDomElement toXml(QDomDocument &) const;
+ virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
- ///PROPERTY
- // X value
- Q_PROPERTY(qreal x READ x WRITE setX)
- // Y value
- Q_PROPERTY(qreal y READ y WRITE setY)
- // Horientation value
- Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
+ virtual QPainterPath shape() const;
+ virtual QRectF boundingRect() const;
+ virtual bool isUseless() const;
+ virtual QRectF sceneGeometricRect() const;
+ virtual void startUserTransformation(const QRectF &);
+ virtual void handleUserTransformation(const QRectF &, const QRectF &);
+
Qet::Orientation orientation() const {return m_orientation;}
void setOrientation(Qet::Orientation ori);
- protected:
- QVariant itemChange(GraphicsItemChange, const QVariant &);
-
private:
- void updateSecondPoint();
+ void updateSecondPoint();
private:
- QPointF saved_position_;
+ QPointF saved_position_;
};
#endif
Modified: trunk/sources/editor/lineeditor.cpp
===================================================================
--- trunk/sources/editor/lineeditor.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/lineeditor.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -120,6 +120,22 @@
}
/**
+ * @brief LineEditor::editedP1
+ * @return The edited P1 in item coordinate
+ */
+QPointF LineEditor::editedP1() const {
+ return part -> mapFromScene(x1->value(), y1->value());
+}
+
+/**
+ * @brief LineEditor::editedP2
+ * @return The edited P2 in item coordinate
+ */
+QPointF LineEditor::editedP2() const {
+ return part -> mapFromScene(x2->value(), y2->value());
+}
+
+/**
Met a jour la ligne a partir des donnees du formulaire
*/
void LineEditor::updateLine() {
@@ -128,28 +144,18 @@
part -> setProperty("length1", end1_length -> value());
part -> setProperty("end2", end2_type -> itemData(end2_type->currentIndex()));
part -> setProperty("length2", end2_length -> value());
- part -> setLine(
- QLineF(
- part -> mapFromScene(
- x1 -> value(),
- y1 -> value()
- ),
- part -> mapFromScene(
- x2 -> value(),
- y2 -> value()
- )
- )
- );
+ part -> setProperty("p1", editedP1());
+ part -> setProperty("p2", editedP2());
}
/// Met a jour l'abscisse du premier point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"), part, "x1", x1 -> value()); }
+void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"), part, "p1", editedP1()); }
/// Met a jour l'ordonnee du premier point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1"), part, "y1", y1 -> value()); }
+void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1"), part, "p1", editedP1()); }
/// Met a jour l'abscisse du second point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"), part, "x2", x2 -> value()); }
+void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"), part, "p2", editedP2()); }
/// Met a jour l'ordonnee du second point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonn\351e point 2"), part, "y2", y2 -> value()); }
+void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonn\351e point 2"), part, "p2", editedP2()); }
/// Met a jour le type de la premiere extremite
void LineEditor::updateLineEndType1() { addChangePartCommand(tr("type fin 1"), part, "end1", end1_type -> itemData(end1_type->currentIndex())); }
/// Met a jour la longueur de la premiere extremite
Modified: trunk/sources/editor/lineeditor.h
===================================================================
--- trunk/sources/editor/lineeditor.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/lineeditor.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -24,41 +24,44 @@
/**
This class provides a widget to edit lines within the element editor.
*/
-class LineEditor : public ElementItemEditor {
+class LineEditor : public ElementItemEditor
+{
Q_OBJECT
// constructors, destructor
public:
- LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0);
- virtual ~LineEditor();
+ LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0);
+ virtual ~LineEditor();
private:
- LineEditor(const LineEditor &);
+ LineEditor(const LineEditor &);
// attributes
private:
- PartLine *part;
- StyleEditor *style_;
- QDoubleSpinBox *x1, *y1, *x2, *y2;
- QComboBox *end1_type, *end2_type;
- QDoubleSpinBox*end1_length, *end2_length;
+ PartLine *part;
+ StyleEditor *style_;
+ QDoubleSpinBox *x1, *y1, *x2, *y2;
+ QComboBox *end1_type, *end2_type;
+ QDoubleSpinBox*end1_length, *end2_length;
// methods
public:
- virtual bool setPart(CustomElementPart *);
- virtual CustomElementPart *currentPart() const;
+ virtual bool setPart(CustomElementPart *);
+ virtual CustomElementPart *currentPart() const;
+ QPointF editedP1() const;
+ QPointF editedP2() const;
public slots:
- void updateLine();
- void updateLineX1();
- void updateLineY1();
- void updateLineX2();
- void updateLineY2();
- void updateLineEndType1();
- void updateLineEndLength1();
- void updateLineEndType2();
- void updateLineEndLength2();
- void updateForm();
+ void updateLine();
+ void updateLineX1();
+ void updateLineY1();
+ void updateLineX2();
+ void updateLineY2();
+ void updateLineEndType1();
+ void updateLineEndLength1();
+ void updateLineEndType2();
+ void updateLineEndLength2();
+ void updateForm();
private:
- void activeConnections(bool);
+ void activeConnections(bool);
};
#endif
Modified: trunk/sources/editor/rectangleeditor.cpp
===================================================================
--- trunk/sources/editor/rectangleeditor.cpp 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/rectangleeditor.cpp 2015-02-09 08:57:40 UTC (rev 3694)
@@ -98,24 +98,31 @@
}
/**
+ * @brief RectangleEditor::topLeft
+ * @return The edited topLeft already mapped to part coordinate
+ */
+QPointF RectangleEditor::editedTopLeft() const {
+ return part -> mapFromScene(x->value(), y->value());
+}
+
+/**
Met a jour le rectangle a partir des donnees du formulaire
*/
void RectangleEditor::updateRectangle() {
if (!part) return;
- part -> setProperty("x", x -> value());
- part -> setProperty("y", y -> value());
+ part -> setProperty("rectTopLeft", editedTopLeft());
part -> setProperty("width", w -> value());
part -> setProperty("height", h -> value());
}
/// Met a jour l'abscisse du coin superieur gauche du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"), part, "x", x -> value()); }
+void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"), part, "rectTopLeft", editedTopLeft());}
/// Met a jour l'ordonnee du coin superieur gauche du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonn\351e"), part, "y", y -> value()); }
+void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonn\351e"), part, "rectTopLeft", editedTopLeft());}
/// Met a jour la largeur du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"), part, "width", w -> value()); }
+void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"), part, "width", w -> value());}
/// Met a jour la hauteur du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"), part, "height", h -> value()); }
+void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"), part, "height", h -> value());}
/**
Met a jour le formulaire d'edition
@@ -123,8 +130,9 @@
void RectangleEditor::updateForm() {
if (!part) return;
activeConnections(false);
- x->setValue(part->property("x").toReal());
- y->setValue(part->property("y").toReal());
+ QPointF p = part->mapToScene(part->property("rectTopLeft").toPointF());
+ x->setValue(p.x());
+ y->setValue(p.y());
w->setValue(part->property("width").toReal());
h->setValue(part->property("height").toReal());
activeConnections(true);
Modified: trunk/sources/editor/rectangleeditor.h
===================================================================
--- trunk/sources/editor/rectangleeditor.h 2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/rectangleeditor.h 2015-02-09 08:57:40 UTC (rev 3694)
@@ -43,6 +43,7 @@
public:
virtual bool setPart(CustomElementPart *);
virtual CustomElementPart *currentPart() const;
+ QPointF editedTopLeft () const;
public slots:
void updateRectangle();