UI, libobs: Add ability to lock individual scene items

Adds a lock checkbox to allow the user to lock a specific scene item.

Closes jp9000/obs-studio#949
This commit is contained in:
cg2121
2017-06-17 19:10:42 -05:00
committed by jp9000
parent 5c2328cca2
commit fce078d997
13 changed files with 144 additions and 0 deletions

View File

@@ -161,6 +161,7 @@ set(obs_SOURCES
adv-audio-control.cpp
item-widget-helpers.cpp
visibility-checkbox.cpp
locked-checkbox.cpp
vertical-scroll-area.cpp
visibility-item-widget.cpp
slider-absoluteset-style.cpp
@@ -208,6 +209,7 @@ set(obs_HEADERS
adv-audio-control.hpp
item-widget-helpers.hpp
visibility-checkbox.hpp
locked-checkbox.hpp
vertical-scroll-area.hpp
visibility-item-widget.hpp
slider-absoluteset-style.hpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@@ -14,6 +14,8 @@
<file>images/up.png</file>
<file>images/obs.png</file>
<file>images/tray_active.png</file>
<file>images/locked_mask.png</file>
<file>images/unlocked_mask.png</file>
</qresource>
<qresource prefix="/settings">
<file>images/settings/advanced.png</file>

36
UI/locked-checkbox.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <QPaintEvent>
#include <QPixmap>
#include <QPainter>
#include "locked-checkbox.hpp"
#include <util/c99defs.h>
LockedCheckBox::LockedCheckBox() : QCheckBox()
{
lockedImage =
QPixmap::fromImage(QImage(":/res/images/locked_mask.png"));
unlockedImage =
QPixmap::fromImage(QImage(":/res/images/unlocked_mask.png"));
setMinimumSize(16, 16);
setStyleSheet("outline: none;");
}
void LockedCheckBox::paintEvent(QPaintEvent *event)
{
UNUSED_PARAMETER(event);
QPixmap &pixmap = isChecked() ? lockedImage : unlockedImage;
QImage image(pixmap.size(), QImage::Format_ARGB32);
QPainter draw(&image);
draw.setCompositionMode(QPainter::CompositionMode_Source);
draw.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap);
draw.setCompositionMode(QPainter::CompositionMode_SourceIn);
draw.fillRect(QRectF(QPointF(0.0f, 0.0f), pixmap.size()),
palette().color(foregroundRole()));
QPainter p(this);
p.drawPixmap(0, 0, image.width(), image.height(),
QPixmap::fromImage(image));
}

17
UI/locked-checkbox.hpp Normal file
View File

@@ -0,0 +1,17 @@
#include <QCheckBox>
#include <QPixmap>
class QPaintEvernt;
class LockedCheckBox : public QCheckBox {
Q_OBJECT
QPixmap lockedImage;
QPixmap unlockedImage;
public:
LockedCheckBox();
protected:
void paintEvent(QPaintEvent *event) override;
};

View File

@@ -1,5 +1,6 @@
#include "visibility-item-widget.hpp"
#include "visibility-checkbox.hpp"
#include "locked-checkbox.hpp"
#include "qt-wrappers.hpp"
#include "obs-app.hpp"
#include <QListWidget>
@@ -49,6 +50,7 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
{
const char *name = obs_source_get_name(source);
bool enabled = obs_sceneitem_visible(item);
bool locked = obs_sceneitem_locked(item);
obs_scene_t *scene = obs_sceneitem_get_scene(item);
obs_source_t *sceneSource = obs_scene_get_source(scene);
@@ -60,13 +62,23 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
#endif
vis->setChecked(enabled);
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);
label = new QLabel(QT_UTF8(name));
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QHBoxLayout *itemLayout = new QHBoxLayout();
itemLayout->addWidget(vis);
itemLayout->addWidget(lock);
itemLayout->addWidget(label);
itemLayout->setContentsMargins(5, 2, 5, 2);
itemLayout->setSpacing(2);
setLayout(itemLayout);
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
@@ -80,6 +92,9 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
connect(vis, SIGNAL(clicked(bool)),
this, SLOT(VisibilityClicked(bool)));
connect(lock, SIGNAL(clicked(bool)),
this, SLOT(LockClicked(bool)));
}
VisibilityItemWidget::~VisibilityItemWidget()
@@ -137,6 +152,18 @@ void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
Q_ARG(bool, enabled));
}
void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
bool locked = calldata_bool(data, "locked");
if (window->item == curItem)
QMetaObject::invokeMethod(window, "SourceLocked",
Q_ARG(bool, locked));
}
void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
@@ -165,12 +192,24 @@ void VisibilityItemWidget::VisibilityClicked(bool visible)
obs_source_set_enabled(source, visible);
}
void VisibilityItemWidget::LockClicked(bool locked)
{
if (item)
obs_sceneitem_set_locked(item, locked);
}
void VisibilityItemWidget::SourceEnabled(bool enabled)
{
if (vis->isChecked() != enabled)
vis->setChecked(enabled);
}
void VisibilityItemWidget::SourceLocked(bool locked)
{
if (lock->isChecked() != locked)
lock->setChecked(locked);
}
void VisibilityItemWidget::SourceRenamed(QString name)
{
if (label && name != label->text())

View File

@@ -9,6 +9,7 @@ class QLineEdit;
class QListWidget;
class QListWidgetItem;
class VisibilityCheckBox;
class LockedCheckBox;
class VisibilityItemWidget : public QWidget {
Q_OBJECT
@@ -18,6 +19,7 @@ private:
OBSSource source;
QLabel *label = nullptr;
VisibilityCheckBox *vis = nullptr;
LockedCheckBox *lock = nullptr;
QString oldName;
OBSSignal sceneRemoveSignal;
@@ -31,6 +33,7 @@ private:
static void OBSSceneRemove(void *param, calldata_t *data);
static void OBSSceneItemRemove(void *param, calldata_t *data);
static void OBSSceneItemVisible(void *param, calldata_t *data);
static void OBSSceneItemLocked(void *param, calldata_t *data);
static void OBSSourceEnabled(void *param, calldata_t *data);
static void OBSSourceRenamed(void *param, calldata_t *data);
@@ -38,8 +41,10 @@ private:
private slots:
void VisibilityClicked(bool visible);
void LockClicked(bool locked);
void SourceEnabled(bool enabled);
void SourceRenamed(QString name);
void SourceLocked(bool locked);
public:
VisibilityItemWidget(obs_source_t *source);

View File

@@ -5004,6 +5004,9 @@ void OBSBasic::Nudge(int dist, MoveDir dir)
auto func = [] (obs_scene_t*, obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
MoveInfo *info = reinterpret_cast<MoveInfo*>(param);
struct vec2 dir;
struct vec2 pos;

View File

@@ -75,6 +75,8 @@ static bool FindItemAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
if (!SceneItemHasVideo(item))
return true;
if (obs_sceneitem_locked(item))
return true;
vec3_set(&pos3, data->pos.x, data->pos.y, 0.0f);
@@ -674,6 +676,9 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
vec2 *offset = reinterpret_cast<vec2*>(param);
if (obs_sceneitem_selected(item)) {
@@ -1084,6 +1089,9 @@ static inline bool crop_enabled(const obs_sceneitem_crop *crop)
bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
if (!obs_sceneitem_selected(item))
return true;
@@ -1183,6 +1191,7 @@ void OBSBasicPreview::DrawSceneEditing()
gs_technique_begin_pass(tech, 0);
OBSScene scene = main->GetCurrentScene();
if (scene)
obs_scene_enum_items(scene, DrawSelectedItem, this);