diff --git a/sources/editor/arceditor.cpp b/sources/editor/arceditor.cpp index 940f0a883..854109210 100644 --- a/sources/editor/arceditor.cpp +++ b/sources/editor/arceditor.cpp @@ -67,6 +67,7 @@ ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) : v_layout -> addWidget(style_); v_layout -> addLayout(grid); + v_layout->addStretch(); updateForm(); diff --git a/sources/editor/ellipseeditor.cpp b/sources/editor/ellipseeditor.cpp index 9c52bc4d8..c396185d2 100644 --- a/sources/editor/ellipseeditor.cpp +++ b/sources/editor/ellipseeditor.cpp @@ -60,6 +60,7 @@ EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWi v_layout -> addWidget(style_); v_layout -> addLayout(grid); + v_layout->addStretch(); activeConnections(true); updateForm(); diff --git a/sources/editor/graphicspart/partrectangle.cpp b/sources/editor/graphicspart/partrectangle.cpp index 31400b645..5f04abfd0 100644 --- a/sources/editor/graphicspart/partrectangle.cpp +++ b/sources/editor/graphicspart/partrectangle.cpp @@ -28,16 +28,13 @@ * @param parent parent item */ PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) : - CustomElementGraphicPart(editor, parent), - m_undo_command(nullptr) + CustomElementGraphicPart(editor, parent) {} /** * @brief PartRectangle::~PartRectangle */ -PartRectangle::~PartRectangle() -{ - if(m_undo_command) delete m_undo_command; +PartRectangle::~PartRectangle() { removeHandler(); } @@ -64,8 +61,8 @@ void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt if (!rect().width() || !rect().height()) t.setWidth(0); - painter -> setPen(t); - painter -> drawRect(rect()); + painter->setPen(t); + painter->drawRoundedRect(m_rect, m_xRadius, m_yRadius); if (m_hovered) drawShadowShape(painter); @@ -88,6 +85,20 @@ const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const xml_element.setAttribute("y", QString("%1").arg(top_left.y())); xml_element.setAttribute("width", QString("%1").arg(m_rect.width())); xml_element.setAttribute("height", QString("%1").arg(m_rect.height())); + + QRectF rect = m_rect.normalized(); + qreal x = m_xRadius; + if (x > rect.width()/2) { + x = rect.width()/2; + } + qreal y = m_yRadius; + if (y > rect.height()/2) { + y = rect.height()/2; + } + + xml_element.setAttribute("rx", QString::number(m_xRadius)); + xml_element.setAttribute("ry", QString::number(m_yRadius)); + stylesToXml(xml_element); return(xml_element); } @@ -107,6 +118,8 @@ void PartRectangle::fromXml(const QDomElement &qde) qde.attribute("height", "0").toDouble())); setRect(rect.normalized()); + setXRadius(qde.attribute("rx", "0").toDouble()); + setYRadius(qde.attribute("ry", "0").toDouble()); } /** @@ -131,6 +144,22 @@ void PartRectangle::setRect(const QRectF &rect) emit rectChanged(); } +void PartRectangle::setXRadius(qreal X) +{ + m_xRadius = X; + update(); + adjusteHandlerPos(); + emit XRadiusChanged(); +} + +void PartRectangle::setYRadius(qreal Y) +{ + m_yRadius = Y; + update(); + adjusteHandlerPos(); + emit YRadiusChanged(); +} + /** * @brief PartRectangle::sceneGeometricRect * @return the minimum, margin-less rectangle this part can fit into, in scene @@ -157,7 +186,7 @@ QPointF PartRectangle::sceneTopLeft() const { QPainterPath PartRectangle::shape() const { QPainterPath shape; - shape.addRect(m_rect); + shape.addRoundedRect(m_rect, m_xRadius, m_yRadius); QPainterPathStroker pps; pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight()); @@ -169,7 +198,7 @@ QPainterPath PartRectangle::shape() const QPainterPath PartRectangle::shadowShape() const { QPainterPath shape; - shape.addRect(m_rect); + shape.addRoundedRect(m_rect, m_xRadius, m_yRadius); QPainterPathStroker pps; pps.setWidth(penWeight()); @@ -333,11 +362,25 @@ void PartRectangle::switchResizeMode() for (QetGraphicsHandlerItem *qghi : m_handler_vector) qghi->setColor(Qt::darkGreen); } - else + else if (m_resize_mode == 2) + { + m_resize_mode = 3; + qDeleteAll(m_handler_vector); + m_handler_vector.clear(); + addHandler(); + for (QetGraphicsHandlerItem *qghi : m_handler_vector) { + qghi->setColor(Qt::magenta); + } + } + else if (m_resize_mode == 3) { m_resize_mode = 1; - for (QetGraphicsHandlerItem *qghi : m_handler_vector) + qDeleteAll(m_handler_vector); + m_handler_vector.clear(); + addHandler(); + for (QetGraphicsHandlerItem *qghi : m_handler_vector) { qghi->setColor(Qt::blue); + } } } @@ -346,10 +389,18 @@ void PartRectangle::switchResizeMode() */ void PartRectangle::adjusteHandlerPos() { - if (m_handler_vector.isEmpty()) + if (m_handler_vector.isEmpty()) { return; + } - QVector points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect); + QVector points_vector; + + if(m_resize_mode != 3) { + points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect); + } + else { + points_vector = QetGraphicsHandlerUtility::pointForRadiusRect(m_rect, m_xRadius, m_yRadius); + } if (m_handler_vector.size() == points_vector.size()) { @@ -357,6 +408,12 @@ void PartRectangle::adjusteHandlerPos() for (int i = 0 ; i < points_vector.size() ; ++i) m_handler_vector.at(i)->setPos(points_vector.at(i)); } + else + { + qDeleteAll(m_handler_vector); + m_handler_vector.clear(); + addHandler(); + } } /** @@ -366,13 +423,15 @@ void PartRectangle::adjusteHandlerPos() */ void PartRectangle::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); - Q_UNUSED(event); - - m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect)); - m_undo_command->setText(tr("Modifier un rectangle")); - m_undo_command->enableAnimation(); - return; + Q_UNUSED(qghi) + Q_UNUSED(event) + + m_old_rect = m_rect; + m_old_xRadius = m_xRadius; + m_old_yRadius = m_yRadius; + if(m_xRadius == 0 && m_yRadius == 0) { + m_modifie_radius_equaly = true; + } } /** @@ -382,7 +441,7 @@ void PartRectangle::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphi */ void PartRectangle::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); + Q_UNUSED(qghi) QPointF new_pos = event->scenePos(); if (event->modifiers() != Qt::ControlModifier) @@ -391,20 +450,48 @@ void PartRectangle::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphic if (m_resize_mode == 1) setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index)); - else + else if (m_resize_mode == 2) setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index)); + else + { + qreal radius = QetGraphicsHandlerUtility::radiusForPosAtIndex(m_rect, new_pos, m_vector_index); + if(m_modifie_radius_equaly) { + setXRadius(radius); + setYRadius(radius); + } + else if(m_vector_index == 0) { + setXRadius(radius); + } + else { + setYRadius(radius); + } + } adjusteHandlerPos(); } void PartRectangle::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); - Q_UNUSED(event); + Q_UNUSED(qghi) + Q_UNUSED(event) - m_undo_command->setNewValue(QVariant(m_rect)); - elementScene()->undoStack().push(m_undo_command); - m_undo_command = nullptr; + m_modifie_radius_equaly = false; + + QUndoCommand *undo = new QUndoCommand("Modifier un rectangle"); + if (m_old_rect != m_rect) { + QPropertyUndoCommand *u = new QPropertyUndoCommand(this, "rect", QVariant(m_old_rect.normalized()), QVariant(m_rect.normalized()), undo); + u->setAnimated(true, false); + } + if (m_old_xRadius != m_xRadius) { + QPropertyUndoCommand *u = new QPropertyUndoCommand(this, "xRadius", QVariant(m_old_xRadius), QVariant(m_xRadius), undo); + u->setAnimated(); + } + if (m_old_yRadius != m_yRadius) { + QPropertyUndoCommand *u = new QPropertyUndoCommand(this, "yRadius", QVariant(m_old_yRadius), QVariant(m_yRadius), undo); + u->setAnimated(); + } + + elementScene()->undoStack().push(undo); m_vector_index = -1; } @@ -427,14 +514,20 @@ void PartRectangle::sceneSelectionChanged() void PartRectangle::addHandler() { if (m_handler_vector.isEmpty() && scene()) - { - m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect))); + { + if (m_resize_mode != 3) { + m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect))); + } + else { + m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointForRadiusRect(m_rect, m_xRadius, m_yRadius))); + } - for(QetGraphicsHandlerItem *handler : m_handler_vector) + for (QetGraphicsHandlerItem *handler : m_handler_vector) { - QColor color = Qt::blue; - if (m_resize_mode == 2) - color = Qt::darkGreen; + QColor color; + if(m_resize_mode == 1) {color = Qt::blue;} + else if (m_resize_mode == 2) {color = Qt::darkGreen;} + else {color = Qt::magenta;} handler->setColor(color); scene()->addItem(handler); diff --git a/sources/editor/graphicspart/partrectangle.h b/sources/editor/graphicspart/partrectangle.h index 0d0a0670a..d9ef39473 100644 --- a/sources/editor/graphicspart/partrectangle.h +++ b/sources/editor/graphicspart/partrectangle.h @@ -20,7 +20,6 @@ #include "customelementgraphicpart.h" -class QPropertyUndoCommand; class QetGraphicsHandlerItem; /** @@ -33,6 +32,8 @@ class PartRectangle : public CustomElementGraphicPart Q_OBJECT Q_PROPERTY(QRectF rect READ rect WRITE setRect) + Q_PROPERTY(qreal xRadius READ XRadius WRITE setXRadius NOTIFY XRadiusChanged) + Q_PROPERTY(qreal yRadius READ YRadius WRITE setYRadius NOTIFY YRadiusChanged) // constructors, destructor public: @@ -44,6 +45,8 @@ class PartRectangle : public CustomElementGraphicPart signals: void rectChanged(); + void XRadiusChanged(); + void YRadiusChanged(); // methods public: @@ -62,6 +65,10 @@ class PartRectangle : public CustomElementGraphicPart QRectF rect() const; void setRect(const QRectF &rect); + qreal XRadius() const {return m_xRadius;} + void setXRadius(qreal X); + qreal YRadius() const {return m_yRadius;} + void setYRadius(qreal Y); QRectF sceneGeometricRect() const override; virtual QPointF sceneTopLeft() const; @@ -91,11 +98,16 @@ class PartRectangle : public CustomElementGraphicPart void removeHandler(); private: - QRectF m_rect; + QRectF m_rect, + m_old_rect; QList saved_points_; - QPropertyUndoCommand *m_undo_command; int m_resize_mode = 1, m_vector_index = -1; QVector m_handler_vector; + qreal m_xRadius = 0, + m_yRadius = 0, + m_old_xRadius, + m_old_yRadius; + bool m_modifie_radius_equaly = false; }; #endif diff --git a/sources/editor/lineeditor.cpp b/sources/editor/lineeditor.cpp index 6c4b02725..ce1845f70 100644 --- a/sources/editor/lineeditor.cpp +++ b/sources/editor/lineeditor.cpp @@ -84,6 +84,7 @@ LineEditor::LineEditor(QETElementEditor *editor, PartLine *line, QWidget *parent v_layout -> addWidget(style_); v_layout -> addLayout(grid); v_layout -> addLayout(grid2); + v_layout->addStretch(); updateForm(); } diff --git a/sources/editor/polygoneditor.cpp b/sources/editor/polygoneditor.cpp index d6a490491..aecd69105 100644 --- a/sources/editor/polygoneditor.cpp +++ b/sources/editor/polygoneditor.cpp @@ -50,6 +50,7 @@ PolygonEditor::PolygonEditor(QETElementEditor *editor, PartPolygon *p, QWidget * layout -> addWidget(new QLabel(tr("Points du polygone :"))); layout -> addWidget(&points_list); layout -> addWidget(&close_polygon); + layout->addStretch(); updateForm(); } diff --git a/sources/editor/qetelementeditor.cpp b/sources/editor/qetelementeditor.cpp index 975199235..f2a1abae5 100644 --- a/sources/editor/qetelementeditor.cpp +++ b/sources/editor/qetelementeditor.cpp @@ -486,29 +486,30 @@ void QETElementEditor::slot_updateTitle() { } /** - Met en place l'interface -*/ -void QETElementEditor::setupInterface() { - // editeur + * @brief QETElementEditor::setupInterface + */ +void QETElementEditor::setupInterface() +{ + // editeur m_elmt_scene = new ElementScene(this, this); m_view = new ElementView(m_elmt_scene, this); slot_setRubberBandToView(); setCentralWidget(m_view); - // widget par defaut dans le QDockWidget + // widget par defaut dans le QDockWidget m_default_informations = new QLabel(); - // ScrollArea pour accueillir un widget d'edition (change a la volee) - m_tools_dock_scroll_area = new QScrollArea(); - m_tools_dock_scroll_area -> setFrameStyle(QFrame::NoFrame); - m_tools_dock_scroll_area -> setAlignment(Qt::AlignHCenter|Qt::AlignTop); + // ScrollArea pour accueillir un widget d'edition (change a la volee) +// m_tools_dock_scroll_area = new QScrollArea(); +// m_tools_dock_scroll_area -> setFrameStyle(QFrame::NoFrame); +// m_tools_dock_scroll_area -> setAlignment(Qt::AlignHCenter|Qt::AlignTop); - // Pile de widgets pour accueillir les deux widgets precedents + // Pile de widgets pour accueillir les deux widgets precedents m_tools_dock_stack = new QStackedWidget(); m_tools_dock_stack -> insertWidget(0, m_default_informations); - m_tools_dock_stack -> insertWidget(1, m_tools_dock_scroll_area); +// m_tools_dock_stack -> insertWidget(1, m_tools_dock_scroll_area); - // widgets d'editions pour les parties + // widgets d'editions pour les parties m_editors["arc"] = new ArcEditor(this); m_editors["ellipse"] = new EllipseEditor(this); m_editors["line"] = new LineEditor(this); @@ -609,7 +610,7 @@ void QETElementEditor::slot_updateInformations() QGraphicsItem *qgi = selected_qgis.first(); if (CustomElementPart *selection = dynamic_cast(qgi)) { - if (QWidget *widget = m_tools_dock_scroll_area->widget()) + if (QWidget *widget = m_tools_dock_stack->widget(1)) { if (ElementItemEditor *editor = dynamic_cast(widget)) { @@ -627,7 +628,7 @@ void QETElementEditor::slot_updateInformations() if (CustomElementPart *selection = dynamic_cast(qgi)) { //The current editor already edit the selected part - if (QWidget *widget = m_tools_dock_scroll_area->widget()) + if (QWidget *widget = m_tools_dock_stack->widget(1)) if (ElementItemEditor *editor = dynamic_cast(widget)) if(editor->currentPart() == selection) return; @@ -640,7 +641,7 @@ void QETElementEditor::slot_updateInformations() { if (selection_editor->setPart(selection)) { - m_tools_dock_scroll_area -> setWidget(selection_editor); + m_tools_dock_stack->insertWidget(1, selection_editor); m_tools_dock_stack -> setCurrentIndex(1); } else @@ -659,7 +660,7 @@ void QETElementEditor::slot_updateInformations() { if (selection_editor -> setParts(cep_list)) { - m_tools_dock_scroll_area -> setWidget(selection_editor); + m_tools_dock_stack->insertWidget(1, selection_editor); m_tools_dock_stack -> setCurrentIndex(1); } else @@ -1267,7 +1268,9 @@ bool QETElementEditor::canClose() { @return le widget enleve, ou 0 s'il n'y avait pas de widget a enlever */ QWidget *QETElementEditor::clearToolsDock() { - if (QWidget *previous_widget = m_tools_dock_scroll_area -> takeWidget()) { + if (QWidget *previous_widget = m_tools_dock_stack->widget(1)) + { + m_tools_dock_stack->removeWidget(previous_widget); previous_widget -> setParent(nullptr); previous_widget -> hide(); return(previous_widget); @@ -1574,7 +1577,7 @@ void QETElementEditor::updateCurrentPartEditor() { if (!m_tools_dock_stack -> currentIndex()) return; // s'il y a un widget d'edition affiche, on le met a jour - if (ElementItemEditor *current_editor = dynamic_cast(m_tools_dock_scroll_area -> widget())) { + if (ElementItemEditor *current_editor = dynamic_cast(m_tools_dock_stack->widget(1))) { current_editor -> updateForm(); } } diff --git a/sources/editor/qetelementeditor.h b/sources/editor/qetelementeditor.h index 810aafccd..9e0272d3e 100644 --- a/sources/editor/qetelementeditor.h +++ b/sources/editor/qetelementeditor.h @@ -17,7 +17,6 @@ */ #ifndef CUSTOM_ELEMENT_EDITOR_H #define CUSTOM_ELEMENT_EDITOR_H -#include #include "qetmainwindow.h" #include "qet.h" #include "elementscene.h" @@ -62,8 +61,6 @@ class QETElementEditor : public QETMainWindow { QLabel *m_default_informations; /// Hash associating primitive names with their matching edition widget QHash m_editors; - /// ScrollArea for the tools_dock DockWidget - QScrollArea *m_tools_dock_scroll_area; /// container for the undo list QDockWidget *m_undo_dock; /// Container for the list of existing primitives diff --git a/sources/editor/rectangleeditor.cpp b/sources/editor/rectangleeditor.cpp deleted file mode 100644 index 9ff190a83..000000000 --- a/sources/editor/rectangleeditor.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright 2006-2017 The QElectroTech Team - This file is part of QElectroTech. - - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . -*/ -#include "rectangleeditor.h" -#include "partrectangle.h" -#include "styleeditor.h" -#include "QPropertyUndoCommand/qpropertyundocommand.h" -#include "elementscene.h" - -/** - Constructeur - @param editor L'editeur d'element concerne - @param rect Le rectangle a editer - @param parent le Widget parent -*/ -RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) : - ElementItemEditor(editor, parent), - part(rect), - m_locked(false) -{ - style_ = new StyleEditor(editor); - - x = new QDoubleSpinBox(); - y = new QDoubleSpinBox(); - w = new QDoubleSpinBox(); - h = new QDoubleSpinBox(); - - x->setRange(-5000, 5000); - y->setRange(-5000, 5000); - w->setRange(-5000, 5000); - h->setRange(-5000, 5000); - - QVBoxLayout *v_layout = new QVBoxLayout(this); - - QGridLayout *grid = new QGridLayout(); - grid -> addWidget(new QLabel(tr("Coin supérieur gauche : ")), 0, 0, 1, 4); - grid -> addWidget(new QLabel("x"), 1, 0, Qt::AlignRight); - grid -> addWidget(x, 1, 1); - grid -> addWidget(new QLabel("y"), 1, 2); - grid -> addWidget(y, 1, 3); - grid -> addWidget(new QLabel(tr("Dimensions : ")), 2, 0, 1, 4); - grid -> addWidget(new QLabel(tr("Largeur :")), 3, 0); - grid -> addWidget(w, 3, 1); - grid -> addWidget(new QLabel(tr("Hauteur :")), 4, 0); - grid -> addWidget(h, 4, 1); - - v_layout -> addWidget(style_); - v_layout -> addLayout(grid); - - activeConnections(true); - updateForm(); -} - -/// Destructeur -RectangleEditor::~RectangleEditor() { -} - -/** - * @brief RectangleEditor::setPart - * Specifie to this editor the part to edit. - * Note that an editor can accept or refuse to edit a part. This editor accept only partRectangle. - * @param new_part - * @return - */ -bool RectangleEditor::setPart(CustomElementPart *new_part) -{ - if (!new_part) - { - if (part) - disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - part = nullptr; - style_ -> setPart(nullptr); - return(true); - } - - if (PartRectangle *part_rectangle = dynamic_cast(new_part)) - { - if (part == part_rectangle) return true; - if (part) - disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - part = part_rectangle; - style_ -> setPart(part); - updateForm(); - connect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - return(true); - } - - return(false); -} - -/** - * @brief RectangleEditor::currentPart - * @return the curent edited part, or 0 if there is no edited part - */ -CustomElementPart *RectangleEditor::currentPart() const { - return(part); -} - -/** - * @brief RectangleEditor::topLeft - * @return The edited topLeft already mapped to part coordinate - */ -QPointF RectangleEditor::editedTopLeft() const { - return part -> mapFromScene(x->value(), y->value()); -} - -/** - * @brief RectangleEditor::updateForm - * Update the values displayed by this widget - */ -void RectangleEditor::updateForm() -{ - if (!part) return; - activeConnections(false); - - QRectF rect = part->property("rect").toRectF(); - QPointF p = part->mapToScene(rect.topLeft()); - x->setValue(p.x()); - y->setValue(p.y()); - w->setValue(rect.width()); - h->setValue(rect.height()); - - activeConnections(true); -} - -/** - * @brief RectangleEditor::editingFinished - * Slot called when a editor widget is finish to be edited - * Update the geometry of the rectangle according to value of editing widget. - */ -void RectangleEditor::editingFinished() -{ - if (m_locked) return; - m_locked = true; - - QRectF rect(editedTopLeft(), QSizeF(w->value(), h->value())); - QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "rect", part->property("rect"), rect); - undo->setText(tr("Modifier un rectangle")); - undo->enableAnimation(); - elementScene()->undoStack().push(undo); - - m_locked = false; -} - -/** - * @brief RectangleEditor::activeConnections - * Enable/disable connection between editor widget and slot editingFinished - * True == enable | false == disable - * @param active - */ -void RectangleEditor::activeConnections(bool active) -{ - if (active) - { - connect(x, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(y, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(w, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(h, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - } - else - { - disconnect(x, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(y, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(w, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(h, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - } -} diff --git a/sources/editor/styleeditor.cpp b/sources/editor/styleeditor.cpp index 27a1a0788..1a6139b11 100644 --- a/sources/editor/styleeditor.cpp +++ b/sources/editor/styleeditor.cpp @@ -118,7 +118,6 @@ StyleEditor::StyleEditor(QETElementEditor *editor, CustomElementGraphicPart *p, main_layout -> addSpacing(10); main_layout -> addWidget(new QLabel("" + tr("Géométrie :") + " ")); - main_layout -> addStretch(); setLayout(main_layout); } diff --git a/sources/editor/ui/rectangleeditor.cpp b/sources/editor/ui/rectangleeditor.cpp new file mode 100644 index 000000000..7443edfc1 --- /dev/null +++ b/sources/editor/ui/rectangleeditor.cpp @@ -0,0 +1,200 @@ +/* + Copyright 2006-2018 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "rectangleeditor.h" +#include "ui_rectangleeditor.h" +#include "styleeditor.h" +#include "partrectangle.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" +#include "qeticons.h" + +/** + * @brief RectangleEditor::RectangleEditor + * @param editor + * @param rect + * @param parent + */ +RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) : + ElementItemEditor(editor, parent), + m_part(rect), + ui(new Ui::RectangleEditor) +{ + ui->setupUi(this); + m_style = new StyleEditor(editor); + ui->verticalLayout->insertWidget(0, m_style); +} + +/** + * @brief RectangleEditor::~RectangleEditor + */ +RectangleEditor::~RectangleEditor() { + delete ui; +} + +/** + * @brief RectangleEditor::setPart + * @param part + * @return + */ +bool RectangleEditor::setPart(CustomElementPart *part) +{ + if (!part) + { + if (m_part) + { + disconnect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + } + m_part = nullptr; + m_style->setPart(nullptr); + return(true); + } + + if (PartRectangle *part_rectangle = dynamic_cast(part)) + { + if (m_part == part_rectangle) { + return true; + } + if (m_part) + { + disconnect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); + disconnect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + } + m_part = part_rectangle; + m_style->setPart(m_part); + updateForm(); + connect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); + connect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); + connect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); + connect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); + connect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + return(true); + } + + return(false); +} + +/** + * @brief RectangleEditor::currentPart + * @return + */ +CustomElementPart *RectangleEditor::currentPart() const { + return m_part; +} + +/** + * @brief RectangleEditor::topLeft + * @return The edited topLeft already mapped to part coordinate + */ +QPointF RectangleEditor::editedTopLeft() const { + return m_part->mapFromScene(ui->m_x_sb->value(), ui->m_y_sb->value()); +} + +/** + * @brief RectangleEditor::updateForm + */ +void RectangleEditor::updateForm() +{ + if (!m_part) { + return; + } + activeConnections(false); + + QRectF rect = m_part->property("rect").toRectF(); + QPointF p = m_part->mapToScene(rect.topLeft()); + ui->m_x_sb->setValue(p.x()); + ui->m_y_sb->setValue(p.y()); + ui->m_width_sb->setValue(rect.width()); + ui->m_height_sb->setValue(rect.height()); + ui->m_rx_sb->setValue(m_part->XRadius()); + ui->m_rx_sb->setMaximum(rect.width()/2); + ui->m_ry_sb->setValue(m_part->YRadius()); + ui->m_ry_sb->setMaximum(rect.height()/2); + + activeConnections(true); +} + +/** + * @brief RectangleEditor::editingFinished + * Slot called when a editor widget is finish to be edited + * Update the geometry of the rectangle according to value of editing widget. + */ +void RectangleEditor::editingFinished() +{ + if (m_locked) { + return; + } + m_locked = true; + + QUndoCommand *undo = new QUndoCommand(); + undo->setText(tr("Modifier un rectangle")); + + QRectF rect(editedTopLeft(), QSizeF(ui->m_width_sb->value(), ui->m_height_sb->value())); + if (m_part->rect() != rect) + { + QPropertyUndoCommand *u = new QPropertyUndoCommand(m_part, "rect", m_part->rect(), rect, undo); + u->enableAnimation(); + } + if (m_part->XRadius() != ui->m_rx_sb->value()) + { + QPropertyUndoCommand *u = new QPropertyUndoCommand(m_part, "xRadius", m_part->XRadius(), ui->m_rx_sb->value(), undo); + u->setAnimated(); + } + if (m_part->YRadius() != ui->m_ry_sb->value()) + { + QPropertyUndoCommand *u = new QPropertyUndoCommand(m_part, "yRadius", m_part->YRadius(), ui->m_ry_sb->value(), undo); + u->setAnimated(); + } + elementScene()->undoStack().push(undo); + + m_locked = false; +} + +/** + * @brief RectangleEditor::activeConnections + * Enable/disable connection between editor widget and slot editingFinished + * True == enable | false == disable + * @param active + */ +void RectangleEditor::activeConnections(bool active) +{ + if (active) + { + connect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + } + else + { + disconnect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + } +} diff --git a/sources/editor/rectangleeditor.h b/sources/editor/ui/rectangleeditor.h similarity index 61% rename from sources/editor/rectangleeditor.h rename to sources/editor/ui/rectangleeditor.h index b9298c318..c9c2f9710 100644 --- a/sources/editor/rectangleeditor.h +++ b/sources/editor/ui/rectangleeditor.h @@ -1,5 +1,5 @@ /* - Copyright 2006-2017 The QElectroTech Team + Copyright 2006-2018 The QElectroTech Team This file is part of QElectroTech. QElectroTech is free software: you can redistribute it and/or modify @@ -15,47 +15,46 @@ You should have received a copy of the GNU General Public License along with QElectroTech. If not, see . */ -#ifndef RECTANGLE_EDITOR_H -#define RECTANGLE_EDITOR_H +#ifndef RECTANGLEEDITOR_H +#define RECTANGLEEDITOR_H #include "elementitemeditor.h" +#include -class PartRectangle; class StyleEditor; -class QDoubleSpinBox; +class PartRectangle; + +namespace Ui { + class RectangleEditor; +} /** - This class provides a widget to edit rectangles within the element editor. -*/ + * @brief The RectangleEditor class + * This class provides a widget to edit rectangles within the element editor. + */ class RectangleEditor : public ElementItemEditor { Q_OBJECT - - // constructors, destructor - public: - RectangleEditor(QETElementEditor *, PartRectangle * = nullptr, QWidget * = nullptr); - ~RectangleEditor() override; - private: - RectangleEditor(const RectangleEditor &); - // attributes - private: - PartRectangle *part; - StyleEditor *style_; - QDoubleSpinBox *x, *y, *w, *h; - bool m_locked; - - // methods public: - bool setPart(CustomElementPart *) override; + explicit RectangleEditor(QETElementEditor *editor, PartRectangle *rect = nullptr, QWidget *parent = nullptr); + ~RectangleEditor(); + + bool setPart(CustomElementPart *part) override; CustomElementPart *currentPart() const override; QPointF editedTopLeft () const; public slots: void updateForm() override; + private: void editingFinished(); + void activeConnections(bool active); private: - void activeConnections(bool); + bool m_locked = false; + StyleEditor *m_style; + PartRectangle *m_part; + Ui::RectangleEditor *ui; }; -#endif + +#endif // RECTANGLEEDITOR_H diff --git a/sources/editor/ui/rectangleeditor.ui b/sources/editor/ui/rectangleeditor.ui new file mode 100644 index 000000000..8b68823af --- /dev/null +++ b/sources/editor/ui/rectangleeditor.ui @@ -0,0 +1,166 @@ + + + RectangleEditor + + + + 0 + 0 + 293 + 147 + + + + + QLayout::SetMinimumSize + + + + + + + -5000.000000000000000 + + + 5000.000000000000000 + + + + + + + Hauteur : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Dimensions : + + + + + + + y + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + -5000.000000000000000 + + + 5000.000000000000000 + + + + + + + -5000.000000000000000 + + + 5000.000000000000000 + + + + + + + 2500.000000000000000 + + + + + + + Coin supérieur gauche : + + + + + + + Largeur : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Arrondi : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + x + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + -5000.000000000000000 + + + 5000.000000000000000 + + + + + + + Arrondi : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 2500.000000000000000 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/sources/qetgraphicsitem/customelement.cpp b/sources/qetgraphicsitem/customelement.cpp index 7af93024a..1c18cdfcb 100644 --- a/sources/qetgraphicsitem/customelement.cpp +++ b/sources/qetgraphicsitem/customelement.cpp @@ -462,13 +462,16 @@ bool CustomElement::parseLine(QDomElement &e, QPainter &qp, bool addtolist) { @param qp Le QPainter a utiliser pour dessiner l'element perso @return true si l'analyse reussit, false sinon */ -bool CustomElement::parseRect(QDomElement &e, QPainter &qp, bool addtolist) { +bool CustomElement::parseRect(QDomElement &e, QPainter &qp, bool addtolist) +{ // verifie la presence des attributs obligatoires - qreal rect_x, rect_y, rect_w, rect_h; + qreal rect_x, rect_y, rect_w, rect_h, rect_rx, rect_ry; if (!QET::attributeIsAReal(e, QString("x"), &rect_x)) return(false); if (!QET::attributeIsAReal(e, QString("y"), &rect_y)) return(false); if (!QET::attributeIsAReal(e, QString("width"), &rect_w)) return(false); if (!QET::attributeIsAReal(e, QString("height"), &rect_h)) return(false); + rect_rx = e.attribute("rx", "0").toDouble(); + rect_ry = e.attribute("ry", "0").toDouble(); if (addtolist){ //Add rectangle to the list @@ -484,7 +487,7 @@ bool CustomElement::parseRect(QDomElement &e, QPainter &qp, bool addtolist) { p.setJoinStyle(Qt::MiterJoin); qp.setPen(p); - qp.drawRect(QRectF(rect_x, rect_y, rect_w, rect_h)); + qp.drawRoundedRect(QRectF(rect_x, rect_y, rect_w, rect_h), rect_rx, rect_ry); qp.restore(); return(true); }