Quellcode durchsuchen

UI: Undo/Redo context bar properties

Implements undo/redo for changing of properties done through the context
bar.
Ford Smith vor 5 Jahren
Ursprung
Commit
999495ca8c
2 geänderte Dateien mit 82 neuen und 0 gelöschten Zeilen
  1. 78 0
      UI/context-bar-controls.cpp
  2. 4 0
      UI/context-bar-controls.hpp

+ 78 - 0
UI/context-bar-controls.cpp

@@ -1,3 +1,4 @@
+#include "window-basic-main.hpp"
 #include "context-bar-controls.hpp"
 #include "qt-wrappers.hpp"
 #include "obs-app.hpp"
@@ -33,6 +34,63 @@ SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
 {
 }
 
+void SourceToolbar::SaveOldProperties(obs_source_t *source)
+{
+	if (oldData)
+		obs_data_release(oldData);
+
+	oldData = obs_data_create();
+	obs_data_t *oldSettings = obs_source_get_settings(source);
+	obs_data_apply(oldData, oldSettings);
+	obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source));
+	obs_data_release(oldSettings);
+	obs_data_release(oldData);
+}
+
+void SourceToolbar::SetUndoProperties(obs_source_t *source)
+{
+	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
+
+	std::string scene_name =
+		obs_source_get_name(main->GetCurrentSceneSource());
+	auto undo_redo = [scene_name,
+			  main = std::move(main)](const std::string &data) {
+		obs_data_t *settings = obs_data_create_from_json(data.c_str());
+		obs_source_t *source = obs_get_source_by_name(
+			obs_data_get_string(settings, "undo_sname"));
+		obs_source_update(source, settings);
+
+		obs_source_t *scene_source =
+			obs_get_source_by_name(scene_name.c_str());
+		main->SetCurrentScene(scene_source);
+		obs_source_release(scene_source);
+
+		obs_data_release(settings);
+		obs_source_release(source);
+
+		main->UpdateContextBar();
+	};
+
+	OBSData new_settings = obs_data_create();
+	OBSData curr_settings = obs_source_get_settings(source);
+	obs_data_apply(new_settings, curr_settings);
+	obs_data_set_string(new_settings, "undo_sname",
+			    obs_source_get_name(source));
+
+	std::string undo_data(obs_data_get_json(oldData));
+	std::string redo_data(obs_data_get_json(new_settings));
+
+	if (undo_data.compare(redo_data) != 0)
+		main->undo_s.add_action(
+			QTStr("Undo.Properties")
+				.arg(obs_source_get_name(source)),
+			undo_redo, undo_redo, undo_data, redo_data, nullptr);
+
+	obs_data_release(new_settings);
+	obs_data_release(curr_settings);
+	obs_data_release(oldData);
+}
+
 /* ========================================================================= */
 
 BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
@@ -163,8 +221,10 @@ void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
 		return;
 	}
 
+	SaveOldProperties(source);
 	UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name,
 				      is_int);
+	SetUndoProperties(source);
 }
 
 AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source)
@@ -370,10 +430,12 @@ void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
 
 	QString id = ui->mode->itemData(idx).toString();
 
+	SaveOldProperties(source);
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+	SetUndoProperties(source);
 
 	UpdateWindowVisibility();
 }
@@ -387,10 +449,12 @@ void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
 
 	QString id = ui->window->itemData(idx).toString();
 
+	SaveOldProperties(source);
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_string(settings, "window", QT_TO_UTF8(id));
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+	SetUndoProperties(source);
 }
 
 /* ========================================================================= */
@@ -434,10 +498,12 @@ void ImageSourceToolbar::on_browse_clicked()
 
 	ui->path->setText(path);
 
+	SaveOldProperties(source);
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_string(settings, "file", QT_TO_UTF8(path));
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+	SetUndoProperties(source);
 }
 
 /* ========================================================================= */
@@ -518,10 +584,14 @@ void ColorSourceToolbar::on_choose_clicked()
 	color = newColor;
 	UpdateColor();
 
+	SaveOldProperties(source);
+
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_int(settings, "color", color_to_int(color));
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+
+	SetUndoProperties(source);
 }
 
 /* ========================================================================= */
@@ -596,6 +666,8 @@ void TextSourceToolbar::on_selectFont_clicked()
 	flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
 	obs_data_set_int(font_obj, "flags", flags);
 
+	SaveOldProperties(source);
+
 	obs_data_t *settings = obs_data_create();
 
 	obs_data_set_obj(settings, "font", font_obj);
@@ -603,6 +675,8 @@ void TextSourceToolbar::on_selectFont_clicked()
 
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+
+	SetUndoProperties(source);
 }
 
 void TextSourceToolbar::on_selectColor_clicked()
@@ -628,6 +702,8 @@ void TextSourceToolbar::on_selectColor_clicked()
 
 	color = newColor;
 
+	SaveOldProperties(source);
+
 	obs_data_t *settings = obs_data_create();
 	if (!strncmp(obs_source_get_id(source), "text_ft2_source", 15)) {
 		obs_data_set_int(settings, "color1", color_to_int(color));
@@ -637,6 +713,8 @@ void TextSourceToolbar::on_selectColor_clicked()
 	}
 	obs_source_update(source, settings);
 	obs_data_release(settings);
+
+	SetUndoProperties(source);
 }
 
 void TextSourceToolbar::on_text_textChanged()

+ 4 - 0
UI/context-bar-controls.hpp

@@ -22,6 +22,10 @@ protected:
 		std::unique_ptr<obs_properties_t, properties_delete_t>;
 
 	properties_t props;
+	OBSData oldData;
+
+	void SaveOldProperties(obs_source_t *source);
+	void SetUndoProperties(obs_source_t *source);
 
 public:
 	SourceToolbar(QWidget *parent, OBSSource source);