From 2932cd0fd3b83e6b07192a784bf3faebdebaa697 Mon Sep 17 00:00:00 2001 From: Ford Smith Date: Sat, 3 Apr 2021 16:20:00 -0400 Subject: [PATCH] UI: Fix wrong behavior with undo/redo and groups --- UI/window-basic-transform.cpp | 3 +- libobs/obs-scene.c | 87 ++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/UI/window-basic-transform.cpp b/UI/window-basic-transform.cpp index b833033a4..47f2bb8d7 100644 --- a/UI/window-basic-transform.cpp +++ b/UI/window-basic-transform.cpp @@ -73,7 +73,8 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) SetScene(scene); SetItem(item); - obs_data_t *wrapper = obs_scene_save_transform_states(scene, false); + obs_data_t *wrapper = + obs_scene_save_transform_states(main->GetCurrentScene(), false); undo_data = std::string(obs_data_get_json(wrapper)); obs_data_release(wrapper); diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index fb105563e..e770f6673 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -2063,6 +2063,7 @@ static void signal_parent(obs_scene_t *parent, const char *command, struct passthrough { obs_data_array_t *ids; + obs_data_array_t *scenes_and_groups; bool all_items; }; @@ -2105,6 +2106,32 @@ bool save_transform_states(obs_scene_t *scene, obs_sceneitem_t *item, obs_data_release(temp); } + obs_source_t *item_source = obs_sceneitem_get_source(item); + + if (obs_source_is_group(item_source)) { + obs_data_t *temp = obs_data_create(); + obs_data_array_t *nids = obs_data_array_create(); + + obs_data_set_string(temp, "scene_name", + obs_source_get_name(item_source)); + obs_data_set_bool(temp, "is_group", true); + obs_data_set_string( + temp, "group_parent", + obs_source_get_name(obs_scene_get_source(scene))); + + struct passthrough npass = {nids, pass->scenes_and_groups, + pass->all_items}; + obs_sceneitem_group_enum_items(item, save_transform_states, + (void *)&npass); + + obs_data_set_array(temp, "items", nids); + + obs_data_array_push_back(pass->scenes_and_groups, temp); + + obs_data_release(temp); + obs_data_array_release(nids); + } + UNUSED_PARAMETER(scene); return true; } @@ -2112,15 +2139,27 @@ bool save_transform_states(obs_scene_t *scene, obs_sceneitem_t *item, obs_data_t *obs_scene_save_transform_states(obs_scene_t *scene, bool all_items) { obs_data_t *wrapper = obs_data_create(); + obs_data_array_t *scenes_and_groups = obs_data_array_create(); obs_data_array_t *item_ids = obs_data_array_create(); - struct passthrough pass = {item_ids, all_items}; + + struct passthrough pass = {item_ids, scenes_and_groups, all_items}; + + obs_data_t *temp = obs_data_create(); + + obs_data_set_string(temp, "scene_name", + obs_source_get_name(obs_scene_get_source(scene))); + obs_data_set_bool(temp, "is_group", false); obs_scene_enum_items(scene, save_transform_states, (void *)&pass); - obs_data_set_array(wrapper, "item_ids", item_ids); - obs_data_set_string(wrapper, "scene_name", - obs_source_get_name(obs_scene_get_source(scene))); + + obs_data_set_array(temp, "items", item_ids); + obs_data_array_push_back(scenes_and_groups, temp); + + obs_data_set_array(wrapper, "scenes_and_groups", scenes_and_groups); obs_data_array_release(item_ids); + obs_data_array_release(scenes_and_groups); + obs_data_release(temp); return wrapper; } @@ -2155,18 +2194,44 @@ void load_transform_states(obs_data_t *temp, void *vp_scene) obs_sceneitem_defer_update_end(item); } +void iterate_scenes_and_groups_transform_states(obs_data_t *data, void *vp) +{ + obs_data_array_t *items = obs_data_get_array(data, "items"); + obs_source_t *scene_source = + obs_get_source_by_name(obs_data_get_string(data, "scene_name")); + obs_scene_t *scene = obs_scene_from_source(scene_source); + + if (obs_data_get_bool(data, "is_group")) { + obs_source_t *parent_source = obs_get_source_by_name( + obs_data_get_string(data, "group_parent")); + obs_scene_t *parent = obs_scene_from_source(parent_source); + obs_sceneitem_t *group = obs_scene_get_group( + parent, obs_data_get_string(data, "scene_name")); + scene = obs_sceneitem_group_get_scene(group); + + obs_source_release(parent_source); + } + + obs_data_array_enum(items, load_transform_states, (void *)scene); + + UNUSED_PARAMETER(vp); + + obs_data_array_release(items); + obs_source_release(scene_source); +} + void obs_scene_load_transform_states(const char *data) { obs_data_t *dat = obs_data_create_from_json(data); - obs_data_array_t *item_ids = obs_data_get_array(dat, "item_ids"); - obs_source_t *source = - obs_get_source_by_name(obs_data_get_string(dat, "scene_name")); - obs_scene_t *scene = obs_scene_from_source(source); - obs_data_array_enum(item_ids, load_transform_states, (void *)scene); + + obs_data_array_t *scenes_and_groups = + obs_data_get_array(dat, "scenes_and_groups"); + + obs_data_array_enum(scenes_and_groups, + iterate_scenes_and_groups_transform_states, NULL); obs_data_release(dat); - obs_data_array_release(item_ids); - obs_source_release(source); + obs_data_array_release(scenes_and_groups); } void obs_sceneitem_select(obs_sceneitem_t *item, bool select)