Logo Search packages:      
Sourcecode: blender version File versions  Download package

ACT_ActionStack.cpp

/**
 * $Id: ACT_ActionStack.cpp,v 1.3 2002/11/25 09:52:46 mein Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

/**

 * $Id: ACT_ActionStack.cpp,v 1.3 2002/11/25 09:52:46 mein Exp $
 * Copyright (C) 2001 NaN Technologies B.V.
 * @author  Maarten Gribnau
 * @date    March 31, 2001
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "ACT_ActionStack.h"


00047 ACT_ActionStack::ACT_ActionStack(unsigned int maxStackDepth)
      : m_maxStackDepth(maxStackDepth),
        m_undoIndex(0), m_undoIndexValid(false),
        m_redoIndex(0), m_redoIndexValid(false)
{
}


00055 ACT_ActionStack::~ACT_ActionStack()
{
      flush();
}


00061 unsigned int ACT_ActionStack::getStackDepth() const
{
      return m_stack.size();
}


00067 unsigned int ACT_ActionStack::getMaxStackDepth() const
{
      return m_maxStackDepth;
}


00073 void ACT_ActionStack::setMaxStackDepth(unsigned int maxStackDepth)
{
      if (maxStackDepth != m_maxStackDepth) {
            if (maxStackDepth) {
                  unsigned int size = m_stack.size();
                  if (maxStackDepth < size) {
                        // New max stack size is smaller than current stack size, need to shrink stack
                        unsigned int numRemove = size - maxStackDepth;
                        if (m_undoIndex >= maxStackDepth) {
                              // Pop items from the front (throw away undo steps)
                              popFront(numRemove);
                              m_undoIndex -= numRemove;
                              m_redoIndex = m_undoIndex + 1;
                              m_redoIndexValid = m_redoIndexValid && (maxStackDepth > 1);
                        }
                        else {
                              // Pop items from the back (throw away redo steps)
                              popBack(numRemove);
                              m_redoIndexValid = m_redoIndexValid && (m_redoIndex < maxStackDepth);
                        }
                  }
            }
            else {
                  // New stack size is zero
                  flush();
            }
            m_maxStackDepth = maxStackDepth;
      }
}


00104 void ACT_ActionStack::push(ACT_Action& action)
{
      if (m_maxStackDepth) {
            unsigned int size = m_stack.size();
            if (m_redoIndexValid) {
                  // Remove items after the current action (throw away redo steps)
                  popBack(size - m_redoIndex);
            }
            else if (size >= m_maxStackDepth) {
                  // Remove items from the front (throw away undo steps)
                  popFront(m_maxStackDepth - size + 1);
            }

            // Store the action
            if (!action.getIsApplied()) {
                  action.apply();
            }
            action.incRef();
            m_stack.push_back(&action);

            // Update action indices
            m_redoIndex = m_stack.size();
            m_redoIndexValid = false;
            m_undoIndex = m_redoIndex - 1;
            m_undoIndexValid = true;
      }
}


00133 ACT_Action* ACT_ActionStack::peekUndo()
{
      unsigned int i;
      return getUndoIndex(i) ? m_stack[i] : 0;
}


00140 ACT_Action* ACT_ActionStack::peekRedo()
{
      unsigned int i;
      return getRedoIndex(i) ? m_stack[i] : 0;
}


00147 void ACT_ActionStack::flush()
{
      popBack(m_stack.size());
      m_undoIndex = 0;
      m_undoIndexValid = false;
      m_redoIndex = 0;
      m_redoIndexValid = false;
}


00157 bool ACT_ActionStack::canUndo() const
{
      unsigned int i;
      return getUndoIndex(i);
}


00164 void ACT_ActionStack::undo()
{
      ACT_Action* action = peekUndo();
      if (action) {
            action->undo();

            // Update action indices
            m_redoIndex = m_undoIndex;
            m_redoIndexValid = true;
            if (m_undoIndex) {
                  m_undoIndex--;
            }
            else {
                  m_undoIndexValid = false;
            }
      }
}


00183 bool ACT_ActionStack::canRedo() const
{
      unsigned int i;
      return getRedoIndex(i);
}


00190 void ACT_ActionStack::redo()
{
      ACT_Action* action = peekRedo();
      if (action) {
            action->apply();

            // Update action indices
            m_undoIndex = m_redoIndex;
            m_undoIndexValid = true;
            m_redoIndex++;
            m_redoIndexValid = m_redoIndex < m_stack.size();
      }
}


00205 unsigned int ACT_ActionStack::popFront(unsigned int numActions)
{
      unsigned int numRemoved = 0;

      while (numActions-- && m_stack.size()) {
            ACT_Action* action = m_stack[0];
            action->decRef();
            m_stack.pop_front();
            numRemoved++;
      }
      return numRemoved;      
}


00219 unsigned int ACT_ActionStack::popBack(unsigned int numActions)
{
      unsigned int numRemoved = 0;
      unsigned int size;

      while (numActions-- && (size = m_stack.size())) {
            ACT_Action* action = m_stack[size-1];
            action->decRef();
            m_stack.pop_back();
            numRemoved++;
      }
      return numRemoved;      
}


00234 bool ACT_ActionStack::getUndoIndex(unsigned int& i) const
{
      i = m_undoIndex;
      return m_undoIndexValid;
}


00241 bool ACT_ActionStack::getRedoIndex(unsigned int& i) const
{
      i = m_redoIndex;
      return m_redoIndexValid;
}

Generated by  Doxygen 1.6.0   Back to index