File: csmenu.h

package info (click to toggle)
crystalspace 0.94-20020412-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 62,276 kB
  • ctags: 52,843
  • sloc: cpp: 274,783; ansic: 6,608; perl: 6,276; objc: 3,952; asm: 2,942; python: 2,354; php: 542; pascal: 530; sh: 430; makefile: 370; awk: 193
file content (311 lines) | stat: -rw-r--r-- 8,441 bytes parent folder | download
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
    Crystal Space Windowing System: menu class
    Copyright (C) 1998,1999 by Andrew Zabolotny <bit@eltech.ru>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CSMENU_H__
#define __CSMENU_H__

#include "cscomp.h"

/**
 * In fact, menu class is a bit messy just now, and as soon as I will have time
 * it should be cleaned up. However, it works reasonably well, so it is just
 * a matter of taste.
 */

/**
 * Menu item styles
 */
/// Menu item has a checkmark at the left
#define CSMIS_CHECKED		0x00000001
/// Menu item is a separator
#define CSMIS_SEPARATOR		0x00000010
/// This menu item starts a new column (if frame style != csmfsBar)
#define CSMIS_NEWCOLUMN		0x00000020
/// Do not close menu when menu item is activated
#define CSMIS_NOCLOSE		0x00000040
/// Default menu item styles
#define CSMIS_DEFAULTVALUE	0

// Forward declaration (for usage in csMenuItem)
class csMenu;

/// This class encapsulates a menu item
class csMenuItem : public csComponent
{
  /// Menu item info (if not NULL) (placed to the right of menu item text)
  char *info;
  /// Character number that should be underlined (-1 == none)
  int underline_pos;
  /// Menu item styles
  int Style;
  /// Menu item command code
  int CommandCode;
  /// Sumbenu object
  csMenu *SubMenu;

public:
  /// Menu item constructor: text item with optional style
  csMenuItem (csComponent *iParent, const char *iText,
    int iCommandCode = 0, int iStyle = CSMIS_DEFAULTVALUE);

  /// Menu item constructor: construct a separator item
  csMenuItem (csComponent *iParent, int iStyle = CSMIS_DEFAULTVALUE);

  /// Menu item constructor: construct a submenu
  csMenuItem (csComponent *iParent, const char *iText, csMenu *iSubMenu,
    int iStyle = CSMIS_DEFAULTVALUE);

  /// Destroy menu item object
  virtual ~csMenuItem ();

  /// Report the minimal size of menu item
  virtual void SuggestSize (int &w, int &h);

  /// Set menu item text
  virtual void SetText (const char *iText);

  /// Handle input events
  virtual bool HandleEvent (iEvent &Event);

  /// Draw the menu item
  virtual void Draw ();

  /// Move child menus when moved
  virtual bool SetRect (int xmin, int ymin, int xmax, int ymax);

protected:
  /// Menu item 'checked' image
  static csPixmap *sprchecked;
  /// "Open submenu" arrow image
  static csPixmap *sprsubmenu;

  /// Common part of constructors
  void Init ();

  /// Activate this menu item
  virtual void Press ();
};

/// csMenu class messages
enum
{
  /**
   * Tell menu or menu item to deactivate.
   * <pre>
   * IN: (int)DismissCode;
   * </pre>
   */
  cscmdDeactivateMenu = 0x00000200,
  /**
   * Tell menu to place all its items on their places and that it should
   * re-size itself (if it is not a menu bar).
   */
  cscmdMenuPlaceItems,
  /**
   * Tell menu to capture the mouse, if its parent menu didn't so.
   * <pre>
   * IN: (csComponent *)Source;
   * OUT: NULL if mouse has been captured
   * </pre>
   */
  cscmdMenuCaptureMouse,
  /**
   * Set menu's current item to command argument.
   * <pre>
   * IN: (csComponent *)Item;
   * OUT: NULL if successfull
   * </pre>
   */
  cscmdMenuSetItem,
  /**
   * If menu has no current item, select the item that was last active.
   */
  cscmdMenuSetLastItem,
  /**
   * Query if submenus are dropped out automatically
   * <pre>
   * IN:  NULL
   * OUT: (bool)DropFlag
   * </pre>
   */
  cscmdMenuQueryDropFlag,
  /**
   * Query if submenus are dropped out automatically
   * <pre>
   * IN:  (bool)DropFlag
   * OUT: (csMenu *)menu if successful
   * </pre>
   */
  cscmdMenuSetDropFlag,
  /**
   * Set/remove 'checked' mark at the right of menu item.<p>
   * This command should be sent to a menu item object to set/unset the
   * check mark to the right of item. Usage example:
   * <pre>
   * menu->GetChild (cscmdQuit)->SendCommand (cscmdMenuItemCheck, true);
   * </pre>
   * <pre>
   * IN: (bool)true (set) or false (unset)
   * </pre>
   */
  cscmdMenuItemCheck,
  /**
   * Query menu item's style
   * <pre>
   * IN: NULL
   * OUT: (int)ItemStyle
   * </pre>
   */
  cscmdMenuItemGetStyle,
  /**
   * Check if menu item's id or id of a menu item in submenu of this menu
   * item has given id.
   * <pre>
   * IN: (int)id;
   * OUT: (csComponent *)menuitem or NULL
   * </pre>
   */
  cscmdMenuItemFindId
};

/// Possible menu frame styles
enum csMenuFrameStyle
{
  /// Menu has no frame
  csmfsNone,
  /// Menu has a single-colored one-pixel border
  csmfsThin,
  /// Menu is a horizontal menu
  csmfsBar,
  /// Normal menu with a 3D border
  csmfs3D
};

/// Menu style flags: hide menu when it deactivates
#define CSMS_HIDEINACTIVE	0x00000001
/// Default menu style value
#define CSMS_DEFAULTVALUE	CSMS_HIDEINACTIVE

/**
 * The Menu class represents two types of menu: vertical (popup)
 * menus and bar menus.
 */
class csMenu : public csComponent
{
  friend class csMenuItem;

  /// Menu border width and height
  int BorderWidth,BorderHeight;
  /// Menu frame style
  int FrameStyle;
  /// Menu style flags
  int MenuStyle;
  /// Remember the first menu item
  csComponent *first;
  /// Remember the last selected menu item
  csComponent *last;
  /// Old parent's focused component
  csComponent *oldparentfocus;
  /// Are submenus opened?
  bool SubMenuOpened;
  /// Flag: re-place items on first ::Draw()?
  bool fPlaceItems;

public:
  /// Current menu item
  csComponent *current;

  /// Create menu object
  csMenu (csComponent *iParent, csMenuFrameStyle iFrameStyle = csmfs3D,
    int iMenuStyle = CSMS_DEFAULTVALUE);

  /// Draw the menu
  virtual void Draw ();

  /// Handle input events
  virtual bool HandleEvent (iEvent &Event);

  /// Pre-handle keyboard events to catch hotkeys
  virtual bool PreHandleEvent (iEvent &Event);

  /// Pass a event to current item
  bool CurrentHandleEvent (iEvent &Event);

  /// Recalculate menu size (called after each menu item insertion)
  virtual void PlaceItems ();

  /// Return true if menu is a menu bar
  bool IsMenuBar ()
  { return (FrameStyle == csmfsBar); }

  /// Set/clear given component state flags
  virtual void SetState (int mask, bool enable);

  /// Set a child as current menu item
  bool SetCurrent (csComponent *newCurrent, bool DropSubmenu = false);

  /// Re-position childs when rescaled
  virtual bool SetRect (int xmin, int ymin, int xmax, int ymax);

  /// Deactivate menu
  void Deactivate (int DismissCode);

  /// Find the item with given command code (even in submenus)
  csComponent *GetItem (int iCommandCode);

  /// Set/remove a checkmark left to menu item
  void SetCheck (int iCommandCode, bool iState);

  /// Set fPlaceItems since a item has been inserted
  virtual void Insert (csComponent *comp);

  /// Set fPlaceItems since a item has been removed
  virtual void Delete (csComponent *comp);

  /// Suggest the size of the menu
  virtual void SuggestSize (int &w, int &h);

private:
  /// Set 'width' for 'count' items from 'start'
  void SetItemWidth (csComponent *start, int count, int width);

  /// Move from current item to next selectable item in one of four directions
  virtual bool ExecuteKey (int key);
};

/**
 * Just a small example how menus can be defined and used:
 * <pre>
 * csComponent *window = new csWindow (app, "Window title");
 * csMenu *menu = (csMenu *)window->GetChild (CSWID_MENUBAR);
 * if (menu)
 * {
 *   submenu = new csMenu (NULL);
 *   (void)new csMenuItem (menu, "~File", submenu);
 *     (void)new csMenuItem (submenu, "~Open\tCtrl+O", cscmdNothing);
 *     (void)new csMenuItem (submenu, "~Save\tCtrl+S", cscmdNothing);
 *     (void)new csMenuItem (submenu, "~Close", cscmdNothing);
 *     (void)new csMenuItem (submenu);
 *     (void)new csMenuItem (submenu, "~Quit\tCtrl+Q", cscmdQuit);
 *   [...]
 * }
 * </pre>
 */

#endif // __CSMENU_H__