mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add option for custom macro condition check interval
This commit is contained in:
parent
9eb4e90291
commit
624b841ca1
|
|
@ -18,6 +18,8 @@ AdvSceneSwitcher.generalTab.status.autoStart.recording="Recording"
|
|||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Streaming"
|
||||
AdvSceneSwitcher.generalTab.status.autoStart.recordingAndStreaming="Recording or Streaming"
|
||||
AdvSceneSwitcher.generalTab.status.checkInterval="Check conditions every"
|
||||
AdvSceneSwitcher.generalTab.status.checkIntervalTooLow="⚠️ Conflict with macro \"%1\"!"
|
||||
AdvSceneSwitcher.generalTab.status.checkIntervalTooLow.tooltip="Macro \"%1\" won't be able to check its condition at the desired interval of %2.\nEither change the condition check value on the General tab or in the settings of macro \"%3\"."
|
||||
AdvSceneSwitcher.generalTab.generalBehavior="General behavior"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet="If no actions are performed for"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="Will only ever be as accurate as the configured check interval."
|
||||
|
|
@ -198,6 +200,8 @@ AdvSceneSwitcher.macroTab.newMacroUseShortCircuitEvaluation="Enable short circui
|
|||
AdvSceneSwitcher.macroTab.currentRegisterHotkeys="Register hotkeys to control the pause state of selected macro"
|
||||
AdvSceneSwitcher.macroTab.currentUseShortCircuitEvaluation="Enable short circuit evaluation of macro conditions for currently selected macro"
|
||||
AdvSceneSwitcher.macroTab.shortCircuit.tooltip="Enabling short circuit evaluation might improve the performance, as some condition checks are skipped, if the overall macro cannot be evaluated to \"true\" anymore.\nHowever, please note that condition checks, which are skipped over, will also not update their duration modifier checks."
|
||||
AdvSceneSwitcher.macroTab.currentUseCustomConditionCheckInterval="Check conditions of the currently selected macro at custom interval:"
|
||||
AdvSceneSwitcher.macroTab.currentUseCustomConditionCheckIntervalWarning="⚠️ The selected value is lower than the interval configured on the General tab.\nThe configured value not have any effect!"
|
||||
AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup="Skip execution of actions of current macro on startup"
|
||||
AdvSceneSwitcher.macroTab.currentStopActionsIfNotDone="Stop and rerun actions of the currently selected macro, if the actions are still running, when a new execution is triggered"
|
||||
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
|
||||
|
|
|
|||
|
|
@ -137,11 +137,22 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="checkIntervalTooLowWarning">
|
||||
<property name="text">
|
||||
<string></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QWidget" name="placeholder2" native="true"/>
|
||||
|
|
|
|||
|
|
@ -381,6 +381,8 @@ signals:
|
|||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||
|
||||
/* --- End of legacy tab section --- */
|
||||
private:
|
||||
void SetCheckIntervalTooLowVisibility() const;
|
||||
};
|
||||
|
||||
void OpenSettingsWindow();
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ void AdvSceneSwitcher::on_checkInterval_valueChanged(int value)
|
|||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->interval = value;
|
||||
|
||||
SetCheckIntervalTooLowVisibility();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
||||
|
|
@ -823,6 +825,28 @@ static void setupGeneralTabInactiveWarning(QTabWidget *tabs)
|
|||
inactiveTimer->start();
|
||||
}
|
||||
|
||||
void advss::AdvSceneSwitcher::SetCheckIntervalTooLowVisibility() const
|
||||
{
|
||||
auto macro = GetMacroWithInvalidConditionInterval();
|
||||
if (!macro) {
|
||||
ui->checkIntervalTooLowWarning->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString labelTextFormat(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.status.checkIntervalTooLow"));
|
||||
const QString labelTooltipFormat(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.status.checkIntervalTooLow.tooltip"));
|
||||
const QString name = QString::fromStdString(macro->Name());
|
||||
const QString duration = QString::fromStdString(
|
||||
macro->GetCustomConditionCheckInterval().ToString());
|
||||
|
||||
ui->checkIntervalTooLowWarning->setText(labelTextFormat.arg(name));
|
||||
ui->checkIntervalTooLowWarning->setToolTip(
|
||||
labelTooltipFormat.arg(name).arg(duration).arg(name));
|
||||
ui->checkIntervalTooLowWarning->show();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupGeneralTab()
|
||||
{
|
||||
PopulateSceneSelection(ui->noMatchSwitchScene, false);
|
||||
|
|
@ -851,6 +875,7 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||
SLOT(NoMatchDelayDurationChanged(const Duration &)));
|
||||
|
||||
ui->checkInterval->setValue(switcher->interval);
|
||||
SetCheckIntervalTooLowVisibility();
|
||||
|
||||
ui->enableCooldown->setChecked(switcher->enableCooldown);
|
||||
ui->cooldownTime->setEnabled(switcher->enableCooldown);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#include "macro-settings.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QScrollArea>
|
||||
|
|
@ -63,6 +64,12 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
|||
"AdvSceneSwitcher.macroTab.currentRegisterHotkeys"))),
|
||||
_currentUseShortCircuitEvaluation(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentUseShortCircuitEvaluation"))),
|
||||
_currentUseCustomConditionCheckInterval(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentUseCustomConditionCheckInterval"))),
|
||||
_currentCustomConditionCheckInterval(
|
||||
new DurationSelection(this, true, 0.01)),
|
||||
_currentCustomConditionCheckIntervalWarning(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentUseCustomConditionCheckIntervalWarning"))),
|
||||
_currentSkipOnStartup(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup"))),
|
||||
_currentStopActionsIfNotDone(new QCheckBox(obs_module_text(
|
||||
|
|
@ -118,6 +125,17 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
|||
generalLayout->addWidget(_currentStopActionsIfNotDone);
|
||||
generalLayout->addWidget(_currentUseShortCircuitEvaluation);
|
||||
generalLayout->addWidget(_newMacroUseShortCircuitEvaluation);
|
||||
|
||||
auto durationLayout = new QHBoxLayout();
|
||||
durationLayout->addWidget(_currentUseCustomConditionCheckInterval);
|
||||
durationLayout->addWidget(_currentCustomConditionCheckInterval);
|
||||
durationLayout->addStretch();
|
||||
auto customConditionIntervalLayout = new QVBoxLayout();
|
||||
customConditionIntervalLayout->addLayout(durationLayout);
|
||||
customConditionIntervalLayout->addWidget(
|
||||
_currentCustomConditionCheckIntervalWarning);
|
||||
|
||||
generalLayout->addLayout(customConditionIntervalLayout);
|
||||
generalOptions->setLayout(generalLayout);
|
||||
|
||||
auto inputOptions = new QGroupBox(
|
||||
|
|
@ -193,6 +211,13 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
|||
&MacroSettingsDialog::PauseButtonEnableChanged);
|
||||
connect(_currentMacroDockAddStatusLabel, &QCheckBox::stateChanged, this,
|
||||
&MacroSettingsDialog::StatusLabelEnableChanged);
|
||||
connect(_currentUseCustomConditionCheckInterval,
|
||||
&QCheckBox::stateChanged, this, [this](int state) {
|
||||
_currentCustomConditionCheckInterval->setEnabled(state);
|
||||
});
|
||||
connect(_currentCustomConditionCheckInterval,
|
||||
&DurationSelection::DurationChanged, this,
|
||||
[this]() { SetCustomConditionIntervalWarningVisibility(); });
|
||||
|
||||
auto scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
|
|
@ -231,6 +256,13 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
|||
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
|
||||
_currentUseShortCircuitEvaluation->setChecked(
|
||||
macro->ShortCircuitEvaluationEnabled());
|
||||
_currentUseCustomConditionCheckInterval->setChecked(
|
||||
macro->CustomConditionCheckIntervalEnabled());
|
||||
_currentCustomConditionCheckInterval->SetDuration(
|
||||
macro->GetCustomConditionCheckInterval());
|
||||
_currentCustomConditionCheckInterval->setEnabled(
|
||||
macro->CustomConditionCheckIntervalEnabled());
|
||||
SetCustomConditionIntervalWarningVisibility();
|
||||
_currentSkipOnStartup->setChecked(macro->SkipExecOnStart());
|
||||
_currentStopActionsIfNotDone->setChecked(macro->StopActionsIfNotDone());
|
||||
_currentInputs->SetInputs(macro->GetInputVariables());
|
||||
|
|
@ -332,6 +364,15 @@ void MacroSettingsDialog::Resize()
|
|||
_dockOptions->updateGeometry();
|
||||
}
|
||||
|
||||
void MacroSettingsDialog::SetCustomConditionIntervalWarningVisibility() const
|
||||
{
|
||||
_currentCustomConditionCheckIntervalWarning->setVisible(
|
||||
_currentUseCustomConditionCheckInterval->isChecked() &&
|
||||
GetIntervalValue() >
|
||||
_currentCustomConditionCheckInterval->GetDuration()
|
||||
.Milliseconds());
|
||||
}
|
||||
|
||||
bool MacroSettingsDialog::AskForSettings(QWidget *parent,
|
||||
GlobalMacroSettings &userInput,
|
||||
Macro *macro)
|
||||
|
|
@ -358,6 +399,10 @@ bool MacroSettingsDialog::AskForSettings(QWidget *parent,
|
|||
dialog._currentMacroRegisterHotkeys->isChecked());
|
||||
macro->SetShortCircuitEvaluation(
|
||||
dialog._currentUseShortCircuitEvaluation->isChecked());
|
||||
macro->SetCustomConditionCheckIntervalEnabled(
|
||||
dialog._currentUseCustomConditionCheckInterval->isChecked());
|
||||
macro->SetCustomConditionCheckInterval(
|
||||
dialog._currentCustomConditionCheckInterval->GetDuration());
|
||||
macro->SetSkipExecOnStart(dialog._currentSkipOnStartup->isChecked());
|
||||
macro->SetStopActionsIfNotDone(
|
||||
dialog._currentStopActionsIfNotDone->isChecked());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "duration-control.hpp"
|
||||
#include "macro-input.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
|
|
@ -44,6 +45,7 @@ private slots:
|
|||
|
||||
private:
|
||||
void Resize();
|
||||
void SetCustomConditionIntervalWarningVisibility() const;
|
||||
|
||||
// Global macro settings
|
||||
QCheckBox *_highlightExecutedMacros;
|
||||
|
|
@ -54,6 +56,9 @@ private:
|
|||
// Current macro specific settings
|
||||
QCheckBox *_currentMacroRegisterHotkeys;
|
||||
QCheckBox *_currentUseShortCircuitEvaluation;
|
||||
QCheckBox *_currentUseCustomConditionCheckInterval;
|
||||
DurationSelection *_currentCustomConditionCheckInterval;
|
||||
QLabel *_currentCustomConditionCheckIntervalWarning;
|
||||
QCheckBox *_currentSkipOnStartup;
|
||||
QCheckBox *_currentStopActionsIfNotDone;
|
||||
MacroInputSelection *_currentInputs;
|
||||
|
|
|
|||
|
|
@ -795,6 +795,8 @@ void AdvSceneSwitcher::on_macroSettings_clicked()
|
|||
resetSegmentHighlights(ui->actionsList);
|
||||
resetSegmentHighlights(ui->elseActionsList);
|
||||
}
|
||||
|
||||
SetCheckIntervalTooLowVisibility();
|
||||
}
|
||||
|
||||
static void moveControlsToSplitter(QSplitter *splitter, int idx,
|
||||
|
|
|
|||
|
|
@ -314,6 +314,21 @@ bool Macro::WasExecutedSince(const TimePoint &time) const
|
|||
return _lastExecutionTime > time;
|
||||
}
|
||||
|
||||
bool Macro::ConditionsShouldBeChecked() const
|
||||
{
|
||||
if (!_useCustomConditionCheckInterval) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto timePassed = std::chrono::high_resolution_clock::now() -
|
||||
LastConditionCheckTime();
|
||||
const auto timePassedMs =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
timePassed);
|
||||
return timePassedMs.count() >=
|
||||
_customConditionCheckInterval.Milliseconds();
|
||||
}
|
||||
|
||||
bool Macro::ShouldRunActions() const
|
||||
{
|
||||
const bool hasActionsToExecute =
|
||||
|
|
@ -426,6 +441,26 @@ bool Macro::ShortCircuitEvaluationEnabled() const
|
|||
return _useShortCircuitEvaluation;
|
||||
}
|
||||
|
||||
void Macro::SetCustomConditionCheckIntervalEnabled(bool enable)
|
||||
{
|
||||
_useCustomConditionCheckInterval = enable;
|
||||
}
|
||||
|
||||
bool Macro::CustomConditionCheckIntervalEnabled() const
|
||||
{
|
||||
return _useCustomConditionCheckInterval;
|
||||
}
|
||||
|
||||
void Macro::SetCustomConditionCheckInterval(const Duration &duration)
|
||||
{
|
||||
_customConditionCheckInterval = duration;
|
||||
}
|
||||
|
||||
Duration Macro::GetCustomConditionCheckInterval() const
|
||||
{
|
||||
return _customConditionCheckInterval;
|
||||
}
|
||||
|
||||
void Macro::SetPaused(bool pause)
|
||||
{
|
||||
if (_paused && !pause) {
|
||||
|
|
@ -645,13 +680,6 @@ bool Macro::Save(obs_data_t *obj, bool saveForCopy) const
|
|||
if (!saveForCopy) {
|
||||
obs_data_set_string(obj, "name", _name.c_str());
|
||||
}
|
||||
obs_data_set_bool(obj, "pause", _paused);
|
||||
obs_data_set_bool(obj, "parallel", _runInParallel);
|
||||
obs_data_set_bool(obj, "onChange", _performActionsOnChange);
|
||||
obs_data_set_bool(obj, "skipExecOnStart", _skipExecOnStart);
|
||||
obs_data_set_bool(obj, "stopActionsIfNotDone", _stopActionsIfNotDone);
|
||||
obs_data_set_bool(obj, "useShortCircuitEvaluation",
|
||||
_useShortCircuitEvaluation);
|
||||
|
||||
obs_data_set_bool(obj, "group", _isGroup);
|
||||
if (_isGroup) {
|
||||
|
|
@ -662,6 +690,17 @@ bool Macro::Save(obs_data_t *obj, bool saveForCopy) const
|
|||
return true;
|
||||
}
|
||||
|
||||
obs_data_set_bool(obj, "pause", _paused);
|
||||
obs_data_set_bool(obj, "parallel", _runInParallel);
|
||||
obs_data_set_bool(obj, "onChange", _performActionsOnChange);
|
||||
obs_data_set_bool(obj, "skipExecOnStart", _skipExecOnStart);
|
||||
obs_data_set_bool(obj, "stopActionsIfNotDone", _stopActionsIfNotDone);
|
||||
obs_data_set_bool(obj, "useShortCircuitEvaluation",
|
||||
_useShortCircuitEvaluation);
|
||||
obs_data_set_bool(obj, "useCustomConditionCheckInterval",
|
||||
_useCustomConditionCheckInterval);
|
||||
_customConditionCheckInterval.Save(obj, "customConditionCheckInterval");
|
||||
|
||||
SaveDockSettings(obj, saveForCopy);
|
||||
|
||||
SaveSplitterPos(_actionConditionSplitterPosition, obj,
|
||||
|
|
@ -710,13 +749,6 @@ bool Macro::Save(obs_data_t *obj, bool saveForCopy) const
|
|||
bool Macro::Load(obs_data_t *obj)
|
||||
{
|
||||
_name = obs_data_get_string(obj, "name");
|
||||
_paused = obs_data_get_bool(obj, "pause");
|
||||
_runInParallel = obs_data_get_bool(obj, "parallel");
|
||||
_performActionsOnChange = obs_data_get_bool(obj, "onChange");
|
||||
_skipExecOnStart = obs_data_get_bool(obj, "skipExecOnStart");
|
||||
_stopActionsIfNotDone = obs_data_get_bool(obj, "stopActionsIfNotDone");
|
||||
_useShortCircuitEvaluation =
|
||||
obs_data_get_bool(obj, "useShortCircuitEvaluation");
|
||||
|
||||
_isGroup = obs_data_get_bool(obj, "group");
|
||||
if (_isGroup) {
|
||||
|
|
@ -728,6 +760,17 @@ bool Macro::Load(obs_data_t *obj)
|
|||
return true;
|
||||
}
|
||||
|
||||
_paused = obs_data_get_bool(obj, "pause");
|
||||
_runInParallel = obs_data_get_bool(obj, "parallel");
|
||||
_performActionsOnChange = obs_data_get_bool(obj, "onChange");
|
||||
_skipExecOnStart = obs_data_get_bool(obj, "skipExecOnStart");
|
||||
_stopActionsIfNotDone = obs_data_get_bool(obj, "stopActionsIfNotDone");
|
||||
_useShortCircuitEvaluation =
|
||||
obs_data_get_bool(obj, "useShortCircuitEvaluation");
|
||||
_useCustomConditionCheckInterval =
|
||||
obs_data_get_bool(obj, "useCustomConditionCheckInterval");
|
||||
_customConditionCheckInterval.Load(obj, "customConditionCheckInterval");
|
||||
|
||||
LoadDockSettings(obj);
|
||||
|
||||
LoadSplitterPos(_actionConditionSplitterPosition, obj,
|
||||
|
|
@ -1289,6 +1332,14 @@ bool CheckMacros()
|
|||
{
|
||||
bool matchFound = false;
|
||||
for (const auto &m : macros) {
|
||||
if (!m->ConditionsShouldBeChecked()) {
|
||||
vblog(LOG_INFO,
|
||||
"skipping condition check for macro \"%s\" "
|
||||
"(custom check interval)",
|
||||
m->Name().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m->CheckConditions() || m->ElseActions().size() > 0) {
|
||||
matchFound = true;
|
||||
// This has to be performed here for now as actions are
|
||||
|
|
@ -1386,4 +1437,27 @@ void InvalidateMacroTempVarValues()
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval()
|
||||
{
|
||||
if (macros.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
for (const auto ¯o : macros) {
|
||||
if (!macro) {
|
||||
continue;
|
||||
}
|
||||
if (!macro->CustomConditionCheckIntervalEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (macro->GetCustomConditionCheckInterval().Milliseconds() <
|
||||
GetIntervalValue()) {
|
||||
return macro;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public:
|
|||
bool CheckConditions(bool ignorePause = false);
|
||||
bool ConditionsMatched() const { return _matched; }
|
||||
TimePoint LastConditionCheckTime() const { return _lastCheckTime; }
|
||||
bool ConditionsShouldBeChecked() const;
|
||||
|
||||
bool ShouldRunActions() const;
|
||||
bool PerformActions(bool match, bool forceParallel = false,
|
||||
|
|
@ -60,6 +61,11 @@ public:
|
|||
void SetShortCircuitEvaluation(bool useShortCircuitEvaluation);
|
||||
bool ShortCircuitEvaluationEnabled() const;
|
||||
|
||||
void SetCustomConditionCheckIntervalEnabled(bool enable);
|
||||
bool CustomConditionCheckIntervalEnabled() const;
|
||||
void SetCustomConditionCheckInterval(const Duration &);
|
||||
Duration GetCustomConditionCheckInterval() const;
|
||||
|
||||
int RunCount() const { return _runCount; };
|
||||
void ResetRunCount() { _runCount = 0; };
|
||||
|
||||
|
|
@ -188,10 +194,13 @@ private:
|
|||
bool _isCollapsed = false;
|
||||
|
||||
bool _useShortCircuitEvaluation = false;
|
||||
bool _useCustomConditionCheckInterval = true;
|
||||
Duration _customConditionCheckInterval = 0.3;
|
||||
bool _conditionSateChanged = false;
|
||||
|
||||
bool _runInParallel = false;
|
||||
bool _matched = false;
|
||||
bool _lastMatched = false;
|
||||
bool _conditionSateChanged = false;
|
||||
bool _performActionsOnChange = true;
|
||||
bool _skipExecOnStart = false;
|
||||
bool _stopActionsIfNotDone = false;
|
||||
|
|
@ -239,5 +248,6 @@ Macro *GetMacroByName(const char *name);
|
|||
Macro *GetMacroByQString(const QString &name);
|
||||
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
|
||||
void InvalidateMacroTempVarValues();
|
||||
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval();
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public:
|
|||
bool showUnitSelection = true,
|
||||
double minValue = 0.0);
|
||||
EXPORT void SetDuration(const Duration &);
|
||||
Duration GetDuration() const { return _current; }
|
||||
EXPORT QDoubleSpinBox *SpinBox() { return _duration->SpinBox(); }
|
||||
|
||||
private slots:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user