mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-01-08 22:38:20 -05:00
296 lines
9.2 KiB
C++
296 lines
9.2 KiB
C++
/******************************************************************************
|
|
Copyright (C) 2023 by Lain Bailey <lain@obsproject.com>
|
|
Zachary Lund <admin@computerquip.com>
|
|
Philippe Groarke <philippe.groarke@gmail.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
******************************************************************************/
|
|
|
|
#include "OBSBasic.hpp"
|
|
|
|
#include <components/ApplicationAudioCaptureToolbar.hpp>
|
|
#include <components/AudioCaptureToolbar.hpp>
|
|
#include <components/BrowserToolbar.hpp>
|
|
#include <components/ColorSourceToolbar.hpp>
|
|
#include <components/DeviceCaptureToolbar.hpp>
|
|
#include <components/DisplayCaptureToolbar.hpp>
|
|
#include <components/GameCaptureToolbar.hpp>
|
|
#include <components/ImageSourceToolbar.hpp>
|
|
#include <components/MediaControls.hpp>
|
|
#include <components/TextSourceToolbar.hpp>
|
|
#include <components/WindowCaptureToolbar.hpp>
|
|
|
|
#include <qt-wrappers.hpp>
|
|
|
|
void OBSBasic::copyActionsDynamicProperties()
|
|
{
|
|
// Themes need the QAction dynamic properties
|
|
for (QAction *x : ui->scenesToolbar->actions()) {
|
|
QWidget *temp = ui->scenesToolbar->widgetForAction(x);
|
|
|
|
if (!temp)
|
|
continue;
|
|
|
|
for (QByteArray &y : x->dynamicPropertyNames()) {
|
|
temp->setProperty(y.constData(), x->property(y.constData()));
|
|
}
|
|
}
|
|
|
|
for (QAction *x : ui->sourcesToolbar->actions()) {
|
|
QWidget *temp = ui->sourcesToolbar->widgetForAction(x);
|
|
|
|
if (!temp)
|
|
continue;
|
|
|
|
for (QByteArray &y : x->dynamicPropertyNames()) {
|
|
temp->setProperty(y.constData(), x->property(y.constData()));
|
|
}
|
|
}
|
|
|
|
for (QAction *x : ui->mixerToolbar->actions()) {
|
|
QWidget *temp = ui->mixerToolbar->widgetForAction(x);
|
|
|
|
if (!temp)
|
|
continue;
|
|
|
|
for (QByteArray &y : x->dynamicPropertyNames()) {
|
|
temp->setProperty(y.constData(), x->property(y.constData()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void OBSBasic::ClearContextBar()
|
|
{
|
|
QLayoutItem *la = ui->emptySpace->layout()->itemAt(0);
|
|
if (la) {
|
|
delete la->widget();
|
|
ui->emptySpace->layout()->removeItem(la);
|
|
}
|
|
}
|
|
|
|
void OBSBasic::UpdateContextBarVisibility()
|
|
{
|
|
int width = ui->centralwidget->size().width();
|
|
|
|
ContextBarSize contextBarSizeNew;
|
|
if (width >= 740) {
|
|
contextBarSizeNew = ContextBarSize_Normal;
|
|
} else if (width >= 600) {
|
|
contextBarSizeNew = ContextBarSize_Reduced;
|
|
} else {
|
|
contextBarSizeNew = ContextBarSize_Minimized;
|
|
}
|
|
|
|
if (contextBarSize == contextBarSizeNew)
|
|
return;
|
|
|
|
contextBarSize = contextBarSizeNew;
|
|
UpdateContextBarDeferred();
|
|
}
|
|
|
|
static bool is_network_media_source(obs_source_t *source, const char *id)
|
|
{
|
|
if (strcmp(id, "ffmpeg_source") != 0)
|
|
return false;
|
|
|
|
OBSDataAutoRelease s = obs_source_get_settings(source);
|
|
bool is_local_file = obs_data_get_bool(s, "is_local_file");
|
|
|
|
return !is_local_file;
|
|
}
|
|
|
|
void OBSBasic::UpdateContextBarDeferred(bool force)
|
|
{
|
|
QMetaObject::invokeMethod(this, "UpdateContextBar", Qt::QueuedConnection, Q_ARG(bool, force));
|
|
}
|
|
|
|
void OBSBasic::SourceToolBarActionsSetEnabled()
|
|
{
|
|
bool enable = false;
|
|
bool disableProps = false;
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
if (item) {
|
|
OBSSource source = obs_sceneitem_get_source(item);
|
|
disableProps = !obs_source_configurable(source);
|
|
|
|
enable = true;
|
|
}
|
|
|
|
if (disableProps)
|
|
ui->actionSourceProperties->setEnabled(false);
|
|
else
|
|
ui->actionSourceProperties->setEnabled(enable);
|
|
|
|
ui->actionRemoveSource->setEnabled(enable);
|
|
ui->actionSourceUp->setEnabled(enable);
|
|
ui->actionSourceDown->setEnabled(enable);
|
|
|
|
RefreshToolBarStyling(ui->sourcesToolbar);
|
|
}
|
|
|
|
void OBSBasic::UpdateContextBar(bool force)
|
|
{
|
|
SourceToolBarActionsSetEnabled();
|
|
|
|
if (!ui->contextContainer->isVisible() && !force)
|
|
return;
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
if (item) {
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
|
|
|
bool updateNeeded = true;
|
|
QLayoutItem *la = ui->emptySpace->layout()->itemAt(0);
|
|
if (la) {
|
|
if (SourceToolbar *toolbar = dynamic_cast<SourceToolbar *>(la->widget())) {
|
|
if (toolbar->GetSource() == source)
|
|
updateNeeded = false;
|
|
} else if (MediaControls *toolbar = dynamic_cast<MediaControls *>(la->widget())) {
|
|
if (toolbar->GetSource() == source)
|
|
updateNeeded = false;
|
|
}
|
|
}
|
|
|
|
const char *id = obs_source_get_unversioned_id(source);
|
|
uint32_t flags = obs_source_get_output_flags(source);
|
|
|
|
ui->sourceInteractButton->setVisible(flags & OBS_SOURCE_INTERACTION);
|
|
|
|
if (contextBarSize >= ContextBarSize_Reduced && (updateNeeded || force)) {
|
|
ClearContextBar();
|
|
if (flags & OBS_SOURCE_CONTROLLABLE_MEDIA) {
|
|
if (!is_network_media_source(source, id)) {
|
|
MediaControls *mediaControls = new MediaControls(ui->emptySpace);
|
|
mediaControls->SetSource(source);
|
|
|
|
ui->emptySpace->layout()->addWidget(mediaControls);
|
|
}
|
|
} else if (strcmp(id, "browser_source") == 0) {
|
|
BrowserToolbar *c = new BrowserToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "wasapi_input_capture") == 0 ||
|
|
strcmp(id, "wasapi_output_capture") == 0 ||
|
|
strcmp(id, "coreaudio_input_capture") == 0 ||
|
|
strcmp(id, "coreaudio_output_capture") == 0 ||
|
|
strcmp(id, "pulse_input_capture") == 0 || strcmp(id, "pulse_output_capture") == 0 ||
|
|
strcmp(id, "alsa_input_capture") == 0) {
|
|
AudioCaptureToolbar *c = new AudioCaptureToolbar(ui->emptySpace, source);
|
|
c->Init();
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "wasapi_process_output_capture") == 0) {
|
|
ApplicationAudioCaptureToolbar *c =
|
|
new ApplicationAudioCaptureToolbar(ui->emptySpace, source);
|
|
c->Init();
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "window_capture") == 0 || strcmp(id, "xcomposite_input") == 0) {
|
|
WindowCaptureToolbar *c = new WindowCaptureToolbar(ui->emptySpace, source);
|
|
c->Init();
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "monitor_capture") == 0 || strcmp(id, "display_capture") == 0 ||
|
|
strcmp(id, "xshm_input") == 0) {
|
|
DisplayCaptureToolbar *c = new DisplayCaptureToolbar(ui->emptySpace, source);
|
|
c->Init();
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "dshow_input") == 0) {
|
|
DeviceCaptureToolbar *c = new DeviceCaptureToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "game_capture") == 0) {
|
|
GameCaptureToolbar *c = new GameCaptureToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "image_source") == 0) {
|
|
ImageSourceToolbar *c = new ImageSourceToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "color_source") == 0) {
|
|
ColorSourceToolbar *c = new ColorSourceToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
|
|
} else if (strcmp(id, "text_ft2_source") == 0 || strcmp(id, "text_gdiplus") == 0) {
|
|
TextSourceToolbar *c = new TextSourceToolbar(ui->emptySpace, source);
|
|
ui->emptySpace->layout()->addWidget(c);
|
|
}
|
|
} else if (contextBarSize == ContextBarSize_Minimized) {
|
|
ClearContextBar();
|
|
}
|
|
|
|
QIcon icon;
|
|
|
|
if (strcmp(id, "scene") == 0)
|
|
icon = GetSceneIcon();
|
|
else if (strcmp(id, "group") == 0)
|
|
icon = GetGroupIcon();
|
|
else
|
|
icon = GetSourceIcon(id);
|
|
|
|
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
|
ui->contextSourceIcon->setPixmap(pixmap);
|
|
ui->contextSourceIconSpacer->hide();
|
|
ui->contextSourceIcon->show();
|
|
|
|
const char *name = obs_source_get_name(source);
|
|
ui->contextSourceLabel->setText(name);
|
|
|
|
ui->sourceFiltersButton->setEnabled(true);
|
|
ui->sourcePropertiesButton->setEnabled(obs_source_configurable(source));
|
|
} else {
|
|
ClearContextBar();
|
|
ui->contextSourceIcon->hide();
|
|
ui->contextSourceIconSpacer->show();
|
|
ui->contextSourceLabel->setText(QTStr("ContextBar.NoSelectedSource"));
|
|
|
|
ui->sourceFiltersButton->setEnabled(false);
|
|
ui->sourcePropertiesButton->setEnabled(false);
|
|
ui->sourceInteractButton->setVisible(false);
|
|
}
|
|
|
|
if (contextBarSize == ContextBarSize_Normal) {
|
|
ui->sourcePropertiesButton->setText(QTStr("Properties"));
|
|
ui->sourceFiltersButton->setText(QTStr("Filters"));
|
|
ui->sourceInteractButton->setText(QTStr("Interact"));
|
|
} else {
|
|
ui->sourcePropertiesButton->setText("");
|
|
ui->sourceFiltersButton->setText("");
|
|
ui->sourceInteractButton->setText("");
|
|
}
|
|
}
|
|
|
|
void OBSBasic::ShowContextBar()
|
|
{
|
|
on_toggleContextBar_toggled(true);
|
|
ui->toggleContextBar->setChecked(true);
|
|
}
|
|
|
|
void OBSBasic::HideContextBar()
|
|
{
|
|
on_toggleContextBar_toggled(false);
|
|
ui->toggleContextBar->setChecked(false);
|
|
}
|
|
|
|
void OBSBasic::on_toggleContextBar_toggled(bool visible)
|
|
{
|
|
config_set_bool(App()->GetUserConfig(), "BasicWindow", "ShowContextToolbars", visible);
|
|
this->ui->contextContainer->setVisible(visible);
|
|
UpdateContextBar(true);
|
|
}
|