mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-29 13:25:29 -05:00
230 lines
5.6 KiB
C++
230 lines
5.6 KiB
C++
#include "duration-control.hpp"
|
|
#include "mouse-wheel-guard.hpp"
|
|
#include "obs-module.h"
|
|
#include "utility.hpp"
|
|
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <QHBoxLayout>
|
|
|
|
namespace advss {
|
|
|
|
Duration::Duration(double initialValueInSeconds) : _value(initialValueInSeconds)
|
|
{
|
|
}
|
|
|
|
void Duration::Save(obs_data_t *obj, const char *name) const
|
|
{
|
|
auto data = obs_data_create();
|
|
_value.Save(data, "value");
|
|
obs_data_set_int(data, "unit", static_cast<int>(_unit));
|
|
obs_data_set_int(data, "version", 1);
|
|
obs_data_set_obj(obj, name, data);
|
|
obs_data_release(data);
|
|
}
|
|
|
|
static int durationUnitToMultiplier(Duration::Unit u)
|
|
{
|
|
switch (u) {
|
|
case Duration::Unit::SECONDS:
|
|
return 1;
|
|
case Duration::Unit::MINUTES:
|
|
return 60;
|
|
case Duration::Unit::HOURS:
|
|
return 3600;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Duration::Load(obs_data_t *obj, const char *name)
|
|
{
|
|
auto data = obs_data_get_obj(obj, name);
|
|
|
|
// TODO: remove this fallback
|
|
if (!data || !obs_data_has_user_value(data, "version") ||
|
|
obs_data_get_int(data, "version") != 1) {
|
|
bool usingDefaultArgs = strcmp("duration", name) == 0;
|
|
if (usingDefaultArgs) {
|
|
_value = obs_data_get_double(obj, "seconds");
|
|
}
|
|
if (_value.GetValue() == 0.0) {
|
|
_value = obs_data_get_double(obj, name);
|
|
}
|
|
|
|
if (usingDefaultArgs) {
|
|
_unit = static_cast<Duration::Unit>(
|
|
obs_data_get_int(obj, "displayUnit"));
|
|
} else if (_value.GetValue() >= 86400) {
|
|
_unit = (_value.GetValue() / 60 >= 86400)
|
|
? Duration::Unit::HOURS
|
|
: Duration::Unit::MINUTES;
|
|
} else {
|
|
_unit = Duration::Unit::SECONDS;
|
|
}
|
|
|
|
_value = _value / durationUnitToMultiplier(_unit);
|
|
|
|
obs_data_release(data);
|
|
return;
|
|
}
|
|
|
|
_value.Load(data, "value");
|
|
_unit = static_cast<Duration::Unit>(obs_data_get_int(data, "unit"));
|
|
obs_data_release(data);
|
|
}
|
|
|
|
bool Duration::DurationReached()
|
|
{
|
|
if (IsReset()) {
|
|
_startTime = std::chrono::high_resolution_clock::now();
|
|
}
|
|
|
|
auto runTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
std::chrono::high_resolution_clock::now() - _startTime);
|
|
return runTime.count() >= Milliseconds();
|
|
}
|
|
|
|
bool Duration::IsReset() const
|
|
{
|
|
return _startTime.time_since_epoch().count() == 0;
|
|
}
|
|
|
|
double Duration::Seconds() const
|
|
{
|
|
return _value.GetValue() * durationUnitToMultiplier(_unit);
|
|
}
|
|
|
|
double Duration::Milliseconds() const
|
|
{
|
|
return Seconds() * 1000.0;
|
|
}
|
|
|
|
double Duration::TimeRemaining() const
|
|
{
|
|
if (IsReset()) {
|
|
return Seconds();
|
|
}
|
|
auto runTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
std::chrono::high_resolution_clock::now() - _startTime);
|
|
|
|
if (runTime.count() >= Milliseconds()) {
|
|
return 0;
|
|
}
|
|
return (Milliseconds() - runTime.count()) / 1000.0;
|
|
}
|
|
|
|
void Duration::SetTimeRemaining(double remaining)
|
|
{
|
|
long long msPassed = (Seconds() - remaining) * 1000;
|
|
_startTime = std::chrono::high_resolution_clock::now() -
|
|
std::chrono::milliseconds(msPassed);
|
|
}
|
|
|
|
void Duration::Reset()
|
|
{
|
|
_startTime = {};
|
|
}
|
|
|
|
static std::string durationUnitToString(Duration::Unit u)
|
|
{
|
|
switch (u) {
|
|
case Duration::Unit::SECONDS:
|
|
return obs_module_text("AdvSceneSwitcher.unit.secends");
|
|
case Duration::Unit::MINUTES:
|
|
return obs_module_text("AdvSceneSwitcher.unit.minutes");
|
|
case Duration::Unit::HOURS:
|
|
return obs_module_text("AdvSceneSwitcher.unit.hours");
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
std::string Duration::ToString() const
|
|
{
|
|
std::ostringstream ss;
|
|
ss << std::fixed << std::setprecision(2) << _value.GetValue() << " "
|
|
<< durationUnitToString(_unit);
|
|
if (!_value.IsFixedType()) {
|
|
ss << " [" << GetWeakVariableName(_value.GetVariable()) << "]";
|
|
}
|
|
return ss.str();
|
|
}
|
|
|
|
void Duration::SetUnit(Unit u)
|
|
{
|
|
double prevMultiplier = durationUnitToMultiplier(_unit);
|
|
double newMultiplier = durationUnitToMultiplier(u);
|
|
_unit = u;
|
|
_value = _value * (prevMultiplier / newMultiplier);
|
|
}
|
|
|
|
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,
|
|
double minValue)
|
|
: QWidget(parent),
|
|
_duration(new VariableDoubleSpinBox(parent)),
|
|
_unitSelection(new QComboBox())
|
|
{
|
|
_duration->setMinimum(minValue);
|
|
_duration->setMaximum(86400); // 24 hours
|
|
PreventMouseWheelAdjustWithoutFocus(_duration);
|
|
|
|
populateUnits(_unitSelection);
|
|
|
|
QWidget::connect(
|
|
_duration,
|
|
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
|
|
this, SLOT(_DurationChanged(const NumberVariable<double> &)));
|
|
|
|
QWidget::connect(_unitSelection, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(_UnitChanged(int)));
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->setSpacing(11);
|
|
layout->addWidget(_duration);
|
|
if (showUnitSelection) {
|
|
layout->addWidget(_unitSelection);
|
|
}
|
|
setLayout(layout);
|
|
}
|
|
|
|
void DurationSelection::SetDuration(const Duration &d)
|
|
{
|
|
_current = d;
|
|
_duration->SetValue(d._value);
|
|
const QSignalBlocker b(_unitSelection);
|
|
_unitSelection->setCurrentIndex(static_cast<int>(d._unit));
|
|
}
|
|
|
|
void DurationSelection::_DurationChanged(const NumberVariable<double> &value)
|
|
{
|
|
_current._value = value;
|
|
emit DurationChanged(_current);
|
|
}
|
|
|
|
void DurationSelection::_UnitChanged(int idx)
|
|
{
|
|
Duration::Unit unit = static_cast<Duration::Unit>(idx);
|
|
double prevMultiplier = durationUnitToMultiplier(_current._unit);
|
|
double newMultiplier = durationUnitToMultiplier(unit);
|
|
_current._unit = unit;
|
|
const QSignalBlocker b(_duration);
|
|
_duration->SetFixedValue(_duration->Value() *
|
|
(prevMultiplier / newMultiplier));
|
|
emit DurationChanged(_current);
|
|
}
|
|
|
|
} // namespace advss
|