mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
UI: Replace/simplify device toolbar
The old version of the device toolbar was a complex situation. Because of the fact that device properties can take significant time to query, this put an unpleasant burden on the UI thread; so to fix this problem, the device toolbar was made to be threaded. However, threading is a complex and dangerous thing, and there is a fear that this could cause complications down the line whenever users are simply selecting devices. So for the time being, as a safety precaution, simplify the device toolbar down to just the "activate" button, and make it so that if users really need to query and change the devices, that they need to explicitly open the properties. That way the devices aren't being queried constantly every time a device source is selected. Alternatively in the future, device enumeration could be cached, but seeing as that's a significant amount of work and needs to take in to account whether a user adds/removes a device while the process is active, that's not going to happen any time soon.
This commit is contained in:
parent
072a886453
commit
50d3130b64
@ -238,7 +238,6 @@ set(obs_SOURCES
|
||||
item-widget-helpers.cpp
|
||||
context-bar-controls.cpp
|
||||
horizontal-scroll-area.cpp
|
||||
context-bar-controls-devices.cpp
|
||||
vertical-scroll-area.cpp
|
||||
visibility-item-widget.cpp
|
||||
slider-absoluteset-style.cpp
|
||||
@ -306,7 +305,6 @@ set(obs_HEADERS
|
||||
item-widget-helpers.hpp
|
||||
visibility-checkbox.hpp
|
||||
context-bar-controls.hpp
|
||||
context-bar-controls-devices.hpp
|
||||
locked-checkbox.hpp
|
||||
horizontal-scroll-area.hpp
|
||||
expand-checkbox.hpp
|
||||
|
@ -1,149 +0,0 @@
|
||||
#include "context-bar-controls.hpp"
|
||||
#include "context-bar-controls-devices.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
|
||||
#include "ui_device-select-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
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceToolbarPropertiesThread::~DeviceToolbarPropertiesThread()
|
||||
{
|
||||
obs_properties_destroy(props);
|
||||
}
|
||||
|
||||
void DeviceToolbarPropertiesThread::run()
|
||||
{
|
||||
props = obs_source_properties(source);
|
||||
source = nullptr;
|
||||
QMetaObject::invokeMethod(this, "Ready");
|
||||
}
|
||||
|
||||
void DeviceToolbarPropertiesThread::Ready()
|
||||
{
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
QLayoutItem *la = main->ui->emptySpace->layout()->itemAt(0);
|
||||
if (la) {
|
||||
DeviceCaptureToolbar *dct =
|
||||
qobject_cast<DeviceCaptureToolbar *>(la->widget());
|
||||
if (dct) {
|
||||
dct->SetProperties(props);
|
||||
props = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
|
||||
: QWidget(parent),
|
||||
weakSource(OBSGetWeakRef(source)),
|
||||
ui(new Ui_DeviceSelectToolbar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#ifndef _WIN32
|
||||
delete ui->activateButton;
|
||||
ui->activateButton = nullptr;
|
||||
#endif
|
||||
|
||||
setEnabled(false);
|
||||
|
||||
obs_module_t *mod =
|
||||
get_os_module("win-dshow", "mac-avcapture", "linux-v4l2");
|
||||
const char *device_str = obs_module_get_locale_text(mod, "Device");
|
||||
ui->deviceLabel->setText(device_str);
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
if (!main->devicePropertiesThread ||
|
||||
!main->devicePropertiesThread->isRunning()) {
|
||||
main->devicePropertiesThread.reset(
|
||||
new DeviceToolbarPropertiesThread(source));
|
||||
main->devicePropertiesThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar()
|
||||
{
|
||||
delete ui;
|
||||
obs_properties_destroy(props);
|
||||
}
|
||||
|
||||
void DeviceCaptureToolbar::UpdateActivateButtonName()
|
||||
{
|
||||
obs_property_t *p = obs_properties_get(props, "activate");
|
||||
ui->activateButton->setText(obs_property_description(p));
|
||||
}
|
||||
|
||||
extern void UpdateSourceComboToolbarProperties(QComboBox *combo,
|
||||
OBSSource source,
|
||||
obs_properties_t *props,
|
||||
const char *prop_name,
|
||||
bool is_int);
|
||||
extern void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source,
|
||||
int idx, const char *prop_name,
|
||||
bool is_int);
|
||||
|
||||
void DeviceCaptureToolbar::SetProperties(obs_properties_t *props_)
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
obs_properties_destroy(props_);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
prop_name = "video_device_id";
|
||||
#elif __APPLE__
|
||||
prop_name = "device";
|
||||
#else
|
||||
prop_name = "device_id";
|
||||
#endif
|
||||
|
||||
props = props_;
|
||||
UpdateSourceComboToolbarProperties(ui->device, source, props, prop_name,
|
||||
false);
|
||||
#ifdef _WIN32
|
||||
UpdateActivateButtonName();
|
||||
#endif
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
void DeviceCaptureToolbar::on_device_currentIndexChanged(int idx)
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (idx == -1 || !source) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name,
|
||||
false);
|
||||
}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *p = obs_properties_get(props, "activate");
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_button_clicked(p, source.Get());
|
||||
#ifdef _WIN32
|
||||
UpdateActivateButtonName();
|
||||
#endif
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <obs.hpp>
|
||||
#include <string>
|
||||
#include <QThread>
|
||||
|
||||
class DeviceToolbarPropertiesThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
OBSSource source;
|
||||
obs_properties_t *props;
|
||||
|
||||
void run() override;
|
||||
|
||||
public:
|
||||
inline DeviceToolbarPropertiesThread(OBSSource source_)
|
||||
: source(source_)
|
||||
{
|
||||
}
|
||||
|
||||
~DeviceToolbarPropertiesThread() override;
|
||||
|
||||
public slots:
|
||||
void Ready();
|
||||
};
|
@ -255,6 +255,65 @@ void DisplayCaptureToolbar::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;
|
||||
|
||||
obs_data_t *settings = obs_source_get_settings(source);
|
||||
active = obs_data_get_bool(settings, "active");
|
||||
obs_data_release(settings);
|
||||
|
||||
obs_module_t *mod = obs_get_module("win-dshow");
|
||||
activateText = obs_module_get_locale_text(mod, "Activate");
|
||||
deactivateText = obs_module_get_locale_text(mod, "Deactivate");
|
||||
|
||||
ui->activateButton->setText(active ? deactivateText : activateText);
|
||||
}
|
||||
|
||||
DeviceCaptureToolbar::~DeviceCaptureToolbar()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DeviceCaptureToolbar::on_activateButton_clicked()
|
||||
{
|
||||
OBSSource source = OBSGetStrongRef(weakSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_data_t *settings = obs_source_get_settings(source);
|
||||
bool now_active = obs_data_get_bool(settings, "active");
|
||||
obs_data_release(settings);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -90,20 +90,17 @@ class DeviceCaptureToolbar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
OBSWeakSource weakSource;
|
||||
Ui_DeviceSelectToolbar *ui;
|
||||
obs_properties_t *props = nullptr;
|
||||
const char *prop_name;
|
||||
|
||||
void UpdateActivateButtonName();
|
||||
Ui_DeviceSelectToolbar *ui;
|
||||
const char *activateText;
|
||||
const char *deactivateText;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
DeviceCaptureToolbar(QWidget *parent, OBSSource source);
|
||||
~DeviceCaptureToolbar();
|
||||
|
||||
void SetProperties(obs_properties_t *prpos);
|
||||
|
||||
public slots:
|
||||
void on_device_currentIndexChanged(int idx);
|
||||
void on_activateButton_clicked();
|
||||
};
|
||||
|
||||
|
@ -2966,9 +2966,7 @@ void OBSBasic::UpdateContextBar()
|
||||
c->Init();
|
||||
ui->emptySpace->layout()->addWidget(c);
|
||||
|
||||
} else if (strcmp(id, "dshow_input") == 0 ||
|
||||
strcmp(id, "av_capture_input") == 0 ||
|
||||
strcmp(id, "v4l2_input") == 0) {
|
||||
} else if (strcmp(id, "dshow_input") == 0) {
|
||||
DeviceCaptureToolbar *c = new DeviceCaptureToolbar(
|
||||
ui->emptySpace, source);
|
||||
ui->emptySpace->layout()->addWidget(c);
|
||||
|
Loading…
Reference in New Issue
Block a user