\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. \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 while 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.