From 6277da1bbde401afc638d9fc7f78f2a88f55bf23 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sun, 2 May 2021 22:29:56 +0200 Subject: [PATCH] Add Duration class and DurationSelection widget --- CMakeLists.txt | 6 +- src/duration-control.cpp | 138 +++++++++++++++++++++++++++++++ src/headers/duration-control.hpp | 55 ++++++++++++ 3 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 src/duration-control.cpp create mode 100644 src/headers/duration-control.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d5b856b0..512ae392 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,8 +63,6 @@ set(advanced-scene-switcher_HEADERS src/headers/advanced-scene-switcher.hpp src/headers/switcher-data-structs.hpp src/headers/utility.hpp - src/headers/curl-helper.hpp - src/headers/volume-control.hpp src/headers/scene-group.hpp src/headers/scene-trigger.hpp src/headers/switch-audio.hpp @@ -82,6 +80,9 @@ set(advanced-scene-switcher_HEADERS src/headers/switch-sequence.hpp src/headers/switch-video.hpp src/headers/switch-generic.hpp + src/headers/curl-helper.hpp + src/headers/duration-control.hpp + src/headers/volume-control.hpp src/headers/version.h ) @@ -111,6 +112,7 @@ set(advanced-scene-switcher_SOURCES src/switch-video.cpp src/switch-generic.cpp src/curl-helper.cpp + src/duration-control.cpp src/volume-control.cpp src/version.cpp ) diff --git a/src/duration-control.cpp b/src/duration-control.cpp new file mode 100644 index 00000000..7fd34278 --- /dev/null +++ b/src/duration-control.cpp @@ -0,0 +1,138 @@ +#include "headers/duration-control.hpp" +#include "obs-module.h" + +#include +#include +#include + +void Duration::Save(obs_data_t *obj, const char *secondsName, + const char *unitName) +{ + obs_data_set_double(obj, secondsName, seconds); + obs_data_set_int(obj, unitName, static_cast(displayUnit)); +} + +void Duration::Load(obs_data_t *obj, const char *secondsName, + const char *unitName) +{ + seconds = obs_data_get_double(obj, secondsName); + displayUnit = + static_cast(obs_data_get_int(obj, unitName)); +} + +bool Duration::DurationReached() +{ + if (_startTime.time_since_epoch().count() == 0) { + _startTime = std::chrono::high_resolution_clock::now(); + } + + auto runTime = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - _startTime); + return runTime.count() >= seconds * 1000; +} + +void Duration::Reset() +{ + _startTime = {}; +} + +int durationUnitToMultiplier(DurationUnit u) +{ + switch (u) { + case DurationUnit::SECONDS: + return 1; + case DurationUnit::MINUTES: + return 60; + case DurationUnit::HOURS: + return 3600; + default: + break; + } + + return 0; +} +std::string durationUnitToString(DurationUnit u) +{ + switch (u) { + case DurationUnit::SECONDS: + return obs_module_text("AdvSceneSwitcher.unit.secends"); + case DurationUnit::MINUTES: + return obs_module_text("AdvSceneSwitcher.unit.minutes"); + case DurationUnit::HOURS: + return obs_module_text("AdvSceneSwitcher.unit.hours"); + default: + break; + } + + return ""; +} + +std::string Duration::ToString() +{ + std::ostringstream ss; + ss << std::fixed << std::setprecision(2) + << seconds / durationUnitToMultiplier(displayUnit) << " " + << durationUnitToString(displayUnit); + return ss.str(); +} + +static void populateUnits(QComboBox *list) +{ + list->addItem(obs_module_text("AdvSceneSwitcher.unit.secends")); + list->addItem(obs_module_text("AdvSceneSwitcher.unit.minutes")); + list->addItem(obs_module_text("AdvSceneSwitcher.unit.hours")); +} + +DurationSelection::DurationSelection(QWidget *parent, bool showUnitSelection) + : QWidget(parent), _unitMultiplier(1) +{ + _duration = new QDoubleSpinBox(parent); + _duration->setMaximum(86400); // 24 hours + + _unitSelection = new QComboBox(); + populateUnits(_unitSelection); + + QWidget::connect(_duration, SIGNAL(valueChanged(double)), this, + SLOT(_DurationChanged(double))); + QWidget::connect(_unitSelection, SIGNAL(currentIndexChanged(int)), this, + SLOT(_UnitChanged(int))); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(_duration); + if (showUnitSelection) { + layout->addWidget(_unitSelection); + } + setLayout(layout); +} + +void DurationSelection::SetValue(double value) +{ + _duration->setValue(value / _unitMultiplier); +} + +void DurationSelection::SetUnit(DurationUnit u) +{ + _unitSelection->setCurrentIndex(static_cast(u)); +} + +void DurationSelection::SetDuration(Duration d) +{ + SetUnit(d.displayUnit); + SetValue(d.seconds); +} + +void DurationSelection::_DurationChanged(double value) +{ + emit DurationChanged(value * _unitMultiplier); +} + +void DurationSelection::_UnitChanged(int idx) +{ + DurationUnit unit = static_cast(idx); + double prevMultiplier = _unitMultiplier; + _unitMultiplier = durationUnitToMultiplier(unit); + _duration->setValue(_duration->value() * + (prevMultiplier / _unitMultiplier)); + + emit UnitChanged(unit); +} diff --git a/src/headers/duration-control.hpp b/src/headers/duration-control.hpp new file mode 100644 index 00000000..32c6a172 --- /dev/null +++ b/src/headers/duration-control.hpp @@ -0,0 +1,55 @@ +#pragma once +#include +#include +#include +#include + +#include "obs-data.h" + +enum class DurationUnit { + SECONDS, + MINUTES, + HOURS, +}; + +class Duration { +public: + void Save(obs_data_t *obj, const char *secondsName = "seconds", + const char *unitName = "displayUnit"); + void Load(obs_data_t *obj, const char *secondsName = "seconds", + const char *unitName = "displayUnit"); + + bool DurationReached(); + void Reset(); + std::string ToString(); + + double seconds = 0.; + // only used for UI + DurationUnit displayUnit = DurationUnit::SECONDS; + +private: + std::chrono::high_resolution_clock::time_point _startTime; +}; + +class DurationSelection : public QWidget { + Q_OBJECT +public: + DurationSelection(QWidget *parent = nullptr, + bool showUnitSelection = true); + void SetValue(double value); + void SetUnit(DurationUnit u); + void SetDuration(Duration d); + +private slots: + void _DurationChanged(double value); + void _UnitChanged(int idx); +signals: + void DurationChanged(double value); // always reutrn value in seconds + void UnitChanged(DurationUnit u); + +private: + QDoubleSpinBox *_duration; + QComboBox *_unitSelection; + + double _unitMultiplier; +};