Steve Mumford outlines the construction of the label printing application
In last month's column, I worked on the theory behind creating a set of data structures to hold our label layouts and information. Taking into account the concept of a master label, the scheme I decided upon consisted of a 'label' object that contained two linked lists - one for text objects and the other for imported Draw files - along with two address-holding variables that could point to two more such lists.
These two pointers would allow a child to hold objects of its own while still referring back to the master label for all its common fields. The 'label' objects could be stored as either a linked list or an array; the former is preferable although it does increase the level of complexity. The text and graphics objects both contain identifying strings, structures to store their position within the window, pointers to the actual data they hold and flags to remember whether they're editable. On top of those, the text objects also contain font name, colour and size information, and a priority variable to determine in which order the text fields should be stepped through and plotted.
Our next main objective is to decide which sections of the program we should code first, and what the overall shape of the graphical user interface should be. When planning the construction of the application, I tried to aim for an interface that was simple and yet provided the functionality we were after. One editing window would be catered for, and this would display the current label along with a toolbar allowing the user to flick from one entry to another. The intended feel is that of a deck of record cards; it's a representation that's been used in a wide range of applications and is one that most people can relate to.
Having one editing window simplifies the design somewhat, but it does mean that the user can only edit one label at once; on top of that, the effects of changes made to the master label on its children can't be seen immediately. However, this technique serves its purpose in the scope of our example and could be expanded later if necessary.
We should now consider some of the functions that the user will want to perform, so that we can build the appropriate code into the application from the outset. The editing window is constructed from a simple toolbar containing the usual navigation buttons and an information icon, with the actual label displayed underneath.
We've got plenty of opportunity for context-sensitive menus here; as well as providing options for the label as a whole (such as changing its title or freeing it from the influ- ence of the master), each object within the label will be provided with its own individual menu - along with the standard cut, paste and copy functions, these would contain entries to change font name and size details for text objects and scaling information for Draw files.
All of these responses will have to be provided by the procedure we write to handle the Mouse_Click event, and we'll have to look at methods of creating the specialised menus used in font and colour selection when we tackle this area. Not only will each object have its own context.sensitive menu; all of these objects, unless explicitly excluded, will be capable of being dragged so that their positions within the label can be altered - this means that we will have to revise and extend the drag-and-drop code first seen in use during a simple save operation. Although bounding boxes won't appear on the printed page, their presence during dragging opera- tions would greatly ease the procedure. Dynamic rescaling of Draw files would also prove extremely useful, and we could look at extending the dragging routines to include this functionality.
The redrawing routines will have a reasonable amount of work to do, so we might want to spend some time optimising the rather generous routines we've used in the past. Because the editing window won't be automatically redrawn, we can specify its precise layout, and although to start with the designs will be pretty straightforward, we'll have the opportunity to play with some more extrovert layouts and decide whether they lend anything to the user interface.
It's at this stage that we can work on the printed output, possibly investigating a method of exporting sheets of labels as native Draw files. Finally, with all this in place, we can work on other forms of data input and output, such as importing raw text or CSV files. While we're on the subject of file transfer, we could try our hand at direct memory transfer between applications to allow us to implement a simple version of OLE - I'll set the wheels in motion next time round.
|Source:||Acorn User - 199 - October 1998|