Optimisation du deplacement des elements

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@122 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet
2007-09-15 22:14:23 +00:00
parent 55c79617e1
commit 271775c8a4
5 changed files with 102 additions and 29 deletions

View File

@@ -379,3 +379,42 @@ QRectF Diagram::border() const {
);
}
/// oublie la liste des elements et conducteurs en mouvement
void Diagram::invalidateMovedElements() {
if (!moved_elements_fetched) return;
moved_elements_fetched = false;
elements_to_move.clear();
conducers_to_move.clear();
conducers_to_update.clear();
}
/// reconstruit la liste des elements et conducteurs en mouvement
void Diagram::fetchMovedElements() {
// recupere les elements deplaces
foreach (QGraphicsItem *item, selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
elements_to_move << elmt;
}
}
// pour chaque element deplace, determine les conducteurs qui seront modifies
foreach(Element *elmt, elements_to_move) {
foreach(Terminal *terminal, elmt -> terminals()) {
foreach(Conducer *conducer, terminal -> conducers()) {
Terminal *other_terminal;
if (conducer -> terminal1 == terminal) {
other_terminal = conducer -> terminal2;
} else {
other_terminal = conducer -> terminal1;
}
// si les deux elements du conducteur sont deplaces
if (elements_to_move.contains(static_cast<Element *>(other_terminal -> parentItem()))) {
conducers_to_move << conducer;
} else {
conducers_to_update.insert(conducer, terminal);
}
}
}
}
moved_elements_fetched = true;
}

View File

@@ -9,6 +9,7 @@
#include "borderinset.h"
class Element;
class Terminal;
class Conducer;
class Diagram : public QGraphicsScene {
Q_OBJECT
@@ -29,6 +30,10 @@ class Diagram : public QGraphicsScene {
QGraphicsLineItem *conducer_setter;
bool draw_grid;
bool use_border;
bool moved_elements_fetched;
QSet<Element *> elements_to_move;
QSet<Conducer *> conducers_to_move;
QHash<Conducer *, Terminal *> conducers_to_update;
// methodes
public:
@@ -55,6 +60,12 @@ class Diagram : public QGraphicsScene {
QImage toImage(int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
QSize imageSize() const;
void invalidateMovedElements();
void fetchMovedElements();
const QSet<Element *> &elementsToMove();
const QSet<Conducer *> &conducersToMove();
const QHash<Conducer *, Terminal *> &conducersToUpdate();
private slots:
void slot_checkSelectionEmptinessChange();
@@ -149,4 +160,22 @@ inline Diagram::BorderOptions Diagram::borderOptions() {
return(retour);
}
/// @return la liste des elements a deplacer
inline const QSet<Element *> &Diagram::elementsToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(elements_to_move);
}
/// @return la liste des conducteurs a deplacer
inline const QSet<Conducer *> &Diagram::conducersToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(conducers_to_move);
}
/// @return la liste des conducteurs a modifier (typiquement les conducteurs dont seul un element est deplace)
inline const QHash<Conducer *, Terminal *> &Diagram::conducersToUpdate() {
if (!moved_elements_fetched) fetchMovedElements();
return(conducers_to_update);
}
#endif

View File

@@ -1,5 +1,6 @@
#include "element.h"
#include "diagram.h"
#include "conducer.h"
#include "elementtextitem.h"
#include <QtDebug>
@@ -103,21 +104,6 @@ QPixmap Element::pixmap() {
return(apercu);
}
/**
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) {
if (change == QGraphicsItem::ItemPositionHasChanged) {
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) p -> updateConducer(value.toPointF());
}
}
return(QGraphicsItem::itemChange(change, value));
}
/**
Permet de specifier l'orientation de l'element
@param o la nouvelle orientation de l'objet
@@ -187,7 +173,7 @@ void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *)
t.setStyle(Qt::DashDotLine);
painter -> setPen(t);
// Le dessin se fait a partir du rectangle delimitant
painter -> drawRoundRect(boundingRect(), 10, 10);
painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
painter -> restore();
}
@@ -236,7 +222,7 @@ void Element::setPos(qreal x, qreal y) {
}
/**
Gere les mouvements de souris lies a l'element, notamment
Gere les mouvements de souris lies a l'element
*/
void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (e -> buttons() & Qt::LeftButton) {
@@ -244,22 +230,41 @@ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
QPointF diff = pos() - oldPos;
// Recupere la liste des elements selectionnes
QList<QGraphicsItem *> selectedItems;
if (scene()) {
selectedItems = scene() -> selectedItems();
} else if (QGraphicsItem *parent = parentItem()) {
while (parent && parent -> isSelected()) selectedItems << parent;
// inutile de deplacer les autres elements s'il n'y a pas eu de mouvement concret
if (diff.isNull()) return;
// recupere le schema parent
if (!scene()) return;
Diagram *diagram = qobject_cast<Diagram *>(scene());
if (!diagram) return;
// deplace les elements selectionnes
foreach(Element *element, diagram -> elementsToMove()) {
if (element == this) continue;
element -> setPos(element -> pos() + diff);
};
// deplace certains conducteurs
foreach(Conducer *conducer, diagram -> conducersToMove()) {
conducer -> setPos(conducer -> pos() + diff);
}
// Deplace tous les elements selectionnes
foreach (QGraphicsItem *item, selectedItems) {
if (!item -> parentItem() || !item -> parentItem() -> isSelected())
if (item != this && qgraphicsitem_cast<Element *>(item)) item -> setPos(item -> pos() + diff);
// recalcule les autres conducteurs
const QHash<Conducer *, Terminal *> &conducers_modify = diagram -> conducersToUpdate();
foreach(Conducer *conducer, conducers_modify.keys()) {
conducer -> updateWithNewPos(QRectF(), conducers_modify[conducer], conducers_modify[conducer] -> scenePos());
}
} else e -> ignore();
}
void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
if (scene()) {
Diagram *diagram = qobject_cast<Diagram *>(scene());
if (diagram) diagram -> invalidateMovedElements();
}
QGraphicsItem::mouseReleaseEvent(e);
}
/**
Permet de savoir si un element XML (QDomElement) represente bien un element
@param e Le QDomElement a valide

View File

@@ -45,7 +45,6 @@ class Element : public QGraphicsItem {
virtual QString nom() const = 0;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const;
QSize setSize(int, int);
QPixmap pixmap();
@@ -78,6 +77,7 @@ class Element : public QGraphicsItem {
protected:
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
void mouseMoveEvent(QGraphicsSceneMouseEvent *);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
private:
bool peut_relier_ses_propres_terminals;

View File

@@ -40,7 +40,7 @@ void Terminal::initialise(QPointF pf, QET::Orientation o) {
setAcceptsHoverEvents(true);
setAcceptedMouseButtons(Qt::LeftButton);
hovered = false;
setToolTip("Terminal");
setToolTip(QObject::tr("Borne"));
}
/**