By late today or tomorrow, the major surgery on the level editor will be done. I'm sure there will be other usability tweaks over time, but I have only 3 out of the dozen or so tabs to do - the vertex, decals and atmosphere tabs.
Over the past couple of days I put in a limited form of Undo, and last night I put in auto-save. I also cleaned up the facet editing so you can't rename or delete important facets, like the 'name' facet.
The undo was an interesting problem. The classic way to do it is to have a command struct that contains enough information to undo itself. On every undoable command, you create one of these and store in some sort of container. When the user hits undo, you roll back the command using the saved undo information.
Of course, depending on how the code works, the amount of data needed to undo some commands can be huge - for instance, selecting the whole level and snapping the verts to a grid could require saving out basically the whole level geometry before the operation.
What I decided was that I would allow undo of rotation, placement and scaling of objects only, not creation/deletion, facet changes or any triangle or vertex geometry manipulation.
Each time the user goes into a modification mode or hits buttons that affect an object's matrix, I go through the selected objects and take snapshots of their matrix, and push it unto a per-object vector of past matrices.
When the user cancels the operation, or does Ctrl-Z later on, it just does a pop_back() on the history vector. With this particular method, the undo buffers are per-object, rather than app-wide, so you can individually undo changes, which I'm sure has its ups and downs.
It works well, but I'm extending it to support re-do also.
I'm also revamping the controls. Since I had so much trouble with the .net controls, I ended up using a bunch of keyboard shortcuts for things that should have been done with the mouse, so I've made a toolbar for manipulating movable objects where you click on a toolbar button, hold down the mouse button, and then the cursor disappears and you can manipulate the selected objects. Much better than the old method which kept the cursor visible, which would cause it to go offscreen, or over a control, etc.
I also added back in dirty handling, so it knows when you've changed something, and also added a new autosave feature. This saves your current name.lvl file as name.bak every minute or so ( configurable ). You can load .bak files just like .lvl files to go back to a saved version.
In other news, I've been a bit sick, but due to all my hoops playing, I'm able to sort of ride out most cold/flu type stuff pretty well. I ended up playing hoops during my break on jury duty on Tuesday. When I came back to the court, they ended up dismissing our case, so I didn't have to give my sob story after all!