mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-19 14:50:53 +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:
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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user