Add help line for assist alignement of element

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3591 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun 2015-01-07 19:21:17 +00:00
parent 16e17438d2
commit ceb2b9bcfd
6 changed files with 242 additions and 28 deletions

View File

@ -930,9 +930,12 @@ void Diagram::invertSelection() {
} }
/** /**
@return Le rectangle (coordonnees par rapport a la scene) delimitant le bord du schema * @brief Diagram::border
*/ * @return The rectangle (coordinates relative to the scene)
QRectF Diagram::border() const { * delimiting the edge of the diagram
*/
QRectF Diagram::border() const
{
return( return(
QRectF( QRectF(
margin, margin,
@ -943,6 +946,32 @@ QRectF Diagram::border() const {
); );
} }
/**
* @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 @return le titre du cartouche
*/ */

View File

@ -169,7 +169,9 @@ class Diagram : public QGraphicsScene
bool drawColoredConductors() const; bool drawColoredConductors() const;
void setDrawColoredConductors(bool); void setDrawColoredConductors(bool);
QRectF border() const; QRectF border () const;
QRectF drawingRect () const;
QString title() const; QString title() const;
bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio); bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
QSize imageSize() const; QSize imageSize() const;

View File

@ -62,6 +62,37 @@ bool Qet::surLeMemeAxe(Qet::Orientation a, Qet::Orientation b) {
else return(false); else return(false);
} }
/**
* @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). Indique si une orientation de borne est horizontale (Est / Ouest).
@param a L'orientation de borne @param a L'orientation de borne

View File

@ -180,11 +180,14 @@ class Qet : public QObject {
West}; West};
static Qet::Orientation nextOrientation(Qet::Orientation); static Qet::Orientation nextOrientation(Qet::Orientation);
static Qet::Orientation previousOrientation(Qet::Orientation); static Qet::Orientation previousOrientation(Qet::Orientation);
static Qet::Orientation orientationFromString(const QString &);
static QString orientationToString(Qet::Orientation); static Qet::Orientation orientationFromString (const QString &);
static bool surLeMemeAxe(Qet::Orientation, Qet::Orientation); static QString orientationToString (Qet::Orientation);
static bool estHorizontale(Qet::Orientation);
static bool estVerticale(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 #endif

View File

@ -78,8 +78,10 @@ void Terminal::init(QPointF pf, Qet::Orientation o, QString number, QString name
*/ */
Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) : Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) :
QGraphicsItem(e), QGraphicsItem(e),
parent_element_(e), m_draw_help_line(false),
hovered_color_(Terminal::neutralColor) m_help_line (nullptr),
parent_element_ (e),
hovered_color_ (Terminal::neutralColor)
{ {
init(pf, o, "_", "_", false); init(pf, o, "_", "_", false);
} }
@ -94,8 +96,10 @@ Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) :
*/ */
Terminal::Terminal(qreal pf_x, qreal pf_y, Qet::Orientation o, Element *e) : Terminal::Terminal(qreal pf_x, qreal pf_y, Qet::Orientation o, Element *e) :
QGraphicsItem(e), QGraphicsItem(e),
parent_element_(e), m_draw_help_line (false),
hovered_color_(Terminal::neutralColor) m_help_line (nullptr),
parent_element_ (e),
hovered_color_ (Terminal::neutralColor)
{ {
init(QPointF(pf_x, pf_y), o, "_", "_", false); init(QPointF(pf_x, pf_y), o, "_", "_", false);
} }
@ -267,10 +271,91 @@ void Terminal::paint(QPainter *p, const QStyleOptionGraphicsItem *options, QWidg
p -> setRenderHint(QPainter::Antialiasing, true); p -> setRenderHint(QPainter::Antialiasing, true);
p -> drawEllipse(QRectF(c.x() - 2.5, c.y() - 2.5, 5.0, 5.0)); p -> drawEllipse(QRectF(c.x() - 2.5, c.y() - 2.5, 5.0, 5.0));
} else p -> drawPoint(c); } 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(); 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. @return Le rectangle (en precision flottante) delimitant la borne et ses alentours.
*/ */
@ -289,6 +374,68 @@ QRectF Terminal::boundingRect() const {
return(*br_); return(*br_);
} }
/**
* @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. Gere l'entree de la souris sur la zone de la Borne.
*/ */

View File

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