UI: Relatively center multiple scene items
Before the scene items would be centered at the same spot when centering them, now they are moved relatively to each other.master
parent
17a4d9166a
commit
3dae4a35a1
|
@ -8256,62 +8256,97 @@ void OBSBasic::on_actionStretchToScreen_triggered()
|
||||||
undo_redo, undo_redo, undo_data, redo_data);
|
undo_redo, undo_redo, undo_data, redo_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class CenterType {
|
void OBSBasic::CenterSelectedSceneItems(const CenterType ¢erType)
|
||||||
Scene,
|
|
||||||
Vertical,
|
|
||||||
Horizontal,
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *param)
|
|
||||||
{
|
{
|
||||||
CenterType centerType = *reinterpret_cast<CenterType *>(param);
|
QModelIndexList selectedItems = GetAllSelectedSourceItems();
|
||||||
|
|
||||||
vec3 tl, br, itemCenter, screenCenter, offset;
|
if (!selectedItems.count())
|
||||||
|
return;
|
||||||
|
|
||||||
|
vector<OBSSceneItem> items;
|
||||||
|
|
||||||
|
// Filter out items that have no size
|
||||||
|
for (int x = 0; x < selectedItems.count(); x++) {
|
||||||
|
OBSSceneItem item = ui->sources->Get(selectedItems[x].row());
|
||||||
|
obs_transform_info oti;
|
||||||
|
obs_sceneitem_get_info(item, &oti);
|
||||||
|
|
||||||
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
||||||
|
float width = float(obs_source_get_width(source)) * oti.scale.x;
|
||||||
|
float height =
|
||||||
|
float(obs_source_get_height(source)) * oti.scale.y;
|
||||||
|
|
||||||
|
if (width == 0.0f || height == 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
items.emplace_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!items.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get center x, y coordinates of items
|
||||||
|
vec3 center;
|
||||||
|
|
||||||
|
float top = M_INFINITE;
|
||||||
|
float left = M_INFINITE;
|
||||||
|
float right = 0.0f;
|
||||||
|
float bottom = 0.0f;
|
||||||
|
|
||||||
|
for (auto &item : items) {
|
||||||
|
vec3 tl, br;
|
||||||
|
|
||||||
|
GetItemBox(item, tl, br);
|
||||||
|
|
||||||
|
left = (std::min)(tl.x, left);
|
||||||
|
top = (std::min)(tl.y, top);
|
||||||
|
right = (std::max)(br.x, right);
|
||||||
|
bottom = (std::max)(br.y, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
center.x = (right + left) / 2.0f;
|
||||||
|
center.y = (top + bottom) / 2.0f;
|
||||||
|
center.z = 0.0f;
|
||||||
|
|
||||||
|
// Get coordinates of screen center
|
||||||
obs_video_info ovi;
|
obs_video_info ovi;
|
||||||
obs_transform_info oti;
|
|
||||||
|
|
||||||
if (obs_sceneitem_is_group(item))
|
|
||||||
obs_sceneitem_group_enum_items(item, center_to_scene,
|
|
||||||
¢erType);
|
|
||||||
if (!obs_sceneitem_selected(item))
|
|
||||||
return true;
|
|
||||||
if (obs_sceneitem_locked(item))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
obs_get_video_info(&ovi);
|
obs_get_video_info(&ovi);
|
||||||
obs_sceneitem_get_info(item, &oti);
|
|
||||||
|
|
||||||
|
vec3 screenCenter;
|
||||||
vec3_set(&screenCenter, float(ovi.base_width), float(ovi.base_height),
|
vec3_set(&screenCenter, float(ovi.base_width), float(ovi.base_height),
|
||||||
0.0f);
|
0.0f);
|
||||||
|
|
||||||
vec3_mulf(&screenCenter, &screenCenter, 0.5f);
|
vec3_mulf(&screenCenter, &screenCenter, 0.5f);
|
||||||
|
|
||||||
GetItemBox(item, tl, br);
|
// Calculate difference between screen center and item center
|
||||||
|
vec3 offset;
|
||||||
|
vec3_sub(&offset, &screenCenter, ¢er);
|
||||||
|
|
||||||
vec3_sub(&itemCenter, &br, &tl);
|
// Shift items by offset
|
||||||
vec3_mulf(&itemCenter, &itemCenter, 0.5f);
|
for (auto &item : items) {
|
||||||
vec3_add(&itemCenter, &itemCenter, &tl);
|
vec3 tl, br;
|
||||||
|
|
||||||
vec3_sub(&offset, &screenCenter, &itemCenter);
|
GetItemBox(item, tl, br);
|
||||||
vec3_add(&tl, &tl, &offset);
|
|
||||||
|
|
||||||
vec3 itemTL = GetItemTL(item);
|
vec3_add(&tl, &tl, &offset);
|
||||||
|
|
||||||
if (centerType == CenterType::Vertical)
|
vec3 itemTL = GetItemTL(item);
|
||||||
tl.x = itemTL.x;
|
|
||||||
else if (centerType == CenterType::Horizontal)
|
|
||||||
tl.y = itemTL.y;
|
|
||||||
|
|
||||||
SetItemTL(item, tl);
|
if (centerType == CenterType::Vertical)
|
||||||
return true;
|
tl.x = itemTL.x;
|
||||||
};
|
else if (centerType == CenterType::Horizontal)
|
||||||
|
tl.y = itemTL.y;
|
||||||
|
|
||||||
|
SetItemTL(item, tl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasic::on_actionCenterToScreen_triggered()
|
void OBSBasic::on_actionCenterToScreen_triggered()
|
||||||
{
|
{
|
||||||
CenterType centerType = CenterType::Scene;
|
CenterType centerType = CenterType::Scene;
|
||||||
OBSDataAutoRelease wrapper =
|
OBSDataAutoRelease wrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType);
|
CenterSelectedSceneItems(centerType);
|
||||||
OBSDataAutoRelease rwrapper =
|
OBSDataAutoRelease rwrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
|
|
||||||
|
@ -8328,7 +8363,7 @@ void OBSBasic::on_actionVerticalCenter_triggered()
|
||||||
CenterType centerType = CenterType::Vertical;
|
CenterType centerType = CenterType::Vertical;
|
||||||
OBSDataAutoRelease wrapper =
|
OBSDataAutoRelease wrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType);
|
CenterSelectedSceneItems(centerType);
|
||||||
OBSDataAutoRelease rwrapper =
|
OBSDataAutoRelease rwrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
|
|
||||||
|
@ -8345,7 +8380,7 @@ void OBSBasic::on_actionHorizontalCenter_triggered()
|
||||||
CenterType centerType = CenterType::Horizontal;
|
CenterType centerType = CenterType::Horizontal;
|
||||||
OBSDataAutoRelease wrapper =
|
OBSDataAutoRelease wrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType);
|
CenterSelectedSceneItems(centerType);
|
||||||
OBSDataAutoRelease rwrapper =
|
OBSDataAutoRelease rwrapper =
|
||||||
obs_scene_save_transform_states(GetCurrentScene(), false);
|
obs_scene_save_transform_states(GetCurrentScene(), false);
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,12 @@ class OBSBasic : public OBSMainWindow {
|
||||||
ContextBarSize_Normal
|
ContextBarSize_Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CenterType {
|
||||||
|
Scene,
|
||||||
|
Vertical,
|
||||||
|
Horizontal,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
obs_frontend_callbacks *api = nullptr;
|
obs_frontend_callbacks *api = nullptr;
|
||||||
|
|
||||||
|
@ -614,6 +620,8 @@ private:
|
||||||
void UpdatePreviewSafeAreas();
|
void UpdatePreviewSafeAreas();
|
||||||
bool drawSafeAreas = false;
|
bool drawSafeAreas = false;
|
||||||
|
|
||||||
|
void CenterSelectedSceneItems(const CenterType ¢erType);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void DeferSaveBegin();
|
void DeferSaveBegin();
|
||||||
void DeferSaveEnd();
|
void DeferSaveEnd();
|
||||||
|
|
Loading…
Reference in New Issue