diff --git a/qelectrotech.pro b/qelectrotech.pro index 78c51d530..6fc5d4311 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -71,6 +71,8 @@ include(sources/PropertiesEditor/PropertiesEditor.pri) include(sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri) include(sources/QPropertyUndoCommand/QPropertyUndoCommand.pri) include(SingleApplication/singleapplication.pri) +include(sources/QWidgetAnimation/QWidgetAnimation.pri) + DEFINES += QAPPLICATION_CLASS=QApplication TEMPLATE = app @@ -280,3 +282,6 @@ macx { unix { QMAKE_COPY_DIR = 'cp -f -r --preserve=timestamps' } + +SUBDIRS += \ + sources/QwidgetAnimation/QWidgetAnimation.pro diff --git a/sources/QWidgetAnimation/QWidgetAnimation.pri b/sources/QWidgetAnimation/QWidgetAnimation.pri new file mode 100644 index 000000000..7072f1b6f --- /dev/null +++ b/sources/QWidgetAnimation/QWidgetAnimation.pri @@ -0,0 +1,5 @@ +HEADERS += \ + $$PWD/qwidgetanimation.h + +SOURCES += \ + $$PWD/qwidgetanimation.cpp diff --git a/sources/QWidgetAnimation/qwidgetanimation.cpp b/sources/QWidgetAnimation/qwidgetanimation.cpp new file mode 100644 index 000000000..df0932a91 --- /dev/null +++ b/sources/QWidgetAnimation/qwidgetanimation.cpp @@ -0,0 +1,162 @@ +/* + Copyright 2006-2020 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 "qwidgetanimation.h" +#include + +/** + * @brief QWidgetAnimation::QWidgetAnimation + * @param widget : widget to animate + * @param orientation : animate widget horizontally or vertically + * @param duration : the duration of animation @see void QVariantAnimation::setDuration(int msecs) + */ +QWidgetAnimation::QWidgetAnimation(QWidget *widget, Qt::Orientation orientation, QWidgetAnimation::Behavior behavior, int duration) : + QPropertyAnimation(widget), + m_orientation(orientation), + m_widget(widget), + m_maximum(widget->maximumSize()), + m_last_rect(widget->geometry()), + m_behavior(behavior) +{ + setTargetObject(widget); + setPropertyName( m_orientation == Qt::Vertical ? "maximumHeight" : "maximumWidth"); + setDuration(duration); + setEasingCurve(QEasingCurve::OutCubic); + + connect(this, &QPropertyAnimation::finished, [this]() + { + m_state = QWidgetAnimation::Finish; + + if ( (this->m_orientation == Qt::Vertical && m_widget->geometry().height() == 0) || + (this->m_orientation == Qt::Horizontal && m_widget->geometry().width() == 0) ) { + m_widget->hide(); + } else { + m_widget->setMaximumSize(m_maximum); + } + }); +} + +/** + * @brief QWidgetAnimation::widgetToSubtract + * Widget to subtract the size when the behavior is availableSpace + * @param widgets + */ +void QWidgetAnimation::widgetToSubtract(QVector widgets) +{ + m_widget_to_substract.clear(); + m_widget_to_substract = widgets; +} + +/** + * @brief QWidgetAnimation::show + * show the widget + */ +void QWidgetAnimation::show() +{ + if (m_state == QWidgetAnimation::Showing) + return; + + stop(); + + m_widget->show(); + + int end_value = 10000; + if (m_behavior == QWidgetAnimation::minimumSizeHint) + { + end_value = m_orientation == Qt::Horizontal ? m_widget->minimumSizeHint().width() : + m_widget->minimumSizeHint().height(); + } + else if (m_behavior == QWidgetAnimation::availableSpace && m_widget->parentWidget()) + { + m_widget->parentWidget()->layout(); + int available_ = m_orientation == Qt::Horizontal ? m_widget->parentWidget()->width() : + m_widget->parentWidget()->height(); + for (auto w : m_widget_to_substract) { + available_ -= m_orientation == Qt::Horizontal ? w->minimumSizeHint().width() : + w->minimumSizeHint().height(); + } + + int mini_ = m_orientation == Qt::Horizontal ? m_widget->minimumSizeHint().width() : + m_widget->minimumSizeHint().height(); + + end_value = available_ > mini_ ? available_ : mini_; + } + else + { + if (m_last_rect.isValid()) { + end_value = m_orientation == Qt::Horizontal ? m_last_rect.width() : + m_last_rect.height(); + } else { + end_value = m_orientation == Qt::Horizontal ? m_maximum.width() : + m_maximum.height(); + } + } + + setStartValue(0); + setEndValue(end_value); + m_state = QWidgetAnimation::Showing; + start(); +} + +/** + * @brief QWidgetAnimation::hide + * Hide the widget + */ +void QWidgetAnimation::hide() +{ + if (m_state == QWidgetAnimation::Hidding) + return; + + if (m_state == Finish && m_widget->isVisible()) { + m_last_rect = m_widget->geometry(); + } + + stop(); + int start_value = m_orientation == Qt::Horizontal ? m_widget->width() : + m_widget->height(); + setStartValue(start_value); + setEndValue(0); + m_state = QWidgetAnimation::Hidding; + start(); +} + +/** + * @brief QWidgetAnimation::setHidden + * true hide, false show + * @param hidden + */ +void QWidgetAnimation::setHidden(bool hidden) +{ + if (hidden) + hide(); + else + show(); +} + +/** + * @brief QWidgetAnimation::setLastShowSize + * Force the last show size value to @size + * @param size + */ +void QWidgetAnimation::setLastShowSize(int size) +{ + if (m_orientation == Qt::Vertical) { + m_last_rect.setHeight(size); + } else { + m_last_rect.setWidth(size); + } +} diff --git a/sources/QWidgetAnimation/qwidgetanimation.h b/sources/QWidgetAnimation/qwidgetanimation.h new file mode 100644 index 000000000..92e6b18b2 --- /dev/null +++ b/sources/QWidgetAnimation/qwidgetanimation.h @@ -0,0 +1,73 @@ +/* + Copyright 2006-2020 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 . +*/ +#ifndef QWIDGETANIMATION_H +#define QWIDGETANIMATION_H + +#include +#include +#include + +/** + * @brief The QWidgetAnimation class + * This class animate the show and hide function of a QWidget. + * + * The role of @behavior is to calcul as best the animation process when widget is show. + * Because this class don't change the current and final size of the widget but her maximum size during the animation process, + * we must to know in advance the final size of the widget. + * Behavior minimumSizeHint : the final size of the widget will be his minimum size hint. + * Behavior availableSpace : the final size of widget will be the available size of her parent. + * Since parent can have other widgets you can add a QVector of widget to subtract of the final size. + * Because we suppose the animated widget will take the maximum available space, we subtract the minimum size hint of widgets in QVector. + * Behavior lastSize : The widget will have the same size as the last time he was showed. + */ +class QWidgetAnimation : public QPropertyAnimation +{ + Q_OBJECT + + public: + enum Behavior { + minimumSizeHint, + availableSpace, + lastSize, + }; + + QWidgetAnimation(QWidget *widget, Qt::Orientation orientation, QWidgetAnimation::Behavior behavior = QWidgetAnimation::minimumSizeHint, int duration = 250); + void widgetToSubtract (QVector widgets); + + void show(); + void hide(); + void setHidden(bool hidden); + void setLastShowSize(int size); + + private: + enum currentState { + Showing, + Hidding, + Finish + }; + + Qt::Orientation m_orientation = Qt::Horizontal; + QVector m_widget_to_substract; + QWidget *m_widget; + QSize m_maximum; + QRect m_last_rect; + QWidgetAnimation::Behavior m_behavior = Behavior::minimumSizeHint; + QWidgetAnimation::currentState m_state = QWidgetAnimation::Finish; +}; + +#endif // QWIDGETANIMATION_H diff --git a/sources/SearchAndReplace/ui/searchandreplacewidget.cpp b/sources/SearchAndReplace/ui/searchandreplacewidget.cpp index 82f0356b7..7ac92b205 100644 --- a/sources/SearchAndReplace/ui/searchandreplacewidget.cpp +++ b/sources/SearchAndReplace/ui/searchandreplacewidget.cpp @@ -44,6 +44,13 @@ SearchAndReplaceWidget::SearchAndReplaceWidget(QWidget *parent) : ui(new Ui::SearchAndReplaceWidget) { ui->setupUi(this); + + m_horizontal_animation = new QWidgetAnimation(ui->m_advanced_button_widget, Qt::Horizontal, QWidgetAnimation::minimumSizeHint, 250); + m_vertical_animation = new QWidgetAnimation(ui->m_advanced_widget, Qt::Vertical, QWidgetAnimation::availableSpace, 250); + QVector v; + v << ui->m_header_widget; + m_vertical_animation->widgetToSubtract(v); + setHideAdvanced(true); setUpTreeItems(); @@ -70,7 +77,6 @@ bool SearchAndReplaceWidget::event(QEvent *event) if (event->type() == QEvent::Hide) { clear(); - setHideAdvanced(true); if (m_highlighted_element) { m_highlighted_element.data()->setHighlighted(false); @@ -204,20 +210,10 @@ void SearchAndReplaceWidget::setUpTreeItems() * Hide advanced widgets * @param hide */ -void SearchAndReplaceWidget::setHideAdvanced(bool hide) const +void SearchAndReplaceWidget::setHideAdvanced(bool hide) { - ui->m_advanced_pb ->setChecked(!hide); - ui->m_replace ->setHidden(hide); - ui->m_replace_le ->setHidden(hide); - ui->m_folio_pb ->setHidden(hide); - ui->m_element_pb ->setHidden(hide); - ui->m_conductor_pb ->setHidden(hide); - ui->m_tree_widget ->setHidden(hide); - ui->m_replace_pb ->setHidden(hide); - ui->m_replace_all_pb ->setHidden(hide); - ui->m_mode_cb ->setHidden(hide); - ui->m_case_sensitive_cb->setHidden(hide); - ui->m_advanced_replace_pb->setHidden(hide); + m_vertical_animation->setHidden(hide); + m_horizontal_animation->setHidden(hide); } /** diff --git a/sources/SearchAndReplace/ui/searchandreplacewidget.h b/sources/SearchAndReplace/ui/searchandreplacewidget.h index c51bddcc5..543c11696 100644 --- a/sources/SearchAndReplace/ui/searchandreplacewidget.h +++ b/sources/SearchAndReplace/ui/searchandreplacewidget.h @@ -24,6 +24,7 @@ #include "element.h" #include "independenttextitem.h" #include "searchandreplaceworker.h" +#include "QWidgetAnimation/qwidgetanimation.h" class QTreeWidgetItem; @@ -39,7 +40,7 @@ class SearchAndReplaceWidget : public QWidget public: explicit SearchAndReplaceWidget(QWidget *parent = nullptr); - ~SearchAndReplaceWidget(); + ~SearchAndReplaceWidget() override; bool event(QEvent *event) override; void clear(); @@ -47,7 +48,7 @@ class SearchAndReplaceWidget : public QWidget private: void setUpTreeItems(); - void setHideAdvanced(bool hide) const; + void setHideAdvanced(bool hide); void fillItemsList(); void addElement(Element *element); void search(); @@ -109,6 +110,8 @@ class SearchAndReplaceWidget : public QWidget QPointer m_last_selected; QHash> m_diagram_hash; SearchAndReplaceWorker m_worker; + QWidgetAnimation *m_vertical_animation; + QWidgetAnimation *m_horizontal_animation; }; #endif // SEARCHANDREPLACEWIDGET_H diff --git a/sources/SearchAndReplace/ui/searchandreplacewidget.ui b/sources/SearchAndReplace/ui/searchandreplacewidget.ui index e5e7e350d..8514000a3 100644 --- a/sources/SearchAndReplace/ui/searchandreplacewidget.ui +++ b/sources/SearchAndReplace/ui/searchandreplacewidget.ui @@ -6,22 +6,331 @@ 0 0 - 970 - 436 + 989 + 661 Form - - - - - Chercher : - + + + 9 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Chercher : + + + + + + + + 1 + 0 + + + + true + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Mode + + + true + + + + Texte brut + + + + + Mots entiers + + + + + + + + Sensible à la casse + + + + + + + + + + Aller à la correspondance suivante + + + + + + + :/ico/16x16/go-bottom.png:/ico/16x16/go-bottom.png + + + true + + + + + + + Aller à la correspondance précédente + + + + + + + :/ico/16x16/go-top.png:/ico/16x16/go-top.png + + + true + + + + + + + Actualiser + + + + + + + :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png + + + true + + + + + + + <html><head/><body><p>Afficher les options avancées</p></body></html> + + + + + + + :/ico/16x16/configure-toolbars.png:/ico/16x16/configure-toolbars.png + + + true + + + false + + + true + + + + - + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 0 + + + + + true + + + <html><head/><body><p>Définir les propriétés à remplacer dans les éléments</p></body></html> + + + Élément + + + + + + + <html><head/><body><p>Définir les propriétés à remplacer dans les conducteurs</p></body></html> + + + Conducteur + + + + + + + false + + + <html><head/><body><p>Remplacer les correspondances cochées</p></body></html> + + + Tout remplacer + + + + + + + avancé + + + + + + + Remplacer : + + + + + + + <html><head/><body><p>Définir les propriétés à remplacer dans les folios</p></body></html> + + + Folio + + + + + + + + 200 + 0 + + + + Champ texte de folio + + + true + + + + + + + false + + + <html><head/><body><p>Remplacer la correspondance sélectionnée</p></body></html> + + + Remplacer + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + true + + + true + + + true + + + false + + + + 1 + + + + + + + + Qt::Horizontal + + + + 100 + 20 + + + + + + + + Quitter @@ -38,217 +347,18 @@ - - - - Mode + + + + Qt::Vertical - - true + + + 20 + 40 + - - - Texte brut - - - - - Mots entiers - - - - - - - - Sensible à la casse - - - - - - - Remplacer : - - - - - - - Aller à la correspondance suivante - - - - - - - :/ico/16x16/go-bottom.png:/ico/16x16/go-bottom.png - - - true - - - - - - - Aller à la correspondance précédente - - - - - - - :/ico/16x16/go-top.png:/ico/16x16/go-top.png - - - true - - - - - - - <html><head/><body><p>Afficher les options avancées</p></body></html> - - - - - - - :/ico/16x16/configure-toolbars.png:/ico/16x16/configure-toolbars.png - - - true - - - false - - - true - - - - - - - Actualiser - - - - - - - :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png - - - true - - - - - - - Champ texte de folio - - - true - - - - - - - <html><head/><body><p>Définir les propriétés à remplacer dans les folios</p></body></html> - - - Folio - - - - - - - true - - - <html><head/><body><p>Définir les propriétés à remplacer dans les éléments</p></body></html> - - - Élément - - - - - - - <html><head/><body><p>Définir les propriétés à remplacer dans les conducteurs</p></body></html> - - - Conducteur - - - - - - - false - - - <html><head/><body><p>Remplacer la correspondance sélectionnée</p></body></html> - - - Remplacer - - - - - - - false - - - <html><head/><body><p>Remplacer les correspondances cochées</p></body></html> - - - Tout remplacer - - - - - - - true - - - true - - - true - - - false - - - - 1 - - - - - - - - avancé - - - - - - - true - - + diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 04a52223f..d9278db8f 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -39,6 +39,7 @@ #include "qetgraphicstableitem.h" #include "bomexportdialog.h" #include "nomenclaturemodel.h" +#include "QWidgetAnimation/qwidgetanimation.h" #include @@ -66,9 +67,17 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) : splitter_->setOrientation(Qt::Vertical); splitter_->addWidget(&m_workspace); splitter_->addWidget(&m_search_and_replace_widget); - m_search_and_replace_widget.setHidden(true); - m_search_and_replace_widget.setEditor(this); setCentralWidget(splitter_); + m_search_and_replace_widget.setEditor(this); + + QList s; + s << m_workspace.maximumHeight() << m_search_and_replace_widget.minimumSizeHint().height(); + splitter_->setSizes(s); //Force the size of the search and replace widget, force have a good animation the first time he is showed + + auto anim = new QWidgetAnimation(&m_search_and_replace_widget, Qt::Vertical, QWidgetAnimation::lastSize, 250); + anim->setObjectName("search and replace animator"); + m_search_and_replace_widget.setHidden(true); + anim->setLastShowSize(m_search_and_replace_widget.minimumSizeHint().height()); //Set object name to be retrieved by the stylesheets m_workspace.setBackground(QBrush(Qt::NoBrush)); @@ -654,8 +663,13 @@ void QETDiagramEditor::setUpActions() m_find = new QAction(tr("Chercher/remplacer"), this); m_find->setShortcut(QKeySequence::Find); - connect(m_find, &QAction::triggered, [this]() { - this->m_search_and_replace_widget.setHidden(!m_search_and_replace_widget.isHidden()); + connect(m_find, &QAction::triggered, [this]() + { + if (auto animator = m_search_and_replace_widget.findChild("search and replace animator")) { + animator->setHidden(!m_search_and_replace_widget.isHidden()); + } else { + this->m_search_and_replace_widget.setHidden(!m_search_and_replace_widget.isHidden()); + } }); }