mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-02-28 04:19:05 -05:00
UI: Rename 'obs' dir to 'UI'
This is to prevent confusion both when prefixing commits and when reading the directory structure for the first time.
This commit is contained in:
290
UI/window-basic-transform.cpp
Normal file
290
UI/window-basic-transform.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
#include "window-basic-transform.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
|
||||
Q_DECLARE_METATYPE(OBSSceneItem);
|
||||
|
||||
static OBSSceneItem FindASelectedItem(OBSScene scene)
|
||||
{
|
||||
auto func = [] (obs_scene_t *scene, obs_sceneitem_t *item, void *param)
|
||||
{
|
||||
OBSSceneItem &dst = *reinterpret_cast<OBSSceneItem*>(param);
|
||||
|
||||
if (obs_sceneitem_selected(item)) {
|
||||
dst = item;
|
||||
return false;
|
||||
}
|
||||
|
||||
UNUSED_PARAMETER(scene);
|
||||
return true;
|
||||
};
|
||||
|
||||
OBSSceneItem item;
|
||||
obs_scene_enum_items(scene, func, &item);
|
||||
return item;
|
||||
}
|
||||
|
||||
void OBSBasicTransform::HookWidget(QWidget *widget, const char *signal,
|
||||
const char *slot)
|
||||
{
|
||||
QObject::connect(widget, signal, this, slot);
|
||||
}
|
||||
|
||||
#define COMBO_CHANGED SIGNAL(currentIndexChanged(int))
|
||||
#define ISCROLL_CHANGED SIGNAL(valueChanged(int))
|
||||
#define DSCROLL_CHANGED SIGNAL(valueChanged(double))
|
||||
|
||||
OBSBasicTransform::OBSBasicTransform(OBSBasic *parent)
|
||||
: QDialog (parent),
|
||||
ui (new Ui::OBSBasicTransform),
|
||||
main (parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
HookWidget(ui->positionX, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->positionY, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->rotation, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->sizeX, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->sizeY, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->align, COMBO_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->boundsType, COMBO_CHANGED, SLOT(OnBoundsType(int)));
|
||||
HookWidget(ui->boundsAlign, COMBO_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->boundsWidth, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->boundsHeight, DSCROLL_CHANGED, SLOT(OnControlChanged()));
|
||||
HookWidget(ui->cropLeft, ISCROLL_CHANGED, SLOT(OnCropChanged()));
|
||||
HookWidget(ui->cropRight, ISCROLL_CHANGED, SLOT(OnCropChanged()));
|
||||
HookWidget(ui->cropTop, ISCROLL_CHANGED, SLOT(OnCropChanged()));
|
||||
HookWidget(ui->cropBottom, ISCROLL_CHANGED, SLOT(OnCropChanged()));
|
||||
|
||||
installEventFilter(CreateShortcutFilter());
|
||||
|
||||
OBSScene curScene = main->GetCurrentScene();
|
||||
SetScene(curScene);
|
||||
SetItem(FindASelectedItem(curScene));
|
||||
|
||||
channelChangedSignal.Connect(obs_get_signal_handler(), "channel_change",
|
||||
OBSChannelChanged, this);
|
||||
}
|
||||
|
||||
void OBSBasicTransform::SetScene(OBSScene scene)
|
||||
{
|
||||
transformSignal.Disconnect();
|
||||
selectSignal.Disconnect();
|
||||
deselectSignal.Disconnect();
|
||||
removeSignal.Disconnect();
|
||||
|
||||
if (scene) {
|
||||
OBSSource source = obs_scene_get_source(scene);
|
||||
signal_handler_t *signal = obs_source_get_signal_handler(source);
|
||||
|
||||
transformSignal.Connect(signal, "item_transform",
|
||||
OBSSceneItemTransform, this);
|
||||
removeSignal.Connect(signal, "item_remove",
|
||||
OBSSceneItemRemoved, this);
|
||||
selectSignal.Connect(signal, "item_select",
|
||||
OBSSceneItemSelect, this);
|
||||
deselectSignal.Connect(signal, "item_deselect",
|
||||
OBSSceneItemDeselect, this);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasicTransform::SetItem(OBSSceneItem newItem)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "SetItemQt",
|
||||
Q_ARG(OBSSceneItem, OBSSceneItem(newItem)));
|
||||
}
|
||||
|
||||
void OBSBasicTransform::SetItemQt(OBSSceneItem newItem)
|
||||
{
|
||||
item = newItem;
|
||||
if (item)
|
||||
RefreshControls();
|
||||
|
||||
setEnabled(!!item);
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OBSChannelChanged(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
uint32_t channel = (uint32_t)calldata_int(data, "channel");
|
||||
OBSSource source = (obs_source_t*)calldata_ptr(data, "source");
|
||||
|
||||
if (channel == 0) {
|
||||
OBSScene scene = obs_scene_from_source(source);
|
||||
window->SetScene(scene);
|
||||
|
||||
if (!scene)
|
||||
window->SetItem(nullptr);
|
||||
else
|
||||
window->SetItem(FindASelectedItem(scene));
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
|
||||
if (item == window->item && !window->ignoreTransformSignal)
|
||||
QMetaObject::invokeMethod(window, "RefreshControls");
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSScene scene = (obs_scene_t*)calldata_ptr(data, "scene");
|
||||
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
|
||||
if (item == window->item)
|
||||
window->SetItem(FindASelectedItem(scene));
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
|
||||
if (item != window->item)
|
||||
window->SetItem(item);
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSScene scene = (obs_scene_t*)calldata_ptr(data, "scene");
|
||||
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
|
||||
if (item == window->item)
|
||||
window->SetItem(FindASelectedItem(scene));
|
||||
}
|
||||
|
||||
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 int AlignToList(uint32_t align)
|
||||
{
|
||||
int index = 0;
|
||||
for (uint32_t curAlign : listToAlign) {
|
||||
if (curAlign == align)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OBSBasicTransform::RefreshControls()
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
obs_transform_info osi;
|
||||
obs_sceneitem_crop crop;
|
||||
obs_sceneitem_get_info(item, &osi);
|
||||
obs_sceneitem_get_crop(item, &crop);
|
||||
|
||||
obs_source_t *source = obs_sceneitem_get_source(item);
|
||||
float width = float(obs_source_get_width(source));
|
||||
float height = float(obs_source_get_height(source));
|
||||
|
||||
int alignIndex = AlignToList(osi.alignment);
|
||||
int boundsAlignIndex = AlignToList(osi.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->boundsType->setCurrentIndex(int(osi.bounds_type));
|
||||
ui->boundsAlign->setCurrentIndex(boundsAlignIndex);
|
||||
ui->boundsWidth->setValue(osi.bounds.x);
|
||||
ui->boundsHeight->setValue(osi.bounds.y);
|
||||
|
||||
ui->cropLeft->setValue(int(crop.left));
|
||||
ui->cropRight->setValue(int(crop.right));
|
||||
ui->cropTop->setValue(int(crop.top));
|
||||
ui->cropBottom->setValue(int(crop.bottom));
|
||||
ignoreItemChange = false;
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OnBoundsType(int index)
|
||||
{
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
obs_bounds_type type = (obs_bounds_type)index;
|
||||
bool enable = (type != OBS_BOUNDS_NONE);
|
||||
|
||||
ui->boundsAlign->setEnabled(enable);
|
||||
ui->boundsWidth->setEnabled(enable);
|
||||
ui->boundsHeight->setEnabled(enable);
|
||||
|
||||
if (!ignoreItemChange) {
|
||||
obs_bounds_type lastType = obs_sceneitem_get_bounds_type(item);
|
||||
if (lastType == 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);
|
||||
|
||||
ui->boundsWidth->setValue(width);
|
||||
ui->boundsHeight->setValue(height);
|
||||
}
|
||||
}
|
||||
|
||||
OnControlChanged();
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OnControlChanged()
|
||||
{
|
||||
if (ignoreItemChange)
|
||||
return;
|
||||
|
||||
obs_source_t *source = obs_sceneitem_get_source(item);
|
||||
double width = double(obs_source_get_width(source));
|
||||
double height = double(obs_source_get_height(source));
|
||||
|
||||
obs_transform_info oti;
|
||||
oti.pos.x = float(ui->positionX->value());
|
||||
oti.pos.y = float(ui->positionY->value());
|
||||
oti.rot = float(ui->rotation->value());
|
||||
oti.scale.x = float(ui->sizeX->value() / width);
|
||||
oti.scale.y = float(ui->sizeY->value() / height);
|
||||
oti.alignment = listToAlign[ui->align->currentIndex()];
|
||||
|
||||
oti.bounds_type = (obs_bounds_type)ui->boundsType->currentIndex();
|
||||
oti.bounds_alignment = listToAlign[ui->boundsAlign->currentIndex()];
|
||||
oti.bounds.x = float(ui->boundsWidth->value());
|
||||
oti.bounds.y = float(ui->boundsHeight->value());
|
||||
|
||||
ignoreTransformSignal = true;
|
||||
obs_sceneitem_set_info(item, &oti);
|
||||
ignoreTransformSignal = false;
|
||||
}
|
||||
|
||||
void OBSBasicTransform::OnCropChanged()
|
||||
{
|
||||
if (ignoreItemChange)
|
||||
return;
|
||||
|
||||
obs_sceneitem_crop crop;
|
||||
crop.left = uint32_t(ui->cropLeft->value());
|
||||
crop.right = uint32_t(ui->cropRight->value());
|
||||
crop.top = uint32_t(ui->cropTop->value());
|
||||
crop.bottom = uint32_t(ui->cropBottom->value());
|
||||
|
||||
ignoreTransformSignal = true;
|
||||
obs_sceneitem_set_crop(item, &crop);
|
||||
ignoreTransformSignal = false;
|
||||
}
|
||||
Reference in New Issue
Block a user