obs-frontend-api,UI,docs: Add API to add custom docks with no toggle

Some plugin does that by deleting the QAction returned by
obs_frontend_add_dock().

Now that obs_frontend_add_dock() is deprecated,
obs_frontend_add_custom_qdock() replace this usage.
This commit is contained in:
tytan652 2022-10-22 11:51:30 +02:00 committed by Lain
parent cde5545f8f
commit 90d96e92c2
7 changed files with 107 additions and 10 deletions

View File

@ -427,6 +427,24 @@ struct OBSStudioAPI : obs_frontend_callbacks {
main->RemoveDockWidget(QT_UTF8(id));
}
bool obs_frontend_add_custom_qdock(const char *id, void *dock) override
{
if (main->IsDockObjectNameUsed(QT_UTF8(id))) {
blog(LOG_WARNING,
"Dock id '%s' already used! "
"Duplicate library?",
id);
return false;
}
QDockWidget *d = reinterpret_cast<QDockWidget *>(dock);
d->setObjectName(QT_UTF8(id));
main->AddCustomDockWidget(d);
return true;
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) override
{

View File

@ -344,6 +344,12 @@ void obs_frontend_remove_dock(const char *id)
c->obs_frontend_remove_dock(id);
}
bool obs_frontend_add_custom_qdock(const char *id, void *dock)
{
return !!callbacks_valid() ? c->obs_frontend_add_custom_qdock(id, dock)
: false;
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data)
{

View File

@ -147,6 +147,9 @@ EXPORT bool obs_frontend_add_dock_by_id(const char *id, const char *title,
EXPORT void obs_frontend_remove_dock(const char *id);
/* takes QDockWidget for dock */
EXPORT bool obs_frontend_add_custom_qdock(const char *id, void *dock);
typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
void *private_data);

View File

@ -70,6 +70,8 @@ struct obs_frontend_callbacks {
const char *title,
void *widget) = 0;
virtual void obs_frontend_remove_dock(const char *id) = 0;
virtual bool obs_frontend_add_custom_qdock(const char *id,
void *dock) = 0;
virtual void
obs_frontend_add_event_callback(obs_frontend_event_cb callback,

View File

@ -9311,10 +9311,12 @@ void OBSBasic::on_resetDocks_triggered(bool force)
#ifdef BROWSER_AVAILABLE
if ((oldExtraDocks.size() || extraDocks.size() ||
extraBrowserDocks.size()) &&
extraCustomDocks.size() || extraBrowserDocks.size()) &&
!force) {
#else
if ((oldExtraDocks.size() || extraDocks.size()) && !force) {
if ((oldExtraDocks.size() || extraDocks.size() ||
extraCustomDocks.size()) &&
!force) {
#endif
QMessageBox::StandardButton button = QMessageBox::question(
this, QTStr("ResetUIWarning.Title"),
@ -9347,6 +9349,7 @@ void OBSBasic::on_resetDocks_triggered(bool force)
}
RESET_DOCKLIST(extraDocks)
RESET_DOCKLIST(extraCustomDocks)
#ifdef BROWSER_AVAILABLE
RESET_DOCKLIST(extraBrowserDocks)
#endif
@ -9406,6 +9409,9 @@ void OBSBasic::on_lockDocks_toggled(bool lock)
for (int i = extraDocks.size() - 1; i >= 0; i--)
extraDocks[i]->setFeatures(features);
for (int i = extraCustomDocks.size() - 1; i >= 0; i--)
extraCustomDocks[i]->setFeatures(features);
#ifdef BROWSER_AVAILABLE
for (int i = extraBrowserDocks.size() - 1; i >= 0; i--)
extraBrowserDocks[i]->setFeatures(features);
@ -10321,13 +10327,17 @@ void OBSBasic::AddDockWidget(QDockWidget *dock, Qt::DockWidgetArea area,
void OBSBasic::RemoveDockWidget(const QString &name)
{
if (!extraDockNames.contains(name))
return;
int idx = extraDockNames.indexOf(name);
extraDockNames.removeAt(idx);
extraDocks[idx].clear();
extraDocks.removeAt(idx);
if (extraDockNames.contains(name)) {
int idx = extraDockNames.indexOf(name);
extraDockNames.removeAt(idx);
extraDocks[idx].clear();
extraDocks.removeAt(idx);
} else if (extraCustomDockNames.contains(name)) {
int idx = extraCustomDockNames.indexOf(name);
extraCustomDockNames.removeAt(idx);
removeDockWidget(extraCustomDocks[idx]);
extraCustomDocks.removeAt(idx);
}
}
bool OBSBasic::IsDockObjectNameUsed(const QString &name)
@ -10341,10 +10351,48 @@ bool OBSBasic::IsDockObjectNameUsed(const QString &name)
<< "statsDock";
list << oldExtraDockNames;
list << extraDockNames;
list << extraCustomDockNames;
return list.contains(name);
}
void OBSBasic::AddCustomDockWidget(QDockWidget *dock)
{
// Prevent the object name from being changed
connect(dock, &QObject::objectNameChanged, this,
&OBSBasic::RepairCustomExtraDockName);
bool lock = ui->lockDocks->isChecked();
QDockWidget::DockWidgetFeatures features =
lock ? QDockWidget::NoDockWidgetFeatures
: (QDockWidget::DockWidgetClosable |
QDockWidget::DockWidgetMovable |
QDockWidget::DockWidgetFloatable);
dock->setFeatures(features);
addDockWidget(Qt::RightDockWidgetArea, dock);
extraCustomDockNames.push_back(dock->objectName());
extraCustomDocks.push_back(dock);
}
void OBSBasic::RepairCustomExtraDockName()
{
QDockWidget *dock = reinterpret_cast<QDockWidget *>(sender());
int idx = extraCustomDocks.indexOf(dock);
QSignalBlocker block(dock);
if (idx == -1) {
blog(LOG_WARNING, "A custom dock got its object name changed");
return;
}
blog(LOG_WARNING, "The custom dock '%s' got its object name restored",
QT_TO_UTF8(extraCustomDockNames[idx]));
dock->setObjectName(extraCustomDockNames[idx]);
}
OBSBasic *OBSBasic::Get()
{
return reinterpret_cast<OBSBasic *>(App()->GetMainWindow());

View File

@ -557,6 +557,9 @@ private:
QStringList extraDockNames;
QList<QSharedPointer<QDockWidget>> extraDocks;
QStringList extraCustomDockNames;
QList<QPointer<QDockWidget>> extraCustomDocks;
#ifdef BROWSER_AVAILABLE
QPointer<QAction> extraBrowserMenuDocksSeparator;
@ -972,6 +975,7 @@ public:
bool extraBrowser = false);
void RemoveDockWidget(const QString &name);
bool IsDockObjectNameUsed(const QString &name);
void AddCustomDockWidget(QDockWidget *dock);
static OBSBasic *Get();
@ -1205,6 +1209,7 @@ private slots:
void ResizeOutputSizeOfSource();
void RepairOldExtraDockName();
void RepairCustomExtraDockName();
public slots:
void on_actionResetTransform_triggered();

View File

@ -448,7 +448,8 @@ Functions
:return: A pointer to the added QAction
.. deprecated:: 29.1
Prefer :c:func:`obs_frontend_add_dock_by_id()` instead.
Prefer :c:func:`obs_frontend_add_dock_by_id()` or
:c:func:`obs_frontend_add_custom_qdock()` instead.
---------------------------------------
@ -476,6 +477,20 @@ Functions
---------------------------------------
.. function:: bool obs_frontend_add_custom_qdock(const char *id, void *dock)
Adds a custom dock to the UI with no toggle.
Note: Use :c:func:`obs_frontend_remove_dock` to remove the dock
reference and id from the UI.
:param id: Unique identifier of the dock
:param dock: QDockWidget to add
:return: *true* if the dock was added, *false* if the id was already
used
---------------------------------------
.. function:: void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data)
Adds a callback that will be called when a frontend event occurs.