Add VariableColorButton

Used for color selection which also support variables
This commit is contained in:
WarmUpTill 2026-06-29 18:41:29 +02:00 committed by WarmUpTill
parent 8f3b5f9dfc
commit 0a2e2cd771
6 changed files with 236 additions and 0 deletions

View File

@ -291,6 +291,10 @@ target_sources(
lib/utils/volume-control.hpp
lib/utils/websocket-api.cpp
lib/utils/websocket-api.hpp
lib/variables/variable-color-button.cpp
lib/variables/variable-color-button.hpp
lib/variables/variable-color.cpp
lib/variables/variable-color.hpp
lib/variables/variable-line-edit.cpp
lib/variables/variable-line-edit.hpp
lib/variables/variable-number.hpp

View File

@ -444,6 +444,7 @@ AdvSceneSwitcher.condition.video.ocrConfigReload="Reload configuration file"
AdvSceneSwitcher.condition.video.ocrConfigHint="Tesseract config files consist of lines with parameter-value pairs (space separated).\nFor example:\n\ntessedit_char_blacklist\t\t\t\t\"abc\"\nlanguage_model_penalty_non_dict_word\t0"
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
AdvSceneSwitcher.condition.video.selectColor="Select Color"
AdvSceneSwitcher.condition.video.colorVariableTooltip="Expected format: #RRGGBB or #AARRGGBB\nInvalid values will default to black."
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="Single column of text of variable sizes"
AdvSceneSwitcher.condition.video.ocrMode.singleBlockVertText="Single uniform block of vertically aligned text"
AdvSceneSwitcher.condition.video.ocrMode.singleBlock="Single uniform block of text"

View File

@ -0,0 +1,106 @@
#include "variable-color-button.hpp"
#include "obs-module-helper.hpp"
#include "ui-helpers.hpp"
#include <QColorDialog>
#include <QHBoxLayout>
namespace advss {
VariableColorButton::VariableColorButton(QWidget *parent,
const QString &selectText)
: QWidget(parent),
_colorSwatch(new QLabel()),
_selectColor(new QPushButton(selectText)),
_variable(new VariableSelection(this)),
_toggleType(new QPushButton())
{
_toggleType->setCheckable(true);
_toggleType->setMaximumWidth(11);
SetButtonIcon(_toggleType, GetThemeTypeName() == "Light"
? ":/res/images/dots-vert.svg"
: "theme:Dark/dots-vert.svg");
QWidget::connect(_selectColor, SIGNAL(clicked()), this,
SLOT(SelectColorClicked()));
QWidget::connect(_toggleType, SIGNAL(toggled(bool)), this,
SLOT(ToggleTypeClicked(bool)));
QWidget::connect(_variable, SIGNAL(SelectionChanged(const QString &)),
this, SLOT(VariableChanged(const QString &)));
auto layout = new QHBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(_colorSwatch);
layout->addWidget(_selectColor);
layout->addWidget(_variable);
layout->addWidget(_toggleType);
setLayout(layout);
SetVisibility();
}
void VariableColorButton::SetValue(const ColorVariable &color)
{
_color = color;
const QSignalBlocker b1(_toggleType);
const QSignalBlocker b2(_variable);
_toggleType->setChecked(!color.IsFixedType());
SetupColorLabel(color.GetFixedValue());
_variable->SetVariable(color.GetVariable());
SetVisibility();
}
void VariableColorButton::SelectColorClicked()
{
const QColor color = QColorDialog::getColor(
_color.GetFixedValue(), this, _selectColor->text(),
QColorDialog::ColorDialogOption());
if (!color.isValid()) {
return;
}
SetupColorLabel(color);
_color._value = color;
emit ColorVariableChanged(_color);
}
void VariableColorButton::VariableChanged(const QString &name)
{
_color._variable = GetWeakVariableByQString(name);
emit ColorVariableChanged(_color);
}
void VariableColorButton::ToggleTypeClicked(bool useVariable)
{
_color._type = useVariable ? ColorVariable::Type::VARIABLE
: ColorVariable::Type::FIXED_VALUE;
SetVisibility();
emit ColorVariableChanged(_color);
}
void VariableColorButton::SetupColorLabel(const QColor &color)
{
_colorSwatch->setText(color.name());
_colorSwatch->setStyleSheet(
QString("background-color: %1;").arg(color.name()));
}
void VariableColorButton::SetVisibility()
{
if (_color.IsFixedType()) {
SetupColorLabel(_color.GetFixedValue());
_colorSwatch->show();
_selectColor->show();
_variable->hide();
_toggleType->setVisible(!GetVariables().empty());
} else {
_colorSwatch->hide();
_selectColor->hide();
_variable->show();
_variable->setToolTip(obs_module_text(
"AdvSceneSwitcher.condition.video.colorVariableTooltip"));
_toggleType->show();
}
adjustSize();
updateGeometry();
}
} // namespace advss

View File

@ -0,0 +1,37 @@
#pragma once
#include "export-symbol-helper.hpp"
#include "variable-color.hpp"
#include <QLabel>
#include <QPushButton>
#include <QWidget>
namespace advss {
class ADVSS_EXPORT VariableColorButton : public QWidget {
Q_OBJECT
public:
VariableColorButton(QWidget *parent, const QString &selectText);
void SetValue(const ColorVariable &);
ColorVariable Value() const { return _color; }
public slots:
void SelectColorClicked();
void VariableChanged(const QString &);
void ToggleTypeClicked(bool useVariable);
signals:
void ColorVariableChanged(const ColorVariable &);
private:
void SetupColorLabel(const QColor &);
void SetVisibility();
ColorVariable _color;
QLabel *_colorSwatch;
QPushButton *_selectColor;
VariableSelection *_variable;
QPushButton *_toggleType;
};
} // namespace advss

View File

@ -0,0 +1,53 @@
#include "variable-color.hpp"
#include <obs.hpp>
namespace advss {
ColorVariable::ColorVariable(const QColor &value) : _value(value) {}
void ColorVariable::Save(obs_data_t *obj, const char *name) const
{
OBSDataAutoRelease data = obs_data_create();
obs_data_set_int(data, "version", 1);
obs_data_set_int(data, "type", static_cast<int>(_type));
auto var = _variable.lock();
if (var) {
obs_data_set_string(data, "variable", var->Name().c_str());
}
obs_data_set_int(data, "red", _value.red());
obs_data_set_int(data, "green", _value.green());
obs_data_set_int(data, "blue", _value.blue());
obs_data_set_obj(obj, name, data);
}
void ColorVariable::Load(obs_data_t *obj, const char *name)
{
OBSDataAutoRelease data = obs_data_get_obj(obj, name);
_value.setRed(obs_data_get_int(data, "red"));
_value.setGreen(obs_data_get_int(data, "green"));
_value.setBlue(obs_data_get_int(data, "blue"));
if (!obs_data_has_user_value(data, "version")) {
// Old format: no variable support, just R/G/B
_type = Type::FIXED_VALUE;
return;
}
auto variableName = obs_data_get_string(data, "variable");
_variable = GetWeakVariableByName(variableName);
_type = static_cast<Type>(obs_data_get_int(data, "type"));
}
QColor ColorVariable::GetValue() const
{
if (_type == Type::FIXED_VALUE) {
return _value;
}
auto var = _variable.lock();
if (!var) {
return Qt::black;
}
const QColor color(QString::fromStdString(var->Value()));
return color.isValid() ? color : Qt::black;
}
} // namespace advss

View File

@ -0,0 +1,35 @@
#pragma once
#include "variable.hpp"
#include <obs-data.h>
#include <QColor>
namespace advss {
class VariableColorButton;
class ADVSS_EXPORT ColorVariable {
public:
enum class Type { FIXED_VALUE, VARIABLE };
ColorVariable() = default;
ColorVariable(const QColor &value);
void Save(obs_data_t *obj, const char *name) const;
void Load(obs_data_t *obj, const char *name);
QColor GetValue() const;
QColor GetFixedValue() const { return _value; }
bool IsFixedType() const { return _type == Type::FIXED_VALUE; }
Type GetType() const { return _type; }
std::weak_ptr<Variable> GetVariable() const { return _variable; }
private:
Type _type = Type::FIXED_VALUE;
QColor _value = Qt::black;
std::weak_ptr<Variable> _variable;
friend class VariableColorButton;
};
} // namespace advss