Amelioration du rendu des conducteurs lors du deplacement d'elements

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@37 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet
2006-11-30 18:05:02 +00:00
parent f1bfb71f1e
commit 4cb641fa2b
7 changed files with 124 additions and 19 deletions

View File

@@ -334,10 +334,19 @@ void Borne::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
/** /**
Met a jour l'eventuel conducteur relie a la Borne. Met a jour l'eventuel conducteur relie a la Borne.
@param newpos Position de l'element parent a prendre en compte
*/ */
void Borne::updateConducteur() { void Borne::updateConducteur(QPointF newpos) {
if (scene()) { if (!scene() || !parentItem()) return;
foreach (Conducteur *conducteur, liste_conducteurs) if (!conducteur -> isDestroyed()) conducteur -> update(QRectF()/*scene()->sceneRect()*/); foreach (Conducteur *conducteur, liste_conducteurs) {
if (conducteur -> isDestroyed()) continue;
if (newpos == QPointF()) conducteur -> update(QRectF());
else {
// determine la translation subie par l'element parent
QPointF translation = newpos - parentItem() -> pos();
// rafraichit le conducteur en tenant compte de la translation
conducteur -> updateWithNewPos(QRectF(), this, amarrageConducteur() + translation);
}
} }
} }
@@ -409,3 +418,4 @@ bool Borne::fromXml(QDomElement &borne) {
borne.attribute("orientation").toInt() == sens borne.attribute("orientation").toInt() == sens
); );
} }

View File

@@ -40,7 +40,7 @@
QList<Conducteur *> conducteurs() const; QList<Conducteur *> conducteurs() const;
Borne::Orientation orientation() const; Borne::Orientation orientation() const;
inline QPointF amarrageConducteur() const { return(mapToScene(amarrage_conducteur)); } inline QPointF amarrageConducteur() const { return(mapToScene(amarrage_conducteur)); }
void updateConducteur(); void updateConducteur(QPointF = QPointF());
// methodes relatives a l'import/export au format XML // methodes relatives a l'import/export au format XML
static bool valideXml(QDomElement &); static bool valideXml(QDomElement &);

View File

@@ -37,6 +37,18 @@ void Conducteur::update(const QRectF &rect = QRectF()) {
QGraphicsPathItem::update(rect); QGraphicsPathItem::update(rect);
} }
/**
Met a jour la representation graphique du conducteur en considerant que la borne b
a pour position pos
@param rect Rectangle a mettre a jour
@param b Borne
@param pos position de la borne b
*/
void Conducteur::updateWithNewPos(const QRectF &rect, const Borne *b, const QPointF &newpos) {
calculeConducteurWithNewPos(b, newpos);
QGraphicsPathItem::update(rect);
}
/** /**
Met a jour la representation graphique du conducteur. Met a jour la representation graphique du conducteur.
@param x abscisse du rectangle a mettre a jour @param x abscisse du rectangle a mettre a jour
@@ -54,11 +66,32 @@ void Conducteur::update(qreal x, qreal y, qreal width, qreal height) {
un conducteur uniquement compose de droites reliant les deux bornes. un conducteur uniquement compose de droites reliant les deux bornes.
*/ */
void Conducteur::calculeConducteur() { void Conducteur::calculeConducteur() {
QPainterPath t;
QPointF p1 = borne1 -> amarrageConducteur(); QPointF p1 = borne1 -> amarrageConducteur();
QPointF p2 = borne2 -> amarrageConducteur(); QPointF p2 = borne2 -> amarrageConducteur();
priv_calculeConducteur(p1, p2);
}
/**
Met a jour le QPainterPath constituant le conducteur pour obtenir
un conducteur uniquement compose de droites reliant les deux bornes.
*/
void Conducteur::calculeConducteurWithNewPos(const Borne *b, const QPointF &newpos) {
QPointF p1, p2;
if (b == borne1) {
p1 = newpos;
p2 = borne2 -> amarrageConducteur();
} else if (b == borne2) {
p1 = borne1 -> amarrageConducteur();
p2 = newpos;
} else {
p1 = borne1 -> amarrageConducteur();
p2 = borne2 -> amarrageConducteur();
}
priv_calculeConducteur(p1, p2);
}
void Conducteur::priv_calculeConducteur(const QPointF &p1, const QPointF &p2) {
QPainterPath t;
QPointF depart, arrivee; QPointF depart, arrivee;
Borne::Orientation ori_depart, ori_arrivee; Borne::Orientation ori_depart, ori_arrivee;
// distingue le depart de l'arrivee : le trajet se fait toujours de gauche a droite // distingue le depart de l'arrivee : le trajet se fait toujours de gauche a droite

View File

@@ -15,8 +15,9 @@
void destroy(); void destroy();
bool isDestroyed() const { return(destroyed); } bool isDestroyed() const { return(destroyed); }
void update(const QRectF & rect); void updateWithNewPos(const QRectF &, const Borne *, const QPointF &);
void update(qreal x, qreal y, qreal width, qreal height); void update(const QRectF &);
void update(qreal, qreal, qreal, qreal);
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
static bool valideXml(QDomElement &); static bool valideXml(QDomElement &);
@@ -29,6 +30,8 @@
bool destroyed; bool destroyed;
void calculeConducteur(); void calculeConducteur();
void calculeConducteurWithNewPos(const Borne *, const QPointF &);
void priv_calculeConducteur(const QPointF &, const QPointF &);
bool surLeMemeAxe(Borne::Orientation, Borne::Orientation); bool surLeMemeAxe(Borne::Orientation, Borne::Orientation);
bool estHorizontale(Borne::Orientation a); bool estHorizontale(Borne::Orientation a);
bool estVerticale(Borne::Orientation a); bool estVerticale(Borne::Orientation a);

View File

@@ -98,10 +98,17 @@ QPixmap Element::pixmap() {
} }
/** /**
@todo distinguer les bornes avec un cast dynamique Gere les changements d'etat de l'element
@param change type du changement d'etat
@param value valeur du changement d'etat
@return la valeur du changement d'etat
*/ */
QVariant Element::itemChange(GraphicsItemChange change, const QVariant &value) { QVariant Element::itemChange(GraphicsItemChange change, const QVariant &value) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) { if (change == QGraphicsItem::ItemPositionChange) {
foreach(QGraphicsItem *qgi, children()) {
if (Borne *p = qgraphicsitem_cast<Borne *>(qgi)) p -> updateConducteur(value.toPointF());
}
} else if (change == QGraphicsItem::ItemSelectedChange) {
foreach(QGraphicsItem *qgi, children()) { foreach(QGraphicsItem *qgi, children()) {
if (Borne *p = qgraphicsitem_cast<Borne *>(qgi)) p -> updateConducteur(); if (Borne *p = qgraphicsitem_cast<Borne *>(qgi)) p -> updateConducteur();
} }
@@ -192,10 +199,6 @@ void Element::setPos(const QPointF &p) {
int p_y = qRound(p.y() / 10.0) * 10; int p_y = qRound(p.y() / 10.0) * 10;
QGraphicsItem::setPos(p_x, p_y); QGraphicsItem::setPos(p_x, p_y);
} else QGraphicsItem::setPos(p); } else QGraphicsItem::setPos(p);
// actualise les bornes / conducteurs
foreach(QGraphicsItem *qgi, children()) {
if (Borne *p = qgraphicsitem_cast<Borne *>(qgi)) p -> updateConducteur();
}
} }
/** /**
@@ -215,7 +218,7 @@ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
/*&& (flags() & ItemIsMovable)*/ // on le sait qu'il est movable /*&& (flags() & ItemIsMovable)*/ // on le sait qu'il est movable
if (e -> buttons() & Qt::LeftButton) { if (e -> buttons() & Qt::LeftButton) {
QPointF oldPos = pos(); QPointF oldPos = pos();
setPos(mapToParent(e->pos()) - matrix().map(e->buttonDownPos(Qt::LeftButton))); setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
QPointF diff = pos() - oldPos; QPointF diff = pos() - oldPos;
// Recupere la liste des elements selectionnes // Recupere la liste des elements selectionnes
@@ -223,13 +226,13 @@ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (scene()) { if (scene()) {
selectedItems = scene() -> selectedItems(); selectedItems = scene() -> selectedItems();
} else if (QGraphicsItem *parent = parentItem()) { } else if (QGraphicsItem *parent = parentItem()) {
while (parent && parent->isSelected()) selectedItems << parent; while (parent && parent -> isSelected()) selectedItems << parent;
} }
// Deplace tous les elements selectionnes // Deplace tous les elements selectionnes
foreach (QGraphicsItem *item, selectedItems) { foreach (QGraphicsItem *item, selectedItems) {
if (!item->parentItem() || !item->parentItem()->isSelected()) if (!item -> parentItem() || !item -> parentItem() -> isSelected())
if (item != this) item->setPos(item->pos() + diff); if (item != this) item -> setPos(item -> pos() + diff);
} }
} else e -> ignore(); } else e -> ignore();
} }

View File

@@ -18,6 +18,7 @@ Schema::Schema(QObject *parent) : QGraphicsScene(parent) {
poseur_de_conducteur -> setPen(t); poseur_de_conducteur -> setPen(t);
poseur_de_conducteur -> setLine(QLineF(QPointF(0.0, 0.0), QPointF(0.0, 0.0))); poseur_de_conducteur -> setLine(QLineF(QPointF(0.0, 0.0), QPointF(0.0, 0.0)));
doit_dessiner_grille = true; doit_dessiner_grille = true;
translation = QPoint(0, 0);
connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChange())); connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChange()));
} }
@@ -332,3 +333,54 @@ void Schema::slot_checkSelectionChange() {
if (cache_selecteditems != selecteditems) emit(selectionChanged()); if (cache_selecteditems != selecteditems) emit(selectionChanged());
cache_selecteditems = selecteditems; cache_selecteditems = selecteditems;
} }
/**
Gere les mouvements de souris sur le schema et, ipso facto, les
deplacements d'elements. Cette fonction veille a ne deplacer que les
elements (les conducteurs sont remis a jour par les bornes des elements)
et tient compte de la grille.
@param mouseEvent Un QGraphicsSceneMouseEvent decrivant l'evenement
"mouvement de souris"
*/
void Schema::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {
if (mouseEvent -> buttons() & Qt::LeftButton) {
translation += (mouseEvent -> scenePos() - mouseEvent -> lastScenePos()).toPoint();
bool doit_translater = false;
int coeffx = 0, coeffy = 0;
if (translation.x() >= GRILLE_X) {
doit_translater = true;
coeffx = translation.x() / GRILLE_X;
translation.setX(translation.x() % GRILLE_X);
} else if (translation.x() <= -GRILLE_X) {
doit_translater = true;
coeffx = translation.x() / GRILLE_X;
translation.setX(translation.x() % GRILLE_X);
}
if (translation.y() >= GRILLE_Y) {
doit_translater = true;
coeffy = translation.y() / GRILLE_Y;
translation.setY(translation.y() % GRILLE_Y);
} else if (translation.y() <= -GRILLE_Y) {
doit_translater = true;
coeffy = translation.y() / GRILLE_Y;
translation.setY(translation.y() % GRILLE_Y);
}
if (doit_translater) {
// parcourt la listes des QGraphicsItem
foreach (QGraphicsItem *qgi, selectedItems()) {
// translate uniquement les elements (pas les conducteurs)
if (Element *e = qgraphicsitem_cast<Element *>(qgi))
e -> setPos(e -> pos() + QPointF(GRILLE_X * coeffx, GRILLE_Y * coeffy));
}
}
}
}
void Schema::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) {
translation = QPoint(0, 0);
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}

View File

@@ -33,10 +33,14 @@
QString folio; // vraiment necessaire ce truc ? QString folio; // vraiment necessaire ce truc ?
QString nom_fichier; // meme remarque QString nom_fichier; // meme remarque
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
private: private:
QGraphicsLineItem *poseur_de_conducteur; QGraphicsLineItem *poseur_de_conducteur;
bool doit_dessiner_grille; bool doit_dessiner_grille;
Element *elementFromXml(QDomElement &e, QHash<int, Borne *> &); Element *elementFromXml(QDomElement &e, QHash<int, Borne *> &);
QPoint translation;
private slots: private slots:
void slot_checkSelectionChange(); void slot_checkSelectionChange();