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)); 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 obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) override void *private_data) override
{ {

View File

@ -344,6 +344,12 @@ void obs_frontend_remove_dock(const char *id)
c->obs_frontend_remove_dock(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 obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) 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); 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, typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
void *private_data); void *private_data);

View File

@ -70,6 +70,8 @@ struct obs_frontend_callbacks {
const char *title, const char *title,
void *widget) = 0; void *widget) = 0;
virtual void obs_frontend_remove_dock(const char *id) = 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 virtual void
obs_frontend_add_event_callback(obs_frontend_event_cb callback, 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 #ifdef BROWSER_AVAILABLE
if ((oldExtraDocks.size() || extraDocks.size() || if ((oldExtraDocks.size() || extraDocks.size() ||
extraBrowserDocks.size()) && extraCustomDocks.size() || extraBrowserDocks.size()) &&
!force) { !force) {
#else #else
if ((oldExtraDocks.size() || extraDocks.size()) && !force) { if ((oldExtraDocks.size() || extraDocks.size() ||
extraCustomDocks.size()) &&
!force) {
#endif #endif
QMessageBox::StandardButton button = QMessageBox::question( QMessageBox::StandardButton button = QMessageBox::question(
this, QTStr("ResetUIWarning.Title"), this, QTStr("ResetUIWarning.Title"),
@ -9347,6 +9349,7 @@ void OBSBasic::on_resetDocks_triggered(bool force)
} }
RESET_DOCKLIST(extraDocks) RESET_DOCKLIST(extraDocks)
RESET_DOCKLIST(extraCustomDocks)
#ifdef BROWSER_AVAILABLE #ifdef BROWSER_AVAILABLE
RESET_DOCKLIST(extraBrowserDocks) RESET_DOCKLIST(extraBrowserDocks)
#endif #endif
@ -9406,6 +9409,9 @@ void OBSBasic::on_lockDocks_toggled(bool lock)
for (int i = extraDocks.size() - 1; i >= 0; i--) for (int i = extraDocks.size() - 1; i >= 0; i--)
extraDocks[i]->setFeatures(features); extraDocks[i]->setFeatures(features);
for (int i = extraCustomDocks.size() - 1; i >= 0; i--)
extraCustomDocks[i]->setFeatures(features);
#ifdef BROWSER_AVAILABLE #ifdef BROWSER_AVAILABLE
for (int i = extraBrowserDocks.size() - 1; i >= 0; i--) for (int i = extraBrowserDocks.size() - 1; i >= 0; i--)
extraBrowserDocks[i]->setFeatures(features); extraBrowserDocks[i]->setFeatures(features);
@ -10321,13 +10327,17 @@ void OBSBasic::AddDockWidget(QDockWidget *dock, Qt::DockWidgetArea area,
void OBSBasic::RemoveDockWidget(const QString &name) void OBSBasic::RemoveDockWidget(const QString &name)
{ {
if (!extraDockNames.contains(name)) if (extraDockNames.contains(name)) {
return;
int idx = extraDockNames.indexOf(name); int idx = extraDockNames.indexOf(name);
extraDockNames.removeAt(idx); extraDockNames.removeAt(idx);
extraDocks[idx].clear(); extraDocks[idx].clear();
extraDocks.removeAt(idx); 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) bool OBSBasic::IsDockObjectNameUsed(const QString &name)
@ -10341,10 +10351,48 @@ bool OBSBasic::IsDockObjectNameUsed(const QString &name)
<< "statsDock"; << "statsDock";
list << oldExtraDockNames; list << oldExtraDockNames;
list << extraDockNames; list << extraDockNames;
list << extraCustomDockNames;
return list.contains(name); 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() OBSBasic *OBSBasic::Get()
{ {
return reinterpret_cast<OBSBasic *>(App()->GetMainWindow()); return reinterpret_cast<OBSBasic *>(App()->GetMainWindow());

View File

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

View File

@ -448,7 +448,8 @@ Functions
:return: A pointer to the added QAction :return: A pointer to the added QAction
.. deprecated:: 29.1 .. 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) .. 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. Adds a callback that will be called when a frontend event occurs.