mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-20 16:20:52 +01:00
Desactivation temporaire de l'edition des conducteurs par les points de jonction ; Implementation de l'edition des conducteurs par des points de saisie situes en leur milieu
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@54 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
283
conducer.cpp
283
conducer.cpp
@@ -1,5 +1,6 @@
|
|||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include "conducer.h"
|
#include "conducer.h"
|
||||||
|
#include "conducersegment.h"
|
||||||
#include "element.h"
|
#include "element.h"
|
||||||
|
|
||||||
bool Conducer::pen_and_brush_initialized = false;
|
bool Conducer::pen_and_brush_initialized = false;
|
||||||
@@ -36,6 +37,7 @@ Conducer::Conducer(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *
|
|||||||
pen_and_brush_initialized = true;
|
pen_and_brush_initialized = true;
|
||||||
}
|
}
|
||||||
// calcul du rendu du conducteur
|
// calcul du rendu du conducteur
|
||||||
|
segments = NULL;
|
||||||
priv_calculeConducer(terminal1 -> amarrageConducer(), terminal1 -> orientation(), terminal2 -> amarrageConducer(), terminal2 -> orientation());
|
priv_calculeConducer(terminal1 -> amarrageConducer(), terminal1 -> orientation(), terminal2 -> amarrageConducer(), terminal2 -> orientation());
|
||||||
setFlags(QGraphicsItem::ItemIsSelectable);
|
setFlags(QGraphicsItem::ItemIsSelectable);
|
||||||
}
|
}
|
||||||
@@ -47,7 +49,7 @@ Conducer::Conducer(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *
|
|||||||
void Conducer::update(const QRectF &rect) {
|
void Conducer::update(const QRectF &rect) {
|
||||||
// utilise soit la fonction priv_modifieConducteur soit la fonction priv_calculeConducteur
|
// utilise soit la fonction priv_modifieConducteur soit la fonction priv_calculeConducteur
|
||||||
void (Conducer::* fonction_update) (const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void (Conducer::* fonction_update) (const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
||||||
fonction_update = (points.count() && modified_path) ? &Conducer::priv_modifieConducer : &Conducer::priv_calculeConducer;
|
fonction_update = (nbSegments() && modified_path) ? &Conducer::priv_modifieConducer : &Conducer::priv_calculeConducer;
|
||||||
|
|
||||||
// appelle la bonne fonction pour calculer l'aspect du conducteur
|
// appelle la bonne fonction pour calculer l'aspect du conducteur
|
||||||
(this ->* fonction_update)(
|
(this ->* fonction_update)(
|
||||||
@@ -76,7 +78,7 @@ void Conducer::updateWithNewPos(const QRectF &rect, const Terminal *b, const QPo
|
|||||||
p1 = terminal1 -> amarrageConducer();
|
p1 = terminal1 -> amarrageConducer();
|
||||||
p2 = terminal2 -> amarrageConducer();
|
p2 = terminal2 -> amarrageConducer();
|
||||||
}
|
}
|
||||||
if (points.count() && modified_path)
|
if (nbSegments() && modified_path)
|
||||||
priv_modifieConducer(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
|
priv_modifieConducer(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
|
||||||
else
|
else
|
||||||
priv_calculeConducer(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
|
priv_calculeConducer(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
|
||||||
@@ -86,15 +88,27 @@ void Conducer::updateWithNewPos(const QRectF &rect, const Terminal *b, const QPo
|
|||||||
/**
|
/**
|
||||||
Genere le QPainterPath a partir de la liste des points
|
Genere le QPainterPath a partir de la liste des points
|
||||||
*/
|
*/
|
||||||
void Conducer::pointsToPath() {
|
void Conducer::segmentsToPath() {
|
||||||
|
// chemin qui sera dessine
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
bool moveto_done = false;
|
|
||||||
foreach(QPointF point, points) {
|
// s'il n'y a pa des segments, on arrete la
|
||||||
if (!moveto_done) {
|
if (segments == NULL) setPath(path);
|
||||||
path.moveTo(point);
|
|
||||||
moveto_done = true;
|
// demarre le chemin
|
||||||
} else path.lineTo(point);
|
path.moveTo(segments -> firstPoint());
|
||||||
|
|
||||||
|
// parcourt les segments pour dessiner le chemin
|
||||||
|
ConducerSegment *segment = segments;
|
||||||
|
while(segment -> hasNextSegment()) {
|
||||||
|
path.lineTo(segment -> secondPoint());
|
||||||
|
segment = segment -> nextSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// termine le chemin
|
||||||
|
path.lineTo(segment -> secondPoint());
|
||||||
|
|
||||||
|
// affecte le chemin au conducteur
|
||||||
setPath(path);
|
setPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +120,7 @@ void Conducer::pointsToPath() {
|
|||||||
@param o2 Orientation de la borne 2
|
@param o2 Orientation de la borne 2
|
||||||
*/
|
*/
|
||||||
void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, const QPointF &p2, Terminal::Orientation) {
|
void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, const QPointF &p2, Terminal::Orientation) {
|
||||||
Q_ASSERT_X(points.count() > 1, "priv_modifieConducer", "pas de points a modifier");
|
Q_ASSERT_X(nbSegments() > 1, "priv_modifieConducer", "pas de points a modifier");
|
||||||
|
|
||||||
// recupere les dernieres coordonnees connues des bornes
|
// recupere les dernieres coordonnees connues des bornes
|
||||||
QPointF old_p1 = mapFromScene(terminal1 -> amarrageConducer());
|
QPointF old_p1 = mapFromScene(terminal1 -> amarrageConducer());
|
||||||
@@ -130,7 +144,8 @@ void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, co
|
|||||||
// genere les nouveaux points
|
// genere les nouveaux points
|
||||||
int limite = moves_x.size() - 1;
|
int limite = moves_x.size() - 1;
|
||||||
int coeff = type_trajet_x ? 1 : -1;
|
int coeff = type_trajet_x ? 1 : -1;
|
||||||
points.clear();
|
|
||||||
|
QList<QPointF> points;
|
||||||
points << (type_trajet_x ? new_p1 : new_p2);
|
points << (type_trajet_x ? new_p1 : new_p2);
|
||||||
for (int i = 0 ; i < limite ; ++ i) {
|
for (int i = 0 ; i < limite ; ++ i) {
|
||||||
QPointF previous_point = points.last();
|
QPointF previous_point = points.last();
|
||||||
@@ -140,8 +155,8 @@ void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, co
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
points << (type_trajet_x ? new_p2 : new_p1);
|
points << (type_trajet_x ? new_p2 : new_p1);
|
||||||
|
pointsToSegments(points);
|
||||||
pointsToPath();
|
segmentsToPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,7 +169,10 @@ void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, co
|
|||||||
void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1, const QPointF &p2, Terminal::Orientation o2) {
|
void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1, const QPointF &p2, Terminal::Orientation o2) {
|
||||||
QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
|
QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
|
||||||
Terminal::Orientation ori_depart, ori_arrivee;
|
Terminal::Orientation ori_depart, ori_arrivee;
|
||||||
points.clear();
|
|
||||||
|
// s'assure qu'il n'y a ni points
|
||||||
|
QList<QPointF> points;
|
||||||
|
|
||||||
type_trajet_x = p1.x() < p2.x();
|
type_trajet_x = p1.x() < p2.x();
|
||||||
// mappe les points par rapport a la scene
|
// mappe les points par rapport a la scene
|
||||||
sp1 = mapFromScene(p1);
|
sp1 = mapFromScene(p1);
|
||||||
@@ -230,7 +248,8 @@ void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1,
|
|||||||
// prolongement de la borne d'arrivee
|
// prolongement de la borne d'arrivee
|
||||||
points << arrivee0;
|
points << arrivee0;
|
||||||
|
|
||||||
pointsToPath();
|
pointsToSegments(points);
|
||||||
|
segmentsToPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,7 +291,6 @@ void Conducer::paint(QPainter *qp, const QStyleOptionGraphicsItem */*qsogi*/, QW
|
|||||||
|
|
||||||
// affectation du QPen et de la QBrush modifies au QPainter
|
// affectation du QPen et de la QBrush modifies au QPainter
|
||||||
qp -> setBrush(conducer_brush);
|
qp -> setBrush(conducer_brush);
|
||||||
//qp -> setBrush(Qt::green);
|
|
||||||
qp -> setPen(conducer_pen);
|
qp -> setPen(conducer_pen);
|
||||||
if (isSelected()) {
|
if (isSelected()) {
|
||||||
QPen tmp = qp -> pen();
|
QPen tmp = qp -> pen();
|
||||||
@@ -286,9 +304,25 @@ void Conducer::paint(QPainter *qp, const QStyleOptionGraphicsItem */*qsogi*/, QW
|
|||||||
// dessin des points d'accroche du conducteur si celui-ci est selectionne
|
// dessin des points d'accroche du conducteur si celui-ci est selectionne
|
||||||
if (isSelected()) {
|
if (isSelected()) {
|
||||||
qp -> setRenderHint(QPainter::Antialiasing, true);
|
qp -> setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
QList<QPointF> points = segmentsToPoints();
|
||||||
|
QPointF previous_point;
|
||||||
|
QBrush square_brush(Qt::darkGreen);
|
||||||
for (int i = 1 ; i < (points.size() -1) ; ++ i) {
|
for (int i = 1 ; i < (points.size() -1) ; ++ i) {
|
||||||
QPointF point = points.at(i);
|
QPointF point = points.at(i);
|
||||||
|
|
||||||
|
if (i > 1) {
|
||||||
|
qp -> fillRect(
|
||||||
|
QRectF(
|
||||||
|
((previous_point.x() + point.x()) / 2.0 ) - 2.5,
|
||||||
|
((previous_point.y() + point.y()) / 2.0 ) - 2.5,
|
||||||
|
5.0,
|
||||||
|
5.0
|
||||||
|
),
|
||||||
|
square_brush
|
||||||
|
);
|
||||||
|
}
|
||||||
qp -> drawEllipse(QRectF(point.x() - 3.0, point.y() - 3.0, 6.0, 6.0));
|
qp -> drawEllipse(QRectF(point.x() - 3.0, point.y() - 3.0, 6.0, 6.0));
|
||||||
|
previous_point = point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qp -> restore();
|
qp -> restore();
|
||||||
@@ -364,20 +398,29 @@ bool Conducer::valideXml(QDomElement &e){
|
|||||||
void Conducer::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
void Conducer::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
// clic gauche
|
// clic gauche
|
||||||
if (e -> buttons() & Qt::LeftButton) {
|
if (e -> buttons() & Qt::LeftButton) {
|
||||||
|
// recupere les coordonnees du clic
|
||||||
press_point = mapFromScene(e -> pos());
|
press_point = mapFromScene(e -> pos());
|
||||||
moving_point = false;
|
|
||||||
for (int i = 1 ; i < points.count() ; ++ i) {
|
/*
|
||||||
QPointF point = points.at(i);
|
parcourt les segments pour determiner si le clic a eu lieu
|
||||||
if (
|
- sur l'extremite d'un segment
|
||||||
press_point.x() >= point.x() - 5.0 &&\
|
- sur le milieu d'un segment
|
||||||
press_point.x() < point.x() + 5.0 &&\
|
- ailleurs
|
||||||
press_point.y() >= point.y() - 5.0 &&\
|
*/
|
||||||
press_point.y() < point.y() + 5.0
|
ConducerSegment *segment = segments;
|
||||||
) {
|
while (segment -> hasNextSegment()) {
|
||||||
|
if (hasClickedOn(press_point, segment -> secondPoint())) {
|
||||||
moving_point = true;
|
moving_point = true;
|
||||||
moved_point = i;
|
moving_segment = false;
|
||||||
|
moved_segment = segment;
|
||||||
|
break;
|
||||||
|
} else if (hasClickedOn(press_point, segment -> middle())) {
|
||||||
|
moving_point = false;
|
||||||
|
moving_segment = true;
|
||||||
|
moved_segment = segment;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
segment = segment -> nextSegment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QGraphicsPathItem::mousePressEvent(e);
|
QGraphicsPathItem::mousePressEvent(e);
|
||||||
@@ -398,103 +441,39 @@ void Conducer::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
|||||||
void Conducer::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
void Conducer::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
// clic gauche
|
// clic gauche
|
||||||
if (e -> buttons() & Qt::LeftButton) {
|
if (e -> buttons() & Qt::LeftButton) {
|
||||||
if (moving_point) {
|
|
||||||
/* recuperation de quelques joyeusetes tres souvent consultees */
|
|
||||||
// indice du dernier point ( = point non modifiable)
|
|
||||||
int ind_max_point = points.count() - 1;
|
|
||||||
|
|
||||||
// position precedente du point
|
|
||||||
QPointF p = points.at(moved_point);
|
|
||||||
qreal p_x = p.x();
|
|
||||||
qreal p_y = p.y();
|
|
||||||
|
|
||||||
// position pointee par la souris
|
// position pointee par la souris
|
||||||
qreal mouse_x = e -> pos().x();
|
qreal mouse_x = e -> pos().x();
|
||||||
qreal mouse_y = e -> pos().y();
|
qreal mouse_y = e -> pos().y();
|
||||||
|
|
||||||
// position du point apres le deplacement
|
if (moving_point) {
|
||||||
qreal new_pos_x;
|
// la modification par points revient bientot
|
||||||
qreal new_pos_y;
|
/*
|
||||||
|
// position precedente du point
|
||||||
|
QPointF p = moved_segment -> secondPoint();
|
||||||
|
qreal p_x = p.x();
|
||||||
|
qreal p_y = p.y();
|
||||||
|
|
||||||
if (moved_point == 1 || moved_point == ind_max_point - 1) {
|
// calcul du deplacement
|
||||||
/* premier et dernier points modifiables du conducteur */
|
moved_segment -> moveX(mouse_x - p_x());
|
||||||
// repere le point qui va imposer la contrainte de base
|
moved_segment -> moveY(mouse_y - p_y());
|
||||||
int ind_depend = moved_point == 1 ? 0 : ind_max_point;
|
|
||||||
qreal depend_x = points.at(ind_depend).x();
|
|
||||||
qreal depend_y = points.at(ind_depend).y();
|
|
||||||
|
|
||||||
// repere le point voisin suivant
|
|
||||||
int ind_voisin = moved_point == 1 ? 2 : moved_point - 1;
|
|
||||||
qreal voisin_x = points.at(ind_voisin).x();
|
|
||||||
qreal voisin_y = points.at(ind_voisin).y();
|
|
||||||
|
|
||||||
if (p_x == depend_x && p_y != depend_y) {
|
|
||||||
// deplacements limites a l'axe vertical
|
|
||||||
new_pos_x = p_x;
|
|
||||||
// si on peut aller plus loin que le point voisin suivant, on le fait... en deplacant le point voisin
|
|
||||||
if (p_x > voisin_x - 1 && p_x < voisin_x + 1) new_pos_y = conducer_bound(mouse_y, depend_y, voisin_y);
|
|
||||||
else {
|
|
||||||
new_pos_y = conducer_bound(mouse_y, depend_y, depend_y < voisin_y);
|
|
||||||
points.replace(ind_voisin, QPointF(voisin_x, new_pos_y));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// deplacements limites a l'axe horizontal
|
|
||||||
// si on peut aller plus loin que le point voisin suivant, on le fait... en deplacant le point voisin
|
|
||||||
if (p_y > voisin_y - 1 && p_y < voisin_y + 1) new_pos_x = conducer_bound(mouse_x, depend_x, voisin_x);
|
|
||||||
else {
|
|
||||||
new_pos_x = conducer_bound(mouse_x, depend_x, depend_x < voisin_x);
|
|
||||||
points.replace(ind_voisin, QPointF(new_pos_x, voisin_y));
|
|
||||||
}
|
|
||||||
new_pos_y = p_y;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* autres points */
|
|
||||||
new_pos_x = mouse_x;
|
|
||||||
new_pos_y = mouse_y;
|
|
||||||
|
|
||||||
/* deplace les deux points voisins (sans cela, le deplacement du point n'est pas possible) */
|
|
||||||
// point precedent
|
|
||||||
int ind_point_precedent = moved_point - 1;
|
|
||||||
qreal pp_x = points.at(ind_point_precedent).x();
|
|
||||||
qreal pp_y = points.at(ind_point_precedent).y();
|
|
||||||
if (ind_point_precedent != 1) {
|
|
||||||
if (pp_x > p_x - 1 && pp_x < p_x + 1) {
|
|
||||||
points.replace(ind_point_precedent, QPointF(new_pos_x, pp_y));
|
|
||||||
} else {
|
|
||||||
points.replace(ind_point_precedent, QPointF(pp_x, new_pos_y));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (pp_x > p_x - 1 && pp_x < p_x + 1) {
|
|
||||||
new_pos_x = p_x;
|
|
||||||
} else {
|
|
||||||
new_pos_y = p_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// point suivant
|
|
||||||
int ind_point_suivant = moved_point + 1;
|
|
||||||
qreal ps_x = points.at(ind_point_suivant).x();
|
|
||||||
qreal ps_y = points.at(ind_point_suivant).y();
|
|
||||||
if (ind_point_suivant != ind_max_point - 1) {
|
|
||||||
if (ps_x > p_x - 1 && ps_x < p_x + 1) {
|
|
||||||
points.replace(ind_point_suivant, QPointF(new_pos_x, ps_y));
|
|
||||||
} else {
|
|
||||||
points.replace(ind_point_suivant, QPointF(ps_x, new_pos_y));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ps_x > p_x - 1 && ps_x < p_x + 1) {
|
|
||||||
new_pos_x = p_x;
|
|
||||||
} else {
|
|
||||||
new_pos_y = p_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// application du deplacement
|
// application du deplacement
|
||||||
modified_path = true;
|
modified_path = true;
|
||||||
points.replace(moved_point, QPointF(new_pos_x, new_pos_y));
|
|
||||||
updatePoints();
|
updatePoints();
|
||||||
pointsToPath();
|
segmentsToPath();
|
||||||
|
*/
|
||||||
|
} else if (moving_segment) {
|
||||||
|
// position precedente du point
|
||||||
|
QPointF p = moved_segment -> middle();
|
||||||
|
|
||||||
|
// calcul du deplacement
|
||||||
|
moved_segment -> moveX(mouse_x - p.x());
|
||||||
|
moved_segment -> moveY(mouse_y - p.y());
|
||||||
|
|
||||||
|
// application du deplacement
|
||||||
|
modified_path = true;
|
||||||
|
updatePoints();
|
||||||
|
segmentsToPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QGraphicsPathItem::mouseMoveEvent(e);
|
QGraphicsPathItem::mouseMoveEvent(e);
|
||||||
@@ -506,11 +485,10 @@ void Conducer::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
|||||||
*/
|
*/
|
||||||
void Conducer::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
void Conducer::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
// clic gauche
|
// clic gauche
|
||||||
if (e -> buttons() & Qt::LeftButton) {
|
|
||||||
moving_point = false;
|
moving_point = false;
|
||||||
|
moving_segment = false;
|
||||||
QGraphicsPathItem::mouseReleaseEvent(e);
|
QGraphicsPathItem::mouseReleaseEvent(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return Le rectangle delimitant l'espace de dessin du conducteur
|
@return Le rectangle delimitant l'espace de dessin du conducteur
|
||||||
@@ -525,6 +503,7 @@ QRectF Conducer::boundingRect() const {
|
|||||||
@return La forme / zone "cliquable" du conducteur
|
@return La forme / zone "cliquable" du conducteur
|
||||||
*/
|
*/
|
||||||
QPainterPath Conducer::shape() const {
|
QPainterPath Conducer::shape() const {
|
||||||
|
QList<QPointF> points = segmentsToPoints();
|
||||||
QPainterPath area;
|
QPainterPath area;
|
||||||
QPointF previous_point;
|
QPointF previous_point;
|
||||||
QPointF *point1, *point2;
|
QPointF *point1, *point2;
|
||||||
@@ -565,6 +544,7 @@ QPainterPath Conducer::shape() const {
|
|||||||
Met à jour deux listes de reels.
|
Met à jour deux listes de reels.
|
||||||
*/
|
*/
|
||||||
void Conducer::updatePoints() {
|
void Conducer::updatePoints() {
|
||||||
|
QList<QPointF> points = segmentsToPoints();
|
||||||
int s = points.size();
|
int s = points.size();
|
||||||
moves_x.clear();
|
moves_x.clear();
|
||||||
moves_y.clear();
|
moves_y.clear();
|
||||||
@@ -591,3 +571,74 @@ qreal Conducer::conducer_bound(qreal tobound, qreal bound, bool positive) {
|
|||||||
qreal space = 5.0;
|
qreal space = 5.0;
|
||||||
return(positive ? qMax(tobound, bound + space) : qMin(tobound, bound - space));
|
return(positive ? qMax(tobound, bound + space) : qMin(tobound, bound - space));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Conducer::nbSegments() {
|
||||||
|
if (segments == NULL) return(0);
|
||||||
|
int nb_seg = 1;
|
||||||
|
ConducerSegment *segment = segments;
|
||||||
|
while (segment -> hasNextSegment()) {
|
||||||
|
++ nb_seg;
|
||||||
|
segment = segment -> nextSegment();
|
||||||
|
}
|
||||||
|
return(nb_seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Genere une liste de points a partir des segments de ce conducteur
|
||||||
|
@return La liste de points representant ce conducteur
|
||||||
|
*/
|
||||||
|
QList<QPointF> Conducer::segmentsToPoints() const {
|
||||||
|
// liste qui sera retournee
|
||||||
|
QList<QPointF> points_list;
|
||||||
|
|
||||||
|
// on retourne la liste tout de suite s'il n'y a pas de segments
|
||||||
|
if (segments == NULL) return(points_list);
|
||||||
|
|
||||||
|
// recupere le premier point
|
||||||
|
points_list << segments -> firstPoint();
|
||||||
|
|
||||||
|
// parcourt les segments pour recuperer les autres points
|
||||||
|
ConducerSegment *segment = segments;
|
||||||
|
while(segment -> hasNextSegment()) {
|
||||||
|
points_list << segment -> secondPoint();
|
||||||
|
segment = segment -> nextSegment();
|
||||||
|
}
|
||||||
|
|
||||||
|
// recupere le dernier point
|
||||||
|
points_list << segment -> secondPoint();
|
||||||
|
|
||||||
|
//retourne la liste
|
||||||
|
return(points_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Regenere les segments de ce conducteur a partir de la liste de points passee en parametre
|
||||||
|
@param points_list Liste de points a utiliser pour generer les segments
|
||||||
|
*/
|
||||||
|
void Conducer::pointsToSegments(QList<QPointF> points_list) {
|
||||||
|
// supprime les segments actuels
|
||||||
|
if (segments != NULL) {
|
||||||
|
ConducerSegment *segment = segments;
|
||||||
|
while (segment -> hasNextSegment()) {
|
||||||
|
ConducerSegment *nextsegment = segment -> nextSegment();
|
||||||
|
delete segment;
|
||||||
|
segment = nextsegment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cree les segments a partir de la liste de points
|
||||||
|
ConducerSegment *last_segment = NULL;
|
||||||
|
for (int i = 0 ; i < points_list.size() - 1 ; ++ i) {
|
||||||
|
last_segment = new ConducerSegment(points_list.at(i), points_list.at(i + 1), last_segment);
|
||||||
|
if (!i) segments = last_segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Conducer::hasClickedOn(QPointF press_point, QPointF point) {
|
||||||
|
return (
|
||||||
|
press_point.x() >= point.x() - 5.0 &&\
|
||||||
|
press_point.x() < point.x() + 5.0 &&\
|
||||||
|
press_point.y() >= point.y() - 5.0 &&\
|
||||||
|
press_point.y() < point.y() + 5.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
12
conducer.h
12
conducer.h
@@ -2,6 +2,7 @@
|
|||||||
#define CONDUCTEUR_H
|
#define CONDUCTEUR_H
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
class ConducerSegment;
|
||||||
class Element;
|
class Element;
|
||||||
/**
|
/**
|
||||||
Cette classe represente un conducteur. Un conducteur relie deux bornes d'element.
|
Cette classe represente un conducteur. Un conducteur relie deux bornes d'element.
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
private:
|
private:
|
||||||
/// booleen indiquant si le fil est encore valide
|
/// booleen indiquant si le fil est encore valide
|
||||||
bool destroyed;
|
bool destroyed;
|
||||||
QList<QPointF> points;
|
ConducerSegment *segments;
|
||||||
QList<qreal> moves_x;
|
QList<qreal> moves_x;
|
||||||
QList<qreal> moves_y;
|
QList<qreal> moves_y;
|
||||||
qreal orig_dist_2_terms_x;
|
qreal orig_dist_2_terms_x;
|
||||||
@@ -43,16 +44,23 @@
|
|||||||
bool type_trajet_x;
|
bool type_trajet_x;
|
||||||
QPointF press_point;
|
QPointF press_point;
|
||||||
bool moving_point;
|
bool moving_point;
|
||||||
|
bool moving_segment;
|
||||||
int moved_point;
|
int moved_point;
|
||||||
|
ConducerSegment *moved_segment;
|
||||||
bool modified_path;
|
bool modified_path;
|
||||||
static QPen conducer_pen;
|
static QPen conducer_pen;
|
||||||
static QBrush conducer_brush;
|
static QBrush conducer_brush;
|
||||||
static bool pen_and_brush_initialized;
|
static bool pen_and_brush_initialized;
|
||||||
|
|
||||||
void pointsToPath();
|
void segmentsToPath();
|
||||||
void updatePoints();
|
void updatePoints();
|
||||||
void priv_calculeConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void priv_calculeConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
||||||
void priv_modifieConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void priv_modifieConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
||||||
|
int nbSegments();
|
||||||
|
|
||||||
|
QList<QPointF> segmentsToPoints() const;
|
||||||
|
void pointsToSegments(QList<QPointF>);
|
||||||
|
bool hasClickedOn(QPointF, QPointF);
|
||||||
static QPointF extendTerminal(const QPointF &, Terminal::Orientation, qreal = 12.0);
|
static QPointF extendTerminal(const QPointF &, Terminal::Orientation, qreal = 12.0);
|
||||||
static bool surLeMemeAxe(Terminal::Orientation, Terminal::Orientation);
|
static bool surLeMemeAxe(Terminal::Orientation, Terminal::Orientation);
|
||||||
static bool estHorizontale(Terminal::Orientation a);
|
static bool estHorizontale(Terminal::Orientation a);
|
||||||
|
|||||||
478
conducersegment.cpp
Normal file
478
conducersegment.cpp
Normal file
@@ -0,0 +1,478 @@
|
|||||||
|
#include "conducersegment.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
ConducerSegment::ConducerSegment(QPointF p1, QPointF p2, ConducerSegment *cs1, ConducerSegment *cs2) {
|
||||||
|
setFirstPoint(p1);
|
||||||
|
setSecondPoint(p2);
|
||||||
|
setPreviousSegment(cs1);
|
||||||
|
setNextSegment(cs2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConducerSegment::~ConducerSegment() {
|
||||||
|
if (hasPreviousSegment()) previousSegment() -> setNextSegment(nextSegment());
|
||||||
|
if (hasNextSegment()) nextSegment() -> setPreviousSegment(previousSegment());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir s'il est possible de deplacer le premier point du segment
|
||||||
|
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
|
||||||
|
sans incoherence est stockee dans le second parametre.
|
||||||
|
@param asked_dx La valeur du mouvement demande
|
||||||
|
@param possible_dx La valeur du mouvement possible (au maximum)
|
||||||
|
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||||
|
*/
|
||||||
|
bool ConducerSegment::canMove1stPointX(qreal asked_dx, qreal &possible_dx) {
|
||||||
|
|
||||||
|
Q_ASSERT_X(isVertical(), "ConducerSegment::canMove1stPointX", "segment non vertical");
|
||||||
|
|
||||||
|
/// On ne bouge jamais le premier point d'un segment statique.
|
||||||
|
if (!hasPreviousSegment()) {
|
||||||
|
possible_dx = 0.0;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
// a ce stade, on a forcement un segment precedent
|
||||||
|
|
||||||
|
/// Si le segment precedent n'est pas statique, le mouvement est possible.
|
||||||
|
if (previous_segment -> hasPreviousSegment()) {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment precedent est forcement statique
|
||||||
|
|
||||||
|
/// Si le segment precedent est vertical, le mouvement est possible :
|
||||||
|
/// il induira la creation d'un segment horizontal supplementaire.
|
||||||
|
if (previous_segment -> isVertical()) {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment precedent est forcement horizontal
|
||||||
|
|
||||||
|
// recupere quelques donnees
|
||||||
|
qreal prev_segment_first_x = previous_segment -> point1.x();
|
||||||
|
qreal first_x = point1.x();
|
||||||
|
|
||||||
|
/// Il se peut que le mouvement doive etre limite de facon a ce
|
||||||
|
/// que le segment statique conserve une taille minimale.
|
||||||
|
if (previous_segment -> length() > 0.0) {
|
||||||
|
if (first_x + asked_dx < prev_segment_first_x + 12.0) {
|
||||||
|
possible_dx = -(first_x - prev_segment_first_x - 12.0);
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (first_x + asked_dx >= prev_segment_first_x - 12.0) {
|
||||||
|
possible_dx = prev_segment_first_x - 12.0 - first_x;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir s'il est possible de deplacer le second point du segment
|
||||||
|
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
|
||||||
|
sans incoherence est stockee dans le second parametre.
|
||||||
|
@param asked_dx La valeur du mouvement demande
|
||||||
|
@param possible_dx La valeur du mouvement possible (au maximum)
|
||||||
|
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||||
|
*/
|
||||||
|
bool ConducerSegment::canMove2ndPointX(qreal asked_dx, qreal &possible_dx) {
|
||||||
|
|
||||||
|
Q_ASSERT_X(isVertical(), "ConducerSegment::canMove2ndPointX", "segment non vertical");
|
||||||
|
|
||||||
|
/// On ne modifie jamais l'ordonnee du second point d'un segment statique.
|
||||||
|
if (!hasNextSegment()) {
|
||||||
|
possible_dx = 0.0;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
// a ce stade, on a forcement un segment suivant
|
||||||
|
|
||||||
|
/// Si le segment suivant n'est pas statique, le mouvement est possible.
|
||||||
|
if (next_segment -> hasNextSegment()) {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment suivant est forcement statique
|
||||||
|
|
||||||
|
/// Si le segment suivant est vertical, le mouvement est possible :
|
||||||
|
/// il induira la creation d'un segment horizontal supplementaire.
|
||||||
|
if (next_segment -> isVertical()) {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment suivant est forcement horizontal
|
||||||
|
|
||||||
|
// recupere quelques donnees
|
||||||
|
qreal next_segment_second_x = next_segment -> point2.x();
|
||||||
|
qreal second_x = point2.x();
|
||||||
|
|
||||||
|
/// Il se peut que le mouvement doive etre limite de facon a ce
|
||||||
|
/// que le segment statique conserve une taille minimale.
|
||||||
|
if (next_segment -> length() < 0.0) {
|
||||||
|
if (second_x + asked_dx < next_segment_second_x + 12.0) {
|
||||||
|
possible_dx = second_x - next_segment_second_x - 12.0;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (second_x + asked_dx >= next_segment_second_x - 12.0) {
|
||||||
|
possible_dx = next_segment_second_x - 12.0 - second_x;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dx = asked_dx;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir s'il est possible de deplacer le premier point du segment
|
||||||
|
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
|
||||||
|
sans incoherence est stockee dans le second parametre.
|
||||||
|
@param asked_dy La valeur du mouvement demande
|
||||||
|
@param possible_dy La valeur du mouvement possible (au maximum)
|
||||||
|
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||||
|
*/
|
||||||
|
bool ConducerSegment::canMove1stPointY(qreal asked_dy, qreal &possible_dy) {
|
||||||
|
|
||||||
|
Q_ASSERT_X(isHorizontal(), "ConducerSegment::canMove1stPointY", "segment non horizontal");
|
||||||
|
|
||||||
|
/// On ne bouge jamais le premier point d'un segment statique.
|
||||||
|
if (!hasPreviousSegment()) {
|
||||||
|
possible_dy = 0.0;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
// a ce stade, on a forcement un segment precedent
|
||||||
|
|
||||||
|
/// Si le segment precedent n'est pas statique, le mouvement est possible.
|
||||||
|
if (previous_segment -> hasPreviousSegment()) {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment precedent est forcement statique
|
||||||
|
|
||||||
|
/// Si le segment precedent est horizontal, le mouvement est possible :
|
||||||
|
/// il induira la creation d'un segment vertical supplementaire.
|
||||||
|
if (previous_segment -> isHorizontal()) {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment precedent est forcement vertical
|
||||||
|
|
||||||
|
// recupere quelques donnees
|
||||||
|
qreal prev_segment_first_y = previous_segment -> point1.y();
|
||||||
|
qreal first_y = point1.y();
|
||||||
|
|
||||||
|
/// Il se peut que le mouvement doive etre limite de facon a ce
|
||||||
|
/// que le segment statique conserve une taille minimale.
|
||||||
|
if (previous_segment -> length() > 0.0) {
|
||||||
|
if (first_y + asked_dy < prev_segment_first_y + 12.0) {
|
||||||
|
possible_dy = -(first_y - prev_segment_first_y - 12.0);
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (first_y + asked_dy >= prev_segment_first_y - 12.0) {
|
||||||
|
possible_dy = prev_segment_first_y - 12.0 - first_y;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir s'il est possible de deplacer le second point du segment
|
||||||
|
sans creer d'incoherence. La valeur du mouvement maximum qu'il est possible de faire
|
||||||
|
sans incoherence est stockee dans le second parametre.
|
||||||
|
@param asked_dy La valeur du mouvement demande
|
||||||
|
@param possible_dy La valeur du mouvement possible (au maximum)
|
||||||
|
@return true si le mouvement est possible ; false s'il doit etre limite
|
||||||
|
*/
|
||||||
|
bool ConducerSegment::canMove2ndPointY(qreal asked_dy, qreal &possible_dy) {
|
||||||
|
|
||||||
|
Q_ASSERT_X(isHorizontal(), "ConducerSegment::canMove2ndPointY", "segment non horizontal");
|
||||||
|
|
||||||
|
/// On ne modifie jamais l'abscisse du second point d'un segment statique.
|
||||||
|
if (!hasNextSegment()) {
|
||||||
|
possible_dy = 0.0;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
// a ce stade, on a forcement un segment suivant
|
||||||
|
|
||||||
|
/// Si le segment suivant n'est pas statique, le mouvement est possible.
|
||||||
|
if (next_segment -> hasNextSegment()) {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment suivant est forcement statique
|
||||||
|
|
||||||
|
/// Si le segment suivant est horizontal, le mouvement est possible :
|
||||||
|
/// il induira la creation d'un segment vertical supplementaire.
|
||||||
|
if (next_segment -> isHorizontal()) {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// a ce stade, le segment suivant est forcement vertical
|
||||||
|
|
||||||
|
// recupere quelques donnees
|
||||||
|
qreal next_segment_second_y = next_segment -> point2.y();
|
||||||
|
qreal second_y = point2.y();
|
||||||
|
|
||||||
|
/// Il se peut que le mouvement doive etre limite de facon a ce
|
||||||
|
/// que le segment statique conserve une taille minimale.
|
||||||
|
if (next_segment -> length() < 0.0) {
|
||||||
|
if (second_y + asked_dy < next_segment_second_y + 12.0) {
|
||||||
|
possible_dy = second_y - next_segment_second_y - 12.0;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (second_y + asked_dy >= next_segment_second_y - 12.0) {
|
||||||
|
possible_dy = next_segment_second_y - 12.0 - second_y;
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
possible_dy = asked_dy;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConducerSegment::moveX(qreal dx) {
|
||||||
|
if (isHorizontal()) return;
|
||||||
|
Q_ASSERT_X(isVertical(), "ConducerSegment::moveX", "segment non vertical");
|
||||||
|
|
||||||
|
bool has_prev_segment = hasPreviousSegment();
|
||||||
|
bool has_next_segment = hasNextSegment();
|
||||||
|
|
||||||
|
if (!has_prev_segment || !has_next_segment) return;
|
||||||
|
|
||||||
|
// determine si le mouvement demande doit etre limite et, le cas echeant, a quelle valeur il faut le limiter
|
||||||
|
qreal real_dx_for_1st_point = 0.0;
|
||||||
|
qreal real_dx_for_2nd_point = 0.0;
|
||||||
|
canMove1stPointX(dx, real_dx_for_1st_point);
|
||||||
|
canMove2ndPointX(dx, real_dx_for_2nd_point);
|
||||||
|
|
||||||
|
qreal final_movement = (dx <= 0.0) ? qMax(real_dx_for_1st_point, real_dx_for_2nd_point) : qMin(real_dx_for_1st_point, real_dx_for_2nd_point);
|
||||||
|
|
||||||
|
// applique le mouvement au premier point
|
||||||
|
if (has_prev_segment) {
|
||||||
|
point1.rx() += final_movement;
|
||||||
|
if (!previous_segment -> hasPreviousSegment() && previous_segment -> isVertical()) {
|
||||||
|
new ConducerSegment(
|
||||||
|
previous_segment -> point2,
|
||||||
|
point1,
|
||||||
|
previous_segment,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
} else previous_segment -> setSecondPoint(point1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// applique le mouvement au second point
|
||||||
|
if (has_next_segment) {
|
||||||
|
point2.rx() += final_movement;
|
||||||
|
if (!next_segment -> hasNextSegment() && next_segment -> isVertical()) {
|
||||||
|
new ConducerSegment(
|
||||||
|
point2,
|
||||||
|
next_segment -> point1,
|
||||||
|
this,
|
||||||
|
next_segment
|
||||||
|
);
|
||||||
|
} else next_segment -> setFirstPoint(point2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConducerSegment::moveY(qreal dy) {
|
||||||
|
if (isVertical()) return;
|
||||||
|
Q_ASSERT_X(isHorizontal(), "ConducerSegment::moveY", "segment non horizontal");
|
||||||
|
|
||||||
|
bool has_prev_segment = hasPreviousSegment();
|
||||||
|
bool has_next_segment = hasNextSegment();
|
||||||
|
|
||||||
|
if (!has_prev_segment || !has_next_segment) return;
|
||||||
|
|
||||||
|
// determine si le mouvement demande doit etre limite et, le cas echeant, a quelle valeur il faut le limiter
|
||||||
|
qreal real_dy_for_1st_point = 0.0;
|
||||||
|
qreal real_dy_for_2nd_point = 0.0;
|
||||||
|
canMove1stPointY(dy, real_dy_for_1st_point);
|
||||||
|
canMove2ndPointY(dy, real_dy_for_2nd_point);
|
||||||
|
|
||||||
|
qreal final_movement = (dy <= 0.0) ? qMax(real_dy_for_1st_point, real_dy_for_2nd_point) : qMin(real_dy_for_1st_point, real_dy_for_2nd_point);
|
||||||
|
|
||||||
|
// applique le mouvement au premier point
|
||||||
|
if (has_prev_segment) {
|
||||||
|
point1.ry() += final_movement;
|
||||||
|
if (!previous_segment -> hasPreviousSegment() && previous_segment -> isHorizontal()) {
|
||||||
|
new ConducerSegment(
|
||||||
|
previous_segment -> point2,
|
||||||
|
point1,
|
||||||
|
previous_segment,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
} else previous_segment -> setSecondPoint(point1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// applique le mouvement au second point
|
||||||
|
if (has_next_segment) {
|
||||||
|
point2.ry() += final_movement;
|
||||||
|
if (!next_segment -> hasNextSegment() && next_segment -> isHorizontal()) {
|
||||||
|
new ConducerSegment(
|
||||||
|
point2,
|
||||||
|
next_segment -> point1,
|
||||||
|
this,
|
||||||
|
next_segment
|
||||||
|
);
|
||||||
|
} else next_segment -> setFirstPoint(point2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void ConducerSegment::moveY(qreal dy) {
|
||||||
|
if (isVertical()) return;
|
||||||
|
Q_ASSERT_X(isHorizontal(), "ConducerSegment::moveY", "segment non horizontal");
|
||||||
|
|
||||||
|
bool has_prev_segment = hasPreviousSegment();
|
||||||
|
bool has_next_segment = hasNextSegment();
|
||||||
|
|
||||||
|
if (!has_prev_segment || !has_next_segment) return;
|
||||||
|
|
||||||
|
// s'il y a un segment precedent
|
||||||
|
if (has_prev_segment) {
|
||||||
|
// et que celui-ci est statique,
|
||||||
|
if (!previous_segment -> hasPreviousSegment()) {
|
||||||
|
// on agit differemment selon que le segment statique est vertical...
|
||||||
|
if (previous_segment -> isVertical()) {
|
||||||
|
// auquel cas, on limite le deplacement
|
||||||
|
qreal real_dy;
|
||||||
|
/// @todo limiter le deplacement
|
||||||
|
real_dy = 0.0;
|
||||||
|
point1.ry() += real_dy;
|
||||||
|
previous_segment -> setSecondPoint(point1);
|
||||||
|
} else {
|
||||||
|
// ou horizontal : auquel cas, on ajoute un segment vertical
|
||||||
|
point1.ry() += dy;
|
||||||
|
new ConducerSegment(
|
||||||
|
previous_segment -> point2,
|
||||||
|
point1,
|
||||||
|
previous_segment,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// si le segment n'est pas statique, on applique le deplacement
|
||||||
|
point1.ry() += dy;
|
||||||
|
previous_segment -> setSecondPoint(point1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// s'il y a un segment suivant
|
||||||
|
if (has_next_segment) {
|
||||||
|
// et que celui-ci est statique,
|
||||||
|
if (!next_segment -> hasNextSegment()) {
|
||||||
|
// on agit differemment selon que le segment statique est vertical...
|
||||||
|
if (next_segment -> isVertical()) {
|
||||||
|
// auquel cas, on limite le deplacement
|
||||||
|
qreal real_dy;
|
||||||
|
/// @todo limiter le deplacement
|
||||||
|
real_dy = 0.0;
|
||||||
|
point2.ry() += real_dy;
|
||||||
|
next_segment -> setFirstPoint(point2);
|
||||||
|
} else {
|
||||||
|
// ou horizontal : auquel cas, on ajoute un segment horizontal
|
||||||
|
point2.ry() += dy;
|
||||||
|
new ConducerSegment(
|
||||||
|
point2,
|
||||||
|
next_segment -> point1,
|
||||||
|
this,
|
||||||
|
next_segment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// si le segment n'est pas statique, on applique le deplacement
|
||||||
|
point2.ry() += dy;
|
||||||
|
next_segment -> setFirstPoint(point2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void ConducerSegment::setPreviousSegment(ConducerSegment *ps) {
|
||||||
|
previous_segment = ps;
|
||||||
|
if (hasPreviousSegment()) {
|
||||||
|
if (previousSegment() -> nextSegment() != this) previousSegment() -> setNextSegment(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConducerSegment::setNextSegment(ConducerSegment *ns) {
|
||||||
|
next_segment = ns;
|
||||||
|
if (hasNextSegment()) {
|
||||||
|
if (nextSegment() -> previousSegment() != this) nextSegment() -> setPreviousSegment(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConducerSegment *ConducerSegment::previousSegment() {
|
||||||
|
return(previous_segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConducerSegment *ConducerSegment::nextSegment() {
|
||||||
|
return(next_segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConducerSegment::isVertical() {
|
||||||
|
return(point1.x() == point2.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConducerSegment::isHorizontal() {
|
||||||
|
return(point1.y() == point2.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF ConducerSegment::firstPoint() {
|
||||||
|
return(point1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF ConducerSegment::secondPoint() {
|
||||||
|
return(point2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConducerSegment::setFirstPoint(QPointF p) {
|
||||||
|
point1 = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConducerSegment::setSecondPoint(QPointF p) {
|
||||||
|
point2 = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConducerSegment::hasPreviousSegment() {
|
||||||
|
return(previous_segment != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConducerSegment::hasNextSegment() {
|
||||||
|
return(next_segment != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF ConducerSegment::middle() {
|
||||||
|
return(
|
||||||
|
QPointF(
|
||||||
|
(point1.x() + point2.x()) / 2.0,
|
||||||
|
(point1.y() + point2.y()) / 2.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal ConducerSegment::length() {
|
||||||
|
if (isHorizontal()) {
|
||||||
|
return(secondPoint().x() - firstPoint().x());
|
||||||
|
} else {
|
||||||
|
return(secondPoint().y() - firstPoint().y());
|
||||||
|
}
|
||||||
|
}
|
||||||
43
conducersegment.h
Normal file
43
conducersegment.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef CONDUCER_SEGMENT_H
|
||||||
|
#define CONDUCER_SEGMENT_H
|
||||||
|
#include <QPointF>
|
||||||
|
/**
|
||||||
|
Cette classe represente un segment de conducteur.
|
||||||
|
*/
|
||||||
|
class ConducerSegment {
|
||||||
|
// constructeurs et destructeur
|
||||||
|
public:
|
||||||
|
ConducerSegment(QPointF, QPointF, ConducerSegment * = NULL, ConducerSegment * = NULL);
|
||||||
|
~ConducerSegment();
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
ConducerSegment *previous_segment;
|
||||||
|
ConducerSegment *next_segment;
|
||||||
|
QPointF point1;
|
||||||
|
QPointF point2;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
void moveX(qreal);
|
||||||
|
void moveY(qreal);
|
||||||
|
ConducerSegment *previousSegment();
|
||||||
|
ConducerSegment *nextSegment();
|
||||||
|
bool hasPreviousSegment();
|
||||||
|
bool hasNextSegment();
|
||||||
|
void setPreviousSegment(ConducerSegment *);
|
||||||
|
void setNextSegment(ConducerSegment *);
|
||||||
|
QPointF firstPoint();
|
||||||
|
QPointF secondPoint();
|
||||||
|
void setFirstPoint(QPointF);
|
||||||
|
void setSecondPoint(QPointF);
|
||||||
|
QPointF middle();
|
||||||
|
bool isHorizontal();
|
||||||
|
bool isVertical();
|
||||||
|
qreal length();
|
||||||
|
bool canMove1stPointX(qreal, qreal &);
|
||||||
|
bool canMove2ndPointX(qreal, qreal &);
|
||||||
|
bool canMove1stPointY(qreal, qreal &);
|
||||||
|
bool canMove2ndPointY(qreal, qreal &);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -19,7 +19,8 @@ HEADERS += aboutqet.h \
|
|||||||
exportdialog.h \
|
exportdialog.h \
|
||||||
fixedelement.h \
|
fixedelement.h \
|
||||||
qetapp.h \
|
qetapp.h \
|
||||||
terminal.h
|
terminal.h \
|
||||||
|
conducersegment.h
|
||||||
SOURCES += aboutqet.cpp \
|
SOURCES += aboutqet.cpp \
|
||||||
borderinset.cpp \
|
borderinset.cpp \
|
||||||
conducer.cpp \
|
conducer.cpp \
|
||||||
@@ -32,7 +33,8 @@ SOURCES += aboutqet.cpp \
|
|||||||
fixedelement.cpp \
|
fixedelement.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
qetapp.cpp \
|
qetapp.cpp \
|
||||||
terminal.cpp
|
terminal.cpp \
|
||||||
|
conducersegment.cpp
|
||||||
RESOURCES += qelectrotech.qrc
|
RESOURCES += qelectrotech.qrc
|
||||||
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
||||||
QT += xml
|
QT += xml
|
||||||
|
|||||||
@@ -170,8 +170,10 @@ void Terminal::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
|
|||||||
t.setColor(couleur_hovered);
|
t.setColor(couleur_hovered);
|
||||||
p -> setPen(t);
|
p -> setPen(t);
|
||||||
p -> setBrush(couleur_hovered);
|
p -> setBrush(couleur_hovered);
|
||||||
if (hovered) p -> drawEllipse(((int)f.x())-2, ((int)f.y())-2, 5, 5);
|
if (hovered) {
|
||||||
else p -> drawPoint(f);
|
p -> setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
p -> drawEllipse(((int)f.x())-2, ((int)f.y())-2, 5, 5);
|
||||||
|
} else p -> drawPoint(f);
|
||||||
|
|
||||||
p -> restore();
|
p -> restore();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user