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)
* delimiting the edge of the diagram
*/
QRectF Diagram::border() const {
QRectF Diagram::border() const
{
return(
QRectF(
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
*/

View File

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

View File

@ -62,6 +62,37 @@ bool Qet::surLeMemeAxe(Qet::Orientation a, Qet::Orientation b) {
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).
@param a L'orientation de borne

View File

@ -180,9 +180,12 @@ class Qet : public QObject {
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 isOpposed (Qet::Orientation a, Qet::Orientation b);
static bool estHorizontale (Qet::Orientation);
static bool estVerticale (Qet::Orientation);
};

View File

@ -78,6 +78,8 @@ void Terminal::init(QPointF pf, Qet::Orientation o, QString number, QString name
*/
Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) :
QGraphicsItem(e),
m_draw_help_line(false),
m_help_line (nullptr),
parent_element_ (e),
hovered_color_ (Terminal::neutralColor)
{
@ -94,6 +96,8 @@ Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) :
*/
Terminal::Terminal(qreal pf_x, qreal pf_y, Qet::Orientation o, Element *e) :
QGraphicsItem(e),
m_draw_help_line (false),
m_help_line (nullptr),
parent_element_ (e),
hovered_color_ (Terminal::neutralColor)
{
@ -268,9 +272,90 @@ void Terminal::paint(QPainter *p, const QStyleOptionGraphicsItem *options, QWidg
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.
*/
@ -289,6 +374,68 @@ QRectF Terminal::boundingRect() const {
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.
*/

View File

@ -41,18 +41,17 @@ class Terminal : public QGraphicsItem {
// methods
public:
/**
Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
Terminal
@return the QGraphicsItem 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 *);
void drawHelpLine (bool draw = true);
QLineF HelpLine () const;
QRectF boundingRect () const;
// methods to manage conductors attached to the terminal
Terminal* alignedWithTerminal () const;
bool addConductor (Conductor *);
void removeConductor (Conductor *);
int conductorsCount () const;
@ -101,6 +100,9 @@ class Terminal : public QGraphicsItem {
static QColor forbiddenColor;
private:
bool m_draw_help_line;
QGraphicsLineItem *m_help_line;
/// Parent electrical element
Element *parent_element_;
/// docking point for conductors