1/* 2 * tkMenu.h -- 3 * 4 * Declarations shared among all of the files that implement menu 5 * widgets. 6 * 7 * Copyright (c) 1996-1998 by Sun Microsystems, Inc. 8 * 9 * See the file "license.terms" for information on usage and redistribution of 10 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 * 12 * RCS: @(#) $Id$ 13 */ 14 15#ifndef _TKMENU 16#define _TKMENU 17 18#ifndef _TK 19#include "tk.h" 20#endif 21 22#ifndef _TKINT 23#include "tkInt.h" 24#endif 25 26#ifndef _DEFAULT 27#include "default.h" 28#endif 29 30#ifdef BUILD_tk 31# undef TCL_STORAGE_CLASS 32# define TCL_STORAGE_CLASS DLLEXPORT 33#endif 34 35/* 36 * Dummy types used by the platform menu code. 37 */ 38 39typedef struct TkMenuPlatformData_ *TkMenuPlatformData; 40typedef struct TkMenuPlatformEntryData_ *TkMenuPlatformEntryData; 41 42/* 43 * Legal values for the "compound" field of TkMenuEntry and TkMenuButton 44 * records. 45 */ 46 47enum compound { 48 COMPOUND_BOTTOM, COMPOUND_CENTER, COMPOUND_LEFT, COMPOUND_NONE, 49 COMPOUND_RIGHT, COMPOUND_TOP 50}; 51 52/* 53 * Additional menu entry drawing parameters for Windows platform. 54 * DRAW_MENU_ENTRY_ARROW makes TkpDrawMenuEntry draw the arrow 55 * itself when cascade entry is disabled. 56 * DRAW_MENU_ENTRY_NOUNDERLINE forbids underline when ODS_NOACCEL 57 * is set, thus obeying the system-wide Windows UI setting. 58 */ 59 60enum drawingParameters { 61 DRAW_MENU_ENTRY_ARROW = (1<<0), 62 DRAW_MENU_ENTRY_NOUNDERLINE = (1<<1) 63}; 64 65/* 66 * One of the following data structures is kept for each entry of each menu 67 * managed by this file: 68 */ 69 70typedef struct TkMenuEntry { 71 int type; /* Type of menu entry; see below for valid 72 * types. */ 73 struct TkMenu *menuPtr; /* Menu with which this entry is 74 * associated. */ 75 Tk_OptionTable optionTable; /* Option table for this menu entry. */ 76 Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL if 77 * no label). */ 78 int labelLength; /* Number of non-NULL characters in label. */ 79 int state; /* State of button for display purposes: 80 * normal, active, or disabled. */ 81 int underline; /* Value of -underline option: specifies index 82 * of character to underline (<0 means don't 83 * underline anything). */ 84 Tcl_Obj *underlinePtr; /* Index of character to underline. */ 85 Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or None. 86 * If not None then label is ignored. */ 87 Tcl_Obj *imagePtr; /* Name of image to display, or NULL. If not 88 * NULL, bitmap, text, and textVarName are 89 * ignored. */ 90 Tk_Image image; /* Image to display in menu entry, or NULL if 91 * none. */ 92 Tcl_Obj *selectImagePtr; /* Name of image to display when selected, or 93 * NULL. */ 94 Tk_Image selectImage; /* Image to display in entry when selected, or 95 * NULL if none. Ignored if image is NULL. */ 96 Tcl_Obj *accelPtr; /* Accelerator string displayed at right of 97 * menu entry. NULL means no such accelerator. 98 * Malloc'ed. */ 99 int accelLength; /* Number of non-NULL characters in 100 * accelerator. */ 101 int indicatorOn; /* True means draw indicator, false means 102 * don't draw it. This field is ignored unless 103 * the entry is a radio or check button. */ 104 /* 105 * Display attributes 106 */ 107 108 Tcl_Obj *borderPtr; /* Structure used to draw background for 109 * entry. NULL means use overall border for 110 * menu. */ 111 Tcl_Obj *fgPtr; /* Foreground color to use for entry. NULL 112 * means use foreground color from menu. */ 113 Tcl_Obj *activeBorderPtr; /* Used to draw background and border when 114 * element is active. NULL means use 115 * activeBorder from menu. */ 116 Tcl_Obj *activeFgPtr; /* Foreground color to use when entry is 117 * active. NULL means use active foreground 118 * from menu. */ 119 Tcl_Obj *indicatorFgPtr; /* Color for indicators in radio and check 120 * button entries. NULL means use indicatorFg 121 * GC from menu. */ 122 Tcl_Obj *fontPtr; /* Text font for menu entries. NULL means use 123 * overall font for menu. */ 124 int columnBreak; /* If this is 0, this item appears below the 125 * item in front of it. If this is 1, this 126 * item starts a new column. This field is 127 * always 0 for tearoff and separator 128 * entries. */ 129 int hideMargin; /* If this is 0, then the item has enough 130 * margin to accomodate a standard check mark 131 * and a default right margin. If this is 1, 132 * then the item has no such margins, and 133 * checkbuttons and radiobuttons with this set 134 * will have a rectangle drawn in the 135 * indicator around the item if the item is 136 * checked. This is useful for palette menus. 137 * This field is ignored for separators and 138 * tearoffs. */ 139 int indicatorSpace; /* The width of the indicator space for this 140 * entry. */ 141 int labelWidth; /* Number of pixels to allow for displaying 142 * labels in menu entries. */ 143 int compound; /* Value of -compound option; specifies 144 * whether the entry should show both an image 145 * and text, and, if so, how. */ 146 147 /* 148 * Information used to implement this entry's action: 149 */ 150 151 Tcl_Obj *commandPtr; /* Command to invoke when entry is invoked. 152 * Malloc'ed. */ 153 Tcl_Obj *namePtr; /* Name of variable (for check buttons and 154 * radio buttons) or menu (for cascade 155 * entries). Malloc'ed. */ 156 Tcl_Obj *onValuePtr; /* Value to store in variable when selected 157 * (only for radio and check buttons). 158 * Malloc'ed. */ 159 Tcl_Obj *offValuePtr; /* Value to store in variable when not 160 * selected (only for check buttons). 161 * Malloc'ed. */ 162 163 /* 164 * Information used for drawing this menu entry. 165 */ 166 167 int width; /* Number of pixels occupied by entry in 168 * horizontal dimension. Not used except in 169 * menubars. The width of norma menus is 170 * dependent on the rest of the menu. */ 171 int x; /* X-coordinate of leftmost pixel in entry. */ 172 int height; /* Number of pixels occupied by entry in 173 * vertical dimension, including raised border 174 * drawn around entry when active. */ 175 int y; /* Y-coordinate of topmost pixel in entry. */ 176 GC textGC; /* GC for drawing text in entry. NULL means 177 * use overall textGC for menu. */ 178 GC activeGC; /* GC for drawing text in entry when active. 179 * NULL means use overall activeGC for 180 * menu. */ 181 GC disabledGC; /* Used to produce disabled effect for entry. 182 * NULL means use overall disabledGC from menu 183 * structure. See comments for disabledFg in 184 * menu structure for more information. */ 185 GC indicatorGC; /* For drawing indicators. None means use GC 186 * from menu. */ 187 188 /* 189 * Miscellaneous fields. 190 */ 191 192 int entryFlags; /* Various flags. See below for 193 * definitions. */ 194 int index; /* Need to know which index we are. This is 195 * zero-based. This is the top-left entry of 196 * the menu. */ 197 198 /* 199 * Bookeeping for master menus and cascade menus. 200 */ 201 202 struct TkMenuReferences *childMenuRefPtr; 203 /* A pointer to the hash table entry for the 204 * child menu. Stored here when the menu entry 205 * is configured so that a hash lookup is not 206 * necessary later.*/ 207 struct TkMenuEntry *nextCascadePtr; 208 /* The next cascade entry that is a parent of 209 * this entry's child cascade menu. NULL end 210 * of list, this is not a cascade entry, or 211 * the menu that this entry point to does not 212 * yet exist. */ 213 TkMenuPlatformEntryData platformEntryData; 214 /* The data for the specific type of menu. 215 * Depends on platform and menu type what kind 216 * of options are in this structure. */ 217} TkMenuEntry; 218 219/* 220 * Flag values defined for menu entries: 221 * 222 * ENTRY_SELECTED: Non-zero means this is a radio or check button 223 * and that it should be drawn in the "selected" 224 * state. 225 * ENTRY_NEEDS_REDISPLAY: Non-zero means the entry should be redisplayed. 226 * ENTRY_LAST_COLUMN: Used by the drawing code. If the entry is in 227 * the last column, the space to its right needs 228 * to be filled. 229 * ENTRY_PLATFORM_FLAG1 - 4 These flags are reserved for use by the 230 * platform-dependent implementation of menus 231 * and should not be used by anything else. 232 */ 233 234#define ENTRY_SELECTED 1 235#define ENTRY_NEEDS_REDISPLAY 2 236#define ENTRY_LAST_COLUMN 4 237#define ENTRY_PLATFORM_FLAG1 (1 << 30) 238#define ENTRY_PLATFORM_FLAG2 (1 << 29) 239#define ENTRY_PLATFORM_FLAG3 (1 << 28) 240#define ENTRY_PLATFORM_FLAG4 (1 << 27) 241 242/* 243 * Types defined for MenuEntries: 244 */ 245 246#define CASCADE_ENTRY 0 247#define CHECK_BUTTON_ENTRY 1 248#define COMMAND_ENTRY 2 249#define RADIO_BUTTON_ENTRY 3 250#define SEPARATOR_ENTRY 4 251#define TEAROFF_ENTRY 5 252 253/* 254 * Menu states 255 */ 256 257MODULE_SCOPE char *tkMenuStateStrings[]; 258 259#define ENTRY_ACTIVE 0 260#define ENTRY_NORMAL 1 261#define ENTRY_DISABLED 2 262 263/* 264 * A data structure of the following type is kept for each menu widget: 265 */ 266 267typedef struct TkMenu { 268 Tk_Window tkwin; /* Window that embodies the pane. NULL means 269 * that the window has been destroyed but the 270 * data structures haven't yet been cleaned 271 * up. */ 272 Display *display; /* Display containing widget. Needed, among 273 * other things, so that resources can be 274 * freed up even after tkwin has gone away. */ 275 Tcl_Interp *interp; /* Interpreter associated with menu. */ 276 Tcl_Command widgetCmd; /* Token for menu's widget command. */ 277 TkMenuEntry **entries; /* Array of pointers to all the entries in the 278 * menu. NULL means no entries. */ 279 int numEntries; /* Number of elements in entries. */ 280 int active; /* Index of active entry. -1 means nothing 281 * active. */ 282 int menuType; /* MASTER_MENU, TEAROFF_MENU, or MENUBAR. See 283 * below for definitions. */ 284 Tcl_Obj *menuTypePtr; /* Used to control whether created tkwin is a 285 * toplevel or not. "normal", "menubar", or 286 * "toplevel" */ 287 288 /* 289 * Information used when displaying widget: 290 */ 291 292 Tcl_Obj *borderPtr; /* Structure used to draw 3-D border and 293 * background for menu. */ 294 Tcl_Obj *borderWidthPtr; /* Width of border around whole menu. */ 295 Tcl_Obj *activeBorderPtr; /* Used to draw background and border for 296 * active element (if any). */ 297 Tcl_Obj *activeBorderWidthPtr; 298 /* Width of border around active element. */ 299 Tcl_Obj *reliefPtr; /* 3-d effect: TK_RELIEF_RAISED, etc. */ 300 Tcl_Obj *fontPtr; /* Text font for menu entries. */ 301 Tcl_Obj *fgPtr; /* Foreground color for entries. */ 302 Tcl_Obj *disabledFgPtr; /* Foreground color when disabled. NULL means 303 * use normalFg with a 50% stipple instead. */ 304 Tcl_Obj *activeFgPtr; /* Foreground color for active entry. */ 305 Tcl_Obj *indicatorFgPtr; /* Color for indicators in radio and check 306 * button entries. */ 307 Pixmap gray; /* Bitmap for drawing disabled entries in a 308 * stippled fashion. None means not allocated 309 * yet. */ 310 GC textGC; /* GC for drawing text and other features of 311 * menu entries. */ 312 GC disabledGC; /* Used to produce disabled effect. If 313 * disabledFg isn't NULL, this GC is used to 314 * draw text and icons for disabled entries. 315 * Otherwise text and icons are drawn with 316 * normalGC and this GC is used to stipple 317 * background across them. */ 318 GC activeGC; /* GC for drawing active entry. */ 319 GC indicatorGC; /* For drawing indicators. */ 320 GC disabledImageGC; /* Used for drawing disabled images. They have 321 * to be stippled. This is created when the 322 * image is about to be drawn the first 323 * time. */ 324 325 /* 326 * Information about geometry of menu. 327 */ 328 329 int totalWidth; /* Width of entire menu. */ 330 int totalHeight; /* Height of entire menu. */ 331 332 /* 333 * Miscellaneous information: 334 */ 335 336 int tearoff; /* 1 means this menu can be torn off. On some 337 * platforms, the user can drag an outline of 338 * the menu by just dragging outside of the 339 * menu, and the tearoff is created where the 340 * mouse is released. On others, an indicator 341 * (such as a dashed stripe) is drawn, and 342 * when the menu is selected, the tearoff is 343 * created. */ 344 Tcl_Obj *titlePtr; /* The title to use when this menu is torn 345 * off. If this is NULL, a default scheme will 346 * be used to generate a title for tearoff. */ 347 Tcl_Obj *tearoffCommandPtr; /* If non-NULL, points to a command to run 348 * whenever the menu is torn-off. */ 349 Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the 350 * C code, but used by keyboard traversal 351 * scripts. Malloc'ed, but may be NULL. */ 352 Tcl_Obj *cursorPtr; /* Current cursor for window, or None. */ 353 Tcl_Obj *postCommandPtr; /* Used to detect cycles in cascade hierarchy 354 * trees when preprocessing postcommands on 355 * some platforms. See PostMenu for more 356 * details. */ 357 int postCommandGeneration; /* Need to do pre-invocation post command 358 * traversal. */ 359 int menuFlags; /* Flags for use by X; see below for 360 * definition. */ 361 TkMenuEntry *postedCascade; /* Points to menu entry for cascaded submenu 362 * that is currently posted or NULL if no 363 * submenu posted. */ 364 struct TkMenu *nextInstancePtr; 365 /* The next instance of this menu in the 366 * chain. */ 367 struct TkMenu *masterMenuPtr; 368 /* A pointer to the original menu for this 369 * clone chain. Points back to this structure 370 * if this menu is a master menu. */ 371 struct TkMenuOptionTables *optionTablesPtr; 372 /* A pointer to the collection of option 373 * tables that work with menus and menu 374 * entries. */ 375 Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the 376 * toplevel that owns the menu. Only 377 * applicable for menubar clones. */ 378 struct TkMenuReferences *menuRefPtr; 379 /* Each menu is hashed into a table with the 380 * name of the menu's window as the key. The 381 * information in this hash table includes a 382 * pointer to the menu (so that cascades can 383 * find this menu), a pointer to the list of 384 * toplevel widgets that have this menu as its 385 * menubar, and a list of menu entries that 386 * have this menu specified as a cascade. */ 387 TkMenuPlatformData platformData; 388 /* The data for the specific type of menu. 389 * Depends on platform and menu type what kind 390 * of options are in this structure. */ 391 Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for 392 * this widget to be extended. */ 393 Tk_SavedOptions *errorStructPtr; 394 /* We actually have to allocate these because 395 * multiple menus get changed during one 396 * ConfigureMenu call. */ 397} TkMenu; 398 399/* 400 * When the toplevel configure -menu command is executed, the menu may not 401 * exist yet. We need to keep a linked list of windows that reference a 402 * particular menu. 403 */ 404 405typedef struct TkMenuTopLevelList { 406 struct TkMenuTopLevelList *nextPtr; 407 /* The next window in the list. */ 408 Tk_Window tkwin; /* The window that has this menu as its 409 * menubar. */ 410} TkMenuTopLevelList; 411 412/* 413 * The following structure is used to keep track of things which reference a 414 * menu. It is created when: 415 * - a menu is created. 416 * - a cascade entry is added to a menu with a non-null name 417 * - the "-menu" configuration option is used on a toplevel widget with a 418 * non-null parameter. 419 * 420 * One of these three fields must be non-NULL, but any of the fields may be 421 * NULL. This structure makes it easy to determine whether or not anything 422 * like recalculating platform data or geometry is necessary when one of the 423 * three actions above is performed. 424 */ 425 426typedef struct TkMenuReferences { 427 struct TkMenu *menuPtr; /* The menu data structure. This is NULL if 428 * the menu does not exist. */ 429 TkMenuTopLevelList *topLevelListPtr; 430 /* First in the list of all toplevels that 431 * have this menu as its menubar. NULL if no 432 * toplevel widgets have this menu as its 433 * menubar. */ 434 TkMenuEntry *parentEntryPtr;/* First in the list of all cascade menu 435 * entries that have this menu as their child. 436 * NULL means no cascade entries. */ 437 Tcl_HashEntry *hashEntryPtr;/* This is needed because the pathname of the 438 * window (which is what we hash on) may not 439 * be around when we are deleting. */ 440} TkMenuReferences; 441 442/* 443 * This structure contains all of the option tables that are needed by menus. 444 */ 445 446typedef struct TkMenuOptionTables { 447 Tk_OptionTable menuOptionTable; 448 /* The option table for menus. */ 449 Tk_OptionTable entryOptionTables[6]; 450 /* The tables for menu entries. */ 451} TkMenuOptionTables; 452 453/* 454 * Flag bits for menus: 455 * 456 * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has 457 * already been queued to redraw this window. 458 * RESIZE_PENDING: Non-zero means a call to ComputeMenuGeometry 459 * has already been scheduled. 460 * MENU_DELETION_PENDING Non-zero means that we are currently 461 * destroying this menu's internal structures. 462 * This is useful when we are in the middle of 463 * cleaning this master menu's chain of menus up 464 * when TkDestroyMenu was called again on this 465 * menu (via a destroy binding or somesuch). 466 * MENU_WIN_DESTRUCTION_PENDING Non-zero means we are in the middle of 467 * destroying this menu's Tk_Window. 468 * MENU_PLATFORM_FLAG1... Reserved for use by the platform-specific menu 469 * code. 470 */ 471 472#define REDRAW_PENDING 1 473#define RESIZE_PENDING 2 474#define MENU_DELETION_PENDING 4 475#define MENU_WIN_DESTRUCTION_PENDING 8 476#define MENU_PLATFORM_FLAG1 (1 << 30) 477#define MENU_PLATFORM_FLAG2 (1 << 29) 478#define MENU_PLATFORM_FLAG3 (1 << 28) 479 480/* 481 * Each menu created by the user is a MASTER_MENU. When a menu is torn off, a 482 * TEAROFF_MENU instance is created. When a menu is assigned to a toplevel as 483 * a menu bar, a MENUBAR instance is created. All instances have the same 484 * configuration information. If the master instance is deleted, all instances 485 * are deleted. If one of the other instances is deleted, only that instance 486 * is deleted. 487 */ 488 489#define UNKNOWN_TYPE -1 490#define MASTER_MENU 0 491#define TEAROFF_MENU 1 492#define MENUBAR 2 493 494/* 495 * Various geometry definitions: 496 */ 497 498#define CASCADE_ARROW_HEIGHT 10 499#define CASCADE_ARROW_WIDTH 8 500#define DECORATION_BORDER_WIDTH 2 501 502/* 503 * Menu-related functions that are shared among Tk modules but not exported to 504 * the outside world: 505 */ 506 507MODULE_SCOPE int TkActivateMenuEntry(TkMenu *menuPtr, int index); 508MODULE_SCOPE void TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr); 509MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp, 510 char *name); 511MODULE_SCOPE void TkDestroyMenu(TkMenu *menuPtr); 512MODULE_SCOPE void TkEventuallyRecomputeMenu(TkMenu *menuPtr); 513MODULE_SCOPE void TkEventuallyRedrawMenu(TkMenu *menuPtr, 514 TkMenuEntry *mePtr); 515MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, char *name); 516MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp, 517 Tcl_Obj *namePtr); 518MODULE_SCOPE int TkFreeMenuReferences(TkMenuReferences *menuRefPtr); 519MODULE_SCOPE Tcl_HashTable *TkGetMenuHashTable(Tcl_Interp *interp); 520MODULE_SCOPE int TkGetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr, 521 Tcl_Obj *objPtr, int lastOK, int *indexPtr); 522MODULE_SCOPE void TkMenuInitializeDrawingFields(TkMenu *menuPtr); 523MODULE_SCOPE void TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr); 524MODULE_SCOPE int TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr, 525 int index); 526MODULE_SCOPE void TkMenuConfigureDrawOptions(TkMenu *menuPtr); 527MODULE_SCOPE int TkMenuConfigureEntryDrawOptions( 528 TkMenuEntry *mePtr, int index); 529MODULE_SCOPE void TkMenuFreeDrawOptions(TkMenu *menuPtr); 530MODULE_SCOPE void TkMenuEntryFreeDrawOptions(TkMenuEntry *mePtr); 531MODULE_SCOPE void TkMenuEventProc(ClientData clientData, 532 XEvent *eventPtr); 533MODULE_SCOPE void TkMenuImageProc(ClientData clientData, int x, int y, 534 int width, int height, int imgWidth, 535 int imgHeight); 536MODULE_SCOPE void TkMenuInit(void); 537MODULE_SCOPE void TkMenuSelectImageProc(ClientData clientData, int x, 538 int y, int width, int height, int imgWidth, 539 int imgHeight); 540MODULE_SCOPE Tcl_Obj * TkNewMenuName(Tcl_Interp *interp, 541 Tcl_Obj *parentNamePtr, TkMenu *menuPtr); 542MODULE_SCOPE int TkPostCommand(TkMenu *menuPtr); 543MODULE_SCOPE int TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr, 544 TkMenuEntry *mePtr); 545MODULE_SCOPE int TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr, 546 int x, int y); 547MODULE_SCOPE int TkPreprocessMenu(TkMenu *menuPtr); 548MODULE_SCOPE void TkRecomputeMenu(TkMenu *menuPtr); 549 550/* 551 * These routines are the platform-dependent routines called by the common 552 * code. 553 */ 554 555MODULE_SCOPE void TkpComputeMenubarGeometry(TkMenu *menuPtr); 556MODULE_SCOPE void TkpComputeStandardMenuGeometry(TkMenu *menuPtr); 557MODULE_SCOPE int TkpConfigureMenuEntry(TkMenuEntry *mePtr); 558MODULE_SCOPE void TkpDestroyMenu(TkMenu *menuPtr); 559MODULE_SCOPE void TkpDestroyMenuEntry(TkMenuEntry *mEntryPtr); 560MODULE_SCOPE void TkpDrawMenuEntry(TkMenuEntry *mePtr, 561 Drawable d, Tk_Font tkfont, 562 const Tk_FontMetrics *menuMetricsPtr, int x, 563 int y, int width, int height, int strictMotif, 564 int drawingParameters); 565MODULE_SCOPE void TkpMenuInit(void); 566MODULE_SCOPE int TkpMenuNewEntry(TkMenuEntry *mePtr); 567MODULE_SCOPE int TkpNewMenu(TkMenu *menuPtr); 568MODULE_SCOPE int TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr, 569 int x, int y); 570MODULE_SCOPE void TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr); 571 572# undef TCL_STORAGE_CLASS 573# define TCL_STORAGE_CLASS DLLIMPORT 574 575#endif /* _TKMENU */ 576