frontend: Update transform dialog

This commit is contained in:
Warchamp7
2025-07-19 19:09:25 -04:00
committed by Ryan Foster
parent c01a9bea49
commit 6fa1a35ad4
6 changed files with 941 additions and 723 deletions

View File

@@ -63,6 +63,8 @@ Left="Left"
Right="Right"
Top="Top"
Bottom="Bottom"
Width="Width"
Height="Height"
Reset="Reset"
Hours="Hours"
Minutes="Minutes"
@@ -699,24 +701,26 @@ Basic.Filters.AddFilter.Text="Please specify the name of the filter"
# transform window
Basic.TransformWindow="Scene Item Transform"
Basic.TransformWindow.Position="Position"
Basic.TransformWindow.PositionX="Position X"
Basic.TransformWindow.PositionY="Position Y"
Basic.TransformWindow.PositionX="X"
Basic.TransformWindow.PositionY="Y"
Basic.TransformWindow.Rotation="Rotation"
Basic.TransformWindow.Size="Size"
Basic.TransformWindow.Width="Width"
Basic.TransformWindow.Height="Height"
Basic.TransformWindow.Alignment="Positional Alignment"
Basic.TransformWindow.BoundsType="Bounding Box Type"
Basic.TransformWindow.BoundsAlignment="Alignment in Bounding Box"
Basic.TransformWindow.Bounds="Bounding Box Size"
Basic.TransformWindow.Alignment="Alignment"
Basic.TransformWindow.BoundsType="Bounds Type"
Basic.TransformWindow.BoundsAlignment="Bounds Alignment"
Basic.TransformWindow.Bounds="Bounds"
Basic.TransformWindow.BoundsWidth="Bounding Box Width"
Basic.TransformWindow.BoundsHeight="Bounding Box Height"
Basic.TransformWindow.CropToBounds="Crop to Bounding Box"
Basic.TransformWindow.CropToBounds="Crop Bounds"
Basic.TransformWindow.Crop="Crop"
Basic.TransformWindow.CropLeft="Crop Left"
Basic.TransformWindow.CropRight="Crop Right"
Basic.TransformWindow.CropTop="Crop Top"
Basic.TransformWindow.CropBottom="Crop Bottom"
Basic.TransformWindow.Accessible.PositionX="X Position"
Basic.TransformWindow.Accessible.PositionY="Y Position"
Basic.TransformWindow.Alignment.TopLeft="Top Left"
Basic.TransformWindow.Alignment.TopCenter="Top Center"
@@ -728,13 +732,13 @@ Basic.TransformWindow.Alignment.BottomLeft="Bottom Left"
Basic.TransformWindow.Alignment.BottomCenter="Bottom Center"
Basic.TransformWindow.Alignment.BottomRight="Bottom Right"
Basic.TransformWindow.BoundsType.None="No bounds"
Basic.TransformWindow.BoundsType.None="Automatic"
Basic.TransformWindow.BoundsType.MaxOnly="Maximum size only"
Basic.TransformWindow.BoundsType.ScaleInner="Scale to inner bounds"
Basic.TransformWindow.BoundsType.ScaleOuter="Scale to outer bounds"
Basic.TransformWindow.BoundsType.ScaleToWidth="Scale to width of bounds"
Basic.TransformWindow.BoundsType.ScaleToHeight="Scale to height of bounds"
Basic.TransformWindow.BoundsType.Stretch="Stretch to bounds"
Basic.TransformWindow.BoundsType.ScaleInner="Fit"
Basic.TransformWindow.BoundsType.ScaleOuter="Cover"
Basic.TransformWindow.BoundsType.ScaleToWidth="Fill Width"
Basic.TransformWindow.BoundsType.ScaleToHeight="Fill Height"
Basic.TransformWindow.BoundsType.Stretch="Stretch"
Basic.TransformWindow.Title="Edit Transform for '%1'"
Basic.TransformWindow.NoSelectedSource="No source selected"
@@ -1635,3 +1639,6 @@ PluginManager.Section.Discover="Browse"
PluginManager.Section.Manage="Installed"
PluginManager.Section.Updates="Updates"
PluginManager.Section.Manage.Title="Manage Enabled Plugins"
# Custom Widget Localization
Accessible.Widget.Name.AlignmentSelector="Alignment Selector"

View File

@@ -335,6 +335,12 @@
margin: var(--spacing_base) 0;
}
.subtitle {
font-size: var(--font_small);
font-weight: bold;
color: var(--text_muted);
}
.button-primary {
background-color: var(--primary_dark);
border-color: var(--primary);

View File

@@ -4,6 +4,7 @@
#include "moc_OBSBasicTransform.cpp"
namespace {
static bool find_sel(obs_scene_t *, obs_sceneitem_t *item, void *param)
{
OBSSceneItem &dst = *static_cast<OBSSceneItem *>(param);
@@ -28,8 +29,28 @@ static OBSSceneItem FindASelectedItem(obs_scene_t *scene)
obs_scene_enum_items(scene, find_sel, &item);
return item;
}
static vec2 getAlignmentConversion(uint32_t alignment)
{
vec2 ratio = {0.5f, 0.5f};
if (alignment & OBS_ALIGN_RIGHT) {
ratio.x = 1.0f;
}
if (alignment & OBS_ALIGN_LEFT) {
ratio.x = 0.0f;
}
if (alignment & OBS_ALIGN_BOTTOM) {
ratio.y = 1.0f;
}
if (alignment & OBS_ALIGN_TOP) {
ratio.y = 0.0f;
}
return ratio;
}
} // namespace
#define COMBO_CHANGED &QComboBox::currentIndexChanged
#define ALIGN_CHANGED &AlignmentSelector::currentIndexChanged
#define ISCROLL_CHANGED &QSpinBox::valueChanged
#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
@@ -42,24 +63,38 @@ OBSBasicTransform::OBSBasicTransform(OBSSceneItem item, OBSBasic *parent)
ui->setupUi(this);
HookWidget(ui->positionX, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->positionY, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->rotation, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->sizeX, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->sizeY, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->align, COMBO_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->boundsType, COMBO_CHANGED, &OBSBasicTransform::OnBoundsType);
HookWidget(ui->boundsAlign, COMBO_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->boundsWidth, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->boundsHeight, DSCROLL_CHANGED, &OBSBasicTransform::OnControlChanged);
HookWidget(ui->cropLeft, ISCROLL_CHANGED, &OBSBasicTransform::OnCropChanged);
HookWidget(ui->cropRight, ISCROLL_CHANGED, &OBSBasicTransform::OnCropChanged);
HookWidget(ui->cropTop, ISCROLL_CHANGED, &OBSBasicTransform::OnCropChanged);
HookWidget(ui->cropBottom, ISCROLL_CHANGED, &OBSBasicTransform::OnCropChanged);
positionAlignment = new AlignmentSelector(this);
positionAlignment->setAccessibleName(QTStr("Basic.TransformWindow.Alignment"));
ui->alignmentLayout->addWidget(positionAlignment);
positionAlignment->setAlignment(Qt::AlignTop | Qt::AlignLeft);
boundsAlignment = new AlignmentSelector(this);
boundsAlignment->setAccessibleName(QTStr("Basic.TransformWindow.BoundsAlignment"));
boundsAlignment->setEnabled(false);
ui->boundsAlignmentLayout->addWidget(boundsAlignment);
boundsAlignment->setAlignment(Qt::AlignTop | Qt::AlignLeft);
setTabOrder(ui->rotation, positionAlignment);
setTabOrder(ui->boundsType, boundsAlignment);
hookWidget(ui->positionX, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->positionY, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->rotation, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->sizeX, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->sizeY, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(positionAlignment.get(), ALIGN_CHANGED, &OBSBasicTransform::onAlignChanged);
hookWidget(ui->boundsType, COMBO_CHANGED, &OBSBasicTransform::onBoundsType);
hookWidget(boundsAlignment.get(), ALIGN_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->boundsWidth, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->boundsHeight, DSCROLL_CHANGED, &OBSBasicTransform::onControlChanged);
hookWidget(ui->cropLeft, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged);
hookWidget(ui->cropRight, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged);
hookWidget(ui->cropTop, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged);
hookWidget(ui->cropBottom, ISCROLL_CHANGED, &OBSBasicTransform::onCropChanged);
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
HookWidget(ui->cropToBounds, &QCheckBox::checkStateChanged, &OBSBasicTransform::OnControlChanged);
hookWidget(ui->cropToBounds, &QCheckBox::checkStateChanged, &OBSBasicTransform::onControlChanged);
#else
HookWidget(ui->cropToBounds, &QCheckBox::stateChanged, &OBSBasicTransform::OnControlChanged);
hookWidget(ui->cropToBounds, &QCheckBox::stateChanged, &OBSBasicTransform::onControlChanged);
#endif
ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
@@ -69,14 +104,18 @@ OBSBasicTransform::OBSBasicTransform(OBSSceneItem item, OBSBasic *parent)
installEventFilter(CreateShortcutFilter());
OBSScene scene = obs_sceneitem_get_scene(item);
SetScene(scene);
SetItem(item);
setScene(scene);
setItem(item);
std::string name = obs_source_get_name(obs_sceneitem_get_source(item));
setWindowTitle(QTStr("Basic.TransformWindow.Title").arg(name.c_str()));
OBSDataAutoRelease wrapper = obs_scene_save_transform_states(main->GetCurrentScene(), false);
undo_data = std::string(obs_data_get_json(wrapper));
adjustSize();
setMinimumSize(size());
setMaximumSize(size());
}
OBSBasicTransform::~OBSBasicTransform()
@@ -97,7 +136,7 @@ OBSBasicTransform::~OBSBasicTransform()
undo_redo, undo_redo, undo_data, redo_data);
}
void OBSBasicTransform::SetScene(OBSScene scene)
void OBSBasicTransform::setScene(OBSScene scene)
{
sigs.clear();
@@ -113,25 +152,27 @@ void OBSBasicTransform::SetScene(OBSScene scene)
}
}
void OBSBasicTransform::SetItem(OBSSceneItem newItem)
void OBSBasicTransform::setItem(OBSSceneItem newItem)
{
QMetaObject::invokeMethod(this, "SetItemQt", Q_ARG(OBSSceneItem, OBSSceneItem(newItem)));
QMetaObject::invokeMethod(this, "setItemQt", Q_ARG(OBSSceneItem, OBSSceneItem(newItem)));
}
void OBSBasicTransform::SetEnabled(bool enable)
void OBSBasicTransform::setEnabled(bool enable)
{
ui->container->setEnabled(enable);
ui->transformSettings->setEnabled(enable);
ui->boundsSettings->setEnabled(enable);
ui->cropSettings->setEnabled(enable);
ui->buttonBox->button(QDialogButtonBox::Reset)->setEnabled(enable);
}
void OBSBasicTransform::SetItemQt(OBSSceneItem newItem)
void OBSBasicTransform::setItemQt(OBSSceneItem newItem)
{
item = newItem;
if (item)
RefreshControls();
refreshControls();
bool enable = !!item && !obs_sceneitem_locked(item);
SetEnabled(enable);
setEnabled(enable);
}
void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data)
@@ -140,7 +181,7 @@ void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data)
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
if (item == window->item && !window->ignoreTransformSignal)
QMetaObject::invokeMethod(window, "RefreshControls");
QMetaObject::invokeMethod(window, "refreshControls");
}
void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data)
@@ -150,7 +191,7 @@ void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data)
obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(data, "item");
if (item == window->item)
window->SetItem(FindASelectedItem(scene));
window->setItem(FindASelectedItem(scene));
}
void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data)
@@ -159,7 +200,7 @@ void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data)
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
if (item != window->item)
window->SetItem(item);
window->setItem(item);
}
void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data)
@@ -170,7 +211,7 @@ void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data)
if (item == window->item) {
window->setWindowTitle(QTStr("Basic.TransformWindow.NoSelectedSource"));
window->SetItem(FindASelectedItem(scene));
window->setItem(FindASelectedItem(scene));
}
}
@@ -179,23 +220,23 @@ void OBSBasicTransform::OBSSceneItemLocked(void *param, calldata_t *data)
OBSBasicTransform *window = static_cast<OBSBasicTransform *>(param);
bool locked = calldata_bool(data, "locked");
QMetaObject::invokeMethod(window, "SetEnabled", Q_ARG(bool, !locked));
QMetaObject::invokeMethod(window, "setEnabled", Q_ARG(bool, !locked));
}
static const uint32_t listToAlign[] = {OBS_ALIGN_TOP | OBS_ALIGN_LEFT,
OBS_ALIGN_TOP,
OBS_ALIGN_TOP | OBS_ALIGN_RIGHT,
OBS_ALIGN_LEFT,
OBS_ALIGN_CENTER,
OBS_ALIGN_RIGHT,
OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT,
OBS_ALIGN_BOTTOM,
OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT};
static const uint32_t indexToAlign[] = {OBS_ALIGN_TOP | OBS_ALIGN_LEFT,
OBS_ALIGN_TOP,
OBS_ALIGN_TOP | OBS_ALIGN_RIGHT,
OBS_ALIGN_LEFT,
OBS_ALIGN_CENTER,
OBS_ALIGN_RIGHT,
OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT,
OBS_ALIGN_BOTTOM,
OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT};
static int AlignToList(uint32_t align)
static int alignToIndex(uint32_t align)
{
int index = 0;
for (uint32_t curAlign : listToAlign) {
for (uint32_t curAlign : indexToAlign) {
if (curAlign == align)
return index;
@@ -205,14 +246,14 @@ static int AlignToList(uint32_t align)
return 0;
}
void OBSBasicTransform::RefreshControls()
void OBSBasicTransform::refreshControls()
{
if (!item)
return;
obs_transform_info osi;
obs_transform_info oti;
obs_sceneitem_crop crop;
obs_sceneitem_get_info2(item, &osi);
obs_sceneitem_get_info2(item, &oti);
obs_sceneitem_get_crop(item, &crop);
obs_source_t *source = obs_sceneitem_get_source(item);
@@ -221,26 +262,26 @@ void OBSBasicTransform::RefreshControls()
float width = float(source_cx);
float height = float(source_cy);
int alignIndex = AlignToList(osi.alignment);
int boundsAlignIndex = AlignToList(osi.bounds_alignment);
int alignIndex = alignToIndex(oti.alignment);
int boundsAlignIndex = alignToIndex(oti.bounds_alignment);
ignoreItemChange = true;
ui->positionX->setValue(osi.pos.x);
ui->positionY->setValue(osi.pos.y);
ui->rotation->setValue(osi.rot);
ui->sizeX->setValue(osi.scale.x * width);
ui->sizeY->setValue(osi.scale.y * height);
ui->align->setCurrentIndex(alignIndex);
ui->positionX->setValue(oti.pos.x);
ui->positionY->setValue(oti.pos.y);
ui->rotation->setValue(oti.rot);
ui->sizeX->setValue(oti.scale.x * width);
ui->sizeY->setValue(oti.scale.y * height);
positionAlignment->setCurrentIndex(alignIndex);
bool valid_size = source_cx != 0 && source_cy != 0;
ui->sizeX->setEnabled(valid_size);
ui->sizeY->setEnabled(valid_size);
ui->boundsType->setCurrentIndex(int(osi.bounds_type));
ui->boundsAlign->setCurrentIndex(boundsAlignIndex);
ui->boundsWidth->setValue(osi.bounds.x);
ui->boundsHeight->setValue(osi.bounds.y);
ui->cropToBounds->setChecked(osi.crop_to_bounds);
ui->boundsType->setCurrentIndex(int(oti.bounds_type));
boundsAlignment->setCurrentIndex(boundsAlignIndex);
ui->boundsWidth->setValue(oti.bounds.x);
ui->boundsHeight->setValue(oti.bounds.y);
ui->cropToBounds->setChecked(oti.crop_to_bounds);
ui->cropLeft->setValue(int(crop.left));
ui->cropRight->setValue(int(crop.right));
@@ -252,7 +293,45 @@ void OBSBasicTransform::RefreshControls()
setWindowTitle(QTStr("Basic.TransformWindow.Title").arg(name.c_str()));
}
void OBSBasicTransform::OnBoundsType(int index)
void OBSBasicTransform::onAlignChanged(int index)
{
uint32_t alignment = indexToAlign[index];
vec2 flipRatio = getAlignmentConversion(alignment);
obs_transform_info oti;
obs_sceneitem_crop crop;
obs_sceneitem_get_info2(item, &oti);
obs_sceneitem_get_crop(item, &crop);
obs_source_t *source = obs_sceneitem_get_source(item);
uint32_t sourceWidth = obs_source_get_width(source);
uint32_t sourceHeight = obs_source_get_height(source);
uint32_t widthForFlip = sourceWidth - crop.left - crop.right;
uint32_t heightForFlip = sourceHeight - crop.top - crop.bottom;
if (oti.bounds_type != OBS_BOUNDS_NONE) {
widthForFlip = oti.bounds.x;
heightForFlip = oti.bounds.y;
}
vec2 currentRatio = getAlignmentConversion(oti.alignment);
float shiftX = (currentRatio.x - flipRatio.x) * widthForFlip * oti.scale.x;
float shiftY = (currentRatio.y - flipRatio.y) * heightForFlip * oti.scale.y;
bool previousIgnoreState = ignoreItemChange;
ignoreItemChange = true;
ui->positionX->setValue(oti.pos.x - shiftX);
ui->positionY->setValue(oti.pos.y - shiftY);
ignoreItemChange = previousIgnoreState;
onControlChanged();
}
void OBSBasicTransform::onBoundsType(int index)
{
if (index == -1)
return;
@@ -260,10 +339,13 @@ void OBSBasicTransform::OnBoundsType(int index)
obs_bounds_type type = (obs_bounds_type)index;
bool enable = (type != OBS_BOUNDS_NONE);
ui->boundsAlign->setEnabled(enable);
boundsAlignment->setEnabled(enable && type != OBS_BOUNDS_STRETCH);
ui->boundsWidth->setEnabled(enable);
ui->boundsHeight->setEnabled(enable);
ui->cropToBounds->setEnabled(enable);
bool isCoverBounds = type == OBS_BOUNDS_SCALE_OUTER || type == OBS_BOUNDS_SCALE_TO_WIDTH ||
type == OBS_BOUNDS_SCALE_TO_HEIGHT;
ui->cropToBounds->setEnabled(isCoverBounds);
if (!ignoreItemChange) {
obs_bounds_type lastType = obs_sceneitem_get_bounds_type(item);
@@ -272,15 +354,56 @@ void OBSBasicTransform::OnBoundsType(int index)
int width = (int)obs_source_get_width(source);
int height = (int)obs_source_get_height(source);
ui->boundsWidth->setValue(width);
ui->boundsHeight->setValue(height);
vec2 scale;
obs_sceneitem_get_scale(item, &scale);
obs_sceneitem_crop crop;
obs_sceneitem_get_crop(item, &crop);
ui->sizeX->setValue(width);
ui->sizeY->setValue(height);
ui->boundsWidth->setValue((width - crop.left - crop.right) * scale.x);
ui->boundsHeight->setValue((height - crop.top - crop.bottom) * scale.y);
} else if (type == OBS_BOUNDS_NONE) {
OBSSource source = obs_sceneitem_get_source(item);
int width = (int)obs_source_get_width(source);
int height = (int)obs_source_get_height(source);
matrix4 draw;
obs_sceneitem_get_draw_transform(item, &draw);
ui->sizeX->setValue(width * draw.x.x);
ui->sizeY->setValue(height * draw.y.y);
obs_transform_info oti;
obs_sceneitem_get_info2(item, &oti);
// We use the draw transform values here which is always a top left coordinate origin.
vec2 currentRatio = getAlignmentConversion(OBS_ALIGN_TOP | OBS_ALIGN_LEFT);
vec2 flipRatio = getAlignmentConversion(oti.alignment);
float drawX = draw.t.x;
float drawY = draw.t.y;
obs_sceneitem_crop crop;
obs_sceneitem_get_crop(item, &crop);
uint32_t widthForFlip = width - crop.left - crop.right;
uint32_t heightForFlip = height - crop.top - crop.bottom;
float shiftX = (currentRatio.x - flipRatio.x) * (widthForFlip * draw.x.x);
float shiftY = (currentRatio.y - flipRatio.y) * (heightForFlip * draw.y.y);
ui->positionX->setValue(oti.pos.x - (oti.pos.x - drawX) - shiftX);
ui->positionY->setValue(oti.pos.y - (oti.pos.y - drawY) - shiftY);
}
}
OnControlChanged();
onControlChanged();
}
void OBSBasicTransform::OnControlChanged()
void OBSBasicTransform::onControlChanged()
{
if (ignoreItemChange)
return;
@@ -303,10 +426,10 @@ void OBSBasicTransform::OnControlChanged()
oti.pos.x = float(ui->positionX->value());
oti.pos.y = float(ui->positionY->value());
oti.rot = float(ui->rotation->value());
oti.alignment = listToAlign[ui->align->currentIndex()];
oti.alignment = indexToAlign[positionAlignment->currentIndex()];
oti.bounds_type = (obs_bounds_type)ui->boundsType->currentIndex();
oti.bounds_alignment = listToAlign[ui->boundsAlign->currentIndex()];
oti.bounds_alignment = indexToAlign[boundsAlignment->currentIndex()];
oti.bounds.x = float(ui->boundsWidth->value());
oti.bounds.y = float(ui->boundsHeight->value());
oti.crop_to_bounds = ui->cropToBounds->isChecked();
@@ -316,7 +439,7 @@ void OBSBasicTransform::OnControlChanged()
ignoreTransformSignal = false;
}
void OBSBasicTransform::OnCropChanged()
void OBSBasicTransform::onCropChanged()
{
if (ignoreItemChange)
return;
@@ -332,11 +455,11 @@ void OBSBasicTransform::OnCropChanged()
ignoreTransformSignal = false;
}
void OBSBasicTransform::OnSceneChanged(QListWidgetItem *current, QListWidgetItem *)
void OBSBasicTransform::onSceneChanged(QListWidgetItem *current, QListWidgetItem *)
{
if (!current)
return;
OBSScene scene = GetOBSRef<OBSScene>(current);
this->SetScene(scene);
this->setScene(scene);
}

View File

@@ -3,8 +3,10 @@
#include "ui_OBSBasicTransform.h"
#include <obs.hpp>
#include <components/AlignmentSelector.hpp>
#include <QDialog>
#include <QPointer>
class OBSBasic;
class QListWidgetItem;
@@ -15,6 +17,9 @@ class OBSBasicTransform : public QDialog {
private:
std::unique_ptr<Ui::OBSBasicTransform> ui;
QPointer<AlignmentSelector> positionAlignment;
QPointer<AlignmentSelector> boundsAlignment;
OBSBasic *main;
OBSSceneItem item;
std::vector<OBSSignal> sigs;
@@ -25,14 +30,14 @@ private:
bool ignoreItemChange = false;
template<typename Widget, typename WidgetParent, typename... SignalArgs, typename... SlotArgs>
void HookWidget(Widget *widget, void (WidgetParent::*signal)(SignalArgs...),
void hookWidget(Widget *widget, void (WidgetParent::*signal)(SignalArgs...),
void (OBSBasicTransform::*slot)(SlotArgs...))
{
QObject::connect(widget, signal, this, slot);
}
void SetScene(OBSScene scene);
void SetItem(OBSSceneItem newItem);
void setScene(OBSScene scene);
void setItem(OBSSceneItem newItem);
static void OBSSceneItemTransform(void *param, calldata_t *data);
static void OBSSceneItemRemoved(void *param, calldata_t *data);
@@ -41,17 +46,18 @@ private:
static void OBSSceneItemLocked(void *param, calldata_t *data);
private slots:
void RefreshControls();
void SetItemQt(OBSSceneItem newItem);
void OnBoundsType(int index);
void OnControlChanged();
void OnCropChanged();
void SetEnabled(bool enable);
void refreshControls();
void setItemQt(OBSSceneItem newItem);
void onAlignChanged(int index);
void onBoundsType(int index);
void onControlChanged();
void onCropChanged();
void setEnabled(bool enable);
public:
OBSBasicTransform(OBSSceneItem item, OBSBasic *parent);
~OBSBasicTransform();
public slots:
void OnSceneChanged(QListWidgetItem *current, QListWidgetItem *prev);
void onSceneChanged(QListWidgetItem *current, QListWidgetItem *prev);
};

View File

File diff suppressed because it is too large Load Diff

View File

@@ -489,7 +489,7 @@ void OBSBasic::CreateEditTransformWindow(obs_sceneitem_t *item)
if (transformWindow)
transformWindow->close();
transformWindow = new OBSBasicTransform(item, this);
connect(ui->scenes, &QListWidget::currentItemChanged, transformWindow, &OBSBasicTransform::OnSceneChanged);
connect(ui->scenes, &QListWidget::currentItemChanged, transformWindow, &OBSBasicTransform::onSceneChanged);
transformWindow->show();
transformWindow->setAttribute(Qt::WA_DeleteOnClose, true);
}