Skip to content

Commit

Permalink
UI: Better way to connect widgets with App state
Browse files Browse the repository at this point in the history
  • Loading branch information
sguionni committed Oct 3, 2024
1 parent f67d1e9 commit 1cc8fd8
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 28 deletions.
25 changes: 23 additions & 2 deletions lib/app/include/app/action/controller.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __VTX_UI_ACTION_VISUALIZATION__
#define __VTX_UI_ACTION_VISUALIZATION__
#ifndef __VTX_UI_ACTION_CONTROLLER__
#define __VTX_UI_ACTION_CONTROLLER__

#include "app/core/controller/concepts.hpp"
#include <app/core/action/base_action.hpp>
Expand Down Expand Up @@ -35,5 +35,26 @@ namespace VTX::App::Action::Controller
ToggleCameraController() {}
void execute() override;
};

class SetCameraProjectionOrthographic final : public App::Core::Action::BaseAction
{
public:
SetCameraProjectionOrthographic() {}
void execute() override;
};

class SetCameraProjectionPerspective final : public App::Core::Action::BaseAction
{
public:
SetCameraProjectionPerspective() {}
void execute() override;
};

class ToggleCameraProjection final : public App::Core::Action::BaseAction
{
public:
ToggleCameraProjection() {}
void execute() override;
};
} // namespace VTX::App::Action::Controller
#endif
5 changes: 3 additions & 2 deletions lib/app/include/app/core/controller/controller_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

namespace VTX::App::Core::Controller
{

// TODO: use an unique camera controller?
// + aniamtion controller.
class ControllerSystem
{
public:
Expand All @@ -29,7 +30,7 @@ namespace VTX::App::Core::Controller
{ controller->update( p_delta, p_elapsed ); };

// Save callback id.
_activeCallbacks[ controller->getName() ] = id;
_activeCallbacks.emplace( controller->getName(), id );

// Set controller active.
controller->setActive( true );
Expand Down
20 changes: 18 additions & 2 deletions lib/app/include/app/ui/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,34 @@ namespace VTX::App::UI
{
using WidgetId = std::string;

/**
* @brief Desribes an UI action that can be added to a menu or toolbar.
*/
struct DescAction
{
public:
std::string name;
std::optional<std::string> group = std::nullopt;
std::optional<std::string> tip = std::nullopt;
std::optional<std::string> icon = std::nullopt;
std::optional<std::string> shortcut;

using TriggerFunction = std::function<void()>;
std::optional<TriggerFunction> trigger = std::nullopt;
/**
* @brief Trigger function is called when button is clicked.
*/
using Callable = std::function<void()>;
std::optional<Callable> trigger = std::nullopt;

/**
* @brief Override this function to connect the action to the application callbacks.
* Used to update the UI when the application state changes, or set default values.
*/
virtual void connect() const {}
};

/**
* @brief Main window requirements.
*/
template<typename MW>
concept ConceptMainWindow = requires( MW p_mw, WidgetId p_id, DescAction p_action ) {
{ p_mw.prepare() } -> std::same_as<void>;
Expand Down
26 changes: 26 additions & 0 deletions lib/app/src/app/action/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,30 @@ namespace VTX::App::Action::Controller
}
}

void SetCameraProjectionOrthographic::execute()
{
auto & camera = SCENE().getCamera();
camera.setCameraProjection( Component::Render::Camera::PROJECTION::ORTHOGRAPHIC );
}

void SetCameraProjectionPerspective::execute()
{
auto & camera = SCENE().getCamera();
camera.setCameraProjection( Component::Render::Camera::PROJECTION::PERSPECTIVE );
}

void ToggleCameraProjection::execute()
{
using namespace Component::Render;
auto & camera = SCENE().getCamera();
if ( camera.getProjection() == Camera::PROJECTION::ORTHOGRAPHIC )
{
camera.setCameraProjection( Camera::PROJECTION::PERSPECTIVE );
}
else
{
camera.setCameraProjection( Camera::PROJECTION::ORTHOGRAPHIC );
}
}

} // namespace VTX::App::Action::Controller
8 changes: 2 additions & 6 deletions lib/app/src/app/component/render/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ namespace VTX::App::Component::Render
_far( Util::Math::max( _near, SETTINGS_SYSTEM().get<float>( Settings::Camera::FAR_CLIP_KEY ) ) ),
_fov( SETTINGS_SYSTEM().get<float>( Settings::Camera::FOV_KEY ) )
{
const PROJECTION & cameraProjection = SETTINGS_SYSTEM().get<PROJECTION>( Settings::Camera::PROJECTION_KEY );

_projection = cameraProjection;
}

void Camera::init()
Expand All @@ -27,11 +24,10 @@ namespace VTX::App::Component::Render
= MAIN_REGISTRY().getComponent<Component::Scene::Transform>( *this );

_transform = &transformComponent;

_transform->onTransform += [ this ]( const Util::Math::Transform & ) { _updateViewMatrix(); };

_updateViewMatrix();
_updateProjectionMatrix();
const PROJECTION & cameraProjection = SETTINGS_SYSTEM().get<PROJECTION>( Settings::Camera::PROJECTION_KEY );
setCameraProjection( cameraProjection );
}

void Camera::setScreenSize( const size_t p_width, const size_t p_height )
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/qt/include/ui/qt/actions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,25 @@ namespace VTX::UI::QT
struct Orthographic : public App::UI::DescAction
{
Orthographic();
void connect() const override;
};

struct Perspective : public App::UI::DescAction
{
Perspective();
void connect() const override;
};

struct Trackball : public App::UI::DescAction
{
Trackball();
void connect() const override;
};

struct Freefly : public App::UI::DescAction
{
Freefly();
void connect() const override;
};

struct Orient : public App::UI::DescAction
Expand Down
18 changes: 2 additions & 16 deletions lib/ui/qt/include/ui/qt/menu/camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,11 @@ namespace VTX::UI::QT::Menu
addAction<Action::Camera::Perspective>();
addAction<Action::Camera::Orthographic>();
addSeparator();
QAction * const trackball = addAction<Action::Camera::Trackball>();
QAction * const freeflly = addAction<Action::Camera::Freefly>();
addAction<Action::Camera::Trackball>();
addAction<Action::Camera::Freefly>();
addSeparator();
addAction<Action::Camera::Orient>();
addAction<Action::Camera::Reset>();

// TODO: where to do this?
using namespace App::Controller::Camera;
App::CONTROLLER_SYSTEM().onControllerEnabled += [ trackball, freeflly ]( const Name p_name )
{
if ( p_name == Trackball::NAME )
{
trackball->setChecked( true );
}
else if ( p_name == Freefly::NAME )
{
freeflly->setChecked( true );
}
};
}

virtual ~Camera() {}
Expand Down
86 changes: 86 additions & 0 deletions lib/ui/qt/src/ui/qt/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <app/action/application.hpp>
#include <app/action/controller.hpp>
#include <app/application/scene.hpp>
#include <app/controller/camera/freefly.hpp>
#include <app/controller/camera/trackball.hpp>
#include <app/core/controller/controller_system.hpp>
#include <util/logger.hpp>

namespace VTX::UI::QT::Action
Expand Down Expand Up @@ -58,6 +61,9 @@ namespace VTX::UI::QT::Action
{
QObject::connect( qAction, &QAction::triggered, p_action.trigger.value() );
}
// Connect.
// TODO: maybe this is dirty (calling this function to get previously created qAction).
p_action.connect();
}

return _ACTIONS.get<QAction>( p_hash );
Expand Down Expand Up @@ -140,6 +146,28 @@ namespace VTX::UI::QT::Action
tip = "Change projection mode (perspective/orthographic)";
icon = "sprite/camera/orthographic.png";
shortcut = "Alt+O";
trigger = []() { App::ACTION_SYSTEM().execute<App::Action::Controller::ToggleCameraProjection>(); };
}

void Orthographic::connect() const
{
using namespace App::Component;

QAction * const qAction = Factory::get<Orthographic>();
Render::Camera & camera = App::SCENE().getCamera();

if ( camera.getProjection() == Render::Camera::PROJECTION::ORTHOGRAPHIC )
{
qAction->setChecked( true );
}

camera.onProjectionChange += [ qAction ]( const Render::Camera::PROJECTION p_projection )
{
if ( p_projection == Render::Camera::PROJECTION::ORTHOGRAPHIC )
{
qAction->setChecked( true );
}
};
}

Perspective::Perspective()
Expand All @@ -149,6 +177,28 @@ namespace VTX::UI::QT::Action
tip = "Change projection mode (perspective/orthographic)";
icon = "sprite/camera/perspective.png";
shortcut = "Alt+P";
trigger = []() { App::ACTION_SYSTEM().execute<App::Action::Controller::ToggleCameraProjection>(); };
}

void Perspective::connect() const
{
using namespace App::Component;

QAction * const qAction = Factory::get<Perspective>();
Render::Camera & camera = App::SCENE().getCamera();

if ( camera.getProjection() == Render::Camera::PROJECTION::PERSPECTIVE )
{
qAction->setChecked( true );
}

camera.onProjectionChange += [ qAction ]( const Render::Camera::PROJECTION p_projection )
{
if ( p_projection == Render::Camera::PROJECTION::PERSPECTIVE )
{
qAction->setChecked( true );
}
};
}

Trackball::Trackball()
Expand All @@ -161,6 +211,24 @@ namespace VTX::UI::QT::Action
trigger = []() { App::ACTION_SYSTEM().execute<App::Action::Controller::ToggleCameraController>(); };
}

void Trackball::connect() const
{
QAction * const qAction = Factory::get<Trackball>();

if ( App::CONTROLLER_SYSTEM().isControllerEnabled<App::Controller::Camera::Trackball>() )
{
qAction->setChecked( true );
}

App::CONTROLLER_SYSTEM().onControllerEnabled += [ qAction ]( const Name p_name )
{
if ( p_name == App::Controller::Camera::Trackball::NAME )
{
qAction->setChecked( true );
}
};
}

Freefly::Freefly()
{
name = "Freefly";
Expand All @@ -171,6 +239,24 @@ namespace VTX::UI::QT::Action
trigger = []() { App::ACTION_SYSTEM().execute<App::Action::Controller::ToggleCameraController>(); };
}

void Freefly::connect() const
{
QAction * const qAction = Factory::get<Freefly>();

if ( App::CONTROLLER_SYSTEM().isControllerEnabled<App::Controller::Camera::Freefly>() )
{
qAction->setChecked( true );
}

App::CONTROLLER_SYSTEM().onControllerEnabled += [ qAction ]( const Name p_name )
{
if ( p_name == App::Controller::Camera::Freefly::NAME )
{
qAction->setChecked( true );
}
};
}

Orient::Orient()
{
name = "Orient";
Expand Down
1 change: 1 addition & 0 deletions lib/ui/qt/src/ui/qt/widget/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ namespace VTX::UI::QT::Widget
_defaultGeometry = saveGeometry();
_defaultState = saveState();


// Connect progress dialog.
APP::onStartBlockingOperation += [ this ]( const std::string & p_text )
{
Expand Down

0 comments on commit 1cc8fd8

Please sign in to comment.