Re: Undo and the text widget

On Wed, Nov 29, 2000 at 09:55:24AM +0100, Alexander Larsson wrote:
> The normal way of implementing Undo/Redo is by making each "change" an
> Action. An Action is an abstract representation of the change, and can be
> applied and after it has been applied it can be unapplied.
> Then when the user runs undo you unapply all Actions since the last time
> the user started doing something. This might be done by placing
> transaction points in the undo stack, or having an group action which
> contains other actions.

	Modern Photoshops (and RDBMSes) of course have a transaction
buffer.  Whatever the API is, it should basically allow for you to have
a structure like so:

Last saved (or known good) full document copy.
	Action A
	Action B
	Action C
	Action D
		Current full document state.

	So that any movement of the current state is simply a playback.
Eg, if you wanted to do "undo twice", the system should support both a
reverse play of actions C and D, and also a reversion to the Last copy,
plus a replay of actions A and B.  This should get you to the same state
via either process.  As you say, you merely have 'insert' and 'delete'
actions, which should satisfy this process easily.
	For things like meta-space, etc, you should do serial groupings,
similar to Gimp's enable/disable_undo().  So meta-space might do:

delete_stuff(buffer, those_pesky_spaces);
insert_stuff(buffer, that_one_space);

	The stack would now contain:

Last saved
	deleted spaces (group id 1)
	inserted space (group id 1)

	A group id of 0 or -1 or something would signify there is no
	The transaction stack, of course, is what would handle said
structure.  This need not be a part of either the buffer or view code.
The buffer just emits 'insert action' and 'delete action' signals
appropriately (the transaction stack has registered itself to listen, of
course), and the view happily does action grouping with meta-space.
	If the transaction stack items are clean and opaque, you get the
macro capability chris likes with a manual stack_add_entry().  You can
replay to any happy stated forward and back with this.  And if you are
implementing a user-known Undo, you can easily take a contiguous action
group and play it back all at once.
	Anyway, from the standpoint of the proper hooks for the text
widget, you'd need it to emit 'insert' and 'delete' signals with the
action group id included, and the start/end_group() functions.
	My $0.02



Life's Little Instruction Book #3

	"Watch a sunrise at least once a year."
			jlbec evilplan org

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]