示例#1
0
void
TkpDisplayMenuButton(
    ClientData clientData)        /* Information about widget. */
{
    TkMenuButton *butPtr = (TkMenuButton *) clientData;
    Tk_Window tkwin = butPtr->tkwin;
    TkWindow *  winPtr;
    Pixmap      pixmap;
    MacMenuButton * mbPtr = (MacMenuButton *) butPtr;
    GWorldPtr dstPort;
    CGrafPtr saveWorld;
    GDHandle saveDevice;
    int      hasImageOrBitmap = 0;
    int      width, height;
    int      err;
    ControlButtonGraphicAlignment theAlignment;

    Rect paneRect, cntrRect;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = ( Pixmap )Tk_WindowId(tkwin);
    GetGWorld(&saveWorld, &saveDevice);
    dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
    SetGWorld(dstPort, NULL);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));

    winPtr=(TkWindow *)butPtr->tkwin;
    paneRect.left=winPtr->privatePtr->xOff;
    paneRect.top=winPtr->privatePtr->yOff;
    paneRect.right=paneRect.left+Tk_Width(butPtr->tkwin)-1;
    paneRect.bottom=paneRect.top+Tk_Height(butPtr->tkwin)-1;
    
    cntrRect=paneRect;
        
    cntrRect.left+=butPtr->inset;
    cntrRect.top+=butPtr->inset;
    cntrRect.right-=butPtr->inset;
    cntrRect.bottom-=butPtr->inset;

    if (mbPtr->userPane) {
        MenuButtonControlParams params;
        bzero(&params, sizeof(params));
        ComputeMenuButtonControlParams(butPtr, &params );
        if (bcmp(&params,&mbPtr->params,sizeof(params))) {
            if (mbPtr->userPane) {
                DisposeControl(mbPtr->userPane);
                mbPtr->userPane = NULL;
                mbPtr->control = NULL;
            }
        }
     }
     if (!mbPtr->userPane) {
         if (MenuButtonInitControl(mbPtr,&paneRect,&cntrRect ) ) {
             fprintf(stderr,"Init Control failed\n" );
             return;
         }
     }
    SetControlBounds(mbPtr->userPane,&paneRect);
    SetControlBounds(mbPtr->control,&cntrRect); 

    /*
     * We need to cache the title and its style
     */
    if (!(mbPtr->flags&2)) {
        ControlTitleParams titleParams;
        int                titleChanged;
        int                styleChanged;
        ComputeControlTitleParams(butPtr,&titleParams);
        CompareControlTitleParams(&titleParams,&mbPtr->titleParams,
            &titleChanged,&styleChanged);
        if (titleChanged) {
            CFStringRef cf;    	    
            cf = CFStringCreateWithCString(NULL,
                  titleParams.title, kCFStringEncodingUTF8);
            if (hasImageOrBitmap) {
                SetControlTitleWithCFString(mbPtr->control, cf);
            } else {
                SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf);
            }
            CFRelease(cf);
            bcopy(titleParams.title,mbPtr->titleParams.title,titleParams.len+1);
            mbPtr->titleParams.len = titleParams.len;
        }
        if ((titleChanged||styleChanged) && titleParams .len) {
            if (hasImageOrBitmap) {
                if ((err=SetControlFontStyle(mbPtr->control,&titleParams.style))!=noErr) {
                    fprintf(stderr,"SetControlFontStyle failed %d\n", err);
                    return;
                }
            }
            bcopy(&titleParams.style,&mbPtr->titleParams.style,sizeof(titleParams.style));
        }
    }
    if (butPtr->image != None) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        hasImageOrBitmap = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        hasImageOrBitmap = 1;
    }
    if (hasImageOrBitmap) {
        mbPtr->picParams.srcRect.right = width;
        mbPtr->picParams.srcRect.bottom = height; 
        /* Set the flag to circumvent clipping and bounds problems with OS 10.0.4 */
        tkPictureIsOpen = 1;
        if (!(mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams)) ) {
            fprintf(stderr,"OpenCPicture failed\n");
        }
        /*
         * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
         * which does not get recorded in the picture.  So the bitmap code
         * will fail in that case.
         */
        if (butPtr->image != NULL) {
            Tk_RedrawImage(butPtr->image, 0, 0, width,
                height, pixmap, 0, 0);
        } else {   
            XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, NULL, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0, 1);
        }
        ClosePicture();
        
        tkPictureIsOpen = 0;
        if ( (err=SetControlData(mbPtr->control, kControlButtonPart,
                    kControlBevelButtonContentTag,
                    sizeof(ControlButtonContentInfo),
                    (char *) &mbPtr->bevelButtonContent)) != noErr ) {
                fprintf(stderr,"SetControlData BevelButtonContent failed, %d\n", err );
        }
        switch (butPtr->anchor) {
            case TK_ANCHOR_N:
                theAlignment = kControlBevelButtonAlignTop;
                break;
            case TK_ANCHOR_NE:
                theAlignment = kControlBevelButtonAlignTopRight;
                break;
            case TK_ANCHOR_E:
                theAlignment = kControlBevelButtonAlignRight;
                break;
            case TK_ANCHOR_SE:
                theAlignment = kControlBevelButtonAlignBottomRight;
                break;
            case TK_ANCHOR_S:
                theAlignment = kControlBevelButtonAlignBottom;
                break;
            case TK_ANCHOR_SW:
                theAlignment = kControlBevelButtonAlignBottomLeft;
                break;
            case TK_ANCHOR_W:
                theAlignment = kControlBevelButtonAlignLeft;
                break;
            case TK_ANCHOR_NW:
                theAlignment = kControlBevelButtonAlignTopLeft;
                break;
            case TK_ANCHOR_CENTER:
                theAlignment = kControlBevelButtonAlignCenter;
                break;
        }
    
        if ((err=SetControlData(mbPtr->control, kControlButtonPart,
                kControlBevelButtonGraphicAlignTag,
                sizeof(ControlButtonGraphicAlignment),
                (char *) &theAlignment)) != noErr ) {
            fprintf(stderr,"SetControlData BevelButtonGraphicAlign failed, %d\n", err );
        }
    }
    if (butPtr->flags & GOT_FOCUS) {
        HiliteControl(mbPtr->control,kControlButtonPart);
    } else {
        HiliteControl(mbPtr->control,kControlNoPart);
    }
    UpdateControlColors(mbPtr);
    if (mbPtr->flags&2) {
        ShowControl(mbPtr->control);
        ShowControl(mbPtr->userPane);
        mbPtr->flags ^= 2;
    } else {
        Draw1Control(mbPtr->userPane);
        SetControlVisibility(mbPtr->control, true, true);
    }
    if (hasImageOrBitmap) {
        KillPicture(mbPtr->bevelButtonContent.u.picture);
    }
    SetGWorld(saveWorld, saveDevice);
}
示例#2
0
static void
TkMacOSXDrawControl(
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button */
{
    TkButton *butPtr = (TkButton *) mbPtr;
    TkWindow *winPtr;
    Rect paneRect, cntrRect;
    int active, enabled;
    int rebuild;

    winPtr = (TkWindow *) butPtr->tkwin;

    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
    paneRect.bottom = paneRect.top + Tk_Height(butPtr->tkwin);

    cntrRect = paneRect;

/*
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
    cntrRect.bottom -= butPtr->inset;
*/
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
    cntrRect.bottom -= DEF_INSET_BOTTOM;

    /*
     * The control has been previously initialised.
     * It may need to be re-initialised
     */
#if 0
    rebuild = (winPtr->flags & TK_REBUILD_TOPLEVEL);
    winPtr->flags &= ~TK_REBUILD_TOPLEVEL;
#else
    rebuild = 0;
#endif
    if (mbPtr->flags) {
	MacControlParams params;

	TkMacOSXComputeControlParams(butPtr, &params);
	if (rebuild || bcmp(&params, &mbPtr->params, sizeof(params))) {
	    /*
	     * The type of control has changed.
	     * Clean it up and clear the flag.
	     */

	    if (mbPtr->userPane) {
		DisposeControl(mbPtr->userPane);
		mbPtr->userPane = NULL;
		mbPtr->control = NULL;
	    }
	    mbPtr->flags = 0;
	}
    }
    if (!(mbPtr->flags & CONTROL_INITIALIZED)) {
	if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap, &paneRect,
		&cntrRect)) {
	    return;
	}
    }
    SetControlBounds(mbPtr->userPane, &paneRect);
    SetControlBounds(mbPtr->control, &cntrRect);

    if (!mbPtr->useTkText) {
	Str255 controlTitle;
	ControlFontStyleRec fontStyle;
	Tk_Font font;
	int len;

	if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
		|| (mbPtr->info.compound != COMPOUND_NONE)) {
	    len = TkFontGetFirstTextLayout(butPtr->textLayout,
		    &font, (char*) controlTitle);
	    controlTitle[len] = 0;
	} else {
	    len = 0;
	    controlTitle[0] = 0;
	}
	if (rebuild || bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
	    CFStringRef cf = CFStringCreateWithCString(NULL,
		    (char*) controlTitle, kCFStringEncodingUTF8);

	    if (cf != NULL) {
		SetControlTitleWithCFString(mbPtr->control, cf);
		CFRelease(cf);
	    }
	    bcopy(controlTitle, mbPtr->controlTitle, len+1);
	}
	if (len) {
	    TkMacOSXInitControlFontStyle(font, &fontStyle);
	    if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
		ChkErr(SetControlFontStyle, mbPtr->control, &fontStyle);
		bcopy(&fontStyle, &mbPtr->fontStyle, sizeof(fontStyle));
	    }
	}
    }
    if (mbPtr->params.isBevel) {
	/*
	 * Initialiase the image/button parameters.
	 */

	SetupBevelButton(mbPtr, mbPtr->control, destPort, gc, pixmap);
    }

    if (butPtr->flags & SELECTED) {
	SetControlValue(mbPtr->control, 1);
#if 0
    } else if (butPtr->flags & TRISTATED) {
	SetControlValue(mbPtr->control, 2);
#endif
    } else {
	SetControlValue(mbPtr->control, 0);
    }

    active = ((mbPtr->flags & ACTIVE) != 0);
    if (active != IsControlActive(mbPtr->control)) {
	if (active) {
	    ChkErr(ActivateControl, mbPtr->control);
	} else {
	    ChkErr(DeactivateControl, mbPtr->control);
	}
    }
    enabled = !(butPtr->state == STATE_DISABLED);
    if (enabled != IsControlEnabled(mbPtr->control)) {
	if (enabled) {
	    ChkErr(EnableControl, mbPtr->control);
	} else {
	    ChkErr(DisableControl, mbPtr->control);
	}
    }
    if (active && enabled) {
	if (butPtr->state == STATE_ACTIVE) {
	    if (mbPtr->params.isBevel) {
		HiliteControl(mbPtr->control, kControlButtonPart);
	    } else {
		switch (butPtr->type) {
		    case TYPE_BUTTON:
			HiliteControl(mbPtr->control, kControlButtonPart);
			break;
		    case TYPE_RADIO_BUTTON:
			HiliteControl(mbPtr->control, kControlRadioButtonPart);
			break;
		    case TYPE_CHECK_BUTTON:
			HiliteControl(mbPtr->control, kControlCheckBoxPart);
			break;
		}
	    }
	} else {
	    HiliteControl(mbPtr->control, kControlNoPart);
	}
    }
    UpdateControlColors(mbPtr);

    if (butPtr->type == TYPE_BUTTON && !mbPtr->params.isBevel) {
	Boolean isDefault;

	if (butPtr->defaultState == STATE_ACTIVE) {
	    isDefault = true;
	} else {
	    isDefault = false;
	}
	ChkErr(SetControlData, mbPtr->control, kControlNoPart,
		kControlPushButtonDefaultTag, sizeof(isDefault), &isDefault);
    }

    if (mbPtr->flags & FIRST_DRAW) {
	ShowControl(mbPtr->userPane);
	ShowControl(mbPtr->control);
	mbPtr->flags ^= FIRST_DRAW;
    } else {
	SetControlVisibility(mbPtr->control, true, true);
	Draw1Control(mbPtr->userPane);
    }

    if (mbPtr->params.isBevel) {
	if (mbPtr->bevelButtonContent.contentType ==
		kControlContentPictHandle) {
	    KillPicture(mbPtr->bevelButtonContent.u.picture);
	}
    }
}