The mechanism for undrawing things should be pretty clear now, but to summarize: when something is drawn by the user, it is saved in a list, and not drawn immediately. Every 1/30 of a second, the event loop calls the draw function, which scans all the drawn items and redraws them.
When the undraw button is pressed using the mouse, it moves the last item from the backstack list to the end of a second list called forestack. Since that element is now not in the backstack list, it will not be drawn. Each time the undraw button is used, another item is moved from the end of backstack to the end of forestack, effectively undrawing it. If the redraw button is pressed, the item at the end of forestack is moved back to the end of backstack, meaning that it will reappear in the drawing.
Whenever the user draws something new, whatever it may be, the forestack list is emptied.
The names backstack and forestack refer to the fact that these lists are being used as stack data structures. A stack is organized so that the last thing saved will be the first thing seen, as would be the case in a pile of books, for example. If a math book is placed on a table, then a history book and then a novel, we have a stack of books. On the top of the stack is the last thing I put there – the novel. If I remove that from the stack, I uncover the next-to-last book I placed there, the history book. Items are removed from the stack – popped, it is called – in reverse order from the way they were put there. This is also called a first-in-last-out (FILO) structure.
Figure 15.4 details how this works using a simple example.
The backstack is not only used as a stack. It is, as has been described, also used as a simple list when redrawing the screen. When used as a stack, it is accessed from the end; when used to redraw, the items are accessed from the start (element 0) through to the last one.
A stack should be implemented as a class. The stack uses a list, so when adding a new element to the end (called pushing), we append a new item to the end of the list (top of the stack) and when an item is popped, it is removed from the end. However, when drawing, we can scan the list from element 0 through to the top and redraw everything in the order it was drawn originally.
An example stack that does what we want is given in the following code:
Because python is so flexible about types, this stack can be used for floats or integers, or anything really. In the case of the paint program, it will be used to push and pop drawing instructions, which will be instances of the class named Mode, which is an implementation of a drawing directive.
Source: Parker James R. (2021), Python: An Introduction to Programming, Mercury Learning and Information; Second edition.