Skip to content
100644 319 lines (282 sloc) 13.7 KB
ee8c778 second tutorial snapshot save
megaannum authored
1 # Glyph Overview
3 Many of the ideas used in developing Forms are derived from Mark Linton's
4 InterViews C++ library which was developed at Stanford University and
5 Silicon Graphics and the Java port of InterViews called Biscotti which was
6 developed at Fujitsu Research Labs. For performance reasons, some limitations
7 were taken with Vim Forms. Specifically, Glyph size and location in the
8 window are static; there in no pick traversal; the size-request and allocation
9 process does not support minimum/maximum ranges - only the 'natural' value;
10 clipping rectangles are not supported; and, generally, a glyph can only appear
11 in one position in a tree of glyphs. The character nature of the underlying
12 Vim text-based editor imposed additional limitations such as the draw
13 traversal did not permit transforming size or rotation; resolution is at the
14 character level rather than pixel; and colors were drawn per character with
15 variation based only upon background versus foreground.
17 Out of the box, Vim's Dictionary, Functions and Dictionary function have
18 no notion of class or object inheritance. The Forms library is built
19 upon the Vim Self library which provides a prototype-base object
20 inheritance framework (Self.vim is the Forms library's sole dependency).
22 At the base of the Glyph inheritance tree is the Glyph (forms#Glyph) which
23 has the Self Object Prototype as its prototype. The Glyph prototype has
24 methods that define the behavior of all derived Glyph types as well as
25 inheriting the Self Object's methods. When the term Glyph is used, much
26 of the time it refers to an object that is based upon the Glyph Prototype.
28 Some Glyphs are primarily involved with controlling the layout and display
29 of the Glyph tree in a window, some are informational while others are
30 designed to interact with the user (i.e., accept user input).
32 ## Glyph
33 Base Object from which all other Forms Glyphs inherit.
34 There are four direct, sub-types of Glyph. They are all in a sense
35 container Glyphs, nodes in a Glyph tree, that contain other Glyphs.
37 ## Leaf
38 A Leaf is a "container" Glyph that contains no children, they
39 are leaf nodes in a Glyph tree.
41 * NullGlyph
42 Does nothing - no size, no display.
43 * HLine
44 Horizontal "line" of a given background character (default '').
45 Height is 1 character.
46 * VLine
47 Vertical "line" of a given background character (default '').
48 Width is 1 character.
49 * Area
50 A region of a given background character (default '').
51 * HSpace
52 A region of a given horizontal size drawing a
53 background character (default '').
54 * VSpace
55 A region of a given vertical size drawing a
56 background character (default '').
57 * Label
58 A (horizontal) text label.
59 * VLabel
60 A vertical text label.
61 * Text
62 Multiple lines of text.
63 * CheckBox
64 A checkbox "[X]" or "[ ]".
65 * RadioButton
66 A radiobutton "(*)" or "( )" can belong to a button group.
67 * FixedLengthField
68 A line editor with fixed number of characters.
69 * VariableLengthField
70 A line editor with a variable number of characters.
71 * TextEditor
72 Simple multi-line text editor.
73 * TextBlock
74 Similar to Text but all lines must be the same length.
75 * SelectList
76 A list of selections.
77 * PopDownList
78 A pop down list of selections in a menu.
79 * HSlider
80 A horizontal slider.
81 * VSlider
82 A vertical slider.
84 ## Mono
85 A Glyph that contains a single child, its body Glyph. Most Mono
86 Glyphs implement a single behavior and delegate all others to its
87 child.
89 * Box
90 Draws a box around child.
91 * Border
92 Draws a border of a character around child (default ' ').
93 * DropShadow
94 Draws a drop shadow (a primitive 3D effect).
95 * Frame
96 Draws inset/outset frame (a primitive 3D effect).
97 * Background
98 Draws a background for child Glyphs
99 (default character ' ', uses highlight "BackgroundHi")
100 * MinWidth
101 Child appears to have a width of at least given size.
102 * MinHeight
103 Child appears to have a height of at least given size.
104 * MinSize
105 Child appears to have a width and height of at least given size.
106 * HAlign
107 Align child horizontally (default Left)
108 * VAlign
109 Align child vertically (default Top)
110 * HVAlign
111 Align child horizontally and vertically (default Left and Top)
112 * Button
113 A button with an associated action.
114 * ToggleButton
115 A toggle button with a select state.
116 * Viewer
117 Event handling Glyph that maps events forwarding them to the
118 child Glyph with current focus and manages redraws.
119 * Form
120 A top-level Viewer and the top Glyph in any Glyph tree
121 application. Forms also manage the preparation for displaying
122 their child Glyphs and the cleanup/redraw of the original window
123 content when the Form is finished.
125 ## Poly
126 A Poly Glyph has any number of child Glyphs stored in a list.
127 Polymorphic methods such as 'draw()' or 'requestSize()' are called
128 on child Glyphs by traversing the list sequentially.
130 * HPoly
131 Child Glyphs are draw horizontally.
132 Provides for a common vertical alignment policy which can be
133 overridden on a per child basis.
134 * VPoly
135 Child Glyphs are draw vertically..
136 Provides for a common horizontal alignment policy which can be
137 overridden on a per child basis.
138 * Deck
139 A single Child Glyph is drawn based upon which is selected - like
140 a deck of cards. In a sense, they are draw in the Z-axis but only
141 the top Glyph appears.
142 Provides for a common horizontal and vertical alignment policy.
143 * FixedLayout
144 Child Glyphs have a fixed (x,y) position within the FixedLayout
145 Glyph. It is up to the developer to make sure that the child Glyphs
146 do not overlap.
147 * MenuBar
148 Child Glyphs (labels for Menus) are draw at the top of the window.
149 * Menu
150 A vertical display of menu items.
152 ## Grid
153 A table of child Glyphs with rows and columns.
155 * Grid
156 Single object of type Grid. Allows for common row-based or
157 column-base alignment policy which can be overridden on a
158 cell basis.
161 ## Events
163 There are two types of input events. The first type is simply the
164 Character or Number returned by calling Vim's 'getchar()' function.
165 These are called "character" events. A Viewer examine all such
166 character events and map some of them into the second type of event
167 supported by Forms, a Dictionary object or object event that must
168 have a 'type' key whose value is one of a set of allowed names. As an
9e930f0 seventh tutorial snapshot save
megaannum authored
169 example, a <LeftMouse> Number returned by 'getchar()' is converted
ee8c778 second tutorial snapshot save
megaannum authored
170 into a Dictionary event object of type 'NewFocus' where the Dictionary
171 also has entries for the line and column (v:mouse_line and
172 v:mouse_column). Some object events are generated by the Forms
173 runtime system. An example of such an object event is a ReSize event
174 which is generated when a Glyph actually changes its size (normally, a
175 very rare occurrence). More common runtime generated event objects are
176 the Cancel and Submit events which are, generally, generated by a
177 "close" and an "accept" button.
179 A user interacts with a form by sending events to the form. Such
180 events are generated by the keyboard and mouse. Events are
181 read by the Viewer with current focus, mapped by that Viewer
182 and then forwarded to the Viewer's child Glyph that has focus.
183 If a Viewer has no child Glyphs that accept focus, then all events
9e930f0 seventh tutorial snapshot save
megaannum authored
184 are ignored (except the <Esc> character which will pop the user out
ee8c778 second tutorial snapshot save
megaannum authored
185 of the current Viewer/Form).
187 If a Glyph consumes an input event, it might require redrawing (such
188 as adding a character to an editor). In this case, the Glyph registers
189 itself with a viewer-redraw-list and when control is returned to the
190 Viewer, the Glyph is redrawn.
192 Sometimes a Glyph will consume an event and an action will be
9e930f0 seventh tutorial snapshot save
megaannum authored
193 triggered. For example, a left mouse click or keyboard <CR> entry
ee8c778 second tutorial snapshot save
megaannum authored
194 on a button will cause the action associated with that button to
195 execute.
197 ## Defining a new Glyph
199 A new Glyph variant is created by cloning an existing Glyph and then
200 tailoring its methods or adding new methods/attributes. Once this
201 new variant is defined additional instances of it can be created by
202 simply cloning it.
204 The clone() method takes an optional argument, a String that defines
205 its type name. As a rule of thumb, if the new object being created is
206 a clone from of an object that itself was cloned with a type name
207 argument, then the developer may add clone with a new type name.
208 Generally, this is done if the new object variant has well defined
209 characteristics and usages making it potentially the prototype object
210 of many objects. On the other hand, if the new object only make minor
211 modifications in the methods/attributes of its prototype and/or will
212 only be used locally and not have general applicability, then cloning
213 without defining a new type (without passing into the clone() method a
214 new type name) is a reasonable approach.
216 An additional point concerning cloning and type name, objects created
217 with a type name are expected to exist before and after any particular
218 form is generated, used, and deleted; while object created via clone
219 without a type name have a life time that only spans that of the form
220 in which they are used.
222 ## Life Cycle
224 ### Initializing
225 After a Glyph is cloned, it is initialized. For most of the Forms
226 library, Glyphs have a "constructor", and associated function that
227 takes a Dictionary of attributes and returns a newly cloned and
228 initialized object. As an example, the Label Glyph has the following
229 function
231 function! forms#newLabel(attrs)
232 return forms#loadLabelPrototype().clone().init(a:attrs)
233 endfunction
235 The Label prototype is cloned and the clone is then initialized.
237 ### Tree
238 For any Glyph to be useful it must be placed into a Glyph tree
239 and that tree ultimately used as the body of Form.
241 ### Form
242 The Form holding the Glyph is started by calling its 'run()' method.
243 This method will return a Dictionary of Glyph tag/values if the Form
244 had a Submit button that was invoked. The Form might instead, simply
245 execute a Vim command and the 'run()' method returns nothing
246 (actually, it will return 0). If the Form had a Cancel or Close
9e930f0 seventh tutorial snapshot save
megaannum authored
247 button that was pushed or the user typed <Esc>, then, again, nothing
ee8c778 second tutorial snapshot save
megaannum authored
248 is returned.
250 ### Size, Drawing and Allocation
251 The first thing that happens to a Glyph in a running Form is for the
252 Glyph's 'requestSize()' method to be called. The Glyph is telling
253 the Form how big it would like to be; number of characters of width
254 and height. Bubbling up the Glyph tree is the total size request for
255 the Form. This is then used to position the form in the window and
256 for the initial, top-down draw traversal. During this traversal,
257 all Glyphs are given their allocation which is the line/column
258 position as well as their allowed width/height. All (well, most)
259 Glyphs should save this allocation as it will be needed for other
260 operations (such as, when a Glyph is asked to redraw itself or,
261 Glyphs with focus, are asked to render their hotspot).
263 ### Cancel or Submit
264 A Form is finished by selecting a Close/Cancel or Submit button.
265 Circumstance will dictate the names of the button (its up to the
266 developer to provide them).
268 When a Form is to finish with no side effects, a Close/Cancel button
269 issues a 'Cancel' event. The active Form then stops running and
270 control is returned to either a parent Form or, if there is no
271 parent Form, control is returned to the code that originally
272 launched the Form. When a Form stops because of a 'Cancel' event,
273 the Form returns nothing (by default 0). At this point, the
274 launching code should respond to the user's desire to do nothing in
275 an appropriate manner.
277 When a Form stops because a 'Submit' event was generated (by a
278 Submit/Accept/Do-Action button or action), then the Form returns a
279 Dictionary that holds Glyph tag/value pairs generated by walking the
280 Form Glyph tree. This will hold all data and selections entered by
281 the user on the Form. It is for the launching code to extract the
282 desired data and take whatever action is appropriate. Developers
283 should remember that if a Glyph is not given a tag-name at
284 initialization, then one is automatically generated and an
285 automatically generated tag-name will certainly be different each
286 time the Form is run. So, it behoves the developer to pick their own
287 meaningful tag-names for Glyphs that will return "application" data.
9e930f0 seventh tutorial snapshot save
megaannum authored
289 Finally, a user can always enter <Esc> to stop running a Form.
ee8c778 second tutorial snapshot save
megaannum authored
290 Remember, a Form is a Viewer. If focus is in the Form's Viewer and
9e930f0 seventh tutorial snapshot save
megaannum authored
291 not a child Viewer of the Form, then entering <Esc> is the same as
ee8c778 second tutorial snapshot save
megaannum authored
292 pressing Close/Cancel button. Most of the time this will be the
293 case; a Form will only have one Viewer - itself. But if a Form has
9e930f0 seventh tutorial snapshot save
megaannum authored
294 one or more child Viewers, then entering <Esc> when focus is in a
ee8c778 second tutorial snapshot save
megaannum authored
295 child Viewer will simply pop the user out to the next higher
296 enclosing Viewer. If the Form has 4 nested Viewers and focus is in
9e930f0 seventh tutorial snapshot save
megaannum authored
297 the bottom most Viewer, it will take entering <Esc> four times to
ee8c778 second tutorial snapshot save
megaannum authored
298 exist the Form.
300 ### Delete
301 After a Form stops running, it and all of its child Glyphs are
302 deleted freeing up memory. One side effect of this is that if the
303 user tries to re-invoke the Form, the Form has to be allocated and
304 initialized all over again. For many Forms this is not much of an
305 issue. But for Forms that are large, complex and/or deeply nested
306 there is be a noticeable delay in re-rendering the Form. The example
307 menu Form is an example of a Form that a user might wish to use over
308 again in a given Vim session and it is certainly large, complex and
309 deeply nested. So, to make its re-display faster, a developer at
310 Form initialization can instruct the Form not to delete itself and
311 its child Glyphs. Of course, the developer must have some global
312 variable that references the Form after its is initially created,
313 but after that, it can simply be re-run in order for it to be
314 re-displayed.
316 I understand that all of this discussion about Glyphs is far to deep for the
317 general user but much too shallow for a developer. Writing detailed developer
318 documentation is an example of a Catch22 situation. I will await feedback.
Something went wrong with that request. Please try again.