From 97e9c61ece5f5f1b53f9ce166922e28443cc1d1e Mon Sep 17 00:00:00 2001 From: Mathias Paulin <mathias.paulin@irit.fr> Date: Sat, 3 Apr 2021 10:03:35 +0200 Subject: [PATCH] Update interface to enable Radium Gizmos --- src/Mara/Gui/Icons/gizmo.png | Bin 0 -> 1844 bytes src/Mara/Gui/Icons/rotate.png | Bin 0 -> 2171 bytes src/Mara/Gui/Icons/scale.png | Bin 0 -> 1077 bytes src/Mara/Gui/Icons/select.png | Bin 0 -> 956 bytes src/Mara/Gui/Icons/translate.png | Bin 0 -> 1644 bytes src/Mara/Gui/MainWindow.cpp | 176 ++++++++++++++++++++++++++++--- src/Mara/Gui/MainWindow.hpp | 24 +++++ src/Mara/Gui/MaraResources.qrc | 5 + src/Mara/Gui/ui/MainWindow.ui | 54 +++++++--- 9 files changed, 229 insertions(+), 30 deletions(-) create mode 100644 src/Mara/Gui/Icons/gizmo.png create mode 100644 src/Mara/Gui/Icons/rotate.png create mode 100644 src/Mara/Gui/Icons/scale.png create mode 100644 src/Mara/Gui/Icons/select.png create mode 100644 src/Mara/Gui/Icons/translate.png diff --git a/src/Mara/Gui/Icons/gizmo.png b/src/Mara/Gui/Icons/gizmo.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce5f231b2ca453988e3e6e4f85efd581f319461 GIT binary patch literal 1844 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 F2>?1WA_D*b literal 0 HcmV?d00001 diff --git a/src/Mara/Gui/Icons/rotate.png b/src/Mara/Gui/Icons/rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..524b79ee23813fea2c545513aa151e73057f1684 GIT binary patch literal 2171 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 T@;zM!1_lOCS3j3^P6<r_fb7$d literal 0 HcmV?d00001 diff --git a/src/Mara/Gui/Icons/scale.png b/src/Mara/Gui/Icons/scale.png new file mode 100644 index 0000000000000000000000000000000000000000..68a9165691c655b0af5b0a5d5a973382b1c5a1b1 GIT binary patch literal 1077 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I0X7B(2IW`Fwlgp=u%tWsIx;Y9?C1WI$O@87 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#JAXlDyqr{(}K$ z#P>T43=EtF9+AZi3=C0VT%f$8mVtqRy~NYkmHj>sCzq6nfeP<J1_q{Go-U3d8TXz> z`W9_+5U6dI4|URdbZqa=CUFDy4_eRME?P^3f8-MkUMl_VU#`wlu1Jf^_nUlNN|Zhc zdt92mvT@<_udmH*c?^`4l>S6s?qUnr^4I&<gS5>zbIe>Gf2{cPjZKEH{qREu4_8h- zi_YZv9UcM-9&<GOI22nf-nY-U&SdS}5YM3S(!6ORhk@_qJ-eB$=K3wa%xL0!*`(Ld zQf(vCw9`+EcCw^hzFA^s%X&oOfXT8(#)O0)Gx``4dJHXVMGQL=EIbP5Gu6*;WL6M3 zz_kBi;k$Epcj_5P^}4NJ-|+tTzW3=X8Zr*NE!+L~2S>>2t65vCSc0eA+?IRW?BbK! zPj)j`9ACPQG3Zw6<`<Vv_A)p&9m?L3GtHiHqEeXI>E4DNLfU3O6dZSIE;z$-#C56{ z<ALKs4_w=;d9(RgJcMID7+r73{<b>XK_dMb%aOSY-h5lV{h$SxZM7&LlTwt9SohIK zlP({4n78}(yKN1LQp*yVKL4z-o6o#!-RoU`C7DT_8hk(87GKOTX*%4K`RsdEty_bQ z2@hNI!32gk-+%9YF6&=?aa!>?OZKY0aqoXd*2aHZn)IYJbpP$QW%K7Xgn_&>DaHP& z*$K<%(-~GbxHJ1n?Rb-(+S#q}d`>*m3Z`|t{{5_daO_|C%t;K2Egb2e!ju-}-Z`*X z-ij;KVb+=Zx5T#2ty{^k=>7Sc9lBE(lopxH^cSws%sQ}j)%?&0uD7RqE1Wi6r?hGd zR{-OA?@vorA4EN?pY>$%vOhX?x}QDc3m&E2D~-Kg`t*PM?UkQx&VSy+!+9cm?dmCp zGJNg&`VRZ=zyDr!{B_|}mE)1qQX@?l1g#9wn)<m==as<;lZlTl`W~-PpVk$z{@UuV zuf9a+{J*i}=K0rOtL|=MIBdXk*yG*uu+>-Jy>Cq0e6yy)!aj7<j-G#EzdzTv|7Ygk zo|pYcmRp>GfkCyzHKHUXu_V<hxhOTUB$dI)z|d6J&`8(7GQ`lp%Fxov#8lhB(8|ET znCXNPiiX_$l+3hB+!~zX3+6E}FvNjuC@xF4N=htF)h#W`WJt@*Nww0~*H5lYPbtbQ zOVuya4=qkDD%SVOFHOzU4=BpdN=+^))=$qY(GN;Y$t=y)b<Io9%uCgGEG|whDc1MQ jO-xTM)-O&@%t_TNE=v~-xfQ{{z`)??>gTe~DWM4fPCLf? literal 0 HcmV?d00001 diff --git a/src/Mara/Gui/Icons/select.png b/src/Mara/Gui/Icons/select.png new file mode 100644 index 0000000000000000000000000000000000000000..fcb01d78412bcfd0b631fbc9167565fcfe44bd48 GIT binary patch literal 956 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I0X7B(2IW`Fwlgp=u%tWsIx;Y9?C1WI$O@87 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#JAXlDyqr{(}K$ z#P>T43=EtF9+AZi3=C0VT%f$8mVtqRy~NYkmHj>sCzq6nfeP<J1_mYvPZ!6KjC*fq zobQ|EAai_wLagl$b>T7tZk~xxH~o;|?yP>`mLk9IE9V!}3a0-mi`c8%m76xRTQ4n4 z-o5Sa8Iz~QKkq*I{r8N8bAUv0kKv!~D;6<#EE80)YRHgcB!=lG#TYp)HS$=*Bo)s| z2HS4GE!!=d92y!L`nB->8j(o5PTBtBk3XKcQDQZ>?kCTi@4x^4)4uTfYt{Dc2j-S7 z&y;c~S@hb<L38O8re&G4mT|6FwQAL>MKQnc_%G@%u3+@NY~q`ov-xI@ndXG&mGhn- zDBFE^nPz~9YoG{2{EkMu3+z@7xmm%p4Nq^<@nSq)D07^VL$O7`;b+?xCW{t<Mf|T8 z)yVO+AAZO%B{gzds%`k|t5sXs#7-YA+W5qp^TnN#JS*7;7puS6@N*nC;Bh|IcKBg| z#Tr+SVzvUE)0=d-Gqy&p4O^{O=gFX7V|RMhno~j&mCE@~7@r?qDth7l_uqf_Es|(U zobl}Tp_+Mo$9Eb0_uc{u0p25pGRF-+JhA`j|L^H$M=M5|!v;OSe}5N$Zmrh$_{US$ z54HFCo8slWg1CPavd0A9`F_7%+C%$5Y3%jV#>;C1#GidG$!3^*GDYb4o*!S&PYiR| z4l=gukwxF<4*~0K_Mcg#(Y1(!qe+3I>GbtG_Sy}}x3~Gey#46$$BI9H{`@|=zj)u) zl-ZfHmSvv0QDZj$Y<kZ}^JDwJ{=T$_>wit-tCspbkJ3H#A1tn9{hqJZ(s6>bfq{WR zwZt`|BqgyV)hf9tHL)a>!N|bSRM*f**T6Ew(7?*j(#phC+rZGuz`&U4gc6E|-29Zx zv`X9>oZ<`SF)%R1gKQ`+OSei&EKb!eEy`p_%gjl&(%08du1rrU$}CIOFVhb#PAw|d z_sK6!&C?Gk%FjwoE-BVe&n(doN=(Tt&DC|yOV7+p)psl|PAw_c_smU9Pc7CjPR&V8 aF3~G4OTSpVSCD~$fx*+&&t;ucLK6Vd{fsvN literal 0 HcmV?d00001 diff --git a/src/Mara/Gui/Icons/translate.png b/src/Mara/Gui/Icons/translate.png new file mode 100644 index 0000000000000000000000000000000000000000..9c52302bb31fbe4b7abdd068e90663040c426558 GIT binary patch literal 1644 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 literal 0 HcmV?d00001 diff --git a/src/Mara/Gui/MainWindow.cpp b/src/Mara/Gui/MainWindow.cpp index 630690b..cafa1e2 100644 --- a/src/Mara/Gui/MainWindow.cpp +++ b/src/Mara/Gui/MainWindow.cpp @@ -6,10 +6,11 @@ #include <QColorDialog> #include <QFileDialog> #include <QMessageBox> +#include <QToolBar> #include <Gui/SelectionManager/SelectionManager.hpp> -#include <Gui/TreeModel/EntityTreeModel.hpp> #include <Gui/Viewer/CameraManipulator.hpp> +#include <Gui/Viewer/Gizmo/GizmoManager.hpp> #include <Gui/Viewer/Viewer.hpp> #include <PluginBase/RadiumPluginInterface.hpp> @@ -41,7 +42,10 @@ MainWindow::MainWindow( QWidget* parent ) : MainWindowInterface( parent ) { // Initialize the scene interactive representation m_sceneModel = new ItemModel( Ra::Engine::RadiumEngine::getInstance(), this ); m_selectionManager = new SelectionManager( m_sceneModel, this ); - + connect( m_selectionManager, + &Ra::Gui::SelectionManager::selectionChanged, + this, + &MainWindow::onSelectionChanged ); // initialize Gui for the application auto viewerwidget = QWidget::createWindowContainer( m_viewer.get() ); viewerwidget->setAutoFillBackground( false ); @@ -71,7 +75,124 @@ void MainWindow::cleanup() { m_viewer.reset( nullptr ); } +void MainWindow::addSelectionToolBar() { + auto selectionToolBar = new QToolBar( "Selection toolbar", this ); + + auto actionGizmoOff = new QAction( selectionToolBar ); + actionGizmoOff->setObjectName( QString::fromUtf8( "actionGizmoOff" ) ); + actionGizmoOff->setCheckable( false ); + actionGizmoOff->setChecked( false ); + QIcon icon3; + icon3.addFile( + QString::fromUtf8( ":/Resources/Icons/select.png" ), QSize(), QIcon::Normal, QIcon::On ); + actionGizmoOff->setIcon( icon3 ); + actionGizmoOff->setText( QCoreApplication::translate( "MainWindow", "No Gizmos", nullptr ) ); + actionGizmoOff->setToolTip( + QCoreApplication::translate( "MainWindow", "Disable transform gizmo.", nullptr ) ); + + auto actionGizmoTranslate = new QAction( selectionToolBar ); + actionGizmoTranslate->setObjectName( QString::fromUtf8( "actionGizmoTranslate" ) ); + actionGizmoTranslate->setCheckable( false ); + QIcon icon; + icon.addFile( + QString::fromUtf8( ":/Resources/Icons/translate.png" ), QSize(), QIcon::Normal, QIcon::On ); + actionGizmoTranslate->setIcon( icon ); + actionGizmoTranslate->setText( + QCoreApplication::translate( "MainWindow", "Translate", nullptr ) ); + actionGizmoTranslate->setToolTip( + QCoreApplication::translate( "MainWindow", "Translate selected object", nullptr ) ); + + auto actionGizmoRotate = new QAction( selectionToolBar ); + actionGizmoRotate->setObjectName( QString::fromUtf8( "actionGizmoRotate" ) ); + actionGizmoRotate->setCheckable( false ); + QIcon icon1; + icon1.addFile( + QString::fromUtf8( ":/Resources/Icons/rotate.png" ), QSize(), QIcon::Normal, QIcon::On ); + actionGizmoRotate->setIcon( icon1 ); + actionGizmoRotate->setText( QCoreApplication::translate( "MainWindow", "Rotate", nullptr ) ); + actionGizmoRotate->setToolTip( + QCoreApplication::translate( "MainWindow", "Rotate selected object", nullptr ) ); + + auto actionToggle_Local_Global = new QAction( selectionToolBar ); + actionToggle_Local_Global->setObjectName( QString::fromUtf8( "actionToggle_Local_Global" ) ); + actionToggle_Local_Global->setCheckable( true ); + QIcon icon2; + icon2.addFile( + QString::fromUtf8( ":/Resources/Icons/gizmo.png" ), QSize(), QIcon::Normal, QIcon::On ); + actionToggle_Local_Global->setIcon( icon2 ); + actionToggle_Local_Global->setText( + QCoreApplication::translate( "MainWindow", "Toggle Local/Global", nullptr ) ); + actionToggle_Local_Global->setToolTip( QCoreApplication::translate( + "MainWindow", "Changes the transform edition mode", nullptr ) ); + + auto actionGizmoScale = new QAction( selectionToolBar ); + actionGizmoScale->setObjectName( QString::fromUtf8( "actionGizmoScale" ) ); + actionGizmoScale->setCheckable( false ); + QIcon icon5; + icon5.addFile( + QString::fromUtf8( ":/Resources/Icons/scale.png" ), QSize(), QIcon::Normal, QIcon::Off ); + actionGizmoScale->setIcon( icon5 ); + actionGizmoScale->setText( QCoreApplication::translate( "MainWindow", "Scale", nullptr ) ); + actionGizmoScale->setToolTip( + QCoreApplication::translate( "MainWindow", "Scale selected object", nullptr ) ); + + selectionToolBar->addAction( actionToggle_Local_Global ); + selectionToolBar->addAction( actionGizmoTranslate ); + selectionToolBar->addAction( actionGizmoRotate ); + selectionToolBar->addAction( actionGizmoScale ); + selectionToolBar->addAction( actionGizmoOff ); + + connect( + this, &MainWindow::selectedItem, m_viewer->getGizmoManager(), &GizmoManager::setEditable ); + connect( actionGizmoOff, &QAction::triggered, this, &MainWindow::gizmoShowNone ); + connect( actionGizmoTranslate, &QAction::triggered, this, &MainWindow::gizmoShowTranslate ); + connect( actionGizmoRotate, &QAction::triggered, this, &MainWindow::gizmoShowRotate ); + connect( actionGizmoScale, &QAction::triggered, this, &MainWindow::gizmoShowScale ); + connect( actionToggle_Local_Global, + &QAction::toggled, + m_viewer->getGizmoManager(), + &GizmoManager::setLocal ); + connect( actionToggle_Local_Global, &QAction::toggled, this, &MainWindow::frameUpdate ); + + this->addToolBar( selectionToolBar ); + + auto showSelectionToolbar = new QAction( this ); + showSelectionToolbar->setObjectName( QString::fromUtf8( "showSelectionToolbar" ) ); + showSelectionToolbar->setCheckable( true ); + showSelectionToolbar->setChecked( true ); + showSelectionToolbar->setText( + QCoreApplication::translate( "MainWindow", "Selection toolbar", nullptr ) ); + showSelectionToolbar->setToolTip( + QCoreApplication::translate( "MainWindow", "Show/hide the selection toolbar", nullptr ) ); + + connect( showSelectionToolbar, &QAction::triggered, selectionToolBar, &QToolBar::setVisible ); + connect( selectionToolBar, &QToolBar::visibilityChanged, [showSelectionToolbar]( bool b ) { + showSelectionToolbar->setChecked( b ); + } ); + + menuToolbars->addAction( showSelectionToolbar ); +} + +void MainWindow::postOpenGLInitializations() { + addSelectionToolBar(); +} + void MainWindow::createConnections() { + // Radium engine and Gui initialization process + connect( m_viewer.get(), &Viewer::glInitialized, this, &MainWindow::postOpenGLInitializations ); + + // Define and connect Engine callbacks + auto add = std::bind( &MainWindow::ItemAdded, this, std::placeholders::_1 ); + auto del = std::bind( &MainWindow::ItemRemoved, this, std::placeholders::_1 ); + // Connect engine signals to the appropriate callbacks + auto theEngine = Ra::Engine::RadiumEngine::getInstance(); + theEngine->getSignalManager()->m_entityCreatedCallbacks.push_back( add ); + theEngine->getSignalManager()->m_entityDestroyedCallbacks.push_back( del ); + theEngine->getSignalManager()->m_componentAddedCallbacks.push_back( add ); + theEngine->getSignalManager()->m_componentRemovedCallbacks.push_back( del ); + theEngine->getSignalManager()->m_roAddedCallbacks.push_back( add ); + theEngine->getSignalManager()->m_roRemovedCallbacks.push_back( del ); + // Qt Gui callbacks connect( action_Load, &QAction::triggered, this, &MainWindow::loadFile ); connect( actionInfo, &QAction::triggered, this, &MainWindow::displayFileInfo ); @@ -88,18 +209,6 @@ void MainWindow::createConnections() { connect( actionTree_view, &QAction::triggered, this, &MainWindow::displayTreeView ); #endif - // Define and connect Engine callbacks - auto add = std::bind( &MainWindow::ItemAdded, this, std::placeholders::_1 ); - auto del = std::bind( &MainWindow::ItemRemoved, this, std::placeholders::_1 ); - // Connect engine signals to the appropriate callbacks - auto theEngine = Ra::Engine::RadiumEngine::getInstance(); - theEngine->getSignalManager()->m_entityCreatedCallbacks.push_back( add ); - theEngine->getSignalManager()->m_entityDestroyedCallbacks.push_back( del ); - theEngine->getSignalManager()->m_componentAddedCallbacks.push_back( add ); - theEngine->getSignalManager()->m_componentRemovedCallbacks.push_back( del ); - theEngine->getSignalManager()->m_roAddedCallbacks.push_back( add ); - theEngine->getSignalManager()->m_roRemovedCallbacks.push_back( del ); - // TODO : connect callbacks roAdded and roRemoved to the renderer and add observable on // RenderObject to manage more efficiently update for rendering connect( m_sceneModel, &ItemModel::visibilityROChanged, this, &MainWindow::setROVisible ); @@ -293,4 +402,43 @@ void MainWindow::on_actionStep_triggered() { Ra::Engine::RadiumEngine::getInstance()->step(); emit frameUpdate(); } + +void MainWindow::gizmoShowNone() { + m_viewer->getGizmoManager()->changeGizmoType( GizmoManager::NONE ); + emit frameUpdate(); +} + +void MainWindow::gizmoShowTranslate() { + m_viewer->getGizmoManager()->changeGizmoType( GizmoManager::TRANSLATION ); + emit frameUpdate(); +} + +void MainWindow::gizmoShowRotate() { + m_viewer->getGizmoManager()->changeGizmoType( GizmoManager::ROTATION ); + emit frameUpdate(); +} + +void MainWindow::gizmoShowScale() { + m_viewer->getGizmoManager()->changeGizmoType( GizmoManager::SCALE ); + emit frameUpdate(); +} + +void MainWindow::onSelectionChanged( const QItemSelection& /*selected*/, + const QItemSelection& /*deselected*/ ) { + std::cerr << "******************* MainWindow::onSelectionChanged " << std::endl; + if ( m_selectionManager->hasSelection() ) + { + const ItemEntry& ent = m_selectionManager->currentItem(); + std::cerr << "******************* MainWindow::onSelectionChanged emit selected item " + << std::endl; + emit selectedItem( ent ); + /* + * @todo : complete this method to handle how events due to election changes + * cf RadiumSandBox/Mainwindow + */ + } + else + { emit selectedItem( ItemEntry() ); } +} + } // namespace Mara diff --git a/src/Mara/Gui/MainWindow.hpp b/src/Mara/Gui/MainWindow.hpp index 276dbfd..ad25425 100644 --- a/src/Mara/Gui/MainWindow.hpp +++ b/src/Mara/Gui/MainWindow.hpp @@ -81,6 +81,9 @@ class MainWindow : public Ra::Gui::MainWindowInterface, private Ui::MainWindow void timeFlow( bool state ); + /// Emitted when a new item is selected. An invalid entry is sent when no item is selected. + void selectedItem( const Ra::Engine::Scene::ItemEntry& entry ); + public slots: /// Called when a scene is ready to display to parameterize the application window and the /// viewer. @@ -133,7 +136,28 @@ class MainWindow : public Ra::Gui::MainWindowInterface, private Ui::MainWindow /// Slot for the user requesting to reset time. void on_actionStop_triggered(); + /// Show/hide gizmos when selected an object + void gizmoShowNone(); + + /// Display translation gizmo + void gizmoShowTranslate(); + + /// Display rotation gizmo + void gizmoShowRotate(); + + /// Display scaling gizmo + void gizmoShowScale(); + + /// React to a selection in the selection manager + void onSelectionChanged( const QItemSelection& selected, const QItemSelection& deselected ); + + /// Slot to init renderers once gl is ready + void postOpenGLInitializations(); + private: + /// add the selection toolbar + void addSelectionToolBar(); + /// create the UI connections void createConnections(); diff --git a/src/Mara/Gui/MaraResources.qrc b/src/Mara/Gui/MaraResources.qrc index 78012a0..bd8f863 100644 --- a/src/Mara/Gui/MaraResources.qrc +++ b/src/Mara/Gui/MaraResources.qrc @@ -8,5 +8,10 @@ <file>Icons/step_on.png</file> <file>Icons/stop_off.png</file> <file>Icons/stop_on.png</file> + <file>Icons/gizmo.png</file> + <file>Icons/rotate.png</file> + <file>Icons/scale.png</file> + <file>Icons/select.png</file> + <file>Icons/translate.png</file> </qresource> </RCC> diff --git a/src/Mara/Gui/ui/MainWindow.ui b/src/Mara/Gui/ui/MainWindow.ui index 12c90b9..003ad74 100644 --- a/src/Mara/Gui/ui/MainWindow.ui +++ b/src/Mara/Gui/ui/MainWindow.ui @@ -50,25 +50,31 @@ <property name="title"> <string>Control</string> </property> - <addaction name="actionShow_toolbar"/> <addaction name="separator"/> <addaction name="actionInfo"/> <addaction name="separator"/> </widget> + <widget class="QMenu" name="menuToolbars"> + <property name="title"> + <string>Toolbars</string> + </property> + <addaction name="showAnimationToolbar"/> + </widget> + <addaction name="menuRadium"/> <addaction name="menu_File"/> <addaction name="menuControl"/> - <addaction name="menuRadium"/> + <addaction name="menuToolbars"/> </widget> <widget class="QStatusBar" name="statusbar"/> - <widget class="QToolBar" name="toolBar"> + <widget class="QToolBar" name="AnimationToolbar"> <property name="enabled"> <bool>true</bool> </property> <property name="windowTitle"> - <string>toolBar</string> + <string>Animation toolbar</string> </property> <property name="movable"> - <bool>false</bool> + <bool>true</bool> </property> <property name="iconSize"> <size> @@ -110,6 +116,9 @@ <property name="text"> <string>&Reload shaders</string> </property> + <property name="shortcut"> + <string>Ctrl+Alt+R</string> + </property> </action> <action name="actionTree_view"> <property name="text"> @@ -149,8 +158,7 @@ <normaloff>:/Resources/Icons/play_on.png</normaloff> <normalon>:/Resources/Icons/pause_on.png</normalon> <activeoff>:/Resources/Icons/play_on.png</activeoff> - <activeon>:/Resources/Icons/pause_on.png</activeon>:/Resources/Icons/play_on.png - </iconset> + <activeon>:/Resources/Icons/pause_on.png</activeon>:/Resources/Icons/play_on.png</iconset> </property> <property name="text"> <string>play</string> @@ -168,8 +176,7 @@ <normaloff>:/Resources/Icons/stop_on.png</normaloff> <normalon>:/Resources/Icons/stop_on.png</normalon> <activeoff>:/Resources/Icons/stop_on.png</activeoff> - <activeon>:/Resources/Icons/stop_on.png</activeon>:/Resources/Icons/stop_on.png - </iconset> + <activeon>:/Resources/Icons/stop_on.png</activeon>:/Resources/Icons/stop_on.png</iconset> </property> <property name="text"> <string>stop</string> @@ -189,8 +196,7 @@ <iconset resource="../MaraResources.qrc"> <normaloff>:/Resources/Icons/step_on.png</normaloff> <normalon>:/Resources/Icons/step_on.png</normalon> - <activeoff>:/Resources/Icons/step_on.png</activeoff>:/Resources/Icons/step_on.png - </iconset> + <activeoff>:/Resources/Icons/step_on.png</activeoff>:/Resources/Icons/step_on.png</iconset> </property> <property name="text"> <string>step</string> @@ -202,7 +208,7 @@ <string>Meta+Space</string> </property> </action> - <action name="actionShow_toolbar"> + <action name="showAnimationToolbar"> <property name="checkable"> <bool>true</bool> </property> @@ -210,10 +216,10 @@ <bool>true</bool> </property> <property name="text"> - <string>Show toolbar</string> + <string>Animation toolbar</string> </property> <property name="toolTip"> - <string>Show/hide the toolbar</string> + <string>Show/hide the animation toolbar</string> </property> </action> </widget> @@ -222,9 +228,9 @@ </resources> <connections> <connection> - <sender>actionShow_toolbar</sender> + <sender>showAnimationToolbar</sender> <signal>triggered(bool)</signal> - <receiver>toolBar</receiver> + <receiver>AnimationToolbar</receiver> <slot>setVisible(bool)</slot> <hints> <hint type="sourcelabel"> @@ -237,5 +243,21 @@ </hint> </hints> </connection> + <connection> + <sender>AnimationToolbar</sender> + <signal>visibilityChanged(bool)</signal> + <receiver>showAnimationToolbar</receiver> + <slot>setChecked(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>399</x> + <y>39</y> + </hint> + <hint type="destinationlabel"> + <x>-1</x> + <y>-1</y> + </hint> + </hints> + </connection> </connections> </ui> -- GitLab