Story Library
Home   Hierarchy   Classes   Files   Functions   Modules   Pages  

Layout Overview

A layout is essentially the series of columns which a story can flow through, and each column is a simple rectangular area.

Typically you will also want frames, pages, chapters, sections, captions, headers, footers etc. These things are very application-specific. The engine's direct support for them is limited to the protocol in Story::CFrame, which columns use to discover information about their wider context. You should build whatever page architecture you want out of columns, have one of your classes implement Story::CFrame, then use Story::CColumn::SetFrame on each column so the columns know what is going on. You should not need to subclass CColumn itself.

For example, PagePlus might have a CPagePlusFrame object which stores a list of the columns inside it and which looks after adding them to the layout and positioning them side by side with gaps and borders and so forth. Like all user events, changes to the layout should be encapsulated by commands, but as the engine doesn't know how PagePlus organises its columns it can't provide any useful commands to work on them. You should provide your own commands for things like "New Frame" instead. For example, to create a new story with a two-column layout your command would:

  1. Create a new Story::CStory.
  2. Add it to the engine with Story::CRoot::Append().
  3. Create a new Story::CLayout.
  4. Add it to the story with Story::CStory::Append().
  5. Create a new CPagePlusFrame.
  6. Add it to some PagePlus page object.
  7. Create a Story::CColumn.
  8. Add it to the layout with Story::CLayout::ClientAppend().
  9. Add it to your PagePlus frame.
  10. Call Story::CColumn::SetFrame with your PagePlus frame.
  11. Set the rectangle the text is to use with Story::CColumn::SetFlowBox().
  12. Repeat (7)-(11) for the second column.
The key point here is that the objects which the application creates must be added to their respective engine containers otherwise the engine doesn't know about them. The engine is not generally fussy about the order in which things happen. You can add columns or call SetFlowBox() on a column whenever you want and the story will reflow. You can keep and manipulate "free" layouts which are not part of any story, or stories which are not part of the root; they just won't be processed (recomposed, spell-checked etc) by the engine.

The columns use Story::CLayout::ClientAppend() rather than Append() because layouts have two kinds of column: client columns, which are created by the application; and overflow columns, which are created by the engine. Overflow columns are used when the story is too long to fit in the client columns but still needs layout information (for example, for RTF export). They never need to be displayed and the application probably shouldn't associate frames with them. For the most part, the application can ignore them.

As well as its basic rectangle flow box, each column has a collection of Story::CWrapShape which are irregular areas the text must wrap inside or outside of. Wrap shapes can be shared between columns, for example, between all the columns on a given page. You can use a Story::WrapStyle::Inside wrap shape to make a column have an irregular, non-rectangular shape.

Instead of composing the text to fit the column's flow box, the engine can change the flow box to fit the text. This behaviour is called "Artistic" or free text, and is selected with Story::CLayout::SetIsArtisticText.

See also Composition Overview, Layout Classes, Page Geometry.


Serif Story Documentation.
This content last built on 30 Oct 2003.