--- /dev/null
+\chapter{OGLEdit: a sample OGL application}\label{ogledit}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}
+
+OGLEdit is a sample OGL application that allows the user to draw, edit,
+save and load a few shapes. It should clarify aspects of OGL usage, and
+can act as a template for similar applications. OGLEdit can be found in\rtfsp
+{\tt samples/ogledit} in the OGL distribution.
+
+$$\image{10cm;0cm}{ogledit.eps}$$\par
+
+The wxWindows document/view model has been used in OGL, to reduce the amount of
+housekeeping logic required to get it up and running. OGLEdit also provides
+a demonstration of the Undo/Redo capability supported by the document/view classes,
+and how a typical application might implement this feature.
+
+{\it Note:} A bug in the wxWindows document/view implementation before
+version 1.66C may cause Do/Undo to misbehave and get out of sync. If this is the case,
+please replace wxCommandProcessor::Submit with the following in wx\_doc.cpp.
+
+{\small
+\begin{verbatim}
+ Bool wxCommandProcessor::Submit(wxCommand *command, Bool storeIt)
+ {
+ Bool success = command->Do();
+ if (success && storeIt)
+ {
+ if (commands.Number() == maxNoCommands)
+ {
+ wxNode *firstNode = commands.First();
+ wxCommand *firstCommand = (wxCommand *)firstNode->Data();
+ delete firstCommand;
+ delete firstNode;
+ }
+
+ // Correct a bug: we must chop off the current 'branch'
+ // so that we're at the end of the command list.
+ if (currentCommand)
+ {
+ wxNode *node = currentCommand->Next();
+ while (node)
+ {
+ wxNode *next = node->Next();
+ delete node;
+ node = next;
+ }
+ }
+
+ commands.Append(command);
+ currentCommand = commands.Last();
+ SetMenuStrings();
+ }
+ return success;
+ }
+\end{verbatim}
+}
+
+\section{OGLEdit files}
+
+OGLEdit comprises the following source files.
+
+\begin{itemize}\itemsep=0pt
+\item doc.h, doc.cpp: MyDiagram, DiagramDocument, DiagramCommand, MyEvtHandler
+classes related to diagram functionality and documents.
+\item view.h, view.cpp: MyCanvas, DiagramView classes related to visualisation of
+the diagram.
+\item ogledit.h, ogledit.cpp: MyFrame, MyApp classes related to the overall application.
+\item palette.h, palette.cpp: EditorToolPalette implementing the shape palette.
+\end{itemize}
+
+\section{How OGLEdit works}
+
+OGLEdit defines a DiagramDocument class, each of instance of which holds a MyDiagram
+member which itself contains the shapes.
+
+In order to implement specific mouse behaviour for shapes, a class MyEvtHandler is
+defined which is `plugged into' each shape when it is created, instead of overriding each shape class
+individually. This event handler class also holds a label string.
+
+The DiagramCommand class is the key to implementing Undo/Redo. Each instance of DiagramCommand
+stores enough information about an operation (create, delete, change colour etc.) to allow
+it to carry out (or undo) its command. In DiagramView::OnMenuCommand, when the user initiates the
+command, a new DiagramCommand instance is created which is then sent to the document's
+command processor (see wxWindows manual for more information about doc/view and command
+processing).
+
+Apart from menu commands, another way commands are initiated is by the user left-clicking on
+the canvas or right-dragging on a node. MyCanvas::OnLeftClick in view.cpp shows how
+the appropriate wxClassInfo is passed to a DiagramCommand, to allow DiagramCommand::Do
+to create a new shape given the wxClassInfo.
+
+The MyEvtHandler right-drag methods in doc.cpp implement drawing a line between
+two shapes, detecting where the right mouse button was released and looking for a second
+shape. Again, a new DiagramCommand instance is created and passed to the command
+processor to carry out the command.
+
+DiagramCommand::Do and DiagramCommand::Undo embody much of the
+interesting interaction with the OGL library. A complication of note
+when implementing undo is the problem of deleting a node shape which has
+one or more arcs attached to it. If you delete the node, the arc(s)
+should be deleted too. But multiple arc deletion represents more information
+that can be incorporated in the existing DiagramCommand scheme. OGLEdit
+copes with this by treating each arc deletion as a separate command, and
+sending Cut commands recursively, providing an undo path. Undoing such a
+Cut will only undo one command at a time - not a one to one
+correspondence with the original command - but it's a reasonable
+compromise and preserves Do/Undo whilst keeping our DiagramCommand class
+simple.
+
+\section{Possible enhancements}
+
+OGLEdit is very simplistic and does not employ the more advanced features
+of OGL, such as:
+
+\begin{itemize}\itemsep=0pt
+\item attachment points (arcs are drawn to particular points on a shape)
+\item metafile and bitmaps shapes
+\item divided rectangles
+\item composite shapes, and constraints
+\item creating labels in shape regions
+\item arc labels (OGL has support for three movable labels per arc)
+\item spline and multiple-segment line arcs
+\item adding annotations to node and arc shapes
+\item line-straightening (supported by OGL) and alignment (not supported directly by OGL)
+\end{itemize}
+
+These could be added to OGLEdit, at the risk of making it a less
+useful example for beginners.