mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 12:40:35 +01:00
Element editor : hover a primitve will highlight it with a blue halo
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3694 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -110,26 +110,26 @@ CustomElementPart *ArcEditor::currentPart() const {
|
||||
*/
|
||||
void ArcEditor::updateArc() {
|
||||
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());
|
||||
part -> setProperty("start_angle", -start_angle -> value() + 90);
|
||||
part -> setProperty("angle", -angle -> 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()); }
|
||||
/// 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()); }
|
||||
/// 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 @@ void ArcEditor::updateForm() {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -567,8 +567,7 @@ void ChangeInformationsCommand::redo() {
|
||||
ScalePartsCommand::ScalePartsCommand(ElementScene *scene, QUndoCommand * parent) :
|
||||
ElementEditionCommand(scene, 0, parent),
|
||||
first_redo(true)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
||||
@@ -849,15 +849,15 @@ ElementContent ElementScene::loadContent(const QDomDocument &xml_document, QStri
|
||||
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++);
|
||||
|
||||
@@ -102,16 +102,16 @@ CustomElementPart *EllipseEditor::currentPart() const {
|
||||
*/
|
||||
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::updateEllipseV() { addChangePartCommand(tr("diam\350tre vert
|
||||
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);
|
||||
|
||||
@@ -45,22 +45,27 @@ ESEventAddArc::~ESEventAddArc() {
|
||||
* @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);
|
||||
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));
|
||||
|
||||
@@ -69,6 +74,7 @@ bool ESEventAddArc::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -120,67 +126,78 @@ bool ESEventAddArc::keyPressEvent(QKeyEvent *event) {
|
||||
* @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 {
|
||||
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()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,9 +52,10 @@ bool ESEventAddEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
@@ -79,15 +80,16 @@ bool ESEventAddEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class ESEventAddEllipse : public ESEventInterface
|
||||
|
||||
private:
|
||||
PartEllipse *m_ellipse;
|
||||
QPointF m_origin;
|
||||
QPointF m_origin, m_new_pos;
|
||||
};
|
||||
|
||||
#endif // ESEVENTADDELLIPSE_H
|
||||
|
||||
@@ -57,8 +57,10 @@ bool ESEventAddLine::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ bool ESEventAddPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,14 +44,20 @@ ESEventAddRect::~ESEventAddRect() {
|
||||
* @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;
|
||||
}
|
||||
@@ -77,7 +83,7 @@ bool ESEventAddRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define ESEVENTADDRECT_H
|
||||
|
||||
#include "eseventinterface.h"
|
||||
#include <QPointF>
|
||||
|
||||
class ElementScene;
|
||||
class PartRectangle;
|
||||
|
||||
@@ -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 @@ bool ESEventAddTerminal::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
||||
//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()));
|
||||
|
||||
|
||||
229
sources/editor/graphicspart/abstractpartellipse.cpp
Normal file
229
sources/editor/graphicspart/abstractpartellipse.cpp
Normal file
@@ -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);
|
||||
}
|
||||
92
sources/editor/graphicspart/abstractpartellipse.h
Normal file
92
sources/editor/graphicspart/abstractpartellipse.h
Normal file
@@ -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
|
||||
@@ -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
|
||||
@@ -37,6 +48,36 @@ CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor) :
|
||||
*/
|
||||
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.
|
||||
@@ -206,3 +247,69 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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 @@ class CustomElementGraphicPart : public QObject, public CustomElementPart
|
||||
// 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 @@ class CustomElementGraphicPart : public QObject, public CustomElementPart
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PartArc::~PartArc() {
|
||||
m_start_angle = 0;
|
||||
m_span_angle = -1440;
|
||||
}
|
||||
|
||||
/**
|
||||
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::~PartArc
|
||||
* Destructor
|
||||
*/
|
||||
PartArc::~PartArc() {}
|
||||
|
||||
/**
|
||||
* @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 @@ const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
|
||||
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()) );
|
||||
|
||||
m_start_angle = qde.attribute("start", "0").toInt() * 16;
|
||||
m_span_angle = qde.attribute("angle", "-1440").toInt() * 16;
|
||||
}
|
||||
|
||||
/**
|
||||
@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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
return (pps.createStroke(shape));
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
* @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
|
||||
// constructors, destructor
|
||||
|
||||
public:
|
||||
PartArc(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||
PartArc(QETElementEditor *editor, QGraphicsItem *parent = 0);
|
||||
virtual ~PartArc();
|
||||
|
||||
private:
|
||||
PartArc(const PartArc &);
|
||||
|
||||
// attributes
|
||||
private:
|
||||
int _angle;
|
||||
int start_angle;
|
||||
|
||||
// methods
|
||||
public:
|
||||
enum { Type = UserType + 1101 };
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartArc.
|
||||
@return the QGraphicsItem type
|
||||
* 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);
|
||||
|
||||
//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 &);
|
||||
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 &);
|
||||
virtual const QDomElement toXml (QDomDocument &) const;
|
||||
virtual void fromXml (const QDomElement &);
|
||||
|
||||
///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;}
|
||||
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
|
||||
private:
|
||||
QList<QPointF> saved_points_;
|
||||
virtual QPainterPath shape() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PartEllipse::~PartEllipse() {
|
||||
}
|
||||
* @brief PartEllipse::PartEllipse
|
||||
* Constructor
|
||||
* @param editor : QETElementEditor of this part
|
||||
* @param parent : parent item
|
||||
*/
|
||||
PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
|
||||
AbstractPartEllipse(editor, parent)
|
||||
{}
|
||||
|
||||
/**
|
||||
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::~PartEllipse
|
||||
* Destructor
|
||||
*/
|
||||
PartEllipse::~PartEllipse() {}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
}
|
||||
else
|
||||
width = height = qde.attribute("diameter", "0").toDouble();
|
||||
}
|
||||
setRect(
|
||||
QRectF(
|
||||
mapFromScene(
|
||||
qde.attribute("x", "0").toDouble(),
|
||||
qde.attribute("y", "0").toDouble()
|
||||
),
|
||||
QSizeF(width, height)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
|
||||
qde.attribute("y", "0").toDouble()),
|
||||
QSizeF(width, height));
|
||||
}
|
||||
|
||||
/**
|
||||
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 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);
|
||||
return (pps.createStroke(shape));
|
||||
}
|
||||
|
||||
@@ -17,17 +17,21 @@
|
||||
*/
|
||||
#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 {
|
||||
* @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);
|
||||
PartEllipse(QETElementEditor *editor, QGraphicsItem * parent = 0);
|
||||
virtual ~PartEllipse();
|
||||
|
||||
private:
|
||||
@@ -37,45 +41,18 @@ class PartEllipse : public CustomElementGraphicPart, public QGraphicsEllipseItem
|
||||
public:
|
||||
enum { Type = UserType + 1103 };
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartEllipse.
|
||||
@return the QGraphicsItem type
|
||||
* 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);
|
||||
|
||||
//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 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 &);
|
||||
virtual const QDomElement toXml (QDomDocument &) const;
|
||||
virtual void fromXml (const QDomElement &);
|
||||
|
||||
///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_;
|
||||
virtual QPainterPath shape() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -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());
|
||||
if (first_end || second_end)
|
||||
painter -> drawPath(path());
|
||||
else
|
||||
painter -> drawLine(m_line);
|
||||
|
||||
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 (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,23 +110,17 @@ const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
|
||||
}
|
||||
|
||||
/**
|
||||
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()
|
||||
)
|
||||
)
|
||||
);
|
||||
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"));
|
||||
@@ -202,25 +128,11 @@ void PartLine::fromXml(const QDomElement &qde) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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()));
|
||||
QPointF PartLine::p1() const {
|
||||
return m_line.p1();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,30 +140,19 @@ void PartLine::setY1(qreal y1) {
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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));
|
||||
QPointF PartLine::p2() const {
|
||||
return m_line.p2();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,105 +160,91 @@ void PartLine::setY2(qreal y2) {
|
||||
* 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));
|
||||
* @brief PartLine::shape
|
||||
* @return the shape of this item
|
||||
*/
|
||||
QPainterPath PartLine::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
|
||||
// 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));
|
||||
//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));
|
||||
}
|
||||
QPainterPathStroker pps;
|
||||
pps.setWidth(penWeight());
|
||||
|
||||
return(t);
|
||||
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 @@ QList<QPointF> PartLine::fourShapePoints() const {
|
||||
}
|
||||
|
||||
/**
|
||||
@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 @@ QRectF PartLine::firstEndCircleRect() const {
|
||||
}
|
||||
|
||||
/**
|
||||
@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 @@ QRectF PartLine::secondEndCircleRect() const {
|
||||
}
|
||||
|
||||
/**
|
||||
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 @@ void PartLine::debugPaint(QPainter *painter) {
|
||||
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());
|
||||
* @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());
|
||||
|
||||
// le rectangle ainsi obtenu ne doit pas avoir une dimension nulle
|
||||
r.adjust(0.0, 0.0, 0.1, 0.1);
|
||||
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;
|
||||
|
||||
// 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);
|
||||
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 @@ QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
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,20 +50,15 @@ class PartLine : public CustomElementGraphicPart, public QGraphicsLineItem {
|
||||
|
||||
// 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 };
|
||||
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartLine.
|
||||
@return the QGraphicsItem type
|
||||
* 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);
|
||||
@@ -73,63 +77,33 @@ class PartLine : public CustomElementGraphicPart, public QGraphicsLineItem {
|
||||
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:
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
setFlags(QGraphicsItem::ItemIsSelectable);
|
||||
#if QT_VERSION >= 0x040600
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||
#endif
|
||||
setAcceptedMouseButtons(Qt::LeftButton);
|
||||
}
|
||||
{}
|
||||
|
||||
/// Destructeur
|
||||
PartPolygon::~PartPolygon() {
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
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);
|
||||
|
||||
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 @@ const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
|
||||
}
|
||||
|
||||
/**
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
@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);
|
||||
}
|
||||
for (int i = 1 ; i < m_polygon.count() ; ++ i)
|
||||
if (m_polygon[i] != m_polygon[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 @@ void PartPolygon::addPoint(const QPointF &point) {
|
||||
* 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();
|
||||
|
||||
if (poly.size())
|
||||
poly.pop_back();
|
||||
|
||||
setPolygon(poly);
|
||||
void PartPolygon::removeLastPoint()
|
||||
{
|
||||
if (m_polygon.size())
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_polygon.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return le rectangle delimitant cette partie.
|
||||
*/
|
||||
QRectF PartPolygon::boundingRect() const {
|
||||
qreal adjust = 1.5;
|
||||
QRectF r(QGraphicsPolygonItem::boundingRect());
|
||||
* @brief PartPolygon::shape
|
||||
* @return the shape of this item
|
||||
*/
|
||||
QPainterPath PartPolygon::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.addPolygon(m_polygon);
|
||||
|
||||
if (m_closed)
|
||||
shape.lineTo(m_polygon.first());
|
||||
|
||||
QPainterPathStroker pps;
|
||||
pps.setWidth(penWeight());
|
||||
|
||||
return (pps.createStroke(shape));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
* @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);
|
||||
PartPolygon(QETElementEditor *editor, QGraphicsItem *parent = 0);
|
||||
virtual ~PartPolygon();
|
||||
|
||||
private:
|
||||
PartPolygon(const PartPolygon &);
|
||||
|
||||
// attributes
|
||||
private:
|
||||
bool m_closed;
|
||||
|
||||
// methods
|
||||
public:
|
||||
enum { Type = UserType + 1105 };
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartPolygon.
|
||||
@return the QGraphicsItem type
|
||||
* 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;
|
||||
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;
|
||||
|
||||
QPolygonF polygon () const;
|
||||
void setPolygon (const QPolygonF &polygon);
|
||||
|
||||
void addPoint (const QPointF &point);
|
||||
void setLastPoint (const QPointF &point);
|
||||
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;}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
bool isClosed () const {return m_closed;}
|
||||
void setClosed (bool c) {m_closed = c;}
|
||||
|
||||
private:
|
||||
bool m_closed;
|
||||
QList<QPointF> saved_points_;
|
||||
QPolygonF m_polygon;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -18,181 +18,213 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
PartRectangle::~PartRectangle() {
|
||||
}
|
||||
* @brief PartRectangle::PartRectangle
|
||||
* Constructor
|
||||
* @param editor the QETElementEditor of this item
|
||||
* @param parent parent item
|
||||
*/
|
||||
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
|
||||
CustomElementGraphicPart(editor, parent)
|
||||
{}
|
||||
|
||||
/**
|
||||
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::~PartRectangle
|
||||
*/
|
||||
PartRectangle::~PartRectangle() {}
|
||||
|
||||
/**
|
||||
* @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()) {
|
||||
t.setColor(Qt::red);
|
||||
}
|
||||
|
||||
// force le type de jointures pour les rectangles
|
||||
if (isSelected())
|
||||
t.setColor(Qt::red);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
@return le coin superieur gauche du rectangle, dans les coordonnees de la
|
||||
scene.
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
@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 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());
|
||||
}
|
||||
|
||||
/**
|
||||
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::sceneTopLeft
|
||||
* @return the top left of rectangle, in scene coordinate
|
||||
*/
|
||||
QPointF PartRectangle::sceneTopLeft() const {
|
||||
return(mapToScene(rect().topLeft()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
saved_points_.clear();
|
||||
@@ -200,19 +232,13 @@ void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect
|
||||
}
|
||||
|
||||
/**
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -17,17 +17,25 @@
|
||||
*/
|
||||
#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 {
|
||||
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);
|
||||
PartRectangle(QETElementEditor *, QGraphicsItem *parent = 0);
|
||||
virtual ~PartRectangle();
|
||||
|
||||
private:
|
||||
@@ -37,45 +45,41 @@ class PartRectangle : public CustomElementGraphicPart, public QGraphicsRectItem
|
||||
public:
|
||||
enum { Type = UserType + 1109 };
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartRectangle.
|
||||
@return the QGraphicsItem type
|
||||
* 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 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 &);
|
||||
|
||||
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 QRectF sceneGeometricRect() const;
|
||||
|
||||
virtual void startUserTransformation(const QRectF &);
|
||||
virtual void handleUserTransformation(const QRectF &, const QRectF &);
|
||||
|
||||
///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);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
|
||||
private:
|
||||
QRectF m_rect;
|
||||
QList<QPointF> saved_points_;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -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 @@ void PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *options, Q
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -137,20 +146,6 @@ void PartTerminal::setOrientation(Qet::Orientation ori) {
|
||||
updateSecondPoint();
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@@ -17,18 +17,22 @@
|
||||
*/
|
||||
#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 {
|
||||
class PartTerminal : public CustomElementGraphicPart
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
|
||||
|
||||
public:
|
||||
// constructors, destructor
|
||||
PartTerminal(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||
PartTerminal(QETElementEditor *editor, QGraphicsItem *parent = 0);
|
||||
virtual ~PartTerminal();
|
||||
private:
|
||||
PartTerminal(const PartTerminal &);
|
||||
@@ -42,9 +46,8 @@ class PartTerminal : public CustomElementGraphicPart, public QGraphicsItem {
|
||||
public:
|
||||
enum { Type = UserType + 1106 };
|
||||
/**
|
||||
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
|
||||
PartTerminal.
|
||||
@return the QGraphicsItem type
|
||||
* 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")); }
|
||||
@@ -52,28 +55,17 @@ class PartTerminal : public CustomElementGraphicPart, public QGraphicsItem {
|
||||
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 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 &);
|
||||
|
||||
///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)
|
||||
Qet::Orientation orientation() const {return m_orientation;}
|
||||
void setOrientation(Qet::Orientation ori);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
|
||||
private:
|
||||
void updateSecondPoint();
|
||||
|
||||
|
||||
@@ -119,6 +119,22 @@ CustomElementPart *LineEditor::currentPart() const {
|
||||
return(part);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
@@ -128,28 +144,18 @@ void LineEditor::updateLine() {
|
||||
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
|
||||
|
||||
@@ -24,7 +24,8 @@ class StyleEditor;
|
||||
/**
|
||||
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:
|
||||
@@ -45,6 +46,8 @@ class LineEditor : public ElementItemEditor {
|
||||
public:
|
||||
virtual bool setPart(CustomElementPart *);
|
||||
virtual CustomElementPart *currentPart() const;
|
||||
QPointF editedP1() const;
|
||||
QPointF editedP2() const;
|
||||
|
||||
public slots:
|
||||
void updateLine();
|
||||
|
||||
@@ -97,25 +97,32 @@ CustomElementPart *RectangleEditor::currentPart() const {
|
||||
return(part);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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::updateRectangleH() { addChangePartCommand(tr("hauteur"),
|
||||
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);
|
||||
|
||||
@@ -43,6 +43,7 @@ class RectangleEditor : public ElementItemEditor {
|
||||
public:
|
||||
virtual bool setPart(CustomElementPart *);
|
||||
virtual CustomElementPart *currentPart() const;
|
||||
QPointF editedTopLeft () const;
|
||||
|
||||
public slots:
|
||||
void updateRectangle();
|
||||
|
||||
Reference in New Issue
Block a user