Subversion Repositories Kolibri OS

Rev

Rev 7253 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // Actions history
  2.  
  3. #define MAX_ACTIONS_COUNT 10
  4.  
  5. struct _ActionsHistory {
  6.         dword stack[MAX_ACTIONS_COUNT];
  7.         dword head;
  8.         dword tail;
  9.         dword currentIndex;
  10.  
  11.         void init();
  12.         bool isEmpty();
  13.  
  14.         void saveCurrentState();
  15.         void restoreState(dword index);
  16.  
  17.         void undoLastAction();
  18.         void redoLastAction();
  19. };
  20.  
  21. void _ActionsHistory::init() {
  22.         dword i;
  23.  
  24.         head = tail = 0;
  25.         currentIndex = -1;
  26.  
  27.         for (i = 0; i < MAX_ACTIONS_COUNT; i++)
  28.                 stack[i] = malloc(image.columns * image.rows);
  29.  
  30.         saveCurrentState();
  31. }
  32.  
  33. bool _ActionsHistory::isEmpty() {
  34.         if (head == tail)
  35.                 return true;
  36.         else
  37.                 return false;
  38. }
  39.  
  40. void _ActionsHistory::saveCurrentState() {
  41.         dword addr, offset;
  42.         int r, c;
  43.        
  44.         tail = currentIndex + 1;
  45.  
  46.         if (tail >= MAX_ACTIONS_COUNT)
  47.                 tail = tail % MAX_ACTIONS_COUNT;
  48.  
  49.         addr = stack[tail];
  50.  
  51.         for (r = 0; r < image.rows; r++)
  52.         {
  53.                 for (c = 0; c < image.columns; c++)
  54.                 {
  55.                         offset = calc(image.columns * r + c) * 4;
  56.  
  57.                         ESDWORD[addr + offset] = image.get_pixel(r, c);
  58.                 }
  59.         }
  60.  
  61.         currentIndex = tail;
  62.         tail = calc(tail + 1) % 10;
  63.  
  64.         if (tail == head)
  65.                 head = calc(head + 1) % 10;
  66. }
  67.  
  68. void _ActionsHistory::restoreState(dword index) {
  69.         dword addr, offset;
  70.         int r, c;
  71.  
  72.         addr = stack[index];
  73.  
  74.         for (r = 0; r < image.rows; r++)
  75.         {
  76.                 for (c = 0; c < image.columns; c++)
  77.                 {
  78.                         offset = calc(image.columns * r + c) * 4;
  79.                         image.set_pixel(r, c, ESDWORD[addr + offset]);
  80.                 }
  81.         }
  82. }
  83.  
  84. void _ActionsHistory::undoLastAction() {
  85.         dword previousAction;
  86.  
  87.         // Если вышли за левую границу, перемещаемся в конец массива
  88.         if (currentIndex == 0) {
  89.                 previousAction = MAX_ACTIONS_COUNT - 1;
  90.         }
  91.         else {
  92.                 previousAction = currentIndex - 1;
  93.         }
  94.  
  95.         if (isEmpty())
  96.                 return;
  97.         else {
  98.                 if (currentIndex != head) {
  99.                         restoreState(previousAction);
  100.                         DrawCanvas();
  101.                 }
  102.  
  103.                 if (currentIndex != head)
  104.                         currentIndex = previousAction;
  105.         }
  106. }
  107.  
  108. void _ActionsHistory::redoLastAction() {
  109.         dword nextAction = calc(currentIndex + 1);
  110.  
  111.         // Если вышли за левую границу, возвращаемся в начало
  112.         if (nextAction >= MAX_ACTIONS_COUNT)
  113.                 nextAction = nextAction % MAX_ACTIONS_COUNT;
  114.  
  115.         if (isEmpty())
  116.                 return;
  117.         else {
  118.                 if (nextAction != tail) {
  119.                         restoreState(nextAction);
  120.                         DrawCanvas();
  121.                 }
  122.  
  123.                 if (nextAction != tail)
  124.                         currentIndex = nextAction;
  125.         }
  126. }