1
0
Эх сурвалжийг харах

UI: Fix wrong behavior with undo/redo and groups

Ford Smith 4 жил өмнө
parent
commit
2932cd0fd3

+ 2 - 1
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);

+ 76 - 11
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};
 
-	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",
+	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(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)