Element editor : hover a primitve will highlight it with a blue halo

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3694 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2015-02-09 08:57:40 +00:00
parent c5036dfb17
commit 9c6499813c
32 changed files with 1741 additions and 1443 deletions

View File

@@ -18,201 +18,227 @@
#include "partrectangle.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce rectangle
@param scene La scene sur laquelle figure ce rectangle
*/
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : CustomElementGraphicPart(editor), QGraphicsRectItem(parent, scene) {
setFlags(QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptedMouseButtons(Qt::LeftButton);
}
/// Destructeur
PartRectangle::~PartRectangle() {
}
* @brief PartRectangle::PartRectangle
* Constructor
* @param editor the QETElementEditor of this item
* @param parent parent item
*/
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
CustomElementGraphicPart(editor, parent)
{}
/**
Dessine le rectangle
@param painter QPainter a utiliser pour rendre le dessin
@param options Options pour affiner le rendu
@param widget Widget sur lequel le rendu est effectue
*/
void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
* @brief PartRectangle::~PartRectangle
*/
PartRectangle::~PartRectangle() {}
/**
* @brief PartRectangle::paint
* Draw this Rectangle
* @param painter
* @param options
* @param widget
*/
void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
{
Q_UNUSED(widget);
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
t.setCosmetic(options && options -> levelOfDetail < 1.0);
if (isSelected()) {
if (isSelected())
t.setColor(Qt::red);
}
// force le type de jointures pour les rectangles
t.setJoinStyle(Qt::MiterJoin);
// force le dessin avec un trait fin si l'une des dimensions du rectangle est nulle
if (!rect().width() || !rect().height()) {
//Force the pen to width 0 if one of dimension is null
if (!rect().width() || !rect().height())
t.setWidth(0);
}
painter -> setPen(t);
painter -> drawRect(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
if (m_hovered)
drawShadowShape(painter);
if (isSelected())
drawCross(m_rect.center(), painter);
}
/**
Exporte le rectangle en XML
@param xml_document Document XML a utiliser pour creer l'element XML
@return un element XML decrivant le rectangle
*/
const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const {
* @brief PartRectangle::toXml
* Export this rectangle in xml
* @param xml_document : Xml document to use for create the xml element.
* @return an xml element that describe this ellipse
*/
const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const
{
QDomElement xml_element = xml_document.createElement("rect");
QPointF top_left(sceneTopLeft());
xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
xml_element.setAttribute("width", QString("%1").arg(rect().width()));
xml_element.setAttribute("height", QString("%1").arg(rect().height()));
xml_element.setAttribute("width", QString("%1").arg(m_rect.width()));
xml_element.setAttribute("height", QString("%1").arg(m_rect.height()));
stylesToXml(xml_element);
return(xml_element);
}
/**
Importe les proprietes d'une rectangle depuis un element XML
@param qde Element XML a lire
*/
void PartRectangle::fromXml(const QDomElement &qde) {
* @brief PartRectangle::fromXml
* Import the properties of this rectangle from a xml element.
* @param qde : Xml document to use.
*/
void PartRectangle::fromXml(const QDomElement &qde)
{
stylesFromXml(qde);
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
qde.attribute("width", "0").toDouble(),
qde.attribute("height", "0").toDouble()
)
)
);
setRect(QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()),
QSizeF(qde.attribute("width", "0").toDouble(),
qde.attribute("height", "0").toDouble())));
}
/**
* @brief PartRectangle::setX
* @param x new value
* @brief PartRectangle::rect
* @return : Returns the item's rectangle.
*/
void PartRectangle::setX(qreal x) {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.topLeft());
setRect(current_rect.translated(x - current_pos.x(), 0.0));
QRectF PartRectangle::rect() const {
return m_rect;
}
/**
* @brief PartRectangle::setY
* @param y new value
* @brief PartRectangle::setRect
* Sets the item's rectangle to be the given rectangle.
* @param rect
*/
void PartRectangle::setY(qreal y) {
QRectF current_rect = rect();
QPointF current_pos = mapToScene(current_rect.topLeft());
setRect(current_rect.translated(0.0, y - current_pos.y()));
void PartRectangle::setRect(const QRectF &rect)
{
if (rect == m_rect) return;
prepareGeometryChange();
m_rect = rect;
}
/**
* @brief PartRectangle::rectTopLeft
* @return the rectangle top left in item coordinate
*/
QPointF PartRectangle::rectTopLeft() const {
return m_rect.topLeft();
}
/**
* @brief PartRectangle::setRectTopLeft
* @param point, set the rectangle top left in item coordinate.
* The rectangle size is unchanged
*/
void PartRectangle::setRectTopLeft(const QPointF &point) {
m_rect.moveTopLeft(point);
}
/**
* @brief PartRectangle::setWidth
* Sets the width of the rectangle to the given width.
* The right edge is changed, but not the left one.
* @param w new value
*/
void PartRectangle::setWidth(qreal w) {
qreal new_width = qAbs(w);
QRectF current_rect = rect();
current_rect.setWidth(new_width);
setRect(current_rect);
void PartRectangle::setWidth(qreal w)
{
prepareGeometryChange();
m_rect.setWidth(qAbs(w));
}
/**
* @brief PartRectangle::setHeight
* Sets the height of the rectangle to the given height.
* The bottom edge is changed, but not the top one.
* @param h new value
*/
void PartRectangle::setHeight(qreal h) {
qreal new_height = qAbs(h);
QRectF current_rect = rect();
current_rect.setHeight(new_height);
setRect(current_rect);
void PartRectangle::setHeight(qreal h)
{
prepareGeometryChange();
m_rect.setHeight(qAbs(h));
}
/**
Gere les changements intervenant sur cette partie
@param change Type de changement
@param value Valeur numerique relative au changement
*/
QVariant PartRectangle::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
updateCurrentPartEditor();
}
}
return(QGraphicsRectItem::itemChange(change, value));
}
/**
@return le coin superieur gauche du rectangle, dans les coordonnees de la
scene.
*/
QPointF PartRectangle::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
conservee / enregistree.
Un rectangle est pertinent des lors que ses dimensions ne sont pas nulles.
*/
bool PartRectangle::isUseless() const {
return(rect().isNull());
}
/**
@return the minimum, margin-less rectangle this part can fit into, in scene
coordinates. It is different from boundingRect() because it is not supposed
to imply any margin, and it is different from shape because it is a regular
rectangle, not a complex shape.
*/
* @brief PartRectangle::sceneGeometricRect
* @return the minimum, margin-less rectangle this part can fit into, in scene
* coordinates. It is different from boundingRect() because it is not supposed
* to imply any margin, and it is different from shape because it is a regular
* rectangle, not a complex shape.
*/
QRectF PartRectangle::sceneGeometricRect() const {
return(mapToScene(rect()).boundingRect());
}
/**
Start the user-induced transformation, provided this primitive is contained
within the \a initial_selection_rect bounding rectangle.
*/
void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect) {
* @brief PartRectangle::sceneTopLeft
* @return the top left of rectangle, in scene coordinate
*/
QPointF PartRectangle::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
/**
* @brief PartRectangle::shape
* @return the shape of this item
*/
QPainterPath PartRectangle::shape() const
{
QPainterPath shape;
shape.addRect(m_rect);
QPainterPathStroker pps;
pps.setWidth(penWeight());
return (pps.createStroke(shape));
}
/**
* @brief PartRectangle::boundingRect
* @return Bounding rectangle this part can fit into
*/
QRectF PartRectangle::boundingRect() const
{
qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
//We add 0.5 because CustomElementGraphicPart::drawShadowShape
//draw a shape bigger of 0.5 when pen weight is to 0.
if (penWeight() == 0) adjust += 0.5;
QRectF r = m_rect.normalized();
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}
/**
* @brief PartRectangle::isUseless
* @return true if this part is irrelevant and does not deserve to be Retained / registered.
* An rectangle is relevant when he's not null.
*/
bool PartRectangle::isUseless() const {
return(rect().isNull());
}
/**
* @brief PartRectangle::startUserTransformation
* Start the user-induced transformation, provided this primitive is contained
* within the initial_selection_rect bounding rectangle.
* @param initial_selection_rect
*/
void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect)
{
Q_UNUSED(initial_selection_rect)
// we keep track of our own rectangle at the moment in scene coordinates too
// we keep track of our own rectangle at the moment in scene coordinates too
saved_points_.clear();
saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
}
/**
Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
*/
void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
* @brief PartRectangle::handleUserTransformation
* Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
* @param initial_selection_rect
* @param new_selection_rect
*/
void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
{
QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
}
/**
@return le rectangle delimitant cette partie.
*/
QRectF PartRectangle::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsRectItem::boundingRect().normalized());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}