📄 tkunixmenu.c
字号:
/* * tkUnixMenu.c -- * * This module implements the UNIX platform-specific features of menus. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkUnixMenu.c 1.76 97/11/05 09:08:22 */#include "tkPort.h"#include "default.h"#include "tkInt.h"#include "tkUnixInt.h"#include "tkMenu.h"/* * Constants used for menu drawing. */#define MENU_MARGIN_WIDTH 2#define MENU_DIVIDER_HEIGHT 2/* * Platform specific flags for Unix. */#define ENTRY_HELP_MENU ENTRY_PLATFORM_FLAG1/* * Procedures used internally. */static void SetHelpMenu _ANSI_ARGS_((TkMenu *menuPtr));static void DrawMenuEntryAccelerator _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, Tk_3DBorder activeBorder, int x, int y, int width, int height, int drawArrow));static void DrawMenuEntryBackground _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, int x, int y, int width, int heigth));static void DrawMenuEntryIndicator _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, GC indicatorGC, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, int width, int height));static void DrawMenuEntryLabel _ANSI_ARGS_(( TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, int width, int height));static void DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, int width, int height));static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, int width, int height));static void DrawMenuUnderline _ANSI_ARGS_((TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, int width, int height));static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr));static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr));static void GetMenuIndicatorGeometry _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr));static void GetMenuSeparatorGeometry _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr));static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr));/* *---------------------------------------------------------------------- * * TkpNewMenu -- * * Gets the platform-specific piece of the menu. Invoked during idle * after the generic part of the menu has been created. * * Results: * Standard TCL error. * * Side effects: * Allocates any platform specific allocations and places them * in the platformData field of the menuPtr. * *---------------------------------------------------------------------- */intTkpNewMenu(menuPtr) TkMenu *menuPtr;{ SetHelpMenu(menuPtr); return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpDestroyMenu -- * * Destroys platform-specific menu structures. Called when the * generic menu structure is destroyed for the menu. * * Results: * None. * * Side effects: * All platform-specific allocations are freed up. * *---------------------------------------------------------------------- */voidTkpDestroyMenu(menuPtr) TkMenu *menuPtr;{ /* * Nothing to do. */}/* *---------------------------------------------------------------------- * * TkpDestroyMenuEntry -- * * Cleans up platform-specific menu entry items. Called when entry * is destroyed in the generic code. * * Results: * None. * * Side effects: * All platform specific allocations are freed up. * *---------------------------------------------------------------------- */voidTkpDestroyMenuEntry(mEntryPtr) TkMenuEntry *mEntryPtr;{ /* * Nothing to do. */}/* *---------------------------------------------------------------------- * * TkpConfigureMenuEntry -- * * Processes configuration options for menu entries. Called when * the generic options are processed for the menu. * * Results: * Returns standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information get set for mePtr; old resources * get freed, if any need it. * *---------------------------------------------------------------------- */intTkpConfigureMenuEntry(mePtr) register TkMenuEntry *mePtr; /* Information about menu entry; may * or may not already have values for * some fields. */{ /* * If this is a cascade menu, and the child menu exists, check to * see if the child menu is a help menu. */ if ((mePtr->type == CASCADE_ENTRY) && (mePtr->name != NULL)) { TkMenuReferences *menuRefPtr; menuRefPtr = TkFindMenuReferences(mePtr->menuPtr->interp, mePtr->name); if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) { SetHelpMenu(menuRefPtr->menuPtr); } } return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpMenuNewEntry -- * * Called when a new entry is created in a menu. Fills in platform * specific data for the entry. The platformEntryData field * is used to store the indicator diameter for radio button * and check box entries. * * Results: * Standard TCL error. * * Side effects: * None on Unix. * *---------------------------------------------------------------------- */intTkpMenuNewEntry(mePtr) TkMenuEntry *mePtr;{ return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpSetWindowMenuBar -- * * Sets up the menu as a menubar in the given window. * * Results: * None. * * Side effects: * Recomputes geometry of given window. * *---------------------------------------------------------------------- */voidTkpSetWindowMenuBar(tkwin, menuPtr) Tk_Window tkwin; /* The window we are setting */ TkMenu *menuPtr; /* The menu we are setting */{ if (menuPtr == NULL) { TkUnixSetMenubar(tkwin, NULL); } else { TkUnixSetMenubar(tkwin, menuPtr->tkwin); }}/* *---------------------------------------------------------------------- * * TkpSetMainMenuBar -- * * Called when a toplevel widget is brought to front. On the * Macintosh, sets up the menubar that goes accross the top * of the main monitor. On other platforms, nothing is necessary. * * Results: * None. * * Side effects: * Recompute geometry of given window. * *---------------------------------------------------------------------- */voidTkpSetMainMenubar(interp, tkwin, menuName) Tcl_Interp *interp; Tk_Window tkwin; char *menuName;{ /* * Nothing to do. */}/* *---------------------------------------------------------------------- * * GetMenuIndicatorGeometry -- * * Fills out the geometry of the indicator in a menu item. Note * that the mePtr->height field must have already been filled in * by GetMenuLabelGeometry since this height depends on the label * height. * * Results: * widthPtr and heightPtr point to the new geometry values. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidGetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, fmPtr, widthPtr, heightPtr) TkMenu *menuPtr; /* The menu we are drawing. */ TkMenuEntry *mePtr; /* The entry we are interested in. */ Tk_Font tkfont; /* The precalculated font */ CONST Tk_FontMetrics *fmPtr; /* The precalculated metrics */ int *widthPtr; /* The resulting width */ int *heightPtr; /* The resulting height */{ if (!mePtr->hideMargin && mePtr->indicatorOn && ((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY))) { if ((mePtr->image != NULL) || (mePtr->bitmap != None)) { *widthPtr = (14 * mePtr->height) / 10; *heightPtr = mePtr->height; if (mePtr->type == CHECK_BUTTON_ENTRY) { mePtr->platformEntryData = (TkMenuPlatformEntryData) ((65 * mePtr->height) / 100); } else { mePtr->platformEntryData = (TkMenuPlatformEntryData) ((75 * mePtr->height) / 100); } } else { *widthPtr = *heightPtr = mePtr->height; if (mePtr->type == CHECK_BUTTON_ENTRY) { mePtr->platformEntryData = (TkMenuPlatformEntryData) ((80 * mePtr->height) / 100); } else { mePtr->platformEntryData = (TkMenuPlatformEntryData) mePtr->height; } } } else { *heightPtr = 0; *widthPtr = menuPtr->borderWidth; }}/* *---------------------------------------------------------------------- * * GetMenuAccelGeometry -- * * Get the geometry of the accelerator area of a menu item. * * Results: * heightPtr and widthPtr are set. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidGetMenuAccelGeometry(menuPtr, mePtr, tkfont, fmPtr, widthPtr, heightPtr) TkMenu *menuPtr; /* The menu was are drawing */ TkMenuEntry *mePtr; /* The entry we are getting the geometry for */ Tk_Font tkfont; /* The precalculated font */ CONST Tk_FontMetrics *fmPtr;/* The precalculated font metrics */ int *widthPtr; /* The width of the acclerator area */ int *heightPtr; /* The height of the accelerator area */{ *heightPtr = fmPtr->linespace; if (mePtr->type == CASCADE_ENTRY) { *widthPtr = 2 * CASCADE_ARROW_WIDTH; } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accel != NULL)) { *widthPtr = Tk_TextWidth(tkfont, mePtr->accel, mePtr->accelLength); } else { *widthPtr = 0; }}/* *---------------------------------------------------------------------- * * DrawMenuEntryBackground -- * * This procedure draws the background part of a menu. * * Results: * None. * * Side effects: * Commands are output to X to display the menu in its * current mode. * *---------------------------------------------------------------------- */static voidDrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, bgBorder, x, y, width, height) TkMenu *menuPtr; /* The menu we are drawing */ TkMenuEntry *mePtr; /* The entry we are drawing. */ Drawable d; /* The drawable we are drawing into */ Tk_3DBorder activeBorder; /* The border for an active item */ Tk_3DBorder bgBorder; /* The background border */ int x; /* Left coordinate of entry rect */ int y; /* Right coordinate of entry rect */ int width; /* Width of entry rect */ int height; /* Height of entry rect */{ if (mePtr->state == tkActiveUid) { int relief; bgBorder = activeBorder; if ((menuPtr->menuType == MENUBAR) && ((menuPtr->postedCascade == NULL) || (menuPtr->postedCascade != mePtr))) { relief = TK_RELIEF_FLAT; } else { relief = TK_RELIEF_RAISED; } Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, menuPtr->activeBorderWidth, relief); } else { Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0, TK_RELIEF_FLAT); }}/* *---------------------------------------------------------------------- * * DrawMenuEntryAccelerator -- * * This procedure draws the background part of a menu. * * Results: * None. * * Side effects: * Commands are output to X to display the menu in its * current mode. * *---------------------------------------------------------------------- */static voidDrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, activeBorder, x, y, width, height, drawArrow) TkMenu *menuPtr; /* The menu we are drawing */ TkMenuEntry *mePtr; /* The entry we are drawing */ Drawable d; /* The drawable we are drawing into */ GC gc; /* The precalculated gc to draw with */ Tk_Font tkfont; /* The precalculated font */ CONST Tk_FontMetrics *fmPtr; /* The precalculated metrics */ Tk_3DBorder activeBorder; /* The border for an active item */ int x; /* Left coordinate of entry rect */ int y; /* Top coordinate of entry rect */ int width; /* Width of entry */ int height; /* Height of entry */ int drawArrow; /* Whether or not to draw arrow. */{ XPoint points[3]; /* * Draw accelerator or cascade arrow. */ if (menuPtr->menuType == MENUBAR) { return; } if ((mePtr->type == CASCADE_ENTRY) && drawArrow) { points[0].x = x + width - menuPtr->borderWidth - menuPtr->activeBorderWidth - CASCADE_ARROW_WIDTH; points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2; points[1].x = points[0].x; points[1].y = points[0].y + CASCADE_ARROW_HEIGHT; points[2].x = points[0].x + CASCADE_ARROW_WIDTH; points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2; Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, 3, DECORATION_BORDER_WIDTH, (menuPtr->postedCascade == mePtr) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); } else if (mePtr->accel != NULL) { int left = x + mePtr->labelWidth + menuPtr->activeBorderWidth + mePtr->indicatorSpace; if (menuPtr->menuType == MENUBAR) { left += 5; } Tk_DrawChars(menuPtr->display, d, gc, tkfont, mePtr->accel, mePtr->accelLength, left, (y + (height + fmPtr->ascent - fmPtr->descent) / 2)); }}/* *---------------------------------------------------------------------- * * DrawMenuEntryIndicator -- * * This procedure draws the background part of a menu. * * Results: * None. * * Side effects: * Commands are output to X to display the menu in its * current mode. * *---------------------------------------------------------------------- */static voidDrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, y, width, height) TkMenu *menuPtr; /* The menu we are drawing */ TkMenuEntry *mePtr; /* The entry we are drawing */ Drawable d; /* The drawable to draw into */ GC gc; /* The gc to draw with */ GC indicatorGC; /* The gc that indicators draw with */ Tk_Font tkfont; /* The font to draw with */ CONST Tk_FontMetrics *fmPtr; /* The font metrics of the font */ int x; /* The left of the entry rect */ int y; /* The top of the entry rect */ int width; /* Width of menu entry */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -