Как реализовать функцию отмены и повтора в as3

#flash #actionscript-3 #apache-flex #flash-builder #flash-cs5

#flash #actionscript-3 #apache-flex #flash-builder #flash-cs5

Вопрос:

Я собираюсь создать приложение, в котором я должен реализовать функцию отмены и повтора. В приложении на сцене будет расположено несколько объектов, и пользователь может настроить положение объектов. Но когда пользователь нажимает на отмену, объект возвращается в положение по умолчанию, и после нажатия на повтор объект переместится на новую позицию.

Итак, мой вопрос в том, как я могу применить эти функции в своем приложении? Есть ли какая-либо библиотека или какие-либо сторонние классы?

Может ли кто-нибудь мне помочь?

Заранее спасибо.

Комментарии:

1. как реализовать отмену и повтор для нескольких объектов? Можем ли мы иметь какие-либо сторонние классы в as3?

Ответ №1:

Взгляните на шаблон команды. Он хорошо подходит для проблем типа отмены / повтора.

Комментарии:

1. Самого шаблона командной строки недостаточно. Обычно он используется в связи с памятным шаблоном.

Ответ №2:

Если вам нужны только два разных состояния (по умолчанию и «изменено»), это должно быть довольно тривиально реализовать. Сохраняйте новые и обновленные значения для каждого объекта в массивах и устанавливайте позиции из соответствующего массива при нажатии «отменить» или «повторить».

Если вам нужно что-то более сложное, вы можете сохранить все, что вы делаете, как «действие», которое нельзя отменить. Например, есть класс (например, «Действие») с несколькими дочерними классами («Переместить», «Изменить цвет» и т.д.). Они содержат выполняемые изменения (сколько пикселей мы должны переместить) и методы для выполнения действия (переместить объект на X пикселей) и отмены действия (переместить объект на X пикселей).

Ответ №3:

самый простой способ, который я могу придумать, — это создать объект действия, где у вас есть старое состояние, новое состояние и объект, который изменился.

каждый раз, когда запускается действие, которое получит функцию отмены, заполните эти данные в объекте действия

когда вы нажмете отменить, вернитесь к предыдущему состоянию объекта и поместите действие в стек повтора.

Это должно быть в состоянии обрабатывать наиболее распространенные изменения. Такие вещи, как удаление / восстановление, нуждаются в небольшой дополнительной настройке. Я бы просто ввел все свойства во время удаления и использовал функцию создания при обработке отмены.

Я бы предложил использовать строку для параметров и комбинаций значений для состояний до и после, чтобы вы могли обрабатывать дополнительные функции, не изменяя функциональность отмены / повтора.

Это более быстрый и грязный способ, вы также можете сделать это, используя шаблоны проектирования и надлежащие способы ООП для решения этой проблемы, как упоминали другие.

Комментарии:

1. можете ли вы предоставить мне какой-нибудь блок кода, чтобы я продолжил это?

Ответ №4:

  package com
 {
    import flashx.undo.IOperation;

    public class UndoOperation implements IOperation
    {

    private var _previousX:Number = 0;
    private var _previousY:Number = 0;
    private var _previousObj:Object = new Object();
    private var _currentX:Number = 0;
    private var _currentY:Number = 0;
    private var _currentObj:Object = new Object();
    private var _shape:Object = new Object();


    public function TransformOperation(currentObj:Object,previousObj:Object,previousX:Number, previousY:Number, currentX:Number, currentY:Number)
    {
        _previousX = previousX;
        _previousY = previousY;
        _previousObj = previousObj;

        _currentX = currentX;
        _currentY = currentY;
        _currentObj = currentObj;
        _shape = _currentObj;

        trace('Transform _previousX:  '   _previousX   ' _previousY:  '  _previousY ' _currentObj ' _currentObj ' _shape ' _shape);
        trace( 'trans _currentX    '  _currentX  '  ' '_currentY     '  _currentY );

    }

    public function performUndo():void
    {
        _shape = _currentObj;
        //trace('_shape.x ' _shape.x " _shape.y " _shape.y);
        _shape.x = _previousX;
        _shape.y = _previousY;
        //trace(_previousX  '  '  _previousY  '  '  _previousWidth  '  '  _previousHeight  '  '   _previousScaleX  '  '   _previousScaleY  '  '  _previousRotation);
        //trace('_shape.x ' _shape.x " _shape.y " _shape.y);
        //trace('_currentX    '  _currentX  '  ' '_currentY     '  _currentY);
    }

    public function performRedo():void
    {
        _shape.x = _currentX;
        _shape.y = _currentY;
        trace(_currentX '  '  _currentY);
    }
  }
}
  

Это мой класс настройки для отмены и повтора нескольких объектов на сцене. Существует другой шаблон, который можно использовать для операции отмены и повтора, но для меня это простой способ отмены и повтора. Я отлично и успешно реализовал это в своем проекте.

Чтобы использовать этот класс, импортируйте только класс

                  import flashx.undo.UndoManager;
  

и после этого

             public static var _undo:UndoManager=new UndoManager();
            public static var _redo:UndoManager=new UndoManager();     
            public static var PrevX:Number=0;
            public static var PrevY:Number=0;
            var operation:TransformOperation = new TransformOperation(this,this,PrevX,PrevY,this.x,this.y);
           _undo.pushUndo(operation);
  

После этого создайте событие щелчка для отмены и повтора:

     public static function Undo(e:MouseEvent):void
    {
        _redo.pushRedo(_undo.peekUndo());
        _undo.undo();
        if(_undo.peekUndo()==null)
        {
            PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("undo_mc").removeEventListener(MouseEvent.CLICK,Undo);
        }
        PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("redo_mc").addEventListener(MouseEvent.CLICK,Redo);
    }

    public static function Redo(e:MouseEvent):void
    {
        _undo.pushUndo(_redo.peekRedo());
        _redo.redo();
        if(_redo.peekRedo()==null)
        {                          PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("redo_mc").removeEventListener(MouseEvent.CLICK,Redo);
        }
        PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("undo_mc").addEventListener(MouseEvent.CLICK,Undo);
    }
  

Для меня это работает нормально… Надеюсь, это поможет и другим …:)