[qet] [3591] Add help line for assist alignement of element

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 3591
Author:   blacksun
Date:     2015-01-07 20:21:17 +0100 (Wed, 07 Jan 2015)
Log Message:
-----------
Add help line for assist alignement of element

Modified Paths:
--------------
    trunk/sources/diagram.cpp
    trunk/sources/diagram.h
    trunk/sources/qet.cpp
    trunk/sources/qet.h
    trunk/sources/qetgraphicsitem/terminal.cpp
    trunk/sources/qetgraphicsitem/terminal.h

Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/diagram.cpp	2015-01-07 19:21:17 UTC (rev 3591)
@@ -930,9 +930,12 @@
 }
 
 /**
-	@return Le rectangle (coordonnees par rapport a la scene) delimitant le bord du schema
-*/
-QRectF Diagram::border() const {
+ * @brief Diagram::border
+ * @return The rectangle (coordinates relative to the scene)
+ * delimiting the edge of the diagram
+ */
+QRectF Diagram::border() const
+{
 	return(
 		QRectF(
 			margin,
@@ -944,6 +947,32 @@
 }
 
 /**
+ * @brief Diagram::drawingRect
+ * @return The rectangle (coordinates relative to the scene)
+ * delimiting the drawing area of the diagram.
+ * It's like border without columns, rows, and titleblock
+ */
+QRectF Diagram::drawingRect() const
+{
+	QPointF topleft(margin, margin);
+	QSizeF size;
+	size.setWidth (border_and_titleblock.columnsTotalWidth());
+	size.setHeight(border_and_titleblock.rowsTotalHeight());
+
+	if (border_and_titleblock.rowsAreDisplayed())
+		topleft.rx() += border_and_titleblock.rowsHeaderWidth();
+	else
+		size.rwidth() += border_and_titleblock.rowsHeaderWidth();
+
+	if (border_and_titleblock.columnsAreDisplayed())
+		topleft.ry() += border_and_titleblock.columnsHeaderHeight();
+	else
+		size.rheight() += border_and_titleblock.columnsHeaderHeight();
+
+	return (QRectF (topleft, size));
+}
+
+/**
 	@return le titre du cartouche
 */
 QString Diagram::title() const {

Modified: trunk/sources/diagram.h
===================================================================
--- trunk/sources/diagram.h	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/diagram.h	2015-01-07 19:21:17 UTC (rev 3591)
@@ -169,7 +169,9 @@
 	bool drawColoredConductors() const;
 	void setDrawColoredConductors(bool);
 	
-	QRectF border() const;
+		QRectF border      () const;
+		QRectF drawingRect () const;
+
 	QString title() const;
 	bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
 	QSize imageSize() const;

Modified: trunk/sources/qet.cpp
===================================================================
--- trunk/sources/qet.cpp	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/qet.cpp	2015-01-07 19:21:17 UTC (rev 3591)
@@ -63,6 +63,37 @@
 }
 
 /**
+ * @brief Qet::isOpposed
+ * @param a
+ * @param b
+ * @return true if a and b is opposed, else false;
+ */
+bool Qet::isOpposed(Qet::Orientation a, Qet::Orientation b)
+{
+	bool result = false;
+
+	switch (a)
+	{
+		case Qet::North:
+			if (b == Qet::South) result = true;
+			break;
+		case Qet::East:
+			if (b == Qet::West) result = true;
+			break;
+		case Qet::South:
+			if (b == Qet::North) result = true;
+			break;
+		case Qet::West:
+			if (b == Qet::East) result = true;
+			break;
+		default:
+			break;
+	}
+
+	return result;
+}
+
+/**
 	Indique si une orientation de borne est horizontale (Est / Ouest).
 	@param a L'orientation de borne
 	@return True si l'orientation de borne est horizontale, false sinon

Modified: trunk/sources/qet.h
===================================================================
--- trunk/sources/qet.h	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/qet.h	2015-01-07 19:21:17 UTC (rev 3591)
@@ -180,11 +180,14 @@
 					  West};
 	static Qet::Orientation nextOrientation(Qet::Orientation);
 	static Qet::Orientation previousOrientation(Qet::Orientation);
-	static Qet::Orientation orientationFromString(const QString &);
-	static QString orientationToString(Qet::Orientation);
-	static bool surLeMemeAxe(Qet::Orientation, Qet::Orientation);
-	static bool estHorizontale(Qet::Orientation);
-	static bool estVerticale(Qet::Orientation);
+
+	static Qet::Orientation orientationFromString (const QString &);
+	static QString          orientationToString   (Qet::Orientation);
+
+	static bool surLeMemeAxe   (Qet::Orientation, Qet::Orientation);
+	static bool isOpposed      (Qet::Orientation a, Qet::Orientation b);
+	static bool estHorizontale (Qet::Orientation);
+	static bool estVerticale   (Qet::Orientation);
 };
 
 #endif

Modified: trunk/sources/qetgraphicsitem/terminal.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/terminal.cpp	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/qetgraphicsitem/terminal.cpp	2015-01-07 19:21:17 UTC (rev 3591)
@@ -78,8 +78,10 @@
 */
 Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) :
 	QGraphicsItem(e),
-	parent_element_(e),
-	hovered_color_(Terminal::neutralColor)
+	m_draw_help_line(false),
+	m_help_line     (nullptr),
+	parent_element_ (e),
+	hovered_color_  (Terminal::neutralColor)
 {
 	init(pf, o, "_", "_", false);
 }
@@ -94,8 +96,10 @@
 */
 Terminal::Terminal(qreal pf_x, qreal pf_y, Qet::Orientation o, Element *e) :
 	QGraphicsItem(e),
-	parent_element_(e),
-	hovered_color_(Terminal::neutralColor)
+	m_draw_help_line (false),
+	m_help_line      (nullptr),
+	parent_element_  (e),
+	hovered_color_   (Terminal::neutralColor)
 {
 	init(QPointF(pf_x, pf_y), o, "_", "_", false);
 }
@@ -267,11 +271,92 @@
 		p -> setRenderHint(QPainter::Antialiasing, true);
 		p -> drawEllipse(QRectF(c.x() - 2.5, c.y() - 2.5, 5.0, 5.0));
 	} else p -> drawPoint(c);
+
+
+		//Draw help line if needed, only if there isn't conductor
+		//docked to this terminal
+	if (m_draw_help_line && conductors().isEmpty())
+	{
+		if (!m_help_line)
+			m_help_line = new QGraphicsLineItem(this);
+
+		QLineF line(HelpLine());
+
+		Terminal *t = alignedWithTerminal();
+		if (t)
+		{
+			line.setP2(t -> dockConductor());
+			m_help_line -> setPen(QPen (Qt::darkGreen));
+		}
+		else
+		{
+			m_help_line -> setPen(QPen (Qt::darkBlue));
+		}
+
+			//Map the line (in scene coordinate) to help_line coordinate
+		line.setP1(m_help_line -> mapFromScene(line.p1()));
+		line.setP2(m_help_line -> mapFromScene(line.p2()));
+		m_help_line -> setLine(line);
+	}
 	
 	p -> restore();
 }
 
 /**
+ * @brief Terminal::drawHelpLine
+ * @param draw : true, display the help line
+ * false, hide it.
+ */
+void Terminal::drawHelpLine(bool draw)
+{
+	if (m_draw_help_line == draw) return;
+
+	m_draw_help_line = draw;
+
+	if (!draw && m_help_line)
+	{
+		delete m_help_line;
+		m_help_line = nullptr;
+	}
+
+	//update();
+}
+
+/**
+ * @brief Terminal::HelpLine
+ * @return a line with coordinate P1 the dock point of conductor
+ * and P2 the border of diagram, according to the orientation of terminal
+ * The line is in scene coordinate;
+ */
+QLineF Terminal::HelpLine() const
+{
+	QPointF scene_dock = dockConductor();
+	QRectF  rect       = diagram() -> drawingRect();
+
+	QLineF line(scene_dock , QPointF());
+
+		//Set te second point of line to the edge of diagram,
+		//according with the orientation of this terminal
+	switch (orientation())
+	{
+		case Qet::North:
+			line.setP2(QPointF(scene_dock.x(), rect.top()));
+			break;
+		case Qet::East:
+			line.setP2(QPointF(rect.right() , scene_dock.y()));
+			break;
+		case Qet::South:
+			line.setP2(QPointF(scene_dock.x(), rect.bottom()));
+			break;
+		case Qet::West:
+			line.setP2(QPointF(rect.left(), scene_dock.y()));
+			break;
+	}
+
+	return line;
+}
+
+/**
 	@return Le rectangle (en precision flottante) delimitant la borne et ses alentours.
 */
 QRectF Terminal::boundingRect() const {
@@ -290,6 +375,68 @@
 }
 
 /**
+ * @brief Terminal::alignedWithTerminal
+ * If this terminal is aligned with an other terminal
+ * and is orientation is opposed return the other terminal
+ * else return nullptr
+ * @return
+ */
+Terminal* Terminal::alignedWithTerminal() const
+{
+	QLineF line(HelpLine());
+
+	QPainterPath path;
+	path.moveTo(line.p1());
+	path.lineTo(line.p2());
+
+		//Get all QGraphicsItem in the alignement of this terminal
+	QList <QGraphicsItem *> qgi_list = diagram() -> items(path);
+
+		//Remove all terminals of the parent element
+	foreach (Terminal *t, parent_element_ -> terminals())
+		qgi_list.removeAll(t);
+
+	if (qgi_list.isEmpty()) return nullptr;
+
+		//Get terminals only if orientation is opposed with this terminal
+	QList <Terminal *>  available_terminals;
+	foreach (QGraphicsItem *qgi, qgi_list)
+	{
+		if (Terminal *tt = qgraphicsitem_cast <Terminal *> (qgi))
+		{
+				//Call QET::lineContainsPoint to be sure the line intersect
+				//the dock point and not an other part of terminal
+			if (Qet::isOpposed(orientation(), tt -> orientation()) &&
+				QET::lineContainsPoint(line, tt -> dockConductor()))
+			{
+				available_terminals << tt;
+			}
+		}
+	}
+
+	if (available_terminals.isEmpty())   return nullptr;
+	if (available_terminals.size() == 1) return (available_terminals.first());
+
+		//Available_terminals have several terminals, we get the nearest terminal
+	line.setP2(available_terminals.first() -> dockConductor());
+	qreal     current_lenght   = line.length();
+	Terminal *nearest_terminal = available_terminals.takeFirst();
+
+		//Search the nearest terminal to this one
+	foreach (Terminal *terminal, available_terminals)
+	{
+		line.setP2(terminal -> dockConductor());
+		if (line.length() < current_lenght)
+		{
+			current_lenght   = line.length();
+			nearest_terminal = terminal;
+		}
+	}
+
+	return nearest_terminal;
+}
+
+/**
 	Gere l'entree de la souris sur la zone de la Borne.
 */
 void Terminal::hoverEnterEvent(QGraphicsSceneHoverEvent *) {

Modified: trunk/sources/qetgraphicsitem/terminal.h
===================================================================
--- trunk/sources/qetgraphicsitem/terminal.h	2015-01-03 14:40:01 UTC (rev 3590)
+++ trunk/sources/qetgraphicsitem/terminal.h	2015-01-07 19:21:17 UTC (rev 3591)
@@ -41,23 +41,22 @@
 	
 	// methods
 	public:
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		Terminal
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
+			//Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a Terminal
+			//@return the QGraphicsItem type
+		virtual int type() const { return Type; }
 	
-	// implementation of QGraphicsItem pure virtual methods
-	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	QRectF boundingRect() const;
+		void   paint        (QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+		void   drawHelpLine (bool draw = true);
+		QLineF HelpLine     () const;
+		QRectF boundingRect () const;
 	
-	// methods to manage conductors attached to the terminal
-	bool addConductor(Conductor *);
-	void removeConductor(Conductor *);
-	int conductorsCount() const;
-	Diagram *diagram() const;
-	Element *parentElement() const;
+			// methods to manage conductors attached to the terminal
+		Terminal* alignedWithTerminal () const;
+		bool      addConductor        (Conductor *);
+		void      removeConductor     (Conductor *);
+		int       conductorsCount     () const;
+		Diagram  *diagram             () const;
+		Element  *parentElement       () const;
 	
 	QList<Conductor *> conductors() const;
 	Qet::Orientation orientation() const;
@@ -101,6 +100,9 @@
 	static QColor forbiddenColor;
 	
 	private:
+		bool               m_draw_help_line;
+		QGraphicsLineItem *m_help_line;
+
 	/// Parent electrical element
 	Element *parent_element_;
 	/// docking point for conductors


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/