Files
panopainter/src/app_core/app_preferences.h

196 lines
5.4 KiB
C++

#pragma once
#include "foundation/result.h"
#include <cstddef>
#include <span>
namespace pp::app {
enum class InterfaceDirection {
left_to_right,
right_to_left,
};
enum class TimelapseRecordingAction {
no_op,
start_recording,
stop_recording,
};
struct ScaleApplicationPlan {
float scale = 1.0F;
float display_density = 1.0F;
float font_scale = 1.0F;
};
struct ScaleOptionSelection {
bool has_selection = false;
std::size_t index = 0;
};
struct InterfaceDirectionPlan {
InterfaceDirection direction = InterfaceDirection::left_to_right;
};
struct TimelapsePreferencePlan {
bool enabled = true;
TimelapseRecordingAction recording_action = TimelapseRecordingAction::no_op;
};
struct StoredIntegerPreferencePlan {
int value = 0;
};
struct StoredBooleanPreferencePlan {
bool value = false;
};
class AppPreferenceServices {
public:
virtual ~AppPreferenceServices() = default;
virtual void apply_ui_scale(const ScaleApplicationPlan& plan) = 0;
virtual void apply_viewport_scale(const ScaleApplicationPlan& plan) = 0;
virtual void apply_interface_direction(const InterfaceDirectionPlan& plan) = 0;
virtual bool apply_vr_mode_preference(const StoredBooleanPreferencePlan& plan) = 0;
virtual void apply_vr_controllers_preference(const StoredBooleanPreferencePlan& plan) = 0;
virtual void apply_timelapse_preference(const TimelapsePreferencePlan& plan) = 0;
virtual void apply_canvas_cursor_mode(const StoredIntegerPreferencePlan& plan) = 0;
};
[[nodiscard]] constexpr ScaleApplicationPlan plan_ui_scale(
float requested_scale,
float display_density) noexcept
{
return {
requested_scale,
display_density,
requested_scale * display_density,
};
}
[[nodiscard]] constexpr ScaleApplicationPlan plan_viewport_scale(
float requested_scale,
float display_density = 1.0F) noexcept
{
return {
requested_scale,
display_density,
requested_scale * display_density,
};
}
[[nodiscard]] constexpr ScaleOptionSelection plan_scale_option_selection(
float current_scale,
std::span<const float> options) noexcept
{
ScaleOptionSelection selection;
for (std::size_t index = 0; index < options.size(); ++index) {
if (current_scale >= options[index]) {
selection.has_selection = true;
selection.index = index;
}
}
return selection;
}
[[nodiscard]] constexpr InterfaceDirectionPlan plan_interface_direction(bool right_to_left) noexcept
{
return {
right_to_left ? InterfaceDirection::right_to_left : InterfaceDirection::left_to_right,
};
}
[[nodiscard]] constexpr TimelapsePreferencePlan plan_timelapse_preference(
bool enabled,
bool recording_running) noexcept
{
if (enabled && !recording_running) {
return { enabled, TimelapseRecordingAction::start_recording };
}
if (!enabled && recording_running) {
return { enabled, TimelapseRecordingAction::stop_recording };
}
return { enabled, TimelapseRecordingAction::no_op };
}
[[nodiscard]] constexpr StoredBooleanPreferencePlan plan_vr_controllers_preference(
bool enabled) noexcept
{
return { enabled };
}
[[nodiscard]] constexpr StoredBooleanPreferencePlan plan_vr_mode_preference(bool enabled) noexcept
{
return { enabled };
}
[[nodiscard]] constexpr StoredIntegerPreferencePlan plan_canvas_cursor_mode(int mode) noexcept
{
return { mode };
}
[[nodiscard]] inline pp::foundation::Status execute_ui_scale_preference(
float requested_scale,
float display_density,
AppPreferenceServices& services)
{
services.apply_ui_scale(plan_ui_scale(requested_scale, display_density));
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_viewport_scale_preference(
float requested_scale,
float display_density,
AppPreferenceServices& services)
{
services.apply_viewport_scale(plan_viewport_scale(requested_scale, display_density));
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_interface_direction_preference(
bool right_to_left,
AppPreferenceServices& services)
{
services.apply_interface_direction(plan_interface_direction(right_to_left));
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_vr_mode_preference(
bool enabled,
AppPreferenceServices& services)
{
if (!services.apply_vr_mode_preference(plan_vr_mode_preference(enabled))) {
return pp::foundation::Status::invalid_argument("VR mode could not start");
}
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_vr_controllers_preference(
bool enabled,
AppPreferenceServices& services)
{
services.apply_vr_controllers_preference(plan_vr_controllers_preference(enabled));
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_timelapse_preference(
bool enabled,
bool recording_running,
AppPreferenceServices& services)
{
services.apply_timelapse_preference(plan_timelapse_preference(enabled, recording_running));
return pp::foundation::Status::success();
}
[[nodiscard]] inline pp::foundation::Status execute_canvas_cursor_mode_preference(
int mode,
AppPreferenceServices& services)
{
services.apply_canvas_cursor_mode(plan_canvas_cursor_mode(mode));
return pp::foundation::Status::success();
}
}