static void
TkMacOSXDrawButton(
    MacButton *mbPtr,    /* Mac button. */
    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;
    HIRect      cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams* dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;

    winPtr = (TkWindow *)butPtr->tkwin;

    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff,
			  winPtr->privatePtr->yOff,
			  Tk_Width(butPtr->tkwin),
			  Tk_Height(butPtr->tkwin));

     cntrRect = CGRectInset(cntrRect,  butPtr->inset, butPtr->inset);

    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}


	if (mbPtr->btnkind == kThemePushButton) {
	    /*
	     * For some reason, pushbuttons get drawn a bit
	     * too low, normally.  Correct for this.
	     */
	    if (cntrRect.size.height < 22) {
		cntrRect.origin.y -= 1;
	    } else if (cntrRect.size.height < 23) {
		cntrRect.origin.y -= 2;
	    }
	}

        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind  = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
            hiinfo.animation.time.start = hiinfo.animation.time.current;
        }

	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context, kHIThemeOrientationNormal, &contHIRec);
	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo, (MacButton *)mbPtr, 32, true);

    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}

	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}
Exemple #2
0
int
TkpDrawEntryBorderAndFocus(
    Entry *entryPtr,
    Drawable d,
    int isSpinbox)
{
    CGRect bounds;
    TkMacOSXDrawingContext dc;
    GC bgGC;
    Tk_Window tkwin = entryPtr->tkwin;
    int oldWidth = 0;
    MacDrawable *macDraw = (MacDrawable *) d;
    const HIThemeFrameDrawInfo info = {
	.version = 0,
	.kind = kHIThemeFrameTextFieldSquare,
	.state = (entryPtr->state == STATE_DISABLED ? kThemeStateInactive :
		kThemeStateActive),
	.isFocused = (entryPtr->flags & GOT_FOCUS ? 1 : 0),
    };

    /*
     * I use 6 as the borderwidth. 2 of the 5 go into the actual frame the 3
     * are because the Mac OS Entry widgets leave more space around the Text
     * than Tk does on X11.
     */

    if (entryPtr->borderWidth != MAC_OSX_ENTRY_BORDER
	    || entryPtr->highlightWidth != MAC_OSX_FOCUS_WIDTH
	    || entryPtr->relief != MAC_OSX_ENTRY_RELIEF) {
	return 0;
    }

    /*
     * For the spinbox, we have to make the entry part smaller by the size of
     * the buttons. We also leave 2 pixels to the left (as per the HIG) and
     * space for one pixel to the right, 'cause it makes the buttons look
     * nicer.
     */

    if (isSpinbox) {
	int incDecWidth;

	oldWidth = Tk_Width(tkwin);

	ComputeIncDecParameters(Tk_Height(tkwin) - 2 * MAC_OSX_FOCUS_WIDTH,
		&incDecWidth);
	Tk_Width(tkwin) -= incDecWidth + 1;
    }

   /*
    * The focus ring is drawn with an Alpha at the outside part of the ring,
    * so we have to draw over the edges of the ring before drawing the focus
    * or the text will peep through.
    */

    bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d);
    TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0);

    /*
     * Inset the entry Frame by the maximum width of the focus rect, which is
     * 3 according to the Carbon docs.
     */

    bounds.origin.x = macDraw->xOff + MAC_OSX_FOCUS_WIDTH;
    bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
    bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
    TkMacOSXRestoreDrawingContext(&dc);
    if (isSpinbox) {
	Tk_Width(tkwin) = oldWidth;
    }
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --
 *
 *	This procedure redraws the buttons of an spinbox widget. It overrides
 *	the generic button drawing code if the spinbox widget parameters are
 *	such that the native widget drawing is a good fit. This version just
 *	returns 0, so platforms that don't do special native drawing don't
 *	have to implement it.
 *
 * Results:
 *	1 if it has drawn the border, 0 if not.
 *
 * Side effects:
 *	May draw the entry border into pixmap.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Drawable d)
{
    CGRect bounds;
    Tk_Window tkwin = sbPtr->entry.tkwin;
    int height = Tk_Height(tkwin);
    int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH;
    int incDecWidth;
    TkMacOSXDrawingContext dc;
    XRectangle rects[1];
    GC bgGC;
    MacDrawable *macDraw = (MacDrawable *) d;
    HIThemeButtonDrawInfo info = {
	.version = 0,
	.adornment = kThemeAdornmentNone,
    };

    /*
     * FIXME: RAISED really makes more sense
     */

    if (sbPtr->buRelief != TK_RELIEF_FLAT) {
	return 0;
    }

    /*
     * The actual sizes of the IncDec button are 21 for the normal, 18 for the
     * small and 15 for the mini. But the spinbox still looks okay if the
     * entry is a little bigger than this, so we give it a little slop.
     */

    info.kind = ComputeIncDecParameters(buttonHeight, &incDecWidth);
    if (info.kind == (ThemeButtonKind) 0) {
	return 0;
    }

    if (sbPtr->entry.state == STATE_DISABLED) {
	info.state = kThemeStateInactive;
	info.value = kThemeButtonOff;
    } else if (sbPtr->selElement == SEL_BUTTONUP) {
	info.state = kThemeStatePressedUp;
	info.value = kThemeButtonOn;
    } else if (sbPtr->selElement == SEL_BUTTONDOWN) {
	info.state = kThemeStatePressedDown;
	info.value = kThemeButtonOn;
    } else {
	info.state = kThemeStateActive;
	info.value = kThemeButtonOff;
    }

    bounds.origin.x = macDraw->xOff + Tk_Width(tkwin) - incDecWidth - 1;
    bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
    bounds.size.width = incDecWidth;
    bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;

    /*
     * We had to make the entry part of the window smaller so that we wouldn't
     * overdraw the spin buttons with the focus highlight. So now we have to
     * draw the highlightbackground.
     */

    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = bounds.origin.x;
    rects[0].y = 0;
    rects[0].width = Tk_Width(tkwin);
    rects[0].height = Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);
    return 1;
}