GEOS SDK TechDocs
|
|
3 GenClass Basics
|
3.2 Composite Links
A visual moniker is a text or graphics string attached to a generic object. This visual moniker displays the given string in a manner relevant to the specific implementation of an object. For example, a GenTrigger might create a button with text inserted as the object's main visual implementation. The visual moniker in this case might cover the object's total area. A GenPrimary, on the other hand, might only add such text in a title bar of the window. In all cases, the specific user interface has final control over how a visual moniker is displayed to the user.
You may set the visual moniker of an object using the
GI_visMoniker
instance field. This instance field expects an argument of type
@visMoniker
. The visual moniker of an object is not actually stored within this instance field, however. The visual moniker of an object is stored within its own chunk, outside of the object itself. The
GI_visMoniker
instance field contains a chunk handle to this visual moniker chunk. Because a visual moniker can only be referenced by a chunk handle, visual monikers for an object must reside in the same block as the object that points to them. The UI will set up this chunk and chunk handle automatically.
Within the object's definition, set the
GI_visMoniker
field to the desired visual moniker (either a text or graphics string). This can be done either by directly setting the
GI_visMoniker
field to the string or by indirectly setting the field to a visual moniker chunk defined elsewhere within your user interface with the Goc keyword
@visMoniker
. (See Setting Visual Monikers
.)
Code Display 2-5 Setting Visual Monikers
/* A visual moniker can be set directly within the object's definition. */
@object GenTriggerClass MyTrigger = {
GI_visMoniker = "Push Me";
}
/* A visual moniker may also be defined indirectly within a .goc file. */
/* The data for MyMoniker is set using the Goc keyword @visMoniker. This moniker * must reside in the same resource block as the object using it. This moniker * should be declared before being used in an object declaration. */
@visMoniker MyMoniker = "Push Me";
@object GenTriggerClass MyTrigger = {
GI_visMoniker = @MyMoniker;
}
Remember that the
GI_visMoniker
instance field only stores a chunk handle to the actual string. The visual moniker for the object is not contained in the object chunk itself.
Text monikers may also specify a character to act as a mnemonic. Mnemonics are keyboard shortcuts used to activate an object without use of the mouse. Menus, menu items, and buttons frequently have mnemonic characters attached. This allows a user to navigate quickly to other UI objects or to activate them. If the specified character is within the text moniker, that letter will be highlighted in whatever fashion the specific UI decides is relevant. For instance, in OSF/Motif, mnemonic characters are underlined.
Usually the first letter of the text moniker is used for the mnemonic, though any character may be used. The specific UI will underline the first such occurrence of the character within the text moniker. If the character is not within the text itself, the specific UI may place the character within parentheses at the end of the text moniker. Mnemonics are activated according to specifications in the specific UI. In OSF/Motif, pressing the ALT key puts the user interface into its keyboard navigation mode. In this mode, all mnemonics for objects in the focus are activated by pressing the character of the mnemonic without need of an additional keystroke.
Mnemonics are set by enclosing the desired character in single quotes before the text string in your instance data. Mnemonics are case specific when defined. For example, if a visual moniker is the text "File," only an uppercase mnemonic of F would highlight the first character in the text. Mnemonics are not case specific in their activation methods, however. For example, either alt -f or alt -F will activate a keyboard mnemonic of F.
Mnemonics are only valid for an object if that object is visually displayed and currently has the focus (see the Input chapter). Therefore, you may duplicate mnemonics for objects that will not exist at the same focus level. (An example of objects at the same focus level would be objects within the same menu.) Be careful not to duplicate the same mnemonic within the same focus level, as the UI will only associate the mnemonic with the first object that matches it.
The mnemonic may also store one of the following constants:
If you need other functionality that requires keyboard control of some form and mnemonics are not satisfactory, see Keyboard Accelerators .
Code Display 2-6 Setting Mnemonic Characters
/* Mnemonics are case specific. If the following example enclosed f instead of * F within single quotes, then the character f in parentheses would follow the * text "File." Note that this case specificity does not apply to the user's * activation of the object. That is, alt f will activate a mnemonic of F. */
@object MyTrigger GenTriggerClass {
GI_visMoniker = `F', "File";
}
/* You can also specify the character to highlight with an actual numerical * position, counting from a zero-based (1st character is 0, 2nd character is 1, * etc.) character position in the text string. The "5" in the following example * will underline the F character (the sixth character in the text string.) */
GI_visMoniker = 5, "Open File";
The GI_
visMoniker
instance field recognizes several keywords. These keywords are listed below and are usually only used in the construction of gstring visual monikers.
VMStyle
in use by this visual moniker.
DisplaySize
that this moniker is intended for. It has nothing to do with the actual size of the moniker, which can be set with the keyword `cachedSize.' Each size corresponds to a display type's resolution level.
DisplayClass
.
Bitmap
operator.Code Display 2-7 Examples of GString Visual Monikers
/* A Graphics string consisting of GString opcodes. */
GI_visMoniker = {
size = tiny;
color = color4;
aspectRatio = normal;
cachedSize = 15,15;
gstring{
GSSaveTransform(),
GSApplyRotation(45),
GSFillEllipse(0,0,10,15),
GSRestoreTransform(),
GSDrawEllipse(0,0,10,15),
GSEndString()
}
}
/* A Graphics string containing a bitmap. */
@visMoniker MyBitmap = {
style = icon;
size = standard;
color = color4;
aspectRatio = normal;
cachedSize = 64, 40;
gstring {
GSDrawBitmapAtCP(166),
Bitmap (64,40,BMC_PACKBITS, (BMT_MASK|BMF_4BIT)),
251, 0,
233, 221,
...,
GSEndString()
}
}
In some cases, an application may wish to use different visual monikers under specific circumstances. For example, a GenApplication's icon may need separate graphics strings for different display types (VGA, SVGA, etc.) In such cases, the argument for the moniker instance field should be given as a list of separate and distinct visual monikers. (See Simple Lists .)
You may then place each of these monikers within its own separate resource. Because only one moniker will be selected from the list, only one resource will be loaded into the object block, thereby conserving memory. When the application selects its appropriate moniker, the list will be replaced with the specific moniker, copied into the object block. The system performs this function automatically.
/* A list of monikers. */
GI_visMoniker = list {
@moniker1,
@moniker2,
@moniker3
}
/* If several monikers are specified in a list, they must be explicitly defined * somewhere else. If these monikers are complicated (as in the case of graphics * strings) they should each reside within their own resource because they will be * loaded in only once per application run. (Those that will be used together can * be within the same resource.) For example, in GEOS, several monikers * pertaining to different display types would be placed within separate resources. * When the appropriate moniker is selected, the list will be replaced with the * specific moniker. */
@start AppMonikerOneResource, notDetachable;
@visMoniker moniker1 = {
size = large;
color = color4;
aspectRatio = normal;
cachedSize = 64, 40;
gstring {gstring data}
}
@end AppMonikerOneResource;
/* That moniker could then be declared within the object's instance data. */
@object GenPrimaryClass MyObject = {
GI_visMoniker = list { @moniker1 }
}
/*
* The GenApplication object usually contains a moniker list that allows the
* specific UI to select a moniker based on the display.
*/
@object GenApplicationClass MyApplication = {
GI_visMoniker = list {
@TrigTextMoniker, /* a simple text string */
@TrigLCMoniker, /* Large Color */
@TrigLMMoniker, /* Large Mono */
@TrigSCMoniker, /* Small Color */
@TrigSMMoniker, /* Small Mono */
@TrigLCGAMoniker, /* Large CGA */
@TrigSCGAMoniker /* Small CGA */
}
}
@visMoniker TrigTextMoniker = "Push Me";
/* Graphics monikers might then appear within their own resource block. This * enables efficient memory management. */
@start AppMonikerResource, notDetachable;
@visMoniker TrigLCMoniker = {
style = icon;
size = large;
color = color4;
aspectRatio = normal;
cachedSize = 64, 40;
gstring {
GSDrawBitmapAtCP(166),
Bitmap (64,40,BMC_PACKBITS, (BMT_MASK|BMF_4BIT)),
/*** insert Bitmap here ***/
GSEndString()
}
}
@end AppMonikerResource
The following section explains the inner workings of visual monikers within GEOS. It is not necessary to understand many of these concepts but it is illustrative of the system, and may aid in debugging and custom moniker use.
GI_visMoniker
can take several types and combinations of arguments, all involving either text or graphics strings. Specifically,
GI_visMoniker
may indicate the following:
Each of these arguments can be set up with the
@visMoniker
Goc keyword, but each will store their data in different manners. GEOS automatically sets up the visual moniker in the correct format.
All visual monikers make use of the
VisMoniker
structure. This basic structure indicates whether the moniker is text, a gstring, or a list of several types.
Code Display 2-9 The Basic VisMoniker Structure
/* The Basic VisMoniker structure contains a header which describes the type of * VisMoniker (VisMonikerType) and stores the cached width (width in pixels) of the * VisMoniker. The actual visual moniker data (either text or a gstring) follows * this header. * * If the visual moniker is text, this VisMoniker structure is contained within a * VisMonikerWithText structure. If the visual moniker is a gstring, this * VisMoniker structure is contained within a VisMonikerWithGString structure.*/
typedef struct {
byte VM_type; /* VisMonikerType */
word VM_width; /* Cached width of moniker */
} VisMoniker;
/* VisMonikerType specifies the type of moniker contained in the VisMoniker * structure. * * The flag VMT_MONIKER_LIST is actually a dummy flag. (This flag is never set * within a VisMoniker structure.) VisMonikerListEntryType has a matching flag * in the same location (VMLET_MONIKER_LIST). If that flag is set, it tells the * system that this isn't actually a VisMoniker structure but is instead a * VisMonikerListEntry. This is used in moniker lists (see below). * * The flag VMT_GSTRING is set if the visual moniker is in the form of a gstring * instead of a simple text string. If this flag is set, VMT_GS_ASPECT_RATIO and * VMT_GS_COLOR specify the DisplayAspectRatio and DisplayClass used by this * gstring. */
typedef ByteFlags VisMonikerType; #define VMT_MONIKER_LIST 0x80 #define VMT_GSTRING 0x40 #define VMT_GS_ASPECT_RATIO 0x30 /* DisplayAspectRatio */ #define VMT_GS_COLOR 0x0f /* Color */
#define VMT_GS_ASPECT_RATIO_OFFSET 4 #define VMT_GS_COLOR_OFFSET 0
If the visual moniker is a simple text string, the ChunkHandle within GI_
visMoniker
will point to a chunk containing a
VisMonikerWithText
structure. This chunk will contain the basic
VisMoniker
header, along with the moniker's mnemonic character and a null-terminated text-string.
Code Display 2-10 VisMonikers With Text
/* If the VisMoniker contains simple text, the ChunkHandle within GI_visMoniker * points to a VisMonikerWithText structure. This structure contains the * basic VisMoniker header and the character of the mnemonic. (A value of -1 is * stored in VMWT_mnemonicOffset if there is no mnemonic for this visual moniker.) */
typedef struct {
VisMoniker VMWT_common;
char VMWT_mnemonicOffset;
} VisMonikerWithText;
/* The text, in the form of a null-terminated text string, follows this structure. * This text may be accessed with the VMWT_text offset. */
#define VMWT_text (sizeof(VisMonikerWithText)) /* Start of text. */
If the visual moniker is a gstring, the ChunkHandle within GI_
visMoniker
will point to a
VisMonikerWithGString
structure instead. This structure will contain the basic
VisMoniker
header, along with the moniker's cached height and the actual gstring. (The cached width is stored within the
VisMoniker
header.)
Code Display 2-11 VisMonikers With GStrings
/* If the VisMoniker contains a gstring, the ChunkHandle within GI_visMoniker * points to a VisMonikerWithGString structure. This structure contains the * basic VisMoniker header and the cached height of the gstring. (The cached width * is stored within the VisMoniker structure. */
typedef struct {
VisMoniker VMWGS_common;
word VMWGS_height;
} VisMonikerWithGSTring;
/* The gstring follows this structure.This gstring may be accessed (though it is * not recommended) with the VMWGS_gString offset. */
#define VMWGS_gString (sizeof(VisMonikerWithGString)) /* Start of gstring. */
If instead of a single visual moniker, be it a text string or a gstring, GI_
visMoniker
specifies a list of monikers, the case is more complex.
If GI_
visMoniker
contains a list of monikers, that ChunkHandle will point to a group of
VisMonikerListEntry
structures (one for each moniker in the list). Each of these list entries will contain the type of moniker it references and the optr of the moniker it refers to. The actual moniker itself is not stored in that chunk. Also, because the moniker may be referred to by an optr, the actual visual monikers may reside in separate resources.
When the object containing the moniker list is first built, the system will select one of the monikers in the list (based on matching criteria in the VMLE_
type
field) and replace the moniker list with the single selected visual moniker.
Code Display 2-12 VisMoniker Lists
/* If GI_visMoniker contains a list of monikers instead of a single moniker, the * ChunkHandle of that instance field actually points to a collection of * VisMonikerListEntry structures. (The total number can be calculated by dividing * the size of the chunk by sizeof(VisMonikerListEntry) if needed.) * * Each VisMonikerListEntry structure contains a header which describes the type of * VisMoniker stored in that list entry (VisMonikerListEntryType) and the optr of * the stored moniker. The actual moniker may reside in a different resource. */
typedef struct {
word VMLE_type;
optr VMLE_moniker;
} VisMonikerListEntry;
/* VisMonikerListEntryType specifies the type of moniker specified in the * VisMonikerListEntry structure. * * The flag VMLET_MONIKER_LIST must be set within this structure. This flag tells * the system that this isn't actually a VisMoniker structure but is instead a * VisMonikerListEntry. * * The system uses the other flags in this structure to determine the type of * moniker contained as the list entry. The system will use this information to * select the most appropriate moniker that will satisfy the system's needs. This * method is used most often in the selection of a GenPrimary's main application * moniker based on the DisplaySize of the system. * * VMLET_GS_SIZE stores the DisplaySize that this moniker is most appropriate for. * This DisplaySize is set using the "size" entry within the visual moniker * declaration. * * VMLET_STYLE stores the VMStyle that this moniker most closely matches. This * VMStyle is set using the "style" entry within the visual moniker declaration. * * VMLET_GSTRING specifies that this moniker list entry is in the form of a gstring * If this flag is set, VMLET_GS_ASPECT_RATIO and VMLET_GS_COLOR specify the * DisplayAspectRatio and DisplayClass used by this gstring. */
typedef ByteFlags VisMonikerListEntryType; #define VMLET_GS_SIZE 0x0300 /* DisplaySize. */ #define VMLET_STYLE 0x0f00 /* VMStyle */ #define VMLET_MONIKER_LIST 0x0080 #define VMLET_GSTRING 0x0040 #define VMLET_GS_ASPECT_RATIO 0x0030 /* DisplayAspectRatio */ #define VMLET_GS_COLOR 0x000f /* DisplayClass */
#define VMLET_GS_SIZE_OFFSET 12 #define VMLET_STYLE_OFFSET 8 #define VMLET_GS_ASPECT_RATIO_OFFSET 4 #define VMLET_GS_COLOR_OFFSET 0
/* VMStyle specifies the style of the visual moniker. The system may select a * moniker based on the style it wishes to display. */
typedef ByteEnum VMStyle; #define VMS_TEXT 0 /* Simple text */ #define VMS_ABBREV_TEXT 1 /* Abbreviated text */ #define VMS_GRAPHIC_TEXT 2 /* Textual graphics string */ #define VMS_ICON 3 /* Normal gstring */ #define VMS_TOOL 4 /* Tool-sized gstring */
For information on manipulating visual monikers dynamically using
GenClass
messages, see Managing Visual Monikers
.
GEOS SDK TechDocs
|
|
3 GenClass Basics
|
3.2 Composite Links