frontend: Split Qt UI component into single file per C++ class
This commit is contained in:
parent
819850c0f6
commit
f4fe30a5b3
@ -1,255 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ApplicationAudioCaptureToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
#include "moc_ApplicationAudioCaptureToolbar.cpp"
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
@ -269,439 +20,3 @@ void ApplicationAudioCaptureToolbar::Init()
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,85 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
#include "ComboSelectToolbar.hpp"
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
@ -88,91 +9,3 @@ public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,18 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "AudioCaptureToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
#include "moc_AudioCaptureToolbar.cpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
@ -25,186 +13,6 @@
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
@ -223,485 +31,3 @@ void AudioCaptureToolbar::Init()
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,69 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
#include "ComboSelectToolbar.hpp"
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
@ -72,107 +9,3 @@ public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,88 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "BrowserToolbar.hpp"
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_BrowserToolbar.cpp"
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
@ -103,605 +21,3 @@ void BrowserToolbar::on_refresh_clicked()
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,39 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
@ -47,132 +16,3 @@ public:
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,500 +1,16 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ColorSourceToolbar.hpp"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
#include <QColorDialog>
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_ColorSourceToolbar.cpp"
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static inline QColor color_from_int(long long val)
|
||||
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)
|
||||
long long color_to_int(QColor color)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift) {
|
||||
return ((val & 0xff) << shift);
|
||||
@ -565,143 +81,3 @@ void ColorSourceToolbar::on_choose_clicked()
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,148 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
@ -159,20 +19,3 @@ public:
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,110 +1,10 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ComboSelectToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
#include <OBSApp.hpp>
|
||||
#include <qt-wrappers.hpp>
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_ComboSelectToolbar.cpp"
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
@ -115,7 +15,7 @@ ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
@ -204,504 +104,3 @@ void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,52 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
@ -64,115 +20,3 @@ public:
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,302 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "DeviceCaptureToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_DeviceCaptureToolbar.cpp"
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
@ -352,356 +56,3 @@ void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,101 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
@ -114,65 +23,3 @@ public:
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,18 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "DisplayCaptureToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
#include "moc_DisplayCaptureToolbar.cpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
@ -25,251 +13,6 @@
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
@ -295,413 +38,3 @@ void DisplayCaptureToolbar::Init()
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,93 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
#include "ComboSelectToolbar.hpp"
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
@ -96,83 +9,3 @@ public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,359 +1,11 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "GameCaptureToolbar.hpp"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
#include "moc_GameCaptureToolbar.cpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
extern int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false);
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
@ -437,271 +89,3 @@ void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,119 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
@ -130,49 +19,3 @@ public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -1,444 +1,9 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "ImageSourceToolbar.hpp"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_ImageSourceToolbar.cpp"
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
@ -486,222 +51,3 @@ void ImageSourceToolbar::on_browse_clicked()
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,135 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
@ -143,36 +16,3 @@ public:
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
@ -15,23 +15,12 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include "preview-controls.hpp"
|
||||
#include <obs-app.hpp>
|
||||
#include "OBSPreviewScalingComboBox.hpp"
|
||||
|
||||
/* Preview Scale Label */
|
||||
void OBSPreviewScalingLabel::PreviewScaleChanged(float scale)
|
||||
{
|
||||
previewScale = scale;
|
||||
UpdateScaleLabel();
|
||||
}
|
||||
#include <OBSApp.hpp>
|
||||
|
||||
void OBSPreviewScalingLabel::UpdateScaleLabel()
|
||||
{
|
||||
float previewScalePercent = floor(100.0f * previewScale);
|
||||
setText(QString::number(previewScalePercent) + "%");
|
||||
}
|
||||
#include "moc_OBSPreviewScalingComboBox.cpp"
|
||||
|
||||
/* Preview Scaling ComboBox */
|
||||
void OBSPreviewScalingComboBox::PreviewFixedScalingChanged(bool fixed)
|
||||
{
|
||||
if (fixedScaling == fixed)
|
||||
|
@ -17,23 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
|
||||
class OBSPreviewScalingLabel : public QLabel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OBSPreviewScalingLabel(QWidget *parent = nullptr) : QLabel(parent) {}
|
||||
|
||||
public slots:
|
||||
void PreviewScaleChanged(float scale);
|
||||
|
||||
private:
|
||||
float previewScale = 0.0f;
|
||||
void UpdateScaleLabel();
|
||||
};
|
||||
|
||||
class OBSPreviewScalingComboBox : public QComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -15,10 +15,9 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include "preview-controls.hpp"
|
||||
#include <obs-app.hpp>
|
||||
#include "OBSPreviewScalingLabel.hpp"
|
||||
#include "moc_OBSPreviewScalingLabel.cpp"
|
||||
|
||||
/* Preview Scale Label */
|
||||
void OBSPreviewScalingLabel::PreviewScaleChanged(float scale)
|
||||
{
|
||||
previewScale = scale;
|
||||
@ -30,104 +29,3 @@ void OBSPreviewScalingLabel::UpdateScaleLabel()
|
||||
float previewScalePercent = floor(100.0f * previewScale);
|
||||
setText(QString::number(previewScalePercent) + "%");
|
||||
}
|
||||
|
||||
/* Preview Scaling ComboBox */
|
||||
void OBSPreviewScalingComboBox::PreviewFixedScalingChanged(bool fixed)
|
||||
{
|
||||
if (fixedScaling == fixed)
|
||||
return;
|
||||
|
||||
fixedScaling = fixed;
|
||||
UpdateSelection();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::CanvasResized(uint32_t width, uint32_t height)
|
||||
{
|
||||
SetCanvasSize(width, height);
|
||||
UpdateCanvasText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::OutputResized(uint32_t width, uint32_t height)
|
||||
{
|
||||
SetOutputSize(width, height);
|
||||
|
||||
bool canvasMatchesOutput = output_width == canvas_width && output_height == canvas_height;
|
||||
|
||||
SetScaleOutputEnabled(!canvasMatchesOutput);
|
||||
UpdateOutputText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::PreviewScaleChanged(float scale)
|
||||
{
|
||||
previewScale = scale;
|
||||
|
||||
if (fixedScaling) {
|
||||
UpdateSelection();
|
||||
UpdateAllText();
|
||||
} else {
|
||||
UpdateScaledText();
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::SetScaleOutputEnabled(bool show)
|
||||
{
|
||||
if (scaleOutputEnabled == show)
|
||||
return;
|
||||
|
||||
scaleOutputEnabled = show;
|
||||
|
||||
if (scaleOutputEnabled) {
|
||||
addItem(QTStr("Basic.MainMenu.Edit.Scale.Output"));
|
||||
} else {
|
||||
removeItem(2);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateAllText()
|
||||
{
|
||||
UpdateCanvasText();
|
||||
UpdateOutputText();
|
||||
UpdateScaledText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateCanvasText()
|
||||
{
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Canvas");
|
||||
text = text.arg(QString::number(canvas_width), QString::number(canvas_height));
|
||||
setItemText(1, text);
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateOutputText()
|
||||
{
|
||||
if (scaleOutputEnabled) {
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Output");
|
||||
text = text.arg(QString::number(output_width), QString::number(output_height));
|
||||
setItemText(2, text);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateScaledText()
|
||||
{
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Manual");
|
||||
text = text.arg(QString::number(floor(canvas_width * previewScale)),
|
||||
QString::number(floor(canvas_height * previewScale)));
|
||||
setPlaceholderText(text);
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateSelection()
|
||||
{
|
||||
QSignalBlocker sb(this);
|
||||
float outputScale = float(output_width) / float(canvas_width);
|
||||
|
||||
if (!fixedScaling) {
|
||||
setCurrentIndex(0);
|
||||
} else {
|
||||
if (previewScale == 1.0f) {
|
||||
setCurrentIndex(1);
|
||||
} else if (scaleOutputEnabled && (previewScale == outputScale)) {
|
||||
setCurrentIndex(2);
|
||||
} else {
|
||||
setCurrentIndex(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
|
||||
class OBSPreviewScalingLabel : public QLabel {
|
||||
Q_OBJECT
|
||||
@ -33,47 +32,3 @@ private:
|
||||
float previewScale = 0.0f;
|
||||
void UpdateScaleLabel();
|
||||
};
|
||||
|
||||
class OBSPreviewScalingComboBox : public QComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OBSPreviewScalingComboBox(QWidget *parent = nullptr) : QComboBox(parent) {}
|
||||
|
||||
inline void SetCanvasSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
canvas_width = width;
|
||||
canvas_height = height;
|
||||
};
|
||||
inline void SetOutputSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
output_width = width;
|
||||
output_height = height;
|
||||
};
|
||||
void UpdateAllText();
|
||||
|
||||
public slots:
|
||||
void PreviewScaleChanged(float scale);
|
||||
void PreviewFixedScalingChanged(bool fixed);
|
||||
void CanvasResized(uint32_t width, uint32_t height);
|
||||
void OutputResized(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
uint32_t canvas_width = 0;
|
||||
uint32_t canvas_height = 0;
|
||||
|
||||
uint32_t output_width = 0;
|
||||
uint32_t output_height = 0;
|
||||
|
||||
float previewScale = 0.0f;
|
||||
|
||||
bool fixedScaling = false;
|
||||
|
||||
bool scaleOutputEnabled = false;
|
||||
void SetScaleOutputEnabled(bool show);
|
||||
|
||||
void UpdateCanvasText();
|
||||
void UpdateOutputText();
|
||||
void UpdateScaledText();
|
||||
void UpdateSelection();
|
||||
};
|
||||
|
@ -1,31 +1,8 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
#include <widgets/OBSBasic.hpp>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_SourceToolbar.cpp"
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
@ -81,627 +58,3 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,15 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
#include <QWidget>
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
@ -34,145 +27,3 @@ public:
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,130 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QPointer>
|
||||
#include "SourceTreeItem.hpp"
|
||||
#include "SourceTreeModel.hpp"
|
||||
|
||||
#include <QListView>
|
||||
#include <QCheckBox>
|
||||
#include <QStaticText>
|
||||
#include <QSvgRenderer>
|
||||
#include <QAbstractListModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
class QLabel;
|
||||
class OBSSourceLabel;
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class SourceTree;
|
||||
class QSpacerItem;
|
||||
class QHBoxLayout;
|
||||
class VisibilityItemWidget;
|
||||
|
||||
class SourceTreeItem : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeModel;
|
||||
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void enterEvent(QEnterEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
|
||||
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
void Update(bool force);
|
||||
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Item,
|
||||
Group,
|
||||
SubItem,
|
||||
};
|
||||
|
||||
void DisconnectSignals();
|
||||
void ReconnectSignals();
|
||||
|
||||
Type type = Type::Unknown;
|
||||
|
||||
public:
|
||||
explicit SourceTreeItem(SourceTree *tree, OBSSceneItem sceneitem);
|
||||
bool IsEditing();
|
||||
|
||||
private:
|
||||
QSpacerItem *spacer = nullptr;
|
||||
QCheckBox *expand = nullptr;
|
||||
QLabel *iconLabel = nullptr;
|
||||
QCheckBox *vis = nullptr;
|
||||
QCheckBox *lock = nullptr;
|
||||
QHBoxLayout *boxLayout = nullptr;
|
||||
OBSSourceLabel *label = nullptr;
|
||||
|
||||
QLineEdit *editor = nullptr;
|
||||
|
||||
std::string newName;
|
||||
|
||||
SourceTree *tree;
|
||||
OBSSceneItem sceneitem;
|
||||
std::vector<OBSSignal> sigs;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void ExitEditModeInternal(bool save);
|
||||
|
||||
private slots:
|
||||
void Clear();
|
||||
|
||||
void EnterEditMode();
|
||||
void ExitEditMode(bool save);
|
||||
|
||||
void VisibilityChanged(bool visible);
|
||||
void LockedChanged(bool locked);
|
||||
|
||||
void ExpandClicked(bool checked);
|
||||
|
||||
void Select();
|
||||
void Deselect();
|
||||
};
|
||||
|
||||
class SourceTreeModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
SourceTree *st;
|
||||
QVector<OBSSceneItem> items;
|
||||
bool hasGroups = false;
|
||||
|
||||
static void OBSFrontendEvent(enum obs_frontend_event event, void *ptr);
|
||||
void Clear();
|
||||
void SceneChanged();
|
||||
void ReorderItems();
|
||||
|
||||
void Add(obs_sceneitem_t *item);
|
||||
void Remove(obs_sceneitem_t *item);
|
||||
OBSSceneItem Get(int idx);
|
||||
QString GetNewGroupName();
|
||||
void AddGroup();
|
||||
|
||||
void GroupSelectedItems(QModelIndexList &indices);
|
||||
void UngroupSelectedGroups(QModelIndexList &indices);
|
||||
|
||||
void ExpandGroup(obs_sceneitem_t *item);
|
||||
void CollapseGroup(obs_sceneitem_t *item);
|
||||
|
||||
void UpdateGroupState(bool update);
|
||||
|
||||
public:
|
||||
explicit SourceTreeModel(SourceTree *st);
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
};
|
||||
|
||||
class SourceTree : public QListView {
|
||||
Q_OBJECT
|
||||
@ -192,11 +73,3 @@ protected:
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
};
|
||||
|
||||
class SourceTreeDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceTreeDelegate(QObject *parent);
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QPointer>
|
||||
#include <QListView>
|
||||
#include <QCheckBox>
|
||||
#include <QStaticText>
|
||||
#include <QSvgRenderer>
|
||||
#include <QAbstractListModel>
|
||||
#include <QModelIndex>
|
||||
#include <QObject>
|
||||
#include <QSize>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
class QLabel;
|
||||
class OBSSourceLabel;
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class SourceTree;
|
||||
class QSpacerItem;
|
||||
class QHBoxLayout;
|
||||
class VisibilityItemWidget;
|
||||
|
||||
class SourceTreeItem : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeModel;
|
||||
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void enterEvent(QEnterEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
|
||||
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
void Update(bool force);
|
||||
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Item,
|
||||
Group,
|
||||
SubItem,
|
||||
};
|
||||
|
||||
void DisconnectSignals();
|
||||
void ReconnectSignals();
|
||||
|
||||
Type type = Type::Unknown;
|
||||
|
||||
public:
|
||||
explicit SourceTreeItem(SourceTree *tree, OBSSceneItem sceneitem);
|
||||
bool IsEditing();
|
||||
|
||||
private:
|
||||
QSpacerItem *spacer = nullptr;
|
||||
QCheckBox *expand = nullptr;
|
||||
QLabel *iconLabel = nullptr;
|
||||
QCheckBox *vis = nullptr;
|
||||
QCheckBox *lock = nullptr;
|
||||
QHBoxLayout *boxLayout = nullptr;
|
||||
OBSSourceLabel *label = nullptr;
|
||||
|
||||
QLineEdit *editor = nullptr;
|
||||
|
||||
std::string newName;
|
||||
|
||||
SourceTree *tree;
|
||||
OBSSceneItem sceneitem;
|
||||
std::vector<OBSSignal> sigs;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void ExitEditModeInternal(bool save);
|
||||
|
||||
private slots:
|
||||
void Clear();
|
||||
|
||||
void EnterEditMode();
|
||||
void ExitEditMode(bool save);
|
||||
|
||||
void VisibilityChanged(bool visible);
|
||||
void LockedChanged(bool locked);
|
||||
|
||||
void ExpandClicked(bool checked);
|
||||
|
||||
void Select();
|
||||
void Deselect();
|
||||
};
|
||||
|
||||
class SourceTreeModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
SourceTree *st;
|
||||
QVector<OBSSceneItem> items;
|
||||
bool hasGroups = false;
|
||||
|
||||
static void OBSFrontendEvent(enum obs_frontend_event event, void *ptr);
|
||||
void Clear();
|
||||
void SceneChanged();
|
||||
void ReorderItems();
|
||||
|
||||
void Add(obs_sceneitem_t *item);
|
||||
void Remove(obs_sceneitem_t *item);
|
||||
OBSSceneItem Get(int idx);
|
||||
QString GetNewGroupName();
|
||||
void AddGroup();
|
||||
|
||||
void GroupSelectedItems(QModelIndexList &indices);
|
||||
void UngroupSelectedGroups(QModelIndexList &indices);
|
||||
|
||||
void ExpandGroup(obs_sceneitem_t *item);
|
||||
void CollapseGroup(obs_sceneitem_t *item);
|
||||
|
||||
void UpdateGroupState(bool update);
|
||||
|
||||
public:
|
||||
explicit SourceTreeModel(SourceTree *st);
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
};
|
||||
|
||||
class SourceTree : public QListView {
|
||||
Q_OBJECT
|
||||
|
||||
bool ignoreReorder = false;
|
||||
|
||||
friend class SourceTreeModel;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
bool textPrepared = false;
|
||||
QStaticText textNoSources;
|
||||
QSvgRenderer iconNoSources;
|
||||
|
||||
OBSData undoSceneData;
|
||||
|
||||
bool iconsVisible = true;
|
||||
|
||||
void UpdateNoSourcesMessage();
|
||||
|
||||
void ResetWidgets();
|
||||
void UpdateWidget(const QModelIndex &idx, obs_sceneitem_t *item);
|
||||
void UpdateWidgets(bool force = false);
|
||||
|
||||
inline SourceTreeModel *GetStm() const { return reinterpret_cast<SourceTreeModel *>(model()); }
|
||||
|
||||
public:
|
||||
inline SourceTreeItem *GetItemWidget(int idx)
|
||||
{
|
||||
QWidget *widget = indexWidget(GetStm()->createIndex(idx, 0));
|
||||
return reinterpret_cast<SourceTreeItem *>(widget);
|
||||
}
|
||||
|
||||
explicit SourceTree(QWidget *parent = nullptr);
|
||||
|
||||
inline bool IgnoreReorder() const { return ignoreReorder; }
|
||||
inline void Clear() { GetStm()->Clear(); }
|
||||
|
||||
inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); }
|
||||
inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); }
|
||||
inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); }
|
||||
|
||||
void SelectItem(obs_sceneitem_t *sceneitem, bool select);
|
||||
|
||||
bool MultipleBaseSelected() const;
|
||||
bool GroupsSelected() const;
|
||||
bool GroupedItemsSelected() const;
|
||||
|
||||
void UpdateIcons();
|
||||
void SetIconsVisible(bool visible);
|
||||
|
||||
public slots:
|
||||
inline void ReorderItems() { GetStm()->ReorderItems(); }
|
||||
inline void RefreshItems() { GetStm()->SceneChanged(); }
|
||||
void Remove(OBSSceneItem item, OBSScene scene);
|
||||
void GroupSelectedItems();
|
||||
void UngroupSelectedGroups();
|
||||
void AddGroup();
|
||||
bool Edit(int idx);
|
||||
void NewGroupEdit(int idx);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
};
|
||||
#include <QStyleOptionViewItem>
|
||||
|
||||
class SourceTreeDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QPointer>
|
||||
#include <QListView>
|
||||
#include <QCheckBox>
|
||||
#include <QStaticText>
|
||||
#include <QSvgRenderer>
|
||||
#include <QAbstractListModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
class QLabel;
|
||||
class OBSSourceLabel;
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class SourceTree;
|
||||
#include <QFrame>
|
||||
|
||||
class QSpacerItem;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QHBoxLayout;
|
||||
class VisibilityItemWidget;
|
||||
class OBSSourceLabel;
|
||||
class QLineEdit;
|
||||
|
||||
class SourceTree;
|
||||
|
||||
class SourceTreeItem : public QFrame {
|
||||
Q_OBJECT
|
||||
@ -86,117 +78,3 @@ private slots:
|
||||
void Select();
|
||||
void Deselect();
|
||||
};
|
||||
|
||||
class SourceTreeModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
SourceTree *st;
|
||||
QVector<OBSSceneItem> items;
|
||||
bool hasGroups = false;
|
||||
|
||||
static void OBSFrontendEvent(enum obs_frontend_event event, void *ptr);
|
||||
void Clear();
|
||||
void SceneChanged();
|
||||
void ReorderItems();
|
||||
|
||||
void Add(obs_sceneitem_t *item);
|
||||
void Remove(obs_sceneitem_t *item);
|
||||
OBSSceneItem Get(int idx);
|
||||
QString GetNewGroupName();
|
||||
void AddGroup();
|
||||
|
||||
void GroupSelectedItems(QModelIndexList &indices);
|
||||
void UngroupSelectedGroups(QModelIndexList &indices);
|
||||
|
||||
void ExpandGroup(obs_sceneitem_t *item);
|
||||
void CollapseGroup(obs_sceneitem_t *item);
|
||||
|
||||
void UpdateGroupState(bool update);
|
||||
|
||||
public:
|
||||
explicit SourceTreeModel(SourceTree *st);
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
};
|
||||
|
||||
class SourceTree : public QListView {
|
||||
Q_OBJECT
|
||||
|
||||
bool ignoreReorder = false;
|
||||
|
||||
friend class SourceTreeModel;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
bool textPrepared = false;
|
||||
QStaticText textNoSources;
|
||||
QSvgRenderer iconNoSources;
|
||||
|
||||
OBSData undoSceneData;
|
||||
|
||||
bool iconsVisible = true;
|
||||
|
||||
void UpdateNoSourcesMessage();
|
||||
|
||||
void ResetWidgets();
|
||||
void UpdateWidget(const QModelIndex &idx, obs_sceneitem_t *item);
|
||||
void UpdateWidgets(bool force = false);
|
||||
|
||||
inline SourceTreeModel *GetStm() const { return reinterpret_cast<SourceTreeModel *>(model()); }
|
||||
|
||||
public:
|
||||
inline SourceTreeItem *GetItemWidget(int idx)
|
||||
{
|
||||
QWidget *widget = indexWidget(GetStm()->createIndex(idx, 0));
|
||||
return reinterpret_cast<SourceTreeItem *>(widget);
|
||||
}
|
||||
|
||||
explicit SourceTree(QWidget *parent = nullptr);
|
||||
|
||||
inline bool IgnoreReorder() const { return ignoreReorder; }
|
||||
inline void Clear() { GetStm()->Clear(); }
|
||||
|
||||
inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); }
|
||||
inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); }
|
||||
inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); }
|
||||
|
||||
void SelectItem(obs_sceneitem_t *sceneitem, bool select);
|
||||
|
||||
bool MultipleBaseSelected() const;
|
||||
bool GroupsSelected() const;
|
||||
bool GroupedItemsSelected() const;
|
||||
|
||||
void UpdateIcons();
|
||||
void SetIconsVisible(bool visible);
|
||||
|
||||
public slots:
|
||||
inline void ReorderItems() { GetStm()->ReorderItems(); }
|
||||
inline void RefreshItems() { GetStm()->SceneChanged(); }
|
||||
void Remove(OBSSceneItem item, OBSScene scene);
|
||||
void GroupSelectedItems();
|
||||
void UngroupSelectedGroups();
|
||||
void AddGroup();
|
||||
bool Edit(int idx);
|
||||
void NewGroupEdit(int idx);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
};
|
||||
|
||||
class SourceTreeDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceTreeDelegate(QObject *parent);
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,91 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QPointer>
|
||||
#include <QListView>
|
||||
#include <QCheckBox>
|
||||
#include <QStaticText>
|
||||
#include <QSvgRenderer>
|
||||
#include <QAbstractListModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <obs.hpp>
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
class QLabel;
|
||||
class OBSSourceLabel;
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class SourceTree;
|
||||
class QSpacerItem;
|
||||
class QHBoxLayout;
|
||||
class VisibilityItemWidget;
|
||||
|
||||
class SourceTreeItem : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
friend class SourceTreeModel;
|
||||
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void enterEvent(QEnterEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
|
||||
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
void Update(bool force);
|
||||
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Item,
|
||||
Group,
|
||||
SubItem,
|
||||
};
|
||||
|
||||
void DisconnectSignals();
|
||||
void ReconnectSignals();
|
||||
|
||||
Type type = Type::Unknown;
|
||||
|
||||
public:
|
||||
explicit SourceTreeItem(SourceTree *tree, OBSSceneItem sceneitem);
|
||||
bool IsEditing();
|
||||
|
||||
private:
|
||||
QSpacerItem *spacer = nullptr;
|
||||
QCheckBox *expand = nullptr;
|
||||
QLabel *iconLabel = nullptr;
|
||||
QCheckBox *vis = nullptr;
|
||||
QCheckBox *lock = nullptr;
|
||||
QHBoxLayout *boxLayout = nullptr;
|
||||
OBSSourceLabel *label = nullptr;
|
||||
|
||||
QLineEdit *editor = nullptr;
|
||||
|
||||
std::string newName;
|
||||
|
||||
SourceTree *tree;
|
||||
OBSSceneItem sceneitem;
|
||||
std::vector<OBSSignal> sigs;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void ExitEditModeInternal(bool save);
|
||||
|
||||
private slots:
|
||||
void Clear();
|
||||
|
||||
void EnterEditMode();
|
||||
void ExitEditMode(bool save);
|
||||
|
||||
void VisibilityChanged(bool visible);
|
||||
void LockedChanged(bool locked);
|
||||
|
||||
void ExpandClicked(bool checked);
|
||||
|
||||
void Select();
|
||||
void Deselect();
|
||||
};
|
||||
|
||||
class SourceTreeModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
@ -125,78 +45,3 @@ public:
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
};
|
||||
|
||||
class SourceTree : public QListView {
|
||||
Q_OBJECT
|
||||
|
||||
bool ignoreReorder = false;
|
||||
|
||||
friend class SourceTreeModel;
|
||||
friend class SourceTreeItem;
|
||||
|
||||
bool textPrepared = false;
|
||||
QStaticText textNoSources;
|
||||
QSvgRenderer iconNoSources;
|
||||
|
||||
OBSData undoSceneData;
|
||||
|
||||
bool iconsVisible = true;
|
||||
|
||||
void UpdateNoSourcesMessage();
|
||||
|
||||
void ResetWidgets();
|
||||
void UpdateWidget(const QModelIndex &idx, obs_sceneitem_t *item);
|
||||
void UpdateWidgets(bool force = false);
|
||||
|
||||
inline SourceTreeModel *GetStm() const { return reinterpret_cast<SourceTreeModel *>(model()); }
|
||||
|
||||
public:
|
||||
inline SourceTreeItem *GetItemWidget(int idx)
|
||||
{
|
||||
QWidget *widget = indexWidget(GetStm()->createIndex(idx, 0));
|
||||
return reinterpret_cast<SourceTreeItem *>(widget);
|
||||
}
|
||||
|
||||
explicit SourceTree(QWidget *parent = nullptr);
|
||||
|
||||
inline bool IgnoreReorder() const { return ignoreReorder; }
|
||||
inline void Clear() { GetStm()->Clear(); }
|
||||
|
||||
inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); }
|
||||
inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); }
|
||||
inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); }
|
||||
|
||||
void SelectItem(obs_sceneitem_t *sceneitem, bool select);
|
||||
|
||||
bool MultipleBaseSelected() const;
|
||||
bool GroupsSelected() const;
|
||||
bool GroupedItemsSelected() const;
|
||||
|
||||
void UpdateIcons();
|
||||
void SetIconsVisible(bool visible);
|
||||
|
||||
public slots:
|
||||
inline void ReorderItems() { GetStm()->ReorderItems(); }
|
||||
inline void RefreshItems() { GetStm()->SceneChanged(); }
|
||||
void Remove(OBSSceneItem item, OBSScene scene);
|
||||
void GroupSelectedItems();
|
||||
void UngroupSelectedGroups();
|
||||
void AddGroup();
|
||||
bool Edit(int idx);
|
||||
void NewGroupEdit(int idx);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
};
|
||||
|
||||
class SourceTreeDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceTreeDelegate(QObject *parent);
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
};
|
||||
|
@ -1,574 +1,18 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "TextSourceToolbar.hpp"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#include <OBSApp.hpp>
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
|
||||
#elif __APPLE__
|
||||
#define get_os_module(win, mac, linux) obs_get_module(mac)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
|
||||
#else
|
||||
#define get_os_module(win, mac, linux) obs_get_module(linux)
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "WindowCapture.Window", "WindowUtils.Window", "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) //linux
|
||||
prop_name = "capture_window";
|
||||
#else
|
||||
prop_name = "window";
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
is_int = true;
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#include "moc_TextSourceToolbar.cpp"
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
extern QColor color_from_int(long long val);
|
||||
extern long long color_to_int(QColor color);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
|
@ -1,165 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
#include "SourceToolbar.hpp"
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -1,69 +1,9 @@
|
||||
#include "moc_visibility-item-widget.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "source-label.hpp"
|
||||
#include "VisibilityItemWidget.hpp"
|
||||
#include "VisibilityItemDelegate.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QListWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QLabel>
|
||||
#include <QKeyEvent>
|
||||
#include <QCheckBox>
|
||||
|
||||
VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
|
||||
: source(source_),
|
||||
enabledSignal(obs_source_get_signal_handler(source), "enable", OBSSourceEnabled, this)
|
||||
{
|
||||
bool enabled = obs_source_enabled(source);
|
||||
|
||||
vis = new QCheckBox();
|
||||
vis->setProperty("class", "checkbox-icon indicator-visibility");
|
||||
vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
vis->setChecked(enabled);
|
||||
|
||||
label = new OBSSourceLabel(source);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
QHBoxLayout *itemLayout = new QHBoxLayout();
|
||||
itemLayout->addWidget(vis);
|
||||
itemLayout->addWidget(label);
|
||||
itemLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
setLayout(itemLayout);
|
||||
|
||||
connect(vis, &QCheckBox::clicked, [this](bool visible) { obs_source_set_enabled(source, visible); });
|
||||
}
|
||||
|
||||
void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
|
||||
{
|
||||
VisibilityItemWidget *window = reinterpret_cast<VisibilityItemWidget *>(param);
|
||||
bool enabled = calldata_bool(data, "enabled");
|
||||
|
||||
QMetaObject::invokeMethod(window, "SourceEnabled", Q_ARG(bool, enabled));
|
||||
}
|
||||
|
||||
void VisibilityItemWidget::SourceEnabled(bool enabled)
|
||||
{
|
||||
if (vis->isChecked() != enabled)
|
||||
vis->setChecked(enabled);
|
||||
}
|
||||
|
||||
void VisibilityItemWidget::SetColor(const QColor &color, bool active_, bool selected_)
|
||||
{
|
||||
/* Do not update unless the state has actually changed */
|
||||
if (active_ == active && selected_ == selected)
|
||||
return;
|
||||
|
||||
QPalette pal = vis->palette();
|
||||
pal.setColor(QPalette::WindowText, color);
|
||||
vis->setPalette(pal);
|
||||
|
||||
label->setStyleSheet(QString("color: %1;").arg(color.name()));
|
||||
|
||||
active = active_;
|
||||
selected = selected_;
|
||||
}
|
||||
#include "moc_VisibilityItemDelegate.cpp"
|
||||
|
||||
VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
@ -124,10 +64,3 @@ bool VisibilityItemDelegate::eventFilter(QObject *object, QEvent *event)
|
||||
|
||||
return QStyledItemDelegate::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, obs_source_t *source)
|
||||
{
|
||||
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
|
||||
|
||||
list->setItemWidget(item, baseWidget);
|
||||
}
|
||||
|
@ -1,39 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QCheckBox;
|
||||
class OBSSourceLabel;
|
||||
|
||||
class VisibilityItemWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
OBSSource source;
|
||||
OBSSourceLabel *label = nullptr;
|
||||
QCheckBox *vis = nullptr;
|
||||
|
||||
OBSSignal enabledSignal;
|
||||
|
||||
bool active = false;
|
||||
bool selected = false;
|
||||
|
||||
static void OBSSourceEnabled(void *param, calldata_t *data);
|
||||
|
||||
private slots:
|
||||
void SourceEnabled(bool enabled);
|
||||
|
||||
public:
|
||||
VisibilityItemWidget(obs_source_t *source);
|
||||
|
||||
void SetColor(const QColor &color, bool active, bool selected);
|
||||
};
|
||||
class QObject;
|
||||
|
||||
class VisibilityItemDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
@ -46,5 +15,3 @@ public:
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
};
|
||||
|
||||
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, obs_source_t *source);
|
||||
|
@ -1,15 +1,11 @@
|
||||
#include "moc_visibility-item-widget.cpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "source-label.hpp"
|
||||
#include "VisibilityItemWidget.hpp"
|
||||
|
||||
#include <components/OBSSourceLabel.hpp>
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QListWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QLabel>
|
||||
#include <QKeyEvent>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "moc_VisibilityItemWidget.cpp"
|
||||
|
||||
VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
|
||||
: source(source_),
|
||||
@ -65,66 +61,6 @@ void VisibilityItemWidget::SetColor(const QColor &color, bool active_, bool sele
|
||||
selected = selected_;
|
||||
}
|
||||
|
||||
VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void VisibilityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
QObject *parentObj = parent();
|
||||
QListWidget *list = qobject_cast<QListWidget *>(parentObj);
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
QListWidgetItem *item = list->item(index.row());
|
||||
VisibilityItemWidget *widget = qobject_cast<VisibilityItemWidget *>(list->itemWidget(item));
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
bool selected = option.state.testFlag(QStyle::State_Selected);
|
||||
bool active = option.state.testFlag(QStyle::State_Active);
|
||||
|
||||
QPalette palette = list->palette();
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
QPalette::ColorGroup group = active ? QPalette::Active : QPalette::Inactive;
|
||||
#else
|
||||
QPalette::ColorGroup group = QPalette::Active;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
QPalette::ColorRole highlightRole = QPalette::WindowText;
|
||||
#else
|
||||
QPalette::ColorRole highlightRole = QPalette::HighlightedText;
|
||||
#endif
|
||||
|
||||
QPalette::ColorRole role;
|
||||
|
||||
if (selected && active)
|
||||
role = highlightRole;
|
||||
else
|
||||
role = QPalette::WindowText;
|
||||
|
||||
widget->SetColor(palette.color(group, role), active, selected);
|
||||
}
|
||||
|
||||
bool VisibilityItemDelegate::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
QWidget *editor = qobject_cast<QWidget *>(object);
|
||||
if (!editor)
|
||||
return false;
|
||||
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, obs_source_t *source)
|
||||
{
|
||||
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
|
||||
|
@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <obs.hpp>
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QCheckBox;
|
||||
#include <QListWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class OBSSourceLabel;
|
||||
class QCheckBox;
|
||||
|
||||
class VisibilityItemWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
@ -35,16 +32,4 @@ public:
|
||||
void SetColor(const QColor &color, bool active, bool selected);
|
||||
};
|
||||
|
||||
class VisibilityItemDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VisibilityItemDelegate(QObject *parent = nullptr);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
};
|
||||
|
||||
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, obs_source_t *source);
|
||||
|
@ -1,18 +1,6 @@
|
||||
#include "window-basic-main.hpp"
|
||||
#include "moc_context-bar-controls.cpp"
|
||||
#include "obs-app.hpp"
|
||||
|
||||
#include <qt-wrappers.hpp>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
#include "ui_browser-source-toolbar.h"
|
||||
#include "WindowCaptureToolbar.hpp"
|
||||
#include "ui_device-select-toolbar.h"
|
||||
#include "ui_game-capture-toolbar.h"
|
||||
#include "ui_image-source-toolbar.h"
|
||||
#include "ui_color-source-toolbar.h"
|
||||
#include "ui_text-source-toolbar.h"
|
||||
#include "moc_WindowCaptureToolbar.cpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define get_os_module(win, mac, linux) obs_get_module(win)
|
||||
@ -25,205 +13,6 @@
|
||||
#define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
props(obs_source_properties(source), obs_properties_destroy)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceToolbar::SaveOldProperties(obs_source_t *source)
|
||||
{
|
||||
oldData = obs_data_create();
|
||||
|
||||
OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
|
||||
obs_data_apply(oldData, oldSettings);
|
||||
obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
|
||||
}
|
||||
|
||||
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
|
||||
{
|
||||
if (!oldData) {
|
||||
blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
OBSSource currentSceneSource = main->GetCurrentSceneSource();
|
||||
if (!currentSceneSource)
|
||||
return;
|
||||
std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
|
||||
auto undo_redo = [scene_uuid = std::move(scene_uuid), main](const std::string &data) {
|
||||
OBSDataAutoRelease settings = obs_data_create_from_json(data.c_str());
|
||||
OBSSourceAutoRelease source = obs_get_source_by_uuid(obs_data_get_string(settings, "undo_suuid"));
|
||||
obs_source_reset_settings(source, settings);
|
||||
|
||||
OBSSourceAutoRelease scene_source = obs_get_source_by_uuid(scene_uuid.c_str());
|
||||
main->SetCurrentScene(scene_source.Get(), true);
|
||||
|
||||
main->UpdateContextBar();
|
||||
};
|
||||
|
||||
OBSDataAutoRelease new_settings = obs_data_create();
|
||||
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
|
||||
obs_data_apply(new_settings, curr_settings);
|
||||
obs_data_set_string(new_settings, "undo_suuid", obs_source_get_uuid(source));
|
||||
|
||||
std::string undo_data(obs_data_get_json(oldData));
|
||||
std::string redo_data(obs_data_get_json(new_settings));
|
||||
|
||||
if (undo_data.compare(redo_data) != 0)
|
||||
main->undo_s.add_action(QTStr("Undo.Properties").arg(obs_source_get_name(source)), undo_redo, undo_redo,
|
||||
undo_data, redo_data, repeatable);
|
||||
|
||||
oldData = nullptr;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_BrowserSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BrowserToolbar::~BrowserToolbar() {}
|
||||
|
||||
void BrowserToolbar::on_refresh_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ComboSelectToolbar::~ComboSelectToolbar() {}
|
||||
|
||||
static int FillPropertyCombo(QComboBox *c, obs_property_t *p, const std::string &cur_id, bool is_int = false)
|
||||
{
|
||||
size_t count = obs_property_list_item_count(p);
|
||||
int cur_idx = -1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const char *name = obs_property_list_item_name(p, i);
|
||||
std::string id;
|
||||
|
||||
if (is_int) {
|
||||
id = std::to_string(obs_property_list_item_int(p, i));
|
||||
} else {
|
||||
const char *val = obs_property_list_item_string(p, i);
|
||||
id = val ? val : "";
|
||||
}
|
||||
|
||||
if (cur_id == id)
|
||||
cur_idx = (int)i;
|
||||
|
||||
c->addItem(name, id.c_str());
|
||||
}
|
||||
|
||||
return cur_idx;
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source, obs_properties_t *props,
|
||||
const char *prop_name, bool is_int)
|
||||
{
|
||||
std::string cur_id;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (is_int) {
|
||||
cur_id = std::to_string(obs_data_get_int(settings, prop_name));
|
||||
} else {
|
||||
cur_id = obs_data_get_string(settings, prop_name);
|
||||
}
|
||||
|
||||
combo->blockSignals(true);
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, prop_name);
|
||||
int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
|
||||
|
||||
if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
|
||||
if (cur_idx == -1) {
|
||||
combo->insertItem(0, QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
|
||||
cur_idx = 0;
|
||||
}
|
||||
|
||||
SetComboItemEnabled(combo, cur_idx, false);
|
||||
}
|
||||
|
||||
combo->setCurrentIndex(cur_idx);
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::Init()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props.get(), prop_name, is_int);
|
||||
}
|
||||
|
||||
void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx, const char *prop_name, bool is_int)
|
||||
{
|
||||
QString id = combo->itemData(idx).toString();
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (is_int) {
|
||||
obs_data_set_int(settings, prop_name, id.toInt());
|
||||
} else {
|
||||
obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
}
|
||||
|
||||
void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveOldProperties(source);
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name, is_int);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void AudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Device", "CoreAudio.Device", "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "device_id";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void WindowCaptureToolbar::Init()
|
||||
@ -250,458 +39,3 @@ void WindowCaptureToolbar::Init()
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
ApplicationAudioCaptureToolbar::ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: ComboSelectToolbar(parent, source)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationAudioCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-wasapi");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Window");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
prop_name = "window";
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source) : ComboSelectToolbar(parent, source) {}
|
||||
|
||||
void DisplayCaptureToolbar::Init()
|
||||
{
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
|
||||
obs_module_t *mod = get_os_module("win-capture", "mac-capture", "linux-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
const char *device_str = get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "monitor_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "display_uuid";
|
||||
#else
|
||||
is_int = true;
|
||||
prop_name = "screen";
|
||||
#endif
|
||||
|
||||
ComboSelectToolbar::Init();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
delete ui->deviceLabel;
|
||||
delete ui->device;
|
||||
ui->deviceLabel = nullptr;
|
||||
ui->device = nullptr;
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar() {}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
|
||||
bool desyncedSetting = now_active != active;
|
||||
|
||||
active = !active;
|
||||
|
||||
const char *text = active ? deactivateText : activateText;
|
||||
ui->activateButton->setText(text);
|
||||
|
||||
if (desyncedSetting) {
|
||||
return;
|
||||
}
|
||||
|
||||
calldata_t cd = {};
|
||||
calldata_set_bool(&cd, "active", active);
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_call(ph, "activate", &cd);
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_GameCaptureToolbar)
|
||||
{
|
||||
obs_property_t *p;
|
||||
int cur_idx;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-capture");
|
||||
if (!mod)
|
||||
return;
|
||||
|
||||
ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
|
||||
ui->windowLabel->setText(obs_module_get_locale_text(mod, "WindowCapture.Window"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string cur_mode = obs_data_get_string(settings, "capture_mode");
|
||||
std::string cur_window = obs_data_get_string(settings, "window");
|
||||
|
||||
ui->mode->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "capture_mode");
|
||||
cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
|
||||
ui->mode->setCurrentIndex(cur_idx);
|
||||
ui->mode->blockSignals(false);
|
||||
|
||||
ui->window->blockSignals(true);
|
||||
p = obs_properties_get(props.get(), "window");
|
||||
cur_idx = FillPropertyCombo(ui->window, p, cur_window);
|
||||
ui->window->setCurrentIndex(cur_idx);
|
||||
ui->window->blockSignals(false);
|
||||
|
||||
if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
|
||||
SetComboItemEnabled(ui->window, cur_idx, false);
|
||||
}
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
GameCaptureToolbar::~GameCaptureToolbar() {}
|
||||
|
||||
void GameCaptureToolbar::UpdateWindowVisibility()
|
||||
{
|
||||
QString mode = ui->mode->currentData().toString();
|
||||
bool is_window = (mode == "window");
|
||||
ui->windowLabel->setVisible(is_window);
|
||||
ui->window->setVisible(is_window);
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->mode->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
|
||||
UpdateWindowVisibility();
|
||||
}
|
||||
|
||||
void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString id = ui->window->itemData(idx).toString();
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "window", QT_TO_UTF8(id));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ImageSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
obs_module_t *mod = obs_get_module("image-source");
|
||||
ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
std::string file = obs_data_get_string(settings, "file");
|
||||
|
||||
ui->path->setText(file.c_str());
|
||||
}
|
||||
|
||||
ImageSourceToolbar::~ImageSourceToolbar() {}
|
||||
|
||||
void ImageSourceToolbar::on_browse_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "file");
|
||||
const char *desc = obs_property_description(p);
|
||||
const char *filter = obs_property_path_filter(p);
|
||||
const char *default_path = obs_property_path_default_path(p);
|
||||
|
||||
QString startDir = ui->path->text();
|
||||
if (startDir.isEmpty())
|
||||
startDir = default_path;
|
||||
|
||||
QString path = OpenFile(this, desc, startDir, filter);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->path->setText(path);
|
||||
|
||||
SaveOldProperties(source);
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_string(settings, "file", QT_TO_UTF8(path));
|
||||
obs_source_update(source, settings);
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_ColorSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
UpdateColor();
|
||||
}
|
||||
|
||||
ColorSourceToolbar::~ColorSourceToolbar() {}
|
||||
|
||||
void ColorSourceToolbar::UpdateColor()
|
||||
{
|
||||
QPalette palette = QPalette(color);
|
||||
ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
||||
ui->color->setText(color.name(QColor::HexRgb));
|
||||
ui->color->setPalette(palette);
|
||||
ui->color->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexRgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexRgb)));
|
||||
ui->color->setAutoFillBackground(true);
|
||||
ui->color->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void ColorSourceToolbar::on_choose_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), "color");
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
UpdateColor();
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
|
||||
|
||||
TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
|
||||
: SourceToolbar(parent, source),
|
||||
ui(new Ui_TextSourceToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
|
||||
const char *id = obs_source_get_unversioned_id(source);
|
||||
bool ft2 = strcmp(id, "text_ft2_source") == 0;
|
||||
bool read_from_file = obs_data_get_bool(settings, ft2 ? "from_file" : "read_from_file");
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
|
||||
MakeQFont(font_obj, font);
|
||||
|
||||
// Use "color1" if it's a freetype source and "color" elsewise
|
||||
unsigned int val = (unsigned int)obs_data_get_int(
|
||||
settings, (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0) ? "color1" : "color");
|
||||
|
||||
color = color_from_int(val);
|
||||
|
||||
const char *text = obs_data_get_string(settings, "text");
|
||||
|
||||
bool single_line = !read_from_file && (!text || (strchr(text, '\n') == nullptr));
|
||||
ui->emptySpace->setVisible(!single_line);
|
||||
ui->text->setVisible(single_line);
|
||||
if (single_line)
|
||||
ui->text->setText(text);
|
||||
}
|
||||
|
||||
TextSourceToolbar::~TextSourceToolbar() {}
|
||||
|
||||
void TextSourceToolbar::on_selectFont_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFontDialog::FontDialogOptions options;
|
||||
uint32_t flags;
|
||||
bool success;
|
||||
|
||||
#ifndef _WIN32
|
||||
options = QFontDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
font = QFontDialog::getFont(&success, font, this, QTStr("Basic.PropertiesWindow.SelectFont.WindowTitle"),
|
||||
options);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease font_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
|
||||
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
|
||||
obs_data_set_int(font_obj, "size", font.pointSize());
|
||||
flags = font.bold() ? OBS_FONT_BOLD : 0;
|
||||
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
|
||||
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
|
||||
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
|
||||
obs_data_set_int(font_obj, "flags", flags);
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
|
||||
obs_data_set_obj(settings, "font", font_obj);
|
||||
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_selectColor_clicked()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool freetype = strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
|
||||
|
||||
obs_property_t *p = obs_properties_get(props.get(), freetype ? "color1" : "color");
|
||||
|
||||
const char *desc = obs_property_description(p);
|
||||
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
|
||||
options |= QColorDialog::ShowAlphaChannel;
|
||||
#ifdef __linux__
|
||||
// TODO: Revisit hang on Ubuntu with native dialog
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
|
||||
QColor newColor = QColorDialog::getColor(color, this, desc, options);
|
||||
if (!newColor.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = newColor;
|
||||
|
||||
SaveOldProperties(source);
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_create();
|
||||
if (freetype) {
|
||||
obs_data_set_int(settings, "color1", color_to_int(color));
|
||||
obs_data_set_int(settings, "color2", color_to_int(color));
|
||||
} else {
|
||||
obs_data_set_int(settings, "color", color_to_int(color));
|
||||
}
|
||||
obs_source_update(source, settings);
|
||||
|
||||
SetUndoProperties(source);
|
||||
}
|
||||
|
||||
void TextSourceToolbar::on_text_textChanged()
|
||||
{
|
||||
OBSSource source = GetSource();
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
std::string newText = QT_TO_UTF8(ui->text->text());
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(source);
|
||||
if (newText == obs_data_get_string(settings, "text")) {
|
||||
return;
|
||||
}
|
||||
SaveOldProperties(source);
|
||||
|
||||
obs_data_set_string(settings, "text", newText.c_str());
|
||||
obs_source_update(source, nullptr);
|
||||
|
||||
SetUndoProperties(source, true);
|
||||
}
|
||||
|
@ -1,77 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <obs.hpp>
|
||||
#include <QWidget>
|
||||
|
||||
class Ui_BrowserSourceToolbar;
|
||||
class Ui_DeviceSelectToolbar;
|
||||
class Ui_GameCaptureToolbar;
|
||||
class Ui_ImageSourceToolbar;
|
||||
class Ui_ColorSourceToolbar;
|
||||
class Ui_TextSourceToolbar;
|
||||
|
||||
class SourceToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
protected:
|
||||
using properties_delete_t = decltype(&obs_properties_destroy);
|
||||
using properties_t = std::unique_ptr<obs_properties_t, properties_delete_t>;
|
||||
|
||||
properties_t props;
|
||||
OBSDataAutoRelease oldData;
|
||||
|
||||
void SaveOldProperties(obs_source_t *source);
|
||||
void SetUndoProperties(obs_source_t *source, bool repeatable = false);
|
||||
|
||||
public:
|
||||
SourceToolbar(QWidget *parent, OBSSource source);
|
||||
|
||||
OBSSource GetSource() { return OBSGetStrongRef(weakSource); }
|
||||
|
||||
public slots:
|
||||
virtual void Update() {}
|
||||
};
|
||||
|
||||
class BrowserToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_BrowserSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
BrowserToolbar(QWidget *parent, OBSSource source);
|
||||
~BrowserToolbar();
|
||||
|
||||
public slots:
|
||||
void on_refresh_clicked();
|
||||
};
|
||||
|
||||
class ComboSelectToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *prop_name;
|
||||
bool is_int = false;
|
||||
|
||||
public:
|
||||
ComboSelectToolbar(QWidget *parent, OBSSource source);
|
||||
~ComboSelectToolbar();
|
||||
virtual void Init();
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class AudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
#include "ComboSelectToolbar.hpp"
|
||||
|
||||
class WindowCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
@ -80,99 +9,3 @@ public:
|
||||
WindowCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class ApplicationAudioCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApplicationAudioCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DisplayCaptureToolbar : public ComboSelectToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
void Init() override;
|
||||
};
|
||||
|
||||
class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
|
||||
std::unique_ptr<Ui_DeviceSelectToolbar> ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
class GameCaptureToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_GameCaptureToolbar> ui;
|
||||
|
||||
void UpdateWindowVisibility();
|
||||
|
||||
public:
|
||||
GameCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~GameCaptureToolbar();
|
||||
|
||||
public slots:
|
||||
void on_mode_currentIndexChanged(int idx);
|
||||
void on_window_currentIndexChanged(int idx);
|
||||
};
|
||||
|
||||
class ImageSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ImageSourceToolbar> ui;
|
||||
|
||||
public:
|
||||
ImageSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ImageSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_browse_clicked();
|
||||
};
|
||||
|
||||
class ColorSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_ColorSourceToolbar> ui;
|
||||
QColor color;
|
||||
|
||||
void UpdateColor();
|
||||
|
||||
public:
|
||||
ColorSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~ColorSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_choose_clicked();
|
||||
};
|
||||
|
||||
class TextSourceToolbar : public SourceToolbar {
|
||||
Q_OBJECT
|
||||
|
||||
std::unique_ptr<Ui_TextSourceToolbar> ui;
|
||||
QFont font;
|
||||
QColor color;
|
||||
|
||||
public:
|
||||
TextSourceToolbar(QWidget *parent, OBSSource source);
|
||||
~TextSourceToolbar();
|
||||
|
||||
public slots:
|
||||
void on_selectFont_clicked();
|
||||
void on_selectColor_clicked();
|
||||
void on_text_textChanged();
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user