⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actsmgr.pas

📁 MiniHex 1.1 源程序说明 “MiniHex11SrcSource”目录中的所有文件是MiniHex 1.1的主程序; “MiniHex11SrcControls”目录中的是该软件
💻 PAS
字号:
{**********************************************************}
{                                                          }
{  功能:管理 Undo 和 Redo.                                }
{  说明:采用循环队列记录Undo动作和Redo动作,              }
{        Undo和Redo是两个不同的队列。                      }
{                                                          }
{**********************************************************}

unit ActsMgr;

interface

uses
  Windows, Messages, SysUtils, Classes,
  Controls, Forms, Dialogs;

type
  TActType = (              //动作类型
              atNone,
              atModify,
              atInsert,
              atDelete
              );

  PAct = ^TAct;
  TAct = record             //动作记录
    Enabled: Boolean;       //该动作是否能用
    ActType: TActType;      //动作类型
    Buf: string;            //缓冲区
    Offset: Integer;        //偏移
    Count: Integer;         //字节数
    CurPos: Integer;        //光标位置
    Prev: PAct;             //Prev指针
    Next: PAct;             //Next指针
  end;

  TActs = array of TAct;

  TActsMgr = class
  private
    FUndoActs: TActs;       //Undo队列
    FUndoHead: PAct;        //队列头指针
    FUndoTail: PAct;        //队列尾指针

    FRedoActs: TActs;       //Redo队列
    FRedoHead: PAct;        //队列头指针
    FRedoTail: PAct;        //队列尾指针

    FMaxUndo: Integer;      //最大Undo次数

    procedure SetMaxUndo(Value: Integer);
    procedure InitAct(var Act: TAct);

  public
    constructor Create(AMaxUndo: Integer);
    destructor Destroy; override;

    property MaxUndo: Integer read FMaxUndo write SetMaxUndo;

    function AddUndoItem: PAct;
    function AddRedoItem: PAct;
    function Undo: PAct;
    function Redo: PAct;

    function CanUndo: Boolean;
    function CanRedo: Boolean;

  end;

implementation

constructor TActsMgr.Create(AMaxUndo: Integer);
begin
  SetMaxUndo(AMaxUndo);
end;

destructor TActsMgr.Destroy;
begin
  SetLength(FUndoActs, 0);
  SetLength(FRedoActs, 0);
end;

procedure TActsMgr.SetMaxUndo(Value: Integer);
var
  i: Integer;
begin
  FMaxUndo := Value;
  SetLength(FUndoActs, FMaxUndo + 1);
  for i := 0 to FMaxUndo do
  begin
    if i = FMaxUndo then
      FUndoActs[i].Next := @FUndoActs[0]
    else
      FUndoActs[i].Next := @FUndoActs[i+1];
    if i = 0 then
      FUndoActs[i].Prev := @FUndoActs[FMaxUndo]
    else
      FUndoActs[i].Prev := @FUndoActs[i-1];
    FUndoActs[i].Enabled := False;
  end;
  FUndoHead := @FUndoActs[0];
  FUndoTail := @FUndoActs[0];

  SetLength(FRedoActs, FMaxUndo + 1);
  for i := 0 to FMaxUndo do
  begin
    if i = FMaxUndo then
      FRedoActs[i].Next := @FRedoActs[0]
    else
      FRedoActs[i].Next := @FRedoActs[i+1];
    if i = 0 then
      FRedoActs[i].Prev := @FRedoActs[FMaxUndo]
    else
      FRedoActs[i].Prev := @FRedoActs[i-1];
    FRedoActs[i].Enabled := False;
  end;
  FRedoHead := @FRedoActs[0];
  FRedoTail := @FRedoActs[0];
end;

procedure TActsMgr.InitAct(var Act: TAct);
begin
  with Act do
  begin
    Enabled := True;
    Buf := '';
    Offset := 0;
    Count := 0;
    CurPos := 0;
  end;
end;

function TActsMgr.AddUndoItem: PAct;
begin
  InitAct(FUndoHead^);
  Result := FUndoHead;

  if FUndoHead^.Next = FUndoTail then
    FUndoTail := FUndoTail^.Next;
  FUndoHead := FUndoHead^.Next;
  FUndoHead^.Enabled := False;
end;

function TActsMgr.AddRedoItem: PAct;
begin
  InitAct(FRedoHead^);
  Result := FRedoHead;

  if FRedoHead^.Next = FRedoTail then
    FRedoTail := FRedoTail^.Next;
  FRedoHead := FRedoHead^.Next;
  FRedoHead^.Enabled := False;
end;

function TActsMgr.Undo: PAct;
begin
  if not CanUndo then
  begin
    Result := nil;
    Exit;
  end;
  FUndoHead := FUndoHead^.Prev;
  FRedoHead := FRedoHead^.Prev;
  Result := FUndoHead;
end;

function TActsMgr.Redo: PAct;
begin
  if not CanRedo then
  begin
    Result := nil;
    Exit;
  end;
  Result := FRedoHead;
  FRedoHead := FRedoHead^.Next;
  FUndoHead := FUndoHead^.Next;
end;

function TActsMgr.CanUndo: Boolean;
begin
  Result := (FUndoHead <> FUndoTail);
end;

function TActsMgr.CanRedo: Boolean;
begin
  Result := FRedoHead^.Enabled;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -