diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini index b02b75e502b4d18de6051fe470929a6453429b96..9ae037ae948474079334102fb7d6964634ecb6a8 100644 --- a/obs/data/locale/en-US.ini +++ b/obs/data/locale/en-US.ini @@ -87,6 +87,7 @@ Basic.SourceSelect.AddExisting="Add Existing" # properties window Basic.PropertiesWindow="Properties for '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (unsupported; autoselect: %2)" +Basic.PropertiesWindow.SelectColor="Select color" # status bar Basic.StatusBar.Reconnecting="Disconnected, reconnecting (attempt %1)" diff --git a/obs/properties-view.cpp b/obs/properties-view.cpp index 5133d92e86de114374e40b5648438f0ae05ac2cb..58c665986cb68c3be71ef7b41841fd459310063f 100644 --- a/obs/properties-view.cpp +++ b/obs/properties-view.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "qt-wrappers.hpp" #include "properties-view.hpp" #include "obs-app.hpp" @@ -15,6 +16,27 @@ using namespace std; +static inline QColor color_from_int(long long val) +{ + return QColor( val & 0xff, + (val >> 8) & 0xff, + (val >> 16) & 0xff, + (val >> 24) & 0xff); +} + +static inline long long color_to_int(QColor color) +{ + auto shift = [&](unsigned val, int shift) + { + return ((val & 0xff) << shift); + }; + + return shift(color.red(), 0) | + shift(color.green(), 8) | + shift(color.blue(), 16) | + shift(color.alpha(), 24); +} + void OBSPropertiesView::RefreshProperties() { children.clear(); @@ -293,6 +315,37 @@ QWidget *OBSPropertiesView::AddButton(obs_property_t prop) return NewWidget(prop, button, SIGNAL(clicked())); } +void OBSPropertiesView::AddColor(obs_property_t prop, QFormLayout *layout, + QLabel *&label) +{ + QPushButton *button = new QPushButton; + QLabel *colorLabel = new QLabel; + const char *name = obs_property_name(prop); + long long val = obs_data_getint(settings, name); + QColor color = color_from_int(val); + + button->setText(QTStr("Basic.PropertiesWindow.SelectColor")); + + colorLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); + colorLabel->setText(color.name(QColor::HexArgb)); + colorLabel->setPalette(QPalette(color)); + colorLabel->setAutoFillBackground(true); + colorLabel->setAlignment(Qt::AlignCenter); + + QHBoxLayout *subLayout = new QHBoxLayout; + subLayout->setContentsMargins(0, 0, 0, 0); + + subLayout->addWidget(colorLabel); + subLayout->addWidget(button); + + WidgetInfo *info = new WidgetInfo(this, prop, colorLabel); + connect(button, SIGNAL(clicked()), info, SLOT(ControlChanged())); + children.emplace_back(info); + + label = new QLabel(QT_UTF8(obs_property_description(prop))); + layout->addRow(label, subLayout); +} + void OBSPropertiesView::AddProperty(obs_property_t property, QFormLayout *layout) { @@ -328,7 +381,7 @@ void OBSPropertiesView::AddProperty(obs_property_t property, widget = AddList(property, warning); break; case OBS_PROPERTY_COLOR: - /* TODO */ + AddColor(property, layout, label); break; case OBS_PROPERTY_BUTTON: widget = AddButton(property); @@ -448,10 +501,35 @@ void WidgetInfo::ListChanged(const char *setting) } } -void WidgetInfo::ColorChanged(const char *setting) +bool WidgetInfo::ColorChanged(const char *setting) { - /* TODO */ - UNUSED_PARAMETER(setting); + const char *desc = obs_property_description(property); + long long val = obs_data_getint(view->settings, setting); + QColor color = color_from_int(val); + + QColorDialog::ColorDialogOptions options = + QColorDialog::ShowAlphaChannel; + + /* The native dialog on OSX has all kinds of problems, like closing + * other open QDialogs on exit, and + * https://bugreports.qt-project.org/browse/QTBUG-34532 + */ +#ifdef __APPLE__ + options |= QColorDialog::DontUseNativeDialog; +#endif + + color = QColorDialog::getColor(color, view, QT_UTF8(desc), options); + + if (!color.isValid()) + return false; + + QLabel *label = static_cast(widget); + label->setText(color.name(QColor::HexArgb)); + label->setPalette(QPalette(color)); + + obs_data_setint(view->settings, setting, color_to_int(color)); + + return true; } void WidgetInfo::ButtonClicked() @@ -471,8 +549,11 @@ void WidgetInfo::ControlChanged() case OBS_PROPERTY_FLOAT: FloatChanged(setting); break; case OBS_PROPERTY_TEXT: TextChanged(setting); break; case OBS_PROPERTY_LIST: ListChanged(setting); break; - case OBS_PROPERTY_COLOR: ColorChanged(setting); break; case OBS_PROPERTY_BUTTON: ButtonClicked(); return; + case OBS_PROPERTY_COLOR: + if (!ColorChanged(setting)) + return; + break; case OBS_PROPERTY_PATH: if (!PathChanged(setting)) return; diff --git a/obs/properties-view.hpp b/obs/properties-view.hpp index 3680076d73b289a9e601fa109b2ef83245e33c2f..eaa7e0f8fd3460700a10fdec6d6e17367bf28d3c 100644 --- a/obs/properties-view.hpp +++ b/obs/properties-view.hpp @@ -27,7 +27,7 @@ private: void TextChanged(const char *setting); bool PathChanged(const char *setting); void ListChanged(const char *setting); - void ColorChanged(const char *setting); + bool ColorChanged(const char *setting); void ButtonClicked(); public: @@ -68,6 +68,7 @@ private: QWidget *AddFloat(obs_property_t prop); QWidget *AddList(obs_property_t prop, bool &warning); QWidget *AddButton(obs_property_t prop); + void AddColor(obs_property_t prop, QFormLayout *layout, QLabel *&label); void AddProperty(obs_property_t property, QFormLayout *layout);