head	1.14;
access;
symbols
	core-8-5-9:1.11.2.2
	core-8-5-8:1.11.2.1
	macosx-cocoa-merge:1.12
	macosx-cocoa-premerge:1.12
	macosx-carbon-freeze:1.12
	core-8-5-7:1.11.2.1
	core-8-5-6:1.11.2.1
	core-8-6-b1:1.12
	core-8-6-a3:1.12
	core-8-5-5:1.11.2.1
	core-8-6-a2:1.12
	core-8-5-4:1.11.2.1
	core-8-5-3:1.11.2.1
	core-8-6-a1:1.12
	core-8-5-branch:1.11.0.2
	core-8-5-2:1.11
	core-8-5-1:1.11
	core-8-5-0:1.11
	core-8-5-b3:1.10
	core-8-5-b2:1.8
	core-8-5-b1:1.8
	core-stablilizer-merge:1.8
	core-stabilizer-branch:1.8.0.2
	core-stabilizer-merge:1.11.2.1
	core-8-5-a6:1.7;
locks; strict;
comment	@ * @;


1.14
date	2011.01.14.23.43.10;	author wordtech;	state Exp;
branches;
next	1.13;

1.13
date	2010.01.22.14.17.53;	author nijtmans;	state Exp;
branches;
next	1.12;

1.12
date	2008.05.23.17.58.33;	author jenglish;	state Exp;
branches;
next	1.11;

1.11
date	2007.12.13.15.26.26;	author dgp;	state Exp;
branches
	1.11.2.1;
next	1.10;

1.10
date	2007.11.19.01.49.07;	author jenglish;	state Exp;
branches;
next	1.9;

1.9
date	2007.11.18.19.20.26;	author jenglish;	state Exp;
branches;
next	1.8;

1.8
date	2007.05.03.22.15.59;	author dkf;	state Exp;
branches
	1.8.2.1;
next	1.7;

1.7
date	2007.01.11.19.59.26;	author jenglish;	state Exp;
branches;
next	1.6;

1.6
date	2007.01.11.15.35.40;	author dkf;	state Exp;
branches;
next	1.5;

1.5
date	2006.12.25.17.16.28;	author jenglish;	state Exp;
branches;
next	1.4;

1.4
date	2006.12.14.19.51.04;	author jenglish;	state Exp;
branches;
next	1.3;

1.3
date	2006.12.09.20.53.35;	author jenglish;	state Exp;
branches;
next	1.2;

1.2
date	2006.11.03.03.06.22;	author das;	state Exp;
branches;
next	1.1;

1.1
date	2006.10.31.01.42.26;	author hobbs;	state Exp;
branches;
next	;

1.8.2.1
date	2007.11.21.16.46.27;	author dgp;	state Exp;
branches;
next	1.8.2.2;

1.8.2.2
date	2008.06.25.16.46.05;	author dgp;	state Exp;
branches;
next	;

1.11.2.1
date	2008.05.23.17.58.08;	author jenglish;	state Exp;
branches;
next	1.11.2.2;

1.11.2.2
date	2010.08.26.02.06.09;	author hobbs;	state Exp;
branches;
next	;


desc
@@


1.14
log
@Remove stippling from disabled images under Aqua; renders as white box currently.
@
text
@/* $Id: ttkLabel.c,v 1.13 2010/01/22 14:17:53 nijtmans Exp $
 *
 * text, image, and label elements.
 *
 * The label element combines text and image elements,
 * with layout determined by the "-compound" option.
 *
 */

#include <tcl.h>
#include <tk.h>
#include "ttkTheme.h"

/*----------------------------------------------------------------------
 * +++ Text element.
 *
 * This element displays a textual label in the foreground color.
 *
 * Optionally underlines the mnemonic character if the -underline resource
 * is present and >= 0.
 */

typedef struct {
    /*
     * Element options:
     */
    Tcl_Obj	*textObj;
    Tcl_Obj	*fontObj;
    Tcl_Obj	*foregroundObj;
    Tcl_Obj	*underlineObj;
    Tcl_Obj	*widthObj;
    Tcl_Obj	*anchorObj;
    Tcl_Obj	*justifyObj;
    Tcl_Obj	*wrapLengthObj;
    Tcl_Obj     *embossedObj;

    /*
     * Computed resources:
     */
    Tk_Font		tkfont;
    Tk_TextLayout	textLayout;
    int 		width;
    int 		height;
    int			embossed;

} TextElement;

/* Text element options table.
 * NB: Keep in sync with label element option table.
 */
static Ttk_ElementOptionSpec TextElementOptions[] = {
    { "-text", TK_OPTION_STRING,
	Tk_Offset(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	Tk_Offset(TextElement,fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	Tk_Offset(TextElement,foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	Tk_Offset(TextElement,underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	Tk_Offset(TextElement,widthObj), "-1"},
    { "-anchor", TK_OPTION_ANCHOR,
	Tk_Offset(TextElement,anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	Tk_Offset(TextElement,justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	Tk_Offset(TextElement,wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	Tk_Offset(TextElement,embossedObj), "0"},
    { NULL, 0, 0, NULL }
};

static int TextSetup(TextElement *text, Tk_Window tkwin)
{
    const char *string = Tcl_GetString(text->textObj);
    Tk_Justify justify = TK_JUSTIFY_LEFT;
    int wrapLength = 0;

    text->tkfont = Tk_GetFontFromObj(tkwin, text->fontObj);
    Tk_GetJustifyFromObj(NULL, text->justifyObj, &justify);
    Tk_GetPixelsFromObj(NULL, tkwin, text->wrapLengthObj, &wrapLength);
    Tcl_GetBooleanFromObj(NULL, text->embossedObj, &text->embossed);

    text->textLayout = Tk_ComputeTextLayout(
	    text->tkfont, string, -1/*numChars*/, wrapLength, justify,
	    0/*flags*/, &text->width, &text->height);

    return 1;
}

/*
 * TextReqWidth -- compute the requested width of a text element.
 *
 * If -width is positive, use that as the width
 * If -width is negative, use that as the minimum width
 * If not specified or empty, use the natural size of the text
 */

static int TextReqWidth(TextElement *text)
{
    int reqWidth;

    if (   text->widthObj
	&& Tcl_GetIntFromObj(NULL, text->widthObj, &reqWidth) == TCL_OK)
    {
	int avgWidth = Tk_TextWidth(text->tkfont, "0", 1);
	if (reqWidth <= 0) {
	    int specWidth = avgWidth * -reqWidth;
	    if (specWidth > text->width)
		return specWidth;
	} else {
	    return avgWidth * reqWidth;
	}
    }
    return text->width;
}

static void TextCleanup(TextElement *text)
{
    Tk_FreeTextLayout(text->textLayout);
}

/*
 * TextDraw --
 * 	Draw a text element.
 * 	Called by TextElementDraw() and LabelElementDraw().
 */
static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
{
    XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj);
    int underline = -1;
    int lastChar = -1;
    XGCValues gcValues;
    GC gc1, gc2;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;

    gcValues.font = Tk_FontId(text->tkfont);
    gcValues.foreground = color->pixel;
    gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);
    gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
    gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);

    /* 
     * Place text according to -anchor:
     */
    Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor);
    b = Ttk_AnchorBox(b, text->width, text->height, anchor);

    /*
     * Clip text if it's too wide:
     * @@@@@@ BUG: This will overclip multi-line text.
     */
    if (b.width < text->width) {
	lastChar = Tk_PointToChar(text->textLayout, b.width, 1) + 1;
    }

    if (text->embossed) {
	Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2,
	    text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, lastChar);
    }
    Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, 0/*firstChar*/, lastChar);

    Tcl_GetIntFromObj(NULL, text->underlineObj, &underline);
    if (underline >= 0 && (lastChar == -1 || underline <= lastChar)) {
	if (text->embossed) {
	    Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc2,
		text->textLayout, b.x+1, b.y+1, underline);
	}
	Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, underline);
    }

    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}

static void TextElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *text = elementRecord;

    if (!TextSetup(text, tkwin))
	return;

    *heightPtr = text->height;
    *widthPtr = TextReqWidth(text);

    TextCleanup(text);

    return;
}

static void TextElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TextElement *text = elementRecord;
    if (TextSetup(text, tkwin)) {
	TextDraw(text, tkwin, d, b);
	TextCleanup(text);
    }
}

static Ttk_ElementSpec TextElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};

/*----------------------------------------------------------------------
 * +++ Image element.
 * Draws an image.
 */

typedef struct {
    Tcl_Obj	*imageObj;
    Tcl_Obj 	*stippleObj;	/* For TTK_STATE_DISABLED */
    Tcl_Obj 	*backgroundObj;	/* " " */

    Ttk_ImageSpec *imageSpec;
    Tk_Image	tkimg;
    int 	width;
    int		height;
} ImageElement;

/* ===> NB: Keep in sync with label element option table.  <===
 */
static Ttk_ElementOptionSpec ImageElementOptions[] = {
    { "-image", TK_OPTION_STRING,
	Tk_Offset(ImageElement,imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	Tk_Offset(ImageElement,stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	Tk_Offset(ImageElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, 0, 0, NULL }
};

/*
 * ImageSetup() --
 * 	Look up the Tk_Image from the image element's imageObj resource.
 * 	Caller must release the image with ImageCleanup().
 *
 * Returns:
 * 	1 if successful, 0 if there was an error (unreported)
 * 	or the image resource was not specified.
 */

static int ImageSetup(
    ImageElement *image, Tk_Window tkwin, Ttk_State state)
{

    if (!image->imageObj) {
	return 0;
    }
    image->imageSpec = TtkGetImageSpec(NULL, tkwin, image->imageObj);
    if (!image->imageSpec) {
	return 0;
    }
    image->tkimg = TtkSelectImage(image->imageSpec, state);
    if (!image->tkimg) {
	TtkFreeImageSpec(image->imageSpec);
	return 0;
    }
    Tk_SizeOfImage(image->tkimg, &image->width, &image->height);

    return 1;
}

static void ImageCleanup(ImageElement *image)
{
    TtkFreeImageSpec(image->imageSpec);
}

/*
 * StippleOver --
 * 	Draw a stipple over the image area, to make it look "grayed-out"
 * 	when TTK_STATE_DISABLED is set.
 */
static void StippleOver(
    ImageElement *image, Tk_Window tkwin, Drawable d, int x, int y)
{
    Pixmap stipple = Tk_AllocBitmapFromObj(NULL, tkwin, image->stippleObj);
    XColor *color = Tk_GetColorFromObj(tkwin, image->backgroundObj);

    if (stipple != None) {
	unsigned long mask = GCFillStyle | GCStipple | GCForeground;
	XGCValues gcvalues;
	GC gc;
	gcvalues.foreground = color->pixel;
	gcvalues.fill_style = FillStippled;
	gcvalues.stipple = stipple;
	gc = Tk_GetGC(tkwin, mask, &gcvalues);
	XFillRectangle(Tk_Display(tkwin),d,gc,x,y,image->width,image->height);
	Tk_FreeGC(Tk_Display(tkwin), gc);
	Tk_FreeBitmapFromObj(tkwin, image->stippleObj);
    }
}

static void ImageDraw(
    ImageElement *image, Tk_Window tkwin,Drawable d,Ttk_Box b,Ttk_State state)
{
    int width = image->width, height = image->height;

    /* Clip width and height to remain within window bounds:
     */
    if (b.x + width > Tk_Width(tkwin)) {
	width = Tk_Width(tkwin) - b.x;
    }
    if (b.y + height > Tk_Height(tkwin)) {
	height = Tk_Height(tkwin) - b.y;
    }

    if (height <= 0 || width <= 0) {
	/* Completely clipped - bail out.
	 */
	return;
    }

    Tk_RedrawImage(image->tkimg, 0,0, width, height, d, b.x, b.y);

    /* If we're disabled there's no state-specific 'disabled' image, 
     * stipple the image.
     * @@@@@@ Possibly: Don't do disabled-stippling at all;
     * @@@@@@ it's ugly and out of fashion.
     * Do not stipple at all under Aqua, just draw the image: it shows up 
     * as a white rectangle otherwise.
     */

    
    if (state & TTK_STATE_DISABLED) {
	if (TtkSelectImage(image->imageSpec, 0ul) == image->tkimg) {
	 #ifndef MAC_OSX_TK
	    StippleOver(image, tkwin, d, b.x,b.y);
	  #endif
	}
    }
}

static void ImageElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ImageElement *image = elementRecord;

    if (ImageSetup(image, tkwin, 0)) {
	*widthPtr = image->width;
	*heightPtr = image->height;
	ImageCleanup(image);
    }
}

static void ImageElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    ImageElement *image = elementRecord;

    if (ImageSetup(image, tkwin, state)) {
	ImageDraw(image, tkwin, d, b, state);
	ImageCleanup(image);
    }
}

static Ttk_ElementSpec ImageElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ImageElement),
    ImageElementOptions,
    ImageElementSize,
    ImageElementDraw
};

/*------------------------------------------------------------------------
 * +++ Label element.
 *
 * Displays an image and/or text, as determined by the -compound option.
 *
 * Differences from Tk 8.4 compound elements:
 *
 * This adds two new values for the -compound option, "text"
 * and "image".  (This is useful for configuring toolbars to
 * display icons, text and icons, or text only, as found in
 * many browsers.)
 *
 * "-compound none" is supported, but I'd like to get rid of it;
 * it makes the logic more complex, and the only benefit is
 * backwards compatibility with Tk < 8.3.0 scripts.
 *
 * This adds a new resource, -space, for determining how much
 * space to leave between the text and image; Tk 8.4 reuses the
 * -padx or -pady option for this purpose.
 *
 * -width always specifies the length in characters of the text part;
 *  in Tk 8.4 it's either characters or pixels, depending on the
 *  value of -compound.
 *
 * Negative values of -width are interpreted as a minimum width
 * on all platforms, not just on Windows.
 *
 * Tk 8.4 ignores -padx and -pady if -compound is set to "none".
 * Here, padding is handled by a different element.
 */

typedef struct {
    /*
     * Element options:
     */
    Tcl_Obj		*compoundObj;
    Tcl_Obj		*spaceObj;
    TextElement 	text;
    ImageElement	image;

    /*
     * Computed values (see LabelSetup)
     */
    Ttk_Compound	compound;
    int  		space;
    int 		totalWidth, totalHeight;
} LabelElement;

static Ttk_ElementOptionSpec LabelElementOptions[] = {
    { "-compound", TK_OPTION_ANY,
	Tk_Offset(LabelElement,compoundObj), "none" },
    { "-space", TK_OPTION_PIXELS,
	Tk_Offset(LabelElement,spaceObj), "4" },

    /* Text element part:
     * NB: Keep in sync with TextElementOptions.
     */
    { "-text", TK_OPTION_STRING,
	Tk_Offset(LabelElement,text.textObj), "" },
    { "-font", TK_OPTION_FONT,
	Tk_Offset(LabelElement,text.fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	Tk_Offset(LabelElement,text.foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	Tk_Offset(LabelElement,text.underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	Tk_Offset(LabelElement,text.widthObj), ""},
    { "-anchor", TK_OPTION_ANCHOR,
	Tk_Offset(LabelElement,text.anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	Tk_Offset(LabelElement,text.justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	Tk_Offset(LabelElement,text.wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	Tk_Offset(LabelElement,text.embossedObj), "0"},

    /* Image element part:
     * NB: Keep in sync with ImageElementOptions.
     */
    { "-image", TK_OPTION_STRING,
	Tk_Offset(LabelElement,image.imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	Tk_Offset(LabelElement,image.stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	Tk_Offset(LabelElement,image.backgroundObj), DEFAULT_BACKGROUND },
    { NULL, 0, 0, NULL }
};

/*
 * LabelSetup --
 * 	Fills in computed fields of the label element.
 *
 * 	Calculate the text, image, and total width and height.
 */

#define MAX(a,b) ((a) > (b) ? a : b);
static void LabelSetup(
    LabelElement *c, Tk_Window tkwin, Ttk_State state)
{
    Ttk_Compound *compoundPtr = &c->compound;

    Tk_GetPixelsFromObj(NULL,tkwin,c->spaceObj,&c->space);
    Ttk_GetCompoundFromObj(NULL,c->compoundObj,(int*)compoundPtr);

    /*
     * Deal with TTK_COMPOUND_NONE.
     */
    if (c->compound == TTK_COMPOUND_NONE) {
	if (ImageSetup(&c->image, tkwin, state)) {
	    c->compound = TTK_COMPOUND_IMAGE;
	} else {
	    c->compound = TTK_COMPOUND_TEXT;
	}
    } else if (c->compound != TTK_COMPOUND_TEXT) {
    	if (!ImageSetup(&c->image, tkwin, state)) {
	    c->compound = TTK_COMPOUND_TEXT;
	}
    }
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextSetup(&c->text, tkwin);

    /*
     * ASSERT:
     * if c->compound != IMAGE, then TextSetup() has been called
     * if c->compound != TEXT, then ImageSetup() has returned successfully
     * c->compound != COMPOUND_NONE.
     */

    switch (c->compound)
    {
	case TTK_COMPOUND_NONE:
	    /* Can't happen */
	    break;
	case TTK_COMPOUND_TEXT:
	    c->totalWidth  = c->text.width;
	    c->totalHeight = c->text.height;
	    break;
	case TTK_COMPOUND_IMAGE:
	    c->totalWidth  = c->image.width;
	    c->totalHeight = c->image.height;
	    break;
	case TTK_COMPOUND_CENTER:
	    c->totalWidth  = MAX(c->image.width, c->text.width);
	    c->totalHeight = MAX(c->image.height, c->text.height);
	    break;
	case TTK_COMPOUND_TOP:
	case TTK_COMPOUND_BOTTOM:
	    c->totalWidth  = MAX(c->image.width, c->text.width);
	    c->totalHeight = c->image.height + c->text.height + c->space;
	    break;

	case TTK_COMPOUND_LEFT:
	case TTK_COMPOUND_RIGHT:
	    c->totalWidth  = c->image.width + c->text.width + c->space;
	    c->totalHeight = MAX(c->image.height, c->text.height);
	    break;
    }
}

static void LabelCleanup(LabelElement *c)
{
    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    LabelElement *label = elementRecord;
    int textReqWidth = 0;

    LabelSetup(label, tkwin, 0);

    *heightPtr = label->totalHeight;

    /* Requested width based on -width option, not actual text width:
     */
    if (label->compound != TTK_COMPOUND_IMAGE)
	textReqWidth = TextReqWidth(&label->text);

    switch (label->compound) 
    {
	case TTK_COMPOUND_TEXT:
	    *widthPtr = textReqWidth;
	    break;
	case TTK_COMPOUND_IMAGE:
	    *widthPtr = label->image.width;
	    break;
	case TTK_COMPOUND_TOP:
	case TTK_COMPOUND_BOTTOM:
	case TTK_COMPOUND_CENTER:
	    *widthPtr = MAX(label->image.width, textReqWidth); 
	    break;
	case TTK_COMPOUND_LEFT:
	case TTK_COMPOUND_RIGHT:
	    *widthPtr = label->image.width + textReqWidth + label->space; 
	    break;
	case TTK_COMPOUND_NONE:
	    break; /* Can't happen */
    }

    LabelCleanup(label);
}

/*
 * DrawCompound --
 * 	Helper routine for LabelElementDraw;
 * 	Handles layout for -compound {left,right,top,bottom}
 */
static void DrawCompound(
    LabelElement *l, Ttk_Box b, Tk_Window tkwin, Drawable d, Ttk_State state,
    int imageSide, int textSide)
{
    Ttk_Box imageBox =
	Ttk_PlaceBox(&b, l->image.width, l->image.height, imageSide, 0);
    Ttk_Box textBox =
	Ttk_PlaceBox(&b, l->text.width, l->text.height, textSide, 0);
    ImageDraw(&l->image,tkwin,d,imageBox,state);
    TextDraw(&l->text,tkwin,d,textBox);
}

static void LabelElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    LabelElement *l = elementRecord;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;

    LabelSetup(l, tkwin, state);

    /*
     * Adjust overall parcel based on -anchor:
     */
    Tk_GetAnchorFromObj(NULL, l->text.anchorObj, &anchor);
    b = Ttk_AnchorBox(b, l->totalWidth, l->totalHeight, anchor);

    /*
     * Draw text and/or image parts based on -compound:
     */
    switch (l->compound)
    {
	case TTK_COMPOUND_NONE:
	    /* Can't happen */
	    break;
	case TTK_COMPOUND_TEXT:
	    TextDraw(&l->text,tkwin,d,b);
	    break;
	case TTK_COMPOUND_IMAGE:
	    ImageDraw(&l->image,tkwin,d,b,state);
	    break;
	case TTK_COMPOUND_CENTER:
	{
	    Ttk_Box pb = Ttk_AnchorBox(
		b, l->image.width, l->image.height, TK_ANCHOR_CENTER);
	    ImageDraw(&l->image, tkwin, d, pb, state);
	    pb = Ttk_AnchorBox(
		b, l->text.width, l->text.height, TK_ANCHOR_CENTER);
	    TextDraw(&l->text, tkwin, d, pb);
	    break;
	}
	case TTK_COMPOUND_TOP:
	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_TOP, TTK_SIDE_BOTTOM);
	    break;
	case TTK_COMPOUND_BOTTOM:
	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_BOTTOM, TTK_SIDE_TOP);
	    break;
	case TTK_COMPOUND_LEFT:
	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_LEFT, TTK_SIDE_RIGHT);
	    break;
	case TTK_COMPOUND_RIGHT:
	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_RIGHT, TTK_SIDE_LEFT);
	    break;
    }

    LabelCleanup(l);
}

static Ttk_ElementSpec LabelElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(LabelElement),
    LabelElementOptions,
    LabelElementSize,
    LabelElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkLabel_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, theme, "text", &TextElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, NULL);
}

@


1.13
log
@fix more gcc warnings: missing initializer
Eliminate use of __argc and __argv for CYGWIN
Make cygwin configuration error into
 a warning: CYGWIN compilation works
although there still are test failures.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.12 2008/05/23 17:58:33 jenglish Exp $
d329 2
d332 2
d336 1
d338 1
@


1.12
log
@Avoid passing width or height <= 0 to Tk_RedrawImage,
as this leads to a panic on Windows [Bug 1967576]
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.11 2007/12/13 15:26:26 dgp Exp $
d70 1
a70 1
    {NULL}
d239 1
a239 1
    {NULL}
d455 1
a455 2

    {NULL}
@


1.11
log
@merge stable branch onto HEAD
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.8.2.1 2007/11/21 16:46:27 dgp Exp $
d317 6
@


1.11.2.1
log
@Avoid passing width or height <= 0 to Tk_RedrawImage,
as this leads to a panic on Windows [Bug 1967576]
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.11 2007/12/13 15:26:26 dgp Exp $
a316 6
    if (height <= 0 || width <= 0) {
	/* Completely clipped - bail out.
	 */
	return;
    }

@


1.11.2.2
log
@        Major backport of 8.6 Ttk for 8.5.9.  Most changes were only being
        committed to head (8.6), although they could apply for 8.5 as well.
        This re-sync makes future work easier to maintain and adds some
        useful work for 8.5 users. Notable changes:
        - Lots of code cleanup
        - Some bug fixes never backported
        - Addition of ttk::spinbox
        - minor color changes
        - Improved Vista/7 styling
        - Move to tile version 0.8.6 (pseudo-package)
        - ABI and API compatible (even $w identify)
        - minor new features (extended $w identify)
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.13 2010/01/22 14:17:53 nijtmans Exp $
d70 1
a70 1
    { NULL, 0, 0, NULL }
d239 1
a239 1
    { NULL, 0, 0, NULL }
d455 2
a456 1
    { NULL, 0, 0, NULL }
@


1.10
log
@* generic/ttk/ttkElements.c, macosx/ttkMacOSXTheme.c:
Add "fill" element: like "background" but only erases parcel.

* generic/ttk/ttkFrame.c: Use fill element in Labelframe Label
sublayout.  Also improved default labelmargins for -labelanchor w*, e*.

* generic/ttk/ttkLabel.c: no longer need Labelframe hack.

* library/ttk/aquaTheme.tcl: ImageTextElement no longer needed.
TextElement no longer needs '-background' option.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.9 2007/11/18 19:20:26 jenglish Exp $
@


1.9
log
@* generic/ttk/ttkFrame.c: Use sublayout for ttk::labelframe labels
instead of single element.
* generic/ttk/ttkLabel.c: Default -anchor for text and label elements
is now "w" instead of "center".  Fixes [Bug 1614540].
* library/ttk/defaults.tcl, library/ttk/*Theme.tcl: Button styles
now need explicit "-anchor center".
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.8 2007/05/03 22:15:59 dkf Exp $
d14 1
a14 2
/*
 *----------------------------------------------------------------------
d23 1
a23 2
typedef struct
{
a29 1
    Tcl_Obj	*backgroundObj;
d51 1
a51 2
static Ttk_ElementOptionSpec TextElementOptions[] =
{
a57 2
    { "-background", TK_OPTION_BORDER,
	Tk_Offset(TextElement,backgroundObj), DEFAULT_BACKGROUND },
d206 1
a206 2
static Ttk_ElementSpec TextElementSpec =
{
d214 1
a214 32
/*
 * ImageTextElement --
 * 	Same as TextElement, but erases the background area first.
 */
static void ImageTextElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TextElement *text = elementRecord;
    Tk_3DBorder bd = Tk_Get3DBorderFromObj(tkwin,text->backgroundObj);

    if (!TextSetup(text, tkwin))
	return;

    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC), b.x, b.y, b.width, b.height);

    TextDraw(text, tkwin, d, b);
    TextCleanup(text);
}

static Ttk_ElementSpec ImageTextElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    ImageTextElementDraw
};

/*
 *----------------------------------------------------------------------
d219 1
a219 2
typedef struct
{
d232 1
a232 2
static Ttk_ElementOptionSpec ImageElementOptions[] =
{
d356 1
a356 2
static Ttk_ElementSpec ImageElementSpec =
{
d395 1
a395 2
typedef struct
{
d412 1
a412 2
static Ttk_ElementOptionSpec LabelElementOptions[] =
{
a426 2
    { "-background", TK_OPTION_BORDER,
	Tk_Offset(LabelElement,text.backgroundObj), DEFAULT_BACKGROUND },
d645 1
a645 2
static Ttk_ElementSpec LabelElementSpec =
{
a664 2
    Ttk_RegisterElement(interp, theme, "Labelframe.text", /* @@@@@@ */
	    				&ImageTextElementSpec,NULL);
@


1.8
log
@Fix more type pun warnings (those not found by my local version of GCC)
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.7 2007/01/11 19:59:26 jenglish Exp $
d69 1
a69 1
	Tk_Offset(TextElement,anchorObj), "center"},
d477 1
a477 1
	Tk_Offset(LabelElement,text.anchorObj), "center"},
@


1.8.2.1
log
@merge updates from 8.5b3
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.8 2007/05/03 22:15:59 dkf Exp $
d14 2
a15 1
/*----------------------------------------------------------------------
d24 2
a25 1
typedef struct {
d32 1
d54 2
a55 1
static Ttk_ElementOptionSpec TextElementOptions[] = {
d62 2
d69 1
a69 1
	Tk_Offset(TextElement,anchorObj), "w"},
d212 2
a213 1
static Ttk_ElementSpec TextElementSpec = {
d221 32
a252 1
/*----------------------------------------------------------------------
d257 2
a258 1
typedef struct {
d271 2
a272 1
static Ttk_ElementOptionSpec ImageElementOptions[] = {
d396 2
a397 1
static Ttk_ElementSpec ImageElementSpec = {
d436 2
a437 1
typedef struct {
d454 2
a455 1
static Ttk_ElementOptionSpec LabelElementOptions[] = {
d470 2
d477 1
a477 1
	Tk_Offset(LabelElement,text.anchorObj), "w"},
d690 2
a691 1
static Ttk_ElementSpec LabelElementSpec = {
d711 2
@


1.8.2.2
log
@merge updates from 8.5 branch
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.8.2.1 2007/11/21 16:46:27 dgp Exp $
a316 6
    if (height <= 0 || width <= 0) {
	/* Completely clipped - bail out.
	 */
	return;
    }

@


1.7
log
@Revert previous change to keep in sync with Tile codebase.
The minor warnings from GCC fixed in the previous revision
were false positives due to improper use of "-Wconversion".

Still compiles cleanly with "gcc -Wall -Werror" (gcc 3.3.5).
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.5 2006/12/25 17:16:28 jenglish Exp $
d509 2
d512 1
a512 1
    Ttk_GetCompoundFromObj(NULL,c->compoundObj,(int*)&c->compound);
@


1.6
log
@Many minute fixes to reduce number of minor warnings from GCC.
@
text
@d236 1
a236 2
	    Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC), b.x, b.y,
	    (unsigned)b.width, (unsigned)b.height);
d337 1
a337 2
	XFillRectangle(Tk_Display(tkwin),d,gc,x,y,
		(unsigned)image->width,(unsigned)image->height);
@


1.5
log
@ImageElement clientData no longer needed.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.4 2006/12/14 19:51:04 jenglish Exp $
d236 2
a237 1
	Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC), b.x, b.y, b.width, b.height);
d338 2
a339 1
	XFillRectangle(Tk_Display(tkwin),d,gc,x,y,image->width,image->height);
@


1.4
log
@Global reduction: use per-file *_Init() routines to reduce
the number of globally-visible initialization records.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.3 2006/12/09 20:53:35 jenglish Exp $
a253 1
 *
a254 3
 *
 * The clientData parameter is a Tcl_Interp, which is needed for
 * the call to Tk_GetImage().
d293 1
a293 1
    ImageElement *image, Tk_Window tkwin, Tcl_Interp *interp, Ttk_State state)
a375 1
    Tcl_Interp *interp = clientData;
d377 1
a377 1
    if (ImageSetup(image, tkwin, interp, 0)) {
a388 1
    Tcl_Interp *interp = clientData;
d390 1
a390 1
    if (ImageSetup(image, tkwin, interp, state)) {
a409 3
 * The clientData parameter is a Tcl_Interp; this is needed for the
 * image part.
 *
d507 1
a507 1
    LabelElement *c, Tk_Window tkwin, Tcl_Interp *interp, Ttk_State state)
d516 1
a516 1
	if (ImageSetup(&c->image, tkwin, interp, state)) {
d522 1
a522 1
    	if (!ImageSetup(&c->image, tkwin, interp, state)) {
a579 1
    Tcl_Interp *interp = clientData;
d582 1
a582 1
    LabelSetup(label, tkwin, interp, 0);
a636 1
    Tcl_Interp *interp = clientData;
d639 1
a639 1
    LabelSetup(l, tkwin, interp, state);
d707 2
a708 2
    Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, interp);
    Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, interp);
@


1.3
log
@Merged duplicate functionality between image element factory,
image element, and -image option processing.  Image element
factory now takes an imageSpec argument instead of a separate
image name and -map option.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.2 2006/11/03 03:06:22 das Exp $
d212 1
a212 2
MODULE_SCOPE Ttk_ElementSpec ttkTextElementSpec;
/*public*/ Ttk_ElementSpec ttkTextElementSpec =
d242 1
a242 2
MODULE_SCOPE Ttk_ElementSpec ttkImageTextElementSpec;
/*public*/ Ttk_ElementSpec ttkImageTextElementSpec =
d402 1
a402 2
MODULE_SCOPE Ttk_ElementSpec ttkImageElementSpec;
/*public*/ Ttk_ElementSpec ttkImageElementSpec =
d699 1
a699 2
MODULE_SCOPE Ttk_ElementSpec ttkLabelElementSpec;
/*public*/ Ttk_ElementSpec ttkLabelElementSpec =
d708 16
@


1.2
log
@	* generic/ttk/ttkBlink.c, generic/ttk/ttkButton.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.h:
	* generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c:
	* generic/ttk/ttkProgress.c, generic/ttk/ttkScale.c:
	* generic/ttk/ttkScroll.c, generic/ttk/ttkScrollbar.c:
	* generic/ttk/ttkSeparator.c, generic/ttk/ttkSquare.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTheme.c, generic/ttk/ttkTheme.h:
	* generic/ttk/ttkThemeInt.h, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h, macosx/ttkMacOSXTheme.c:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c: ensure
	all global Ttk symbols have Ttk or ttk prefix; declare all externally
	visible Ttk symbols not contained in stubs table as MODULE_SCOPE (or as
	static when possible); so that 'make check{exports,stubs}' once again
	complete without errors.
@
text
@d1 1
a1 1
/* $Id: ttkLabel.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $
d3 1
a3 1
 * Ttk widget set: text, image, and label elements.
a265 1

d269 1
a272 1
    int		doStipple;
a287 7
/* NullImageChanged --
 * 	No-op Tk_ImageChangedProc for Tk_GetImage.
 */
static void NullImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ }

a300 4
    const char *imageName;
    Tcl_Obj *imageObj = image->imageObj;
    Tcl_Obj **mapList = NULL;
    int i, mapCnt = 0;
d302 1
a302 1
    if (!imageObj)		/* No -image option specified */
d304 3
a306 2

    if (Tcl_ListObjGetElements(interp,imageObj,&mapCnt,&mapList) == TCL_ERROR)
d308 4
a311 2

    if (mapCnt == 0)		/* -image is an empty list */
a312 22

    /* Only enable disabled-stippling if there's no state map:
     * @@@@@@ Possibly: Don't do disabled-stippling at all;
     * @@@@@@ it's ugly and out of fashion.
     */
    image->doStipple = mapCnt == 1;

    /* Locate which image to use based on current state:
     */
    imageObj = mapList[0];
    for (i = 1; i < mapCnt - 1; i += 2) {
	Ttk_StateSpec stateSpec;

	if (Ttk_GetStateSpecFromObj(interp,mapList[i],&stateSpec) != TCL_OK) {
	    /* shouldn't happen, but can */
	    break;
	}

	if (Ttk_StateMatches(state, &stateSpec)) {
	    imageObj = mapList[i+1];
	    break;
	}
a313 9

    imageName = Tcl_GetString(imageObj);
    if (!imageName || !*imageName)	/* Empty string. */
	return 0;

    image->tkimg = Tk_GetImage(interp, tkwin, imageName, NullImageChanged, 0);
    if (!image->tkimg)			/* No such image */
	return 0;

d321 1
a321 1
    Tk_FreeImage(image->tkimg);
d365 9
a373 2
    if (image->doStipple && (state & TTK_STATE_DISABLED)) {
	StippleOver(image, tkwin, d, b.x,b.y);
@


1.1
log
@	* doc/ttk_Geometry.3, doc/ttk_Theme.3, doc/ttk_button.n:
	* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
	* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n:
	* doc/ttk_intro.n, doc/ttk_label.n, doc/ttk_labelframe.n:
	* doc/ttk_menubutton.n, doc/ttk_notebook.n, doc/ttk_panedwindow.n:
	* doc/ttk_progressbar.n, doc/ttk_radiobutton.n, doc/ttk_scrollbar.n:
	* doc/ttk_separator.n, doc/ttk_sizegrip.n, doc/ttk_style.n:
	* doc/ttk_treeview.n, doc/ttk_widget.n,:
	* generic/ttk/ttk.decls, generic/ttk/ttkBlink.c:
	* generic/ttk/ttkButton.c, generic/ttk/ttkCache.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.c:
	* generic/ttk/ttkManager.h, generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c:
	* generic/ttk/ttkScale.c, generic/ttk/ttkScroll.c:
	* generic/ttk/ttkScrollbar.c, generic/ttk/ttkSeparator.c:
	* generic/ttk/ttkSquare.c, generic/ttk/ttkState.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c:
	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h:
	* generic/ttk/ttkTrace.c, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h:
	* library/demos/ttk_demo.tcl, library/demos/ttk_iconlib.tcl:
	* library/demos/ttk_repeater.tcl:
	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl:
	* library/ttk/button.tcl, library/ttk/clamTheme.tcl:
	* library/ttk/classicTheme.tcl, library/ttk/combobox.tcl:
	* library/ttk/cursors.tcl, library/ttk/defaults.tcl:
	* library/ttk/dialog.tcl, library/ttk/entry.tcl:
	* library/ttk/fonts.tcl, library/ttk/icons.tcl:
	* library/ttk/keynav.tcl, library/ttk/menubutton.tcl:
	* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl:
	* library/ttk/progress.tcl, library/ttk/scale.tcl:
	* library/ttk/scrollbar.tcl, library/ttk/sizegrip.tcl:
	* library/ttk/treeview.tcl, library/ttk/ttk.tcl:
	* library/ttk/utils.tcl, library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* macosx/ttkMacOSXTheme.c:
	* tests/ttk/all.tcl, tests/ttk/bwidget.test, tests/ttk/combobox.test:
	* tests/ttk/entry.test, tests/ttk/image.test:
	* tests/ttk/labelframe.test, tests/ttk/layout.test:
	* tests/ttk/misc.test, tests/ttk/notebook.test:
	* tests/ttk/panedwindow.test, tests/ttk/progressbar.test:
	* tests/ttk/scrollbar.test, tests/ttk/treetags.test:
	* tests/ttk/treeview.test, tests/ttk/ttk.test, tests/ttk/validate.test:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c:
	First import of Ttk themed Tk widgets as branched from tile 0.7.8

	* generic/tkInt.h, generic/tkWindow.c: add Ttk_Init call, copy
	tk classic widgets to ::tk namespace.
	* library/tk.tcl: add source of ttk/ttk.tcl, define $::ttk::library.
	* unix/Makefile.in, win/Makefile.in: add Ttk build bits
	* win/configure, win/configure.in: check for uxtheme.h (XP theme).
@
text
@d1 1
a1 1
/* $Id: label.c,v 1.16 2006/04/17 01:53:13 jenglish Exp $
d212 2
a213 1
/*public*/ Ttk_ElementSpec TextElementSpec =
d243 2
a244 1
/*public*/ Ttk_ElementSpec ImageTextElementSpec =
d437 2
a438 1
/*public*/ Ttk_ElementSpec ImageElementSpec =
d735 2
a736 1
/*public*/ Ttk_ElementSpec LabelElementSpec =
@

