Jelajahi Sumber

UI: Refactor scene action undo/redo

Allows this code to be used for other actions where the scene data needs
to be backed up
jp9000 4 tahun lalu
induk
melakukan
f1c120df2e
2 mengubah file dengan 80 tambahan dan 81 penghapusan
  1. 76 81
      UI/window-basic-main.cpp
  2. 4 0
      UI/window-basic-main.hpp

+ 76 - 81
UI/window-basic-main.cpp

@@ -5491,49 +5491,8 @@ static bool remove_items(obs_scene_t *, obs_sceneitem_t *item, void *param)
 	return true;
 };
 
-void OBSBasic::on_actionRemoveSource_triggered()
+OBSData OBSBasic::BackupScene(obs_source_t *scene_source)
 {
-	vector<OBSSceneItem> items;
-	OBSScene scene = GetCurrentScene();
-	obs_source_t *scene_source = obs_scene_get_source(scene);
-
-	obs_scene_enum_items(scene, remove_items, &items);
-
-	if (!items.size())
-		return;
-
-	/* ------------------------------------- */
-	/* confirm action with user              */
-
-	bool confirmed = false;
-
-	if (items.size() > 1) {
-		QString text = QTStr("ConfirmRemove.TextMultiple")
-				       .arg(QString::number(items.size()));
-
-		QMessageBox remove_items(this);
-		remove_items.setText(text);
-		QPushButton *Yes = remove_items.addButton(QTStr("Yes"),
-							  QMessageBox::YesRole);
-		remove_items.setDefaultButton(Yes);
-		remove_items.addButton(QTStr("No"), QMessageBox::NoRole);
-		remove_items.setIcon(QMessageBox::Question);
-		remove_items.setWindowTitle(QTStr("ConfirmRemove.Title"));
-		remove_items.exec();
-
-		confirmed = Yes == remove_items.clickedButton();
-	} else {
-		OBSSceneItem &item = items[0];
-		obs_source_t *source = obs_sceneitem_get_source(item);
-		if (source && QueryRemoveSource(source))
-			confirmed = true;
-	}
-	if (!confirmed)
-		return;
-
-	/* ----------------------------------------------- */
-	/* save undo data                                  */
-
 	obs_data_array_t *undo_array = obs_data_array_create();
 
 	obs_source_enum_full_tree(scene_source, save_undo_source_enum,
@@ -5543,41 +5502,18 @@ void OBSBasic::on_actionRemoveSource_triggered()
 	obs_data_array_push_back(undo_array, scene_data);
 	obs_data_release(scene_data);
 
-	obs_data_t *undo_data = obs_data_create();
-	obs_data_set_array(undo_data, "array", undo_array);
-	obs_data_array_release(undo_array);
-
-	/* because undo_array and redo_array will share settings data,
-	 * generate json here */
-	const char *undo_json = obs_data_get_json(undo_data);
-
-	/* ----------------------------------------------- */
-	/* remove items                                    */
-
-	for (auto &item : items)
-		obs_sceneitem_remove(item);
-
-	/* ----------------------------------------------- */
-	/* save redo data                                  */
-
-	obs_data_array_t *redo_array = obs_data_array_create();
-
-	obs_source_enum_full_tree(scene_source, save_undo_source_enum,
-				  redo_array);
-
-	scene_data = obs_save_source(scene_source);
-	obs_data_array_push_back(redo_array, scene_data);
-	obs_data_release(scene_data);
-
-	obs_data_t *redo_data = obs_data_create();
-	obs_data_set_array(redo_data, "array", redo_array);
-	obs_data_array_release(redo_array);
-
-	const char *redo_json = obs_data_get_json(redo_data);
+	OBSData data = obs_data_create();
+	obs_data_release(data);
 
-	/* ----------------------------------------------- */
-	/* undo/redo callback                              */
+	obs_data_set_array(data, "array", undo_array);
+	obs_data_get_json(data);
+	obs_data_array_release(undo_array);
+	return data;
+}
 
+void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
+					 OBSData undo_data, OBSData redo_data)
+{
 	auto undo_redo = [this](const std::string &json) {
 		obs_data_t *base = obs_data_create_from_json(json.c_str());
 		obs_data_array_t *array = obs_data_get_array(base, "array");
@@ -5623,8 +5559,71 @@ void OBSBasic::on_actionRemoveSource_triggered()
 		ui->sources->RefreshItems();
 	};
 
+	const char *undo_json = obs_data_get_last_json(undo_data);
+	const char *redo_json = obs_data_get_last_json(redo_data);
+
+	undo_s.add_action(action_name, undo_redo, undo_redo, undo_json,
+			  redo_json, nullptr);
+}
+
+void OBSBasic::on_actionRemoveSource_triggered()
+{
+	vector<OBSSceneItem> items;
+	OBSScene scene = GetCurrentScene();
+	obs_source_t *scene_source = obs_scene_get_source(scene);
+
+	obs_scene_enum_items(scene, remove_items, &items);
+
+	if (!items.size())
+		return;
+
+	/* ------------------------------------- */
+	/* confirm action with user              */
+
+	bool confirmed = false;
+
+	if (items.size() > 1) {
+		QString text = QTStr("ConfirmRemove.TextMultiple")
+				       .arg(QString::number(items.size()));
+
+		QMessageBox remove_items(this);
+		remove_items.setText(text);
+		QPushButton *Yes = remove_items.addButton(QTStr("Yes"),
+							  QMessageBox::YesRole);
+		remove_items.setDefaultButton(Yes);
+		remove_items.addButton(QTStr("No"), QMessageBox::NoRole);
+		remove_items.setIcon(QMessageBox::Question);
+		remove_items.setWindowTitle(QTStr("ConfirmRemove.Title"));
+		remove_items.exec();
+
+		confirmed = Yes == remove_items.clickedButton();
+	} else {
+		OBSSceneItem &item = items[0];
+		obs_source_t *source = obs_sceneitem_get_source(item);
+		if (source && QueryRemoveSource(source))
+			confirmed = true;
+	}
+	if (!confirmed)
+		return;
+
 	/* ----------------------------------------------- */
-	/* undo/redo                                       */
+	/* save undo data                                  */
+
+	OBSData undo_data = BackupScene(scene_source);
+
+	/* ----------------------------------------------- */
+	/* remove items                                    */
+
+	for (auto &item : items)
+		obs_sceneitem_remove(item);
+
+	/* ----------------------------------------------- */
+	/* save redo data                                  */
+
+	OBSData redo_data = BackupScene(scene_source);
+
+	/* ----------------------------------------------- */
+	/* add undo/redo action                            */
 
 	QString action_name;
 	if (items.size() > 1) {
@@ -5636,11 +5635,7 @@ void OBSBasic::on_actionRemoveSource_triggered()
 			obs_sceneitem_get_source(items[0])));
 	}
 
-	undo_s.add_action(action_name, undo_redo, undo_redo, undo_json,
-			  redo_json, nullptr);
-
-	obs_data_release(undo_data);
-	obs_data_release(redo_data);
+	CreateSceneUndoRedoAction(action_name, undo_data, redo_data);
 }
 
 void OBSBasic::on_actionInteract_triggered()

+ 4 - 0
UI/window-basic-main.hpp

@@ -857,6 +857,10 @@ public:
 
 	void ShowStatusBarMessage(const QString &message);
 
+	static OBSData BackupScene(obs_source_t *scene_source);
+	void CreateSceneUndoRedoAction(const QString &action_name,
+				       OBSData undo_data, OBSData redo_data);
+
 protected:
 	virtual void closeEvent(QCloseEvent *event) override;
 	virtual void changeEvent(QEvent *event) override;