2016-02-23 23:16:51 +00:00
|
|
|
#include "visibility-item-widget.hpp"
|
|
|
|
#include "visibility-checkbox.hpp"
|
2018-02-19 19:54:37 +00:00
|
|
|
#include "locked-checkbox.hpp"
|
2016-02-23 23:16:51 +00:00
|
|
|
#include "qt-wrappers.hpp"
|
|
|
|
#include "obs-app.hpp"
|
|
|
|
#include <QListWidget>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QLabel>
|
|
|
|
|
|
|
|
VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
|
2019-09-22 21:19:10 +00:00
|
|
|
: source(source_),
|
|
|
|
enabledSignal(obs_source_get_signal_handler(source), "enable",
|
|
|
|
OBSSourceEnabled, this),
|
|
|
|
renamedSignal(obs_source_get_signal_handler(source), "rename",
|
|
|
|
OBSSourceRenamed, this)
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
const char *name = obs_source_get_name(source);
|
|
|
|
bool enabled = obs_source_enabled(source);
|
|
|
|
|
|
|
|
vis = new VisibilityCheckBox();
|
|
|
|
vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
|
|
|
/* Fix for non-apple systems where the spacing would be too big */
|
|
|
|
#ifndef __APPLE__
|
|
|
|
vis->setMaximumSize(16, 16);
|
|
|
|
#endif
|
|
|
|
vis->setChecked(enabled);
|
|
|
|
|
|
|
|
label = new QLabel(QT_UTF8(name));
|
|
|
|
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
|
|
|
|
|
|
QHBoxLayout *itemLayout = new QHBoxLayout();
|
|
|
|
itemLayout->addWidget(vis);
|
|
|
|
itemLayout->addWidget(label);
|
|
|
|
itemLayout->setContentsMargins(5, 2, 5, 2);
|
|
|
|
|
|
|
|
setLayout(itemLayout);
|
|
|
|
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
connect(vis, SIGNAL(clicked(bool)), this,
|
|
|
|
SLOT(VisibilityClicked(bool)));
|
2016-02-23 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
|
2019-09-22 21:19:10 +00:00
|
|
|
: item(item_),
|
|
|
|
source(obs_sceneitem_get_source(item)),
|
|
|
|
renamedSignal(obs_source_get_signal_handler(source), "rename",
|
|
|
|
OBSSourceRenamed, this)
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
const char *name = obs_source_get_name(source);
|
|
|
|
bool enabled = obs_sceneitem_visible(item);
|
2018-02-19 19:54:37 +00:00
|
|
|
bool locked = obs_sceneitem_locked(item);
|
2016-02-23 23:16:51 +00:00
|
|
|
obs_scene_t *scene = obs_sceneitem_get_scene(item);
|
|
|
|
obs_source_t *sceneSource = obs_scene_get_source(scene);
|
|
|
|
|
|
|
|
vis = new VisibilityCheckBox();
|
|
|
|
vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
|
|
|
/* Fix for non-apple systems where the spacing would be too big */
|
|
|
|
#ifndef __APPLE__
|
|
|
|
vis->setMaximumSize(16, 16);
|
|
|
|
#endif
|
|
|
|
vis->setChecked(enabled);
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
lock = new LockedCheckBox();
|
|
|
|
lock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
|
|
|
/* Fix for non-apple systems where the spacing would be too big */
|
|
|
|
#ifndef __APPLE__
|
|
|
|
lock->setMaximumSize(16, 16);
|
|
|
|
#endif
|
|
|
|
lock->setChecked(locked);
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
label = new QLabel(QT_UTF8(name));
|
|
|
|
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
#ifdef __APPLE__
|
|
|
|
vis->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
|
|
|
lock->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
|
|
|
#endif
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
QHBoxLayout *itemLayout = new QHBoxLayout();
|
|
|
|
itemLayout->addWidget(vis);
|
2018-02-19 19:54:37 +00:00
|
|
|
itemLayout->addWidget(lock);
|
2016-02-23 23:16:51 +00:00
|
|
|
itemLayout->addWidget(label);
|
|
|
|
itemLayout->setContentsMargins(5, 2, 5, 2);
|
2018-02-19 19:54:37 +00:00
|
|
|
itemLayout->setSpacing(2);
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
setLayout(itemLayout);
|
|
|
|
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
|
|
|
|
|
|
|
|
signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
|
|
|
|
signal_handler_connect(signal, "remove", OBSSceneRemove, this);
|
2019-09-22 21:19:10 +00:00
|
|
|
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, this);
|
2016-02-23 23:16:51 +00:00
|
|
|
signal_handler_connect(signal, "item_visible", OBSSceneItemVisible,
|
2019-09-22 21:19:10 +00:00
|
|
|
this);
|
|
|
|
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked, this);
|
2016-02-23 23:16:51 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
connect(vis, SIGNAL(clicked(bool)), this,
|
|
|
|
SLOT(VisibilityClicked(bool)));
|
2018-02-19 19:54:37 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
connect(lock, SIGNAL(clicked(bool)), this, SLOT(LockClicked(bool)));
|
2016-02-23 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VisibilityItemWidget::~VisibilityItemWidget()
|
|
|
|
{
|
|
|
|
DisconnectItemSignals();
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::DisconnectItemSignals()
|
|
|
|
{
|
|
|
|
if (!item || sceneRemoved)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs_scene_t *scene = obs_sceneitem_get_scene(item);
|
|
|
|
obs_source_t *sceneSource = obs_scene_get_source(scene);
|
|
|
|
signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
|
|
|
|
|
|
|
|
signal_handler_disconnect(signal, "remove", OBSSceneRemove, this);
|
|
|
|
signal_handler_disconnect(signal, "item_remove", OBSSceneItemRemove,
|
2019-09-22 21:19:10 +00:00
|
|
|
this);
|
2016-02-23 23:16:51 +00:00
|
|
|
signal_handler_disconnect(signal, "item_visible", OBSSceneItemVisible,
|
2019-09-22 21:19:10 +00:00
|
|
|
this);
|
|
|
|
signal_handler_disconnect(signal, "item_locked", OBSSceneItemLocked,
|
|
|
|
this);
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
sceneRemoved = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
window->DisconnectItemSignals();
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
|
|
|
obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(data, "item");
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
if (item == window->item)
|
|
|
|
window->DisconnectItemSignals();
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
|
|
|
obs_sceneitem_t *curItem =
|
|
|
|
(obs_sceneitem_t *)calldata_ptr(data, "item");
|
2016-02-23 23:16:51 +00:00
|
|
|
bool enabled = calldata_bool(data, "visible");
|
|
|
|
|
|
|
|
if (window->item == curItem)
|
|
|
|
QMetaObject::invokeMethod(window, "SourceEnabled",
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_ARG(bool, enabled));
|
2016-02-23 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
|
|
|
obs_sceneitem_t *curItem =
|
|
|
|
(obs_sceneitem_t *)calldata_ptr(data, "item");
|
2018-02-19 19:54:37 +00:00
|
|
|
bool locked = calldata_bool(data, "locked");
|
|
|
|
|
|
|
|
if (window->item == curItem)
|
|
|
|
QMetaObject::invokeMethod(window, "SourceLocked",
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_ARG(bool, locked));
|
2018-02-19 19:54:37 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
2016-02-23 23:16:51 +00:00
|
|
|
bool enabled = calldata_bool(data, "enabled");
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SourceEnabled",
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_ARG(bool, enabled));
|
2016-02-23 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data)
|
|
|
|
{
|
|
|
|
VisibilityItemWidget *window =
|
2019-09-22 21:19:10 +00:00
|
|
|
reinterpret_cast<VisibilityItemWidget *>(param);
|
2016-02-23 23:16:51 +00:00
|
|
|
const char *name = calldata_string(data, "new_name");
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SourceRenamed",
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_ARG(QString, QT_UTF8(name)));
|
2016-02-23 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemWidget::VisibilityClicked(bool visible)
|
|
|
|
{
|
|
|
|
if (item)
|
|
|
|
obs_sceneitem_set_visible(item, visible);
|
|
|
|
else
|
|
|
|
obs_source_set_enabled(source, visible);
|
|
|
|
}
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
void VisibilityItemWidget::LockClicked(bool locked)
|
|
|
|
{
|
|
|
|
if (item)
|
|
|
|
obs_sceneitem_set_locked(item, locked);
|
|
|
|
}
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
void VisibilityItemWidget::SourceEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
if (vis->isChecked() != enabled)
|
|
|
|
vis->setChecked(enabled);
|
|
|
|
}
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
void VisibilityItemWidget::SourceLocked(bool locked)
|
|
|
|
{
|
|
|
|
if (lock->isChecked() != locked)
|
|
|
|
lock->setChecked(locked);
|
|
|
|
}
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
void VisibilityItemWidget::SourceRenamed(QString name)
|
|
|
|
{
|
|
|
|
if (label && name != label->text())
|
|
|
|
label->setText(name);
|
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
void VisibilityItemWidget::SetColor(const QColor &color, bool active_,
|
|
|
|
bool selected_)
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
/* 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_;
|
|
|
|
}
|
|
|
|
|
|
|
|
VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent)
|
|
|
|
: QStyledItemDelegate(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisibilityItemDelegate::paint(QPainter *painter,
|
2019-09-22 21:19:10 +00:00
|
|
|
const QStyleOptionViewItem &option,
|
|
|
|
const QModelIndex &index) const
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
QStyledItemDelegate::paint(painter, option, index);
|
|
|
|
|
|
|
|
QObject *parentObj = parent();
|
2019-09-22 21:19:10 +00:00
|
|
|
QListWidget *list = qobject_cast<QListWidget *>(parentObj);
|
2016-02-23 23:16:51 +00:00
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QListWidgetItem *item = list->item(index.row());
|
|
|
|
VisibilityItemWidget *widget =
|
2019-09-22 21:19:10 +00:00
|
|
|
qobject_cast<VisibilityItemWidget *>(list->itemWidget(item));
|
2016-02-23 23:16:51 +00:00
|
|
|
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__)
|
2019-09-22 21:19:10 +00:00
|
|
|
QPalette::ColorGroup group = active ? QPalette::Active
|
|
|
|
: QPalette::Inactive;
|
2016-02-23 23:16:51 +00:00
|
|
|
#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);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_source_t *source)
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
|
|
|
|
|
|
|
|
item->setSizeHint(baseWidget->sizeHint());
|
|
|
|
list->setItemWidget(item, baseWidget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_sceneitem_t *sceneItem)
|
2016-02-23 23:16:51 +00:00
|
|
|
{
|
|
|
|
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(sceneItem);
|
|
|
|
|
|
|
|
item->setSizeHint(baseWidget->sizeHint());
|
|
|
|
list->setItemWidget(item, baseWidget);
|
|
|
|
}
|