1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
/* -*- mode: C++; tab-width: 4 -*- */
/* ===================================================================== *\
Copyright (c) 2001 Palm, Inc. or its subsidiaries.
All rights reserved.
This file is part of the Palm OS Emulator.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
\* ===================================================================== */
#ifndef EmMenus_h
#define EmMenus_h
#include "EmCommands.h" // EmCommandID
#include <string>
#include <vector>
/*
This file defines the objects and routines for creating, managing,
and manipulating menubars, menus, and menu items.
Menu items (EmMenuItem) are the base object clients deal with. A
menu item is pretty much what you think it is: a distinct item in
a menu. Every menu item has the following properties:
Title
This is the text that appears on screen. The title can also
contain an '&' to indicate any mnemonic character, and can
optionally be broken into two fields with a TAB character,
with the second field containing a single character to be
used as a shortcut or accelerator. Example:
"&New\tN"
Shortcut
This is the Cmd, Ctrl, or Alt shortcut character. It can
be specified along with the title (which makes associating
the title and shortcut easy in a string resource) or
separately via dedicated API.
Command
This is the value indicating what menu item was just selected
and what action should be taken. There is no rule that says
all menu items should have unique command numbers, but it makes
looking up menu items by their command number easier.
Flags
A set of Boolean flags.
Active/Inactive
Indicates whether the menu item is drawn normally and is
selectable, or is drawn grayed out and is not selectable.
Checked/Unchecked
Indicates whether or not the menu item is drawn with a
check mark next to it.
Visible/Invisible
Indicates whether or not the menu item appears in the
host menu at all.
Divider
Menu items marked as dividers appear as dividers or
separators in the host menu. The are implicitly inactive
and unchecked, implicitly have no children or shortcuts,
and their titles are ignored.
Children
Each menu item can have zero or more children. A menu item
with children is called a hierarchical menu, and the children
are grouped together in a sub-menu. Hierarchical menus
cannot be selected themselves (that is, highlighting one and
dismissing the menu does not result in a command number being
generated).
A menu (EmMenu) is merely an ordered collection of menu items.
A menubar is merely a menu where all the menu items are hierarchical.
*/
class EmMenuItem;
typedef vector<EmMenuItem> EmMenuItemList;
// This class is pretty straightforward. It's an example of what we
// called "structification" at Taligent (and were told not to use).
// The class is mostly data with getters and setters for that data.
// The only non-straightforward parts are:
//
// * Calling SetTitle will check to see if a shortcut character
// is included. If so, it is removed, stored as the shortcut
// character, and the remaining string is stored as the title
// without it.
//
// * GetChildren returns a non-const reference to the children.
// Thus, you can modify the collection directly. Of course,
// you can also just replace whatever collection is there by
// calling SetChildren.
class EmMenuItem
{
public:
EmMenuItem (void); // Creates a divider
EmMenuItem (const EmMenuItem&);
EmMenuItem (StrCode, EmCommandID);
EmMenuItem (const string&, EmCommandID);
~EmMenuItem (void);
string GetTitle (void) const;
char GetShortcut (void) const;
EmCommandID GetCommand (void) const;
EmMenuItemList& GetChildren (void);
const EmMenuItemList& GetChildren (void) const;
Bool GetIsActive (void) const;
Bool GetIsChecked (void) const;
Bool GetIsDivider (void) const;
void SetTitle (const string&);
void SetShortcut (char);
void SetCommand (EmCommandID);
void SetChildren (const EmMenuItemList&);
void SetIsActive (Bool);
void SetIsChecked (Bool);
void SetIsDivider (Bool);
private:
string ExtractTitle (const string&) const;
char ExtractShortcut (const string&) const;
private:
string fTitle;
char fShortcut;
EmCommandID fCommand;
Bool fFlagActive;
Bool fFlagChecked;
Bool fFlagDivider;
EmMenuItemList fChildren;
};
// An EmMenu is a top-level menu. It is the same as an EmMenuItemList,
// with the addition of a changecount used as a timestamp. This
// changecount is used to determine if the menu needs to be updated in
// the face of any changes (such as the MRU lists changing).
class EmMenu : public EmMenuItemList
{
public:
EmMenu (void) : EmMenuItemList () {}
EmMenu (const EmMenuItemList& o) : EmMenuItemList (o) {}
~EmMenu (void) {}
unsigned long GetChangeCount (void) { return fChangeCount; };
void SetChangeCount (unsigned long v) { fChangeCount = v; }
private:
unsigned long fChangeCount;
};
enum EmMenuID
{
kMenuNone,
kMenuMenubarPreferred,
kMenuMenubarFull,
kMenuMenubarPartiallyBound,
kMenuMenubarFullyBound,
kMenuPopupMenuPreferred,
kMenuPopupMenuFull,
kMenuPopupMenuPartiallyBound,
kMenuPopupMenuFullyBound
};
void MenuInitialize (Bool alternateLayout);
EmMenu* MenuFindMenu (EmMenuID);
EmMenuItem* MenuFindMenuItemByCommandID (EmMenuItemList&, EmCommandID, Bool recurse);
EmMenuItemList* MenuFindMenuContainingCommandID (EmMenuItemList&, EmCommandID);
void MenuUpdateMruMenus (EmMenu&);
void MenuUpdateMenuItemStatus (EmMenuItemList&);
#endif // EmMenus_h
|