OSDN Git Service

Updated to tk 8.4.1
[pf3gnuchains/sourceware.git] / tk / win / tkWinMenu.c
index 52a4aca..cd58053 100644 (file)
@@ -461,7 +461,7 @@ GetEntryText(mePtr)
                : Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
        char *accel = (mePtr->accelPtr == NULL) ? "" 
                : Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
-       char *p, *next;
+       CONST char *p, *next;
        Tcl_DString itemString;
 
        /*
@@ -481,7 +481,7 @@ GetEntryText(mePtr)
                Tcl_DStringAppend(&itemString, "&", 1);
            }
            next = Tcl_UtfNext(p);
-           Tcl_DStringAppend(&itemString, p, next - p);
+           Tcl_DStringAppend(&itemString, p, (int) (next - p));
        }
         if (mePtr->accelLength > 0) {
            Tcl_DStringAppend(&itemString, "\t", 1);
@@ -490,7 +490,7 @@ GetEntryText(mePtr)
                    Tcl_DStringAppend(&itemString, "&", 1);
                }
                next = Tcl_UtfNext(p);
-               Tcl_DStringAppend(&itemString, p, next - p);
+               Tcl_DStringAppend(&itemString, p, (int) (next - p));
            }
        }           
 
@@ -913,6 +913,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
                            (ClientData) menuPtr);
                    ReconfigureWindowsMenu((ClientData) menuPtr);
                }
+               RecursivelyClearActiveMenu(menuPtr);
                if (!tsdPtr->inPostMenu) {
                    Tcl_Interp *interp;
                    int code;
@@ -1078,6 +1079,18 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
                    } else {
                        TkActivateMenuEntry(menuPtr, -1);
                    }
+               } else {
+                   /* On windows, menu entries should highlight even if they
+                   ** are disabled. (I know this seems dumb, but it is the way
+                   ** native windows menus works so we ought to mimic it.)
+                   ** The ENTRY_PLATFORM_FLAG1 flag will indicate that the
+                   ** entry should be highlighted even though it is disabled.
+                   */
+                   if (itemPtr->itemState & ODS_SELECTED) {
+                       mePtr->entryFlags |= ENTRY_PLATFORM_FLAG1;
+                   } else {
+                       mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
+                   }
                }
 
                tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
@@ -1101,8 +1114,8 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
            TkMenuInit();
 
            if ((flags == 0xFFFF) && (*plParam == 0)) {
-               Tcl_SetServiceMode(tsdPtr->oldServiceMode);
                if (tsdPtr->modalMenuPtr != NULL) {
+                   Tcl_SetServiceMode(tsdPtr->oldServiceMode);
                    RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr);
                }
            } else {
@@ -1140,6 +1153,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
                    Tcl_ServiceAll();
                }
            }
+           break;
        }
     }
     return returnResult;
@@ -1172,6 +1186,10 @@ RecursivelyClearActiveMenu(
     MenuSelectEvent(menuPtr);
     for (i = 0; i < menuPtr->numEntries; i++) {
        mePtr = menuPtr->entries[i];
+       if (mePtr->state == ENTRY_ACTIVE) {
+           mePtr->state = ENTRY_NORMAL;
+       }
+       mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
        if (mePtr->type == CASCADE_ENTRY) {
            if ((mePtr->childMenuRefPtr != NULL)
                    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
@@ -1222,16 +1240,15 @@ TkpSetWindowMenuBar(tkwin, menuPtr)
        Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr);
        menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
        TkWinSetMenu(tkwin, winMenuHdl);
-       if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
-           Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
+       if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
            menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+           Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
        }
     } else {
        TkWinSetMenu(tkwin, NULL);
     }
 }
 \f
-
 /*
  *----------------------------------------------------------------------
  *
@@ -1449,7 +1466,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
     DPtoLP(hdc, &ptSize, 1);
 
     ptOrg.y = ptOrg.x = 0;
-    DPtoLP(hdc, &ptOrg, 1);
+    DPtoLP(scratchDC, &ptOrg, 1);
 
     if (alignFlags & ALIGN_BITMAP_TOP) {
        topOffset = 0;
@@ -1710,13 +1727,13 @@ DrawMenuUnderline(
 {
     if (mePtr->underline >= 0) {
        char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
-       char *start = Tcl_UtfAtIndex(label, mePtr->underline);
-       char *end = Tcl_UtfNext(start);
+       CONST char *start = Tcl_UtfAtIndex(label, mePtr->underline);
+       CONST char *end = Tcl_UtfNext(start);
 
        Tk_UnderlineChars(menuPtr->display, d,
                gc, tkfont, label, x + mePtr->indicatorSpace,
                y + (height + fmPtr->ascent - fmPtr->descent) / 2, 
-               start - label, end - label);
+               (int) (start - label), (int) (end - label));
     }          
 }
 \f
@@ -1889,7 +1906,6 @@ TkpInitializeMenuBindings(interp, bindingTable)
  *
  *----------------------------------------------------------------------
  */
-
 static void
 DrawMenuEntryLabel(
     TkMenu *menuPtr,                   /* The menu we are drawing */
@@ -1903,46 +1919,122 @@ DrawMenuEntryLabel(
     int width,                         /* width of entry */
     int height)                                /* height of entry */
 {
-    int baseline;
     int indicatorSpace =  mePtr->indicatorSpace;
     int activeBorderWidth;
     int leftEdge;
     int imageHeight, imageWidth;
+    int textHeight, textWidth;
+    int haveImage = 0, haveText = 0;
+    int imageXOffset = 0, imageYOffset = 0;
+    int textXOffset = 0, textYOffset = 0;
 
     Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
            menuPtr->activeBorderWidthPtr, &activeBorderWidth);
     leftEdge = x + indicatorSpace + activeBorderWidth;
 
     /*
-     * Draw label or bitmap or image for entry.
+     * Work out what we will need to draw first.
      */
 
-    baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
     if (mePtr->image != NULL) {
        Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
+        haveImage = 1;
+    } else if (mePtr->bitmapPtr != NULL) {
+       Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
+       Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight);
+       haveImage = 1;
+    }
+    if (!haveImage || (mePtr->compound != COMPOUND_NONE)) {
+        if (mePtr->labelLength > 0) {
+           char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
+           textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
+           textHeight = fmPtr->linespace;
+           haveText = 1;
+        }
+    }
+    
+    /*
+     * Now work out what the relative positions are.
+     */
+
+    if (haveImage && haveText) {
+       int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth);
+       switch ((enum compound) mePtr->compound) {
+           case COMPOUND_TOP: {
+               textXOffset = (fullWidth - textWidth)/2;
+               textYOffset = imageHeight/2 + 2;
+               imageXOffset = (fullWidth - imageWidth)/2;
+               imageYOffset = -textHeight/2;
+               break;
+           }
+           case COMPOUND_BOTTOM: {
+               textXOffset = (fullWidth - textWidth)/2;
+               textYOffset = -imageHeight/2;
+               imageXOffset = (fullWidth - imageWidth)/2;
+               imageYOffset = textHeight/2 + 2;
+               break;
+           }
+           case COMPOUND_LEFT: {
+               textXOffset = imageWidth + 2;
+               textYOffset = 0;
+               imageXOffset = 0;
+               imageYOffset = 0;
+               break;
+           }
+           case COMPOUND_RIGHT: {
+               textXOffset = 0;
+               textYOffset = 0;
+               imageXOffset = textWidth + 2;
+               imageYOffset = 0;
+               break;
+           }
+           case COMPOUND_CENTER: {
+               textXOffset = (fullWidth - textWidth)/2;
+               textYOffset = 0;
+               imageXOffset = (fullWidth - imageWidth)/2;
+               imageYOffset = 0;
+               break;
+           }
+           case COMPOUND_NONE: {break;}
+       }
+    } else {
+       textXOffset = 0;
+       textYOffset = 0;
+       imageXOffset = 0;
+       imageYOffset = 0;
+    }
+    
+    /*
+     * Draw label and/or bitmap or image for entry.
+     */
+
+    if (mePtr->image != NULL) {
        if ((mePtr->selectImage != NULL)
                && (mePtr->entryFlags & ENTRY_SELECTED)) {
            Tk_RedrawImage(mePtr->selectImage, 0, 0,
-                   imageWidth, imageHeight, d, leftEdge,
-                   (int) (y + (mePtr->height - imageHeight)/2));
+                   imageWidth, imageHeight, d, leftEdge + imageXOffset,
+                   (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset));
        } else {
            Tk_RedrawImage(mePtr->image, 0, 0, imageWidth,
-                   imageHeight, d, leftEdge,
-                   (int) (y + (mePtr->height - imageHeight)/2));
+                   imageHeight, d, leftEdge + imageXOffset,
+                   (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset));
        }
     } else if (mePtr->bitmapPtr != NULL) {
-       int width, height;
        Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
-        Tk_SizeOfBitmap(menuPtr->display, bitmap, &width, &height);
-       XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, (unsigned) width, 
-               (unsigned) height, leftEdge,
-               (int) (y + (mePtr->height - height)/2), 1);
-    } else {
+       XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, 
+               (unsigned) imageWidth, (unsigned) imageHeight, 
+               leftEdge + imageXOffset,
+               (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1);
+    }
+    if ((mePtr->compound != COMPOUND_NONE) || !haveImage) {
        if (mePtr->labelLength > 0) {
+           int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
            char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
            Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, 
-                   mePtr->labelLength, leftEdge, baseline);
-           DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y,
+                   mePtr->labelLength, leftEdge + textXOffset, 
+                   baseline + textYOffset);
+           DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, 
+                   x + textXOffset, y + textYOffset,
                    width, height);
        }
     }
@@ -1954,8 +2046,8 @@ DrawMenuEntryLabel(
        } else if ((mePtr->image != NULL) 
                && (menuPtr->disabledImageGC != None)) {
            XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
-                   leftEdge,
-                   (int) (y + (mePtr->height - imageHeight)/2),
+                   leftEdge + imageXOffset,
+                   (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset),
                    (unsigned) imageWidth, (unsigned) imageHeight);
        }
     }
@@ -2237,21 +2329,68 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr)
                                         * portion */
 {
     TkMenu *menuPtr = mePtr->menuPtr;
+    int haveImage = 0, haveText = 0;
  
     if (mePtr->image != NULL) {
        Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
+       haveImage = 1;
     } else if (mePtr->bitmapPtr != NULL) {
        Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
        Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
+       haveImage = 1;
     } else {
-       *heightPtr = fmPtr->linespace;
+       *heightPtr = 0;
+       *widthPtr = 0;
+    }
        
+    if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
+       /* We don't care about the text in this case */
+    } else {
+       /* Either it is compound or we don't have an image */
        if (mePtr->labelPtr != NULL) {
+           int textWidth;
            char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
-
-           *widthPtr = Tk_TextWidth(tkfont, label, mePtr->labelLength);
+           textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength);
+
+           if ((mePtr->compound != COMPOUND_NONE) && haveImage) {
+               switch ((enum compound) mePtr->compound) {
+                   case COMPOUND_TOP:
+                   case COMPOUND_BOTTOM: {
+                       if (textWidth > *widthPtr) {
+                           *widthPtr = textWidth;
+                       }
+                       /* Add text and padding */
+                       *heightPtr += fmPtr->linespace + 2;
+                       break;
+                   }
+                   case COMPOUND_LEFT:
+                   case COMPOUND_RIGHT: {
+                       if (fmPtr->linespace > *heightPtr) {
+                           *heightPtr = fmPtr->linespace;
+                       }
+                       /* Add text and padding */
+                       *widthPtr += textWidth + 2;
+                       break;
+                   }
+                   case COMPOUND_CENTER: {
+                       if (fmPtr->linespace > *heightPtr) {
+                           *heightPtr = fmPtr->linespace;
+                       }
+                       if (textWidth > *widthPtr) {
+                           *widthPtr = textWidth;
+                       }
+                       break;
+                   }
+                   case COMPOUND_NONE: {break;}
+               }
        } else {
-           *widthPtr = 0;
+               /* We don't have an image or we're not compound */
+               *heightPtr = fmPtr->linespace;
+               *widthPtr = textWidth;
+           }
+       } else {
+           /* An empty entry still has this height */
+           *heightPtr = fmPtr->linespace;
        }
     }
     *heightPtr += 1;
@@ -2286,7 +2425,8 @@ DrawMenuEntryBackground(
     int width,                         /* width of rectangle to draw */
     int height)                                /* height of rectangle to draw */
 {
-    if (mePtr->state == ENTRY_ACTIVE) {
+    if (mePtr->state == ENTRY_ACTIVE 
+               || (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)!=0 ) {
        bgBorder = activeBorder;
     }
     Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder,
@@ -2603,8 +2743,8 @@ MenuExitHandler(
 Tcl_Obj *
 TkWinGetMenuSystemDefault(
     Tk_Window tkwin,           /* A window to use. */
-    char *dbName,              /* The option database name. */
-    char *className)           /* The name of the option class. */
+    CONST char *dbName,                /* The option database name. */
+    CONST char *className)     /* The name of the option class. */
 {
     Tcl_Obj *valuePtr = NULL;
 
@@ -2715,7 +2855,7 @@ SetDefaults(
      * documented.
      */
 
-    if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) {
+    if (TkWinGetPlatformId() >= VER_PLATFORM_WIN32_WINDOWS) {
        indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK);
        indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) +
                GetSystemMetrics(SM_CXBORDER)