Skip to content
Snippets Groups Projects
MainWindow.hpp 5.69 KiB
#pragma once

#include <Gui/RaGui.hpp>

#include <Gui/MainWindowInterface.hpp>
#include <Gui/TreeModel/EntityTreeModel.hpp>

#ifdef SHOWTREEVIEW
#    include <QTreeView>
#endif

#include "ui_MainWindow.h"
#include <Gui/ControlDialogWindow.hpp>
#include <Gui/RendererControl.hpp>

#include <QKeySequence>

namespace Ra::Engine::Scene {
class Camera;
}
namespace Mara {
class MainWindow : public Ra::Gui::MainWindowInterface, private Ui::MainWindow
{
    Q_OBJECT

  public:
    /** Constructors and destructor.
     *  https://en.cppreference.com/w/cpp/language/rule_of_three
     */
    /** @{ */
    explicit MainWindow( QWidget* parent = nullptr );
    MainWindow( const MainWindow& ) = delete;
    MainWindow& operator=( const MainWindow& ) = delete;
    MainWindow( MainWindow&& )                 = delete;
    MainWindow& operator=( MainWindow&& ) = delete;
    ~MainWindow() override;
    /**@}*/

    /// Access the viewer, i.e. the rendering widget.
    Ra::Gui::Viewer* getViewer() override;

    /// Access the selection manager.
    Ra::Gui::SelectionManager* getSelectionManager() override;

    /// Access the timeline.
    Ra::Gui::Timeline* getTimeline() override;

    /// Update the ui from the plugins loaded.
    void updateUi( Ra::Plugins::RadiumPluginInterface* plugin ) override;

    /// Update the UI ( most importantly gizmos ) to the modifications of the
    /// engine/
    void onFrameComplete() override;

    /// Add render in the application: UI, viewer - this method does not associate a control panel.
    void addRenderer( const std::string& name,
                      std::shared_ptr<Ra::Engine::Rendering::Renderer> e ) override;

    /// Add render in the application: UI, viewer.
    void addRenderer( const std::string& name,
                      std::shared_ptr<Ra::Engine::Rendering::Renderer> e,
                      RadiumNBR::Gui::RendererPanel* controlPanel );

    /// Add a control to the application. This is defined a menu entry and an interaction panel
    void addControl( const QString& tabName, const QKeySequence& shortcut );

  signals:
    /// Emitted when the frame loads
    void fileLoading( const QString& path );
    /// Emitted when frame must be updated
    void frameUpdate();

    /// Emitted to add plugins dir
    void addPluginsDir();

    /// Emitted to clear plugins locations
    void clearPluginsDir();

    void roChanged( Ra::Core::Utils::Index roIndex, bool visible );

    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.
    void prepareDisplay() override;
    /// Cleanup resources.
    void cleanup() override;

    /// Display some informations about the loaded scene
    /// @todo extend the signature to include geometry statistics
    void displayFileInfo();

    /// Fit the camera so that the bounding box of the scene is included in the camera frustum
    void fitCamera();

    /// Slot to reset Camera to its original position (the one at scene loading)
    void resetCamera();

    /**
     *     Configure the application.
     *     @todo, implement a QSetting editor
     */
    void configure();

#ifdef SHOWTREEVIEW
    /// Display the scene tree
    void displayTreeView();
#endif
    /** @{ */
    /** Callback to rebuild the item model when the engine objects change.
     *  https://en.cppreference.com/w/cpp/language/rule_of_three
     *  @{
     */
    void ItemAdded( const Ra::Engine::Scene::ItemEntry& ent );
    void ItemRemoved( const Ra::Engine::Scene::ItemEntry& ent );
    /**@}*/
  private slots:

    /// Slot for the "load file" menu.
    void loadFile();

    /// Slot for the tree view checkboxes
    void setROVisible( Ra::Core::Utils::Index roIndex, bool visible );

    /// Slot for the user requesting to play/pause time through the time actions.
    void on_actionPlay_triggered( bool checked );

    /// Slot for the user requesting to step time.
    void on_actionStep_triggered();

    /// 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();

    /// After loading a file, set the first camera loaded (if any) as the active camera.
    /// if multiple files are loaded, use the first camera of the first loaded file
    void activateCamera( const std::string& sceneName );

    /// viewer widget
    std::unique_ptr<Ra::Gui::Viewer> m_viewer;

    /// Control dialog
    ControlDialogWindow* m_controlWindow;

    /// renderer control
    RendererControl* m_rendererControler;

    /// Stores and manages the current selection.
    /// Even if no selection is provided by this application, used plugins require this
    Ra::Gui::SelectionManager* m_selectionManager;

    /// Stores the internal model of engine objects for selection and visibility.
    Ra::Gui::ItemModel* m_sceneModel;

#ifdef SHOWTREEVIEW
    /// QTreeview of the scene
    QTreeView* m_sceneTreeView;
#endif
    Ra::Engine::Scene::Camera* m_initialCamera{nullptr};
};
} // namespace Mara