diff --git a/src/plugins/world_control/WorldControl.cc b/src/plugins/world_control/WorldControl.cc index f09c5ba60..4568ce2a1 100644 --- a/src/plugins/world_control/WorldControl.cc +++ b/src/plugins/world_control/WorldControl.cc @@ -311,6 +311,18 @@ void WorldControl::OnPause() this->dataPtr->SendEventMsg(msg); } +///////////////////////////////////////////////// +void WorldControl::OnReset() +{ + msgs::WorldControl msg; + auto msgReset = new msgs::WorldReset(); + msgReset->set_all(true); + msg.set_pause(true); + msg.set_allocated_reset(msgReset); + + this->dataPtr->SendEventMsg(msg); +} + ///////////////////////////////////////////////// void WorldControl::OnStepCount(const unsigned int _steps) { diff --git a/src/plugins/world_control/WorldControl.hh b/src/plugins/world_control/WorldControl.hh index e93e8806b..3b6fa11a3 100644 --- a/src/plugins/world_control/WorldControl.hh +++ b/src/plugins/world_control/WorldControl.hh @@ -82,6 +82,9 @@ namespace plugins /// \brief Callback in Qt thread when pause button is clicked. public slots: void OnPause(); + /// \brief Callback in Qt thread when reset button is clicked. + public slots: void OnReset(); + /// \brief Callback in Qt thread when step button is clicked. public slots: void OnStep(); @@ -95,6 +98,9 @@ namespace plugins /// \brief Notify that it's now paused. signals: void paused(); + /// \brief Notify that it's now resetted. + signals: void reset(); + /// \brief Subscriber callback when new world statistics are received private: void OnWorldStatsMsg(const gz::msgs::WorldStatistics &_msg); diff --git a/src/plugins/world_control/WorldControl.qml b/src/plugins/world_control/WorldControl.qml index b66864064..9fa39f1aa 100644 --- a/src/plugins/world_control/WorldControl.qml +++ b/src/plugins/world_control/WorldControl.qml @@ -15,7 +15,7 @@ * */ import QtQuick 2.9 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.5 import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.3 import "qrc:/qml" @@ -24,7 +24,7 @@ RowLayout { id: worldControl width: 200 spacing: 2 - Layout.minimumWidth: 121 + Layout.minimumWidth: 100 Layout.minimumHeight: 100 Connections { @@ -52,6 +52,11 @@ RowLayout { */ property bool showPlay: false + /** + * True to show reset button + */ + property bool showReset: true + /** * True to show step buttons */ @@ -67,6 +72,11 @@ RowLayout { */ property string playIcon: "\u25B6" + /** + * Reset button + */ + property string resetIcon: "\u21bb" + /** * Pause icon */ @@ -92,7 +102,6 @@ RowLayout { text: paused ? playIcon : pauseIcon checkable: true Layout.alignment : Qt.AlignVCenter - Layout.minimumWidth: width Layout.leftMargin: 10 onClicked: { if (paused) @@ -100,7 +109,71 @@ RowLayout { else WorldControl.OnPause() } + ToolTip.visible: hovered + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: paused ? qsTr("Run the simulation") : qsTr("Pause the simulation") + Material.background: Material.primary + } + + /** + * Reset + */ + RoundButton { + id: resetButton + objectName: "resetButton" + visible: showReset + text: resetIcon + checkable: true + implicitHeight: stepButton.height + implicitWidth: stepButton.width + onClicked: { + confirmationDialogOnReset.open() + } Material.background: Material.primary + ToolTip.visible: hovered + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: qsTr("Reset the simulation") + } + + Shortcut { + sequence: "Ctrl+R" + onActivated: confirmationDialogOnReset.open() + } + + /** + * Confirmation dialog on close button + */ + Dialog { + id: confirmationDialogOnReset + title: "Do you really want to reset the simulation?" + objectName: "confirmationDialogOnReset" + + modal: true + focus: true + parent: ApplicationWindow.overlay + width: 500 + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + closePolicy: Popup.CloseOnEscape + standardButtons: Dialog.Ok | Dialog.Discard + + onAboutToShow: function () { + footer.standardButton(Dialog.Discard).text = "Abort" + footer.standardButton(Dialog.Ok).text = "Reset" + } + + footer: + DialogButtonBox + { + onClicked: function (btn) + { + confirmationDialogOnReset.close() + if (btn == this.standardButton(Dialog.Ok)) + { + WorldControl.OnReset() + } + } + } } /** @@ -112,7 +185,6 @@ RowLayout { Layout.fillWidth: true onEntered: { - var minX = 0; var maxX = worldControl.parent.card().parent.width - stepPopup.width * 0.5; diff --git a/src/plugins/world_control/WorldControlEventListener.cc b/src/plugins/world_control/WorldControlEventListener.cc index 3c728da0b..c091122f5 100644 --- a/src/plugins/world_control/WorldControlEventListener.cc +++ b/src/plugins/world_control/WorldControlEventListener.cc @@ -38,6 +38,8 @@ bool WorldControlEventListener::eventFilter(QObject *_obj, QEvent *_event) { this->listenedToPlay = !worldControlEvent->WorldControlInfo().pause(); this->listenedToPause = worldControlEvent->WorldControlInfo().pause(); + this->listenedToReset = + worldControlEvent->WorldControlInfo().reset().all(); this->listenedToStep = worldControlEvent->WorldControlInfo().multi_step() > 0u; } diff --git a/src/plugins/world_control/WorldControlEventListener.hh b/src/plugins/world_control/WorldControlEventListener.hh index 8f288c089..00719b94d 100644 --- a/src/plugins/world_control/WorldControlEventListener.hh +++ b/src/plugins/world_control/WorldControlEventListener.hh @@ -49,8 +49,11 @@ namespace gui /// \brief Whether a pause event has been received (true) or not (false) public: bool listenedToPause{false}; - /// \brief Whether a pause event has been received (true) or not (false) + /// \brief Whether a step event has been received (true) or not (false) public: bool listenedToStep{false}; + + /// \brief Whether a reset event has been received (true) or not (false) + public: bool listenedToReset{false}; }; } }