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__
|