UI: Initial Undo/Redo

Starting to develop Undo/Redo. This just implmements the undo/redo stack
and its api.
This commit is contained in:
Ford Smith 2021-03-21 22:16:17 -04:00 committed by Ford Smith
parent eaf992119f
commit eced5a320b
3 changed files with 175 additions and 0 deletions

View file

@ -262,6 +262,34 @@ Basic.SceneTransitions="Scene Transitions"
Basic.TransitionDuration="Duration"
Basic.TogglePreviewProgramMode="Studio Mode"
# undo
Undo.Undo="Undo"
Undo.Redo="Redo"
Undo.Add="Add '%1'"
Undo.Delete="Delete '%1'"
Undo.Rename="Rename '%1'"
Undo.SceneCollection.Switch="Switch to '%1'"
Undo.Item.Undo="Undo %1"
Undo.Item.Redo="Redo %1"
Undo.Sources.Multi="Delete %1 Sources"
Undo.Filters="Filter Changes on '%1'"
Undo.Transform="Transform source(s) In '%1'"
Undo.Transform.Paste="Paste Transformation in '%1'"
Undo.Transform.Rotate="Rotation In '%1'"
Undo.Transform.Reset="Transform Reset In '%1'"
Undo.Transform.HFlip="Horizontal Flip In '%1'"
Undo.Transform.VFlip="Vertical Flip In '%1'"
Undo.Transform.FitToScren="Fit to Screen In '%1'"
Undo.Transform.StretchToScreen="Stretch to Screen in '%1'"
Undo.Transform.Center="Center to Screen in '%1'"
Undo.Transform.VCenter="Vertical Center to Screen in '%1'"
Undo.Transform.HCenter="Horizontal Center to Screen in '%1'"
Undo.Volume.Change="Volume Change on '%1'"
Undo.Audio="Audio Changes"
Undo.Properties="Property Change on '%1'"
Undo.Scene.Duplicate="Duplicate Scene '%1'"
# transition name dialog
TransitionNameDlg.Text="Please enter the name of the transition"
TransitionNameDlg.Title="Transition Name"

101
UI/undo-stack-obs.cpp Normal file
View file

@ -0,0 +1,101 @@
#include "undo-stack-obs.hpp"
#include <util/util.hpp>
undo_stack::undo_stack(ui_ptr ui) : ui(ui) {}
void undo_stack::release()
{
for (auto f : undo_items)
if (f.d)
f.d(true);
for (auto f : redo_items)
if (f.d)
f.d(false);
}
void undo_stack::add_action(const QString &name, undo_redo_cb undo,
undo_redo_cb redo, std::string undo_data,
std::string redo_data, func d)
{
undo_redo_t n = {name, undo_data, redo_data, undo, redo, d};
undo_items.push_front(n);
clear_redo();
ui->actionMainUndo->setText(QTStr("Undo.Item.Undo").arg(name));
ui->actionMainUndo->setEnabled(true);
ui->actionMainRedo->setText(QTStr("Undo.Redo"));
ui->actionMainRedo->setDisabled(true);
}
void undo_stack::undo()
{
if (undo_items.size() == 0 || disabled)
return;
undo_redo_t temp = undo_items.front();
temp.undo(temp.undo_data);
redo_items.push_front(temp);
undo_items.pop_front();
ui->actionMainRedo->setText(QTStr("Undo.Item.Redo").arg(temp.name));
ui->actionMainRedo->setEnabled(true);
if (undo_items.size() == 0) {
ui->actionMainUndo->setDisabled(true);
ui->actionMainUndo->setText(QTStr("Undo.Undo"));
} else {
ui->actionMainUndo->setText(
QTStr("Undo.Item.Undo").arg(undo_items.front().name));
}
}
void undo_stack::redo()
{
if (redo_items.size() == 0 || disabled)
return;
undo_redo_t temp = redo_items.front();
temp.redo(temp.redo_data);
undo_items.push_front(temp);
redo_items.pop_front();
ui->actionMainUndo->setText(QTStr("Undo.Item.Undo").arg(temp.name));
ui->actionMainUndo->setEnabled(true);
if (redo_items.size() == 0) {
ui->actionMainRedo->setDisabled(true);
ui->actionMainRedo->setText(QTStr("Undo.Redo"));
} else {
ui->actionMainRedo->setText(
QTStr("Undo.Item.Redo").arg(redo_items.front().name));
}
}
void undo_stack::enable_undo_redo()
{
disabled = false;
ui->actionMainUndo->setDisabled(false);
ui->actionMainRedo->setDisabled(false);
}
void undo_stack::disable_undo_redo()
{
disabled = true;
ui->actionMainUndo->setDisabled(true);
ui->actionMainRedo->setDisabled(true);
}
void undo_stack::clear_redo()
{
for (auto f : redo_items)
if (f.d)
f.d(false);
redo_items.clear();
}

46
UI/undo-stack-obs.hpp Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include <QString>
#include <deque>
#include <functional>
#include <string>
#include <memory>
#include "ui_OBSBasic.h"
typedef std::function<void(const std::string &data)> undo_redo_cb;
typedef std::function<void(bool is_undo)> func;
typedef std::unique_ptr<Ui::OBSBasic> &ui_ptr;
struct undo_redo_t {
QString name;
std::string undo_data;
std::string redo_data;
undo_redo_cb undo;
undo_redo_cb redo;
func d;
};
class undo_stack {
private:
ui_ptr ui;
std::deque<undo_redo_t> undo_items;
std::deque<undo_redo_t> redo_items;
bool disabled = false;
void clear_redo();
public:
undo_stack(ui_ptr ui);
void enable_undo_redo();
void disable_undo_redo();
void release();
void add_action(const QString &name, undo_redo_cb undo,
undo_redo_cb redo, std::string undo_data,
std::string redo_data, func d);
void undo();
void redo();
};