Tk Source Code

Artifact [08ef21c3]
Login

Artifact 08ef21c38c358962c081c7ce1a1010f818ae413b:

Attachment "tip109.patch" to ticket [776545ff] added by bgriffin 2003-07-24 04:48:56.
Index: tkUnixButton.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixButton.c,v
retrieving revision 1.13
diff -p -r1.13 tkUnixButton.c
*** tkUnixButton.c	26 Apr 2003 02:59:20 -0000	1.13
--- tkUnixButton.c	23 Jul 2003 20:22:30 -0000
***************
*** 13,18 ****
--- 13,19 ----
   */
  
  #include "tkButton.h"
+ #include "tk3d.h"
  
  /*
   * Declaration of Unix specific button structure.
*************** Tk_ClassProcs tkpButtonProcs = {
*** 30,35 ****
--- 31,222 ----
      sizeof(Tk_ClassProcs),	/* size */
      TkButtonWorldChanged,	/* worldChangedProc */
  };
+ 
+ /*
+  * The button image
+  * the header info here is ignored, it's the image that's
+  * important.  The colors will be applied as follows:
+  *   A = Background
+  *   B = Background
+  *   C = 3D light
+  *   D = selectColor
+  *   E = 3D dark
+  *   F = Background
+  *   G = Foreground
+  */
+ /* XPM */
+ static char *button_images[] =
+ {
+ /* width height ncolors chars_per_pixel */
+ "52 26 7 1",
+ /* colors */
+ "A c #808000000000",
+ "B c #000080800000",
+ "C c #808080800000",
+ "D c #000000008080",
+ "E c #808000008080",
+ "F c #000080808080",
+ "G c #000000000000",
+ /* pixels */
+ "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
+ "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
+ "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
+ "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFGFCB",
+ "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFGGFCB",
+ "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFGFFFGGGFCB",
+ "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFGGFGGGFFCB",
+ "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFGGGGGFFFCB",
+ "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFGGGFFFFCB",
+ "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFGFFFFFCB",
+ "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
+ "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
+ "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
+ "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
+ "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
+ "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
+ "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFGGFFFCBF",
+ "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFGGGGFFCBF",
+ "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFGGGGFFCBF",
+ "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFGGFFFCBF",
+ "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
+ "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
+ "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
+ "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ };
+ 
+ #define CHECK_BUTTON_DIM    13
+ #define CHECK_MENU_DIM       9
+ #define CHECK_START          8
+ #define CHECK_ON_OFFSET     13
+ #define CHECK_OFF_OFFSET     0
+ #define CHECK_DISON_OFFSET  39
+ #define CHECK_DISOFF_OFFSET 26
+ #define RADIO_BUTTON_DIM    13
+ #define RADIO_MENU_DIM       6
+ #define RADIO_WIDTH         13
+ #define RADIO_START         21
+ #define RADIO_ON_OFFSET     13
+ #define RADIO_OFF_OFFSET     0
+ #define RADIO_DISON_OFFSET  39
+ #define RADIO_DISOFF_OFFSET 26
+ 
+ /*
+  * Indicator Draw Modes
+  */
+ #define CHECK_BUTTON 0
+ #define CHECK_MENU   1
+ #define RADIO_BUTTON 2
+ #define RADIO_MENU   3
+ 
+ 
+ /*
+  *----------------------------------------------------------------------
+  *
+  * TkpDrawCheckButton image -
+  *
+  *	Draws the checkbox image in the drawable at the (x,y) location,
+  *	value, and state given.  
+  *	This routine is use by the button and menu widgets
+  *
+  * Results:
+  *	None.
+  *
+  * Side effects:
+  *	An image is drawn in the drawable at the location given.
+  *
+  *----------------------------------------------------------------------
+  */
+ 
+ void 
+ TkpDrawCheckButton(tkwin, display, d, x, y, bgBorder, fgColor, indicatorColor, selectColor, disableColor, on, disabled, mode)
+      Tk_Window tkwin;
+      Display *display;
+      Drawable d;
+      int x;
+      int y;
+      Tk_3DBorder bgBorder;
+      XColor   *fgColor;
+      XColor   *indicatorColor;
+      XColor   *selectColor;
+      XColor   *disableColor;
+      int on;
+      int disabled;
+      int mode;
+ {
+     int ix, iy;
+     int dim;
+     int imgsel, imgstart;
+     TkBorder *bg_brdr = (TkBorder*)bgBorder;
+     XGCValues gcValues;
+     GC copyGC;
+     unsigned long img_colors[7];
+     XImage *img;
+     Pixmap pixmap;
+     int depth = Tk_Depth(tkwin);
+ 
+     /*
+      * Compute starting point and dimensions of
+      * image inside button_images to be used.
+      */
+     switch (mode) {
+       case CHECK_BUTTON:
+ 	imgsel = on ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
+ 	imgsel += disabled ? CHECK_DISOFF_OFFSET : 0;
+ 	imgstart = CHECK_START;
+ 	dim = CHECK_BUTTON_DIM;
+ 	break;
+       case CHECK_MENU:
+ 	imgsel = on ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
+ 	imgsel += disabled ? CHECK_DISOFF_OFFSET : 0;
+ 	imgstart = CHECK_START + 2;
+ 	imgsel += 2;
+ 	dim = CHECK_MENU_DIM;
+ 	break;
+       case RADIO_BUTTON:
+ 	imgsel = on ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
+ 	imgsel += disabled ? RADIO_DISOFF_OFFSET : 0;
+ 	imgstart = RADIO_START;
+ 	dim = RADIO_BUTTON_DIM;
+ 	break;
+       case RADIO_MENU:    
+ 	imgsel = on ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
+ 	imgsel += disabled ? RADIO_DISOFF_OFFSET : 0;
+ 	imgstart = RADIO_START + 3;
+ 	imgsel += 3;
+ 	dim = RADIO_MENU_DIM;
+ 	break;
+     }
+ 
+     pixmap = Tk_GetPixmap(display, d, dim, dim, depth);
+ 
+     x -= dim/2;
+     y -= dim/2;
+     img = XGetImage(display, pixmap, 0, 0, (unsigned int)dim, (unsigned int)dim, AllPlanes, ZPixmap);
+     TkpGetShadows(bg_brdr, tkwin);
+     img_colors[0/*A*/] = bg_brdr->bgColorPtr->pixel;
+     img_colors[1/*B*/] = bg_brdr->bgColorPtr->pixel;
+     img_colors[2/*C*/] = bg_brdr->lightColorPtr->pixel;
+     img_colors[3/*D*/] = selectColor->pixel;
+     img_colors[4/*E*/] = bg_brdr->darkColorPtr->pixel;
+     img_colors[5/*F*/] = bg_brdr->bgColorPtr->pixel;
+     img_colors[6/*G*/] = indicatorColor->pixel;
+     for(iy=0; iy<dim; iy++) {
+ 	for(ix=0; ix<dim; ix++) {
+ 	    XPutPixel(img, ix, iy, img_colors[(button_images[imgstart + iy][imgsel + ix]) - 'A'] );
+ 	}
+     }
+     gcValues.foreground = fgColor->pixel;
+     gcValues.background = bg_brdr->bgColorPtr->pixel;
+     gcValues.graphics_exposures = False;
+     copyGC = Tk_GetGC(tkwin, 0, &gcValues);
+     XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0, (unsigned int)dim, (unsigned int)dim);
+     XCopyArea(display, pixmap, d, copyGC, 0, 0, (unsigned int)dim, (unsigned int)dim, x, y);
+     Tk_FreeGC(display,copyGC);
+     XDestroyImage(img);
+     Tk_FreePixmap(display,pixmap);
+ }
  
  /*
   *----------------------------------------------------------------------
*************** TkpDisplayButton(clientData)
*** 341,429 ****
       */
  
      if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
! 	int dim;
! 
! 	dim = butPtr->indicatorDiameter;
! 	x -= butPtr->indicatorSpace;
! 	y -= dim/2;
! 	if (dim > 2*butPtr->borderWidth) {
! 	    Tk_Draw3DRectangle(tkwin, pixmap, border, x, y, dim, dim,
! 		    butPtr->borderWidth,
! 		    (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN :
! 		    TK_RELIEF_RAISED);
! 	    x += butPtr->borderWidth;
! 	    y += butPtr->borderWidth;
! 	    dim -= 2*butPtr->borderWidth;
! 	    if (butPtr->flags & SELECTED) {
! 		GC gc;
! 		if (butPtr->state != STATE_DISABLED) {
! 		    if (butPtr->selectBorder != NULL) {
! 			gc = Tk_3DBorderGC(tkwin, butPtr->selectBorder,
! 				TK_3D_FLAT_GC);
! 		    } else {
! 			gc = Tk_3DBorderGC(tkwin, butPtr->normalBorder,
! 				TK_3D_FLAT_GC);
! 		    }
! 		} else {
! 		    if (butPtr->disabledFg != NULL) {
! 			gc = butPtr->disabledGC;
! 		    } else {
! 			gc = butPtr->normalTextGC; 
! 			XSetForeground(butPtr->display, butPtr->disabledGC,
! 				Tk_3DBorderColor(butPtr->normalBorder)->pixel);
! 		    }
! 		}
! 
! 		XFillRectangle(butPtr->display, pixmap, gc, x, y,
! 			(unsigned int) dim, (unsigned int) dim);
! 	    } else {
! 		Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, x, y,
! 			dim, dim, butPtr->borderWidth, TK_RELIEF_FLAT);
! 	    }
  	}
      } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {
! 	XPoint points[4];
! 	int radius;
! 
! 	radius = butPtr->indicatorDiameter/2;
! 	points[0].x = x - butPtr->indicatorSpace;
! 	points[0].y = y;
! 	points[1].x = points[0].x + radius;
! 	points[1].y = points[0].y + radius;
! 	points[2].x = points[1].x + radius;
! 	points[2].y = points[0].y;
! 	points[3].x = points[1].x;
! 	points[3].y = points[0].y - radius;
! 	if (butPtr->flags & SELECTED) {
! 	    GC gc;
! 
! 	    if (butPtr->state != STATE_DISABLED) {
! 		if (butPtr->selectBorder != NULL) {
! 		    gc = Tk_3DBorderGC(tkwin, butPtr->selectBorder,
! 			    TK_3D_FLAT_GC);
! 		} else {
! 		    gc = Tk_3DBorderGC(tkwin, butPtr->normalBorder,
! 			    TK_3D_FLAT_GC);
! 		}
! 	    } else {
! 		if (butPtr->disabledFg != NULL) {
! 		    gc = butPtr->disabledGC;
! 		} else {
! 		    gc = butPtr->normalTextGC; 
! 		    XSetForeground(butPtr->display, butPtr->disabledGC,
! 			    Tk_3DBorderColor(butPtr->normalBorder)->pixel);
! 		}
! 	    }
! 
! 	    XFillPolygon(butPtr->display, pixmap, gc, points, 4, Convex,
! 		    CoordModeOrigin);
! 	} else {
! 	    Tk_Fill3DPolygon(tkwin, pixmap, butPtr->normalBorder, points,
! 		    4, butPtr->borderWidth, TK_RELIEF_FLAT);
  	}
- 	Tk_Draw3DPolygon(tkwin, pixmap, border, points, 4, butPtr->borderWidth,
- 		(butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN :
- 		TK_RELIEF_RAISED);
      }
  
      /*
--- 528,566 ----
       */
  
      if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
! 	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
! 	    TkBorder *sl_brdr = (TkBorder*)butPtr->selectBorder;
! 	    x -= butPtr->indicatorSpace/2;
! 	    y = Tk_Height(tkwin)/2;
! 
! 	    TkpDrawCheckButton(tkwin, butPtr->display, pixmap, 
! 			       x, y, 
! 			       border, 
! 			       butPtr->normalFg, 
! 			       butPtr->normalFg,
! 			       sl_brdr->bgColorPtr, 
! 			       butPtr->disabledFg, 
! 			       (butPtr->flags & SELECTED), 
! 			       (butPtr->state == STATE_DISABLED),
! 			       CHECK_BUTTON);
  	}
      } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {
! 	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
! 	    TkBorder *sl_brdr = (TkBorder*)butPtr->selectBorder;
! 	    x -= butPtr->indicatorSpace/2;
! 	    y = Tk_Height(tkwin)/2;
! 
! 	    TkpDrawCheckButton(tkwin, butPtr->display, pixmap, 
! 			       x, y, 
! 			       border, 
! 			       butPtr->normalFg, 
! 			       butPtr->normalFg,
! 			       sl_brdr->bgColorPtr, 
! 			       butPtr->disabledFg, 
! 			       (butPtr->flags & SELECTED), 
! 			       (butPtr->state == STATE_DISABLED),
! 			       RADIO_BUTTON);
  	}
      }
  
      /*
Index: tkUnixMenu.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixMenu.c,v
retrieving revision 1.7
diff -p -r1.7 tkUnixMenu.c
*** tkUnixMenu.c	22 Feb 2002 13:13:13 -0000	1.7
--- tkUnixMenu.c	23 Jul 2003 20:22:56 -0000
***************
*** 31,36 ****
--- 31,55 ----
  #define ENTRY_HELP_MENU		ENTRY_PLATFORM_FLAG1
  
  /*
+  * Shared with button widget
+  */
+ extern void TkpDrawCheckButton _ANSI_ARGS_((
+ 				Tk_Window tkwin, Display *display, Drawable d,
+ 				int x, int y, 
+ 				Tk_3DBorder bgBorder, XColor *fgColor,
+ 				XColor *indicatorColor, XColor *selectColor, 
+ 				XColor *disColor, 
+ 				int on, int disabled,
+ 				int mode));
+ /*
+  * Indicator Draw Modes
+  */
+ #define CHECK_BUTTON 0
+ #define CHECK_MENU   1
+ #define RADIO_BUTTON 2
+ #define RADIO_MENU   3
+ 
+ /*
   * Procedures used internally.
   */
  
*************** DrawMenuEntryIndicator(menuPtr, mePtr, d
*** 571,597 ****
  	int dim, top, left;
  	int activeBorderWidth;
  	Tk_3DBorder border;
! 	
  	dim = (int) mePtr->platformEntryData;
  	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
! 		menuPtr->activeBorderWidthPtr, &activeBorderWidth);
! 	left = x + activeBorderWidth + (mePtr->indicatorSpace - dim)/2;
! 	if (menuPtr->menuType == MENUBAR) {
! 	    left += 5;
! 	}
! 	top = y + (height - dim)/2;
  	border = Tk_Get3DBorderFromObj(menuPtr->tkwin,
! 		menuPtr->borderPtr);
! 	Tk_Fill3DRectangle(menuPtr->tkwin, d, border, left, top, dim,
! 		dim, DECORATION_BORDER_WIDTH, TK_RELIEF_SUNKEN);
! 	left += DECORATION_BORDER_WIDTH;
! 	top += DECORATION_BORDER_WIDTH;
! 	dim -= 2*DECORATION_BORDER_WIDTH;
! 	if ((dim > 0) && (mePtr->entryFlags
! 		& ENTRY_SELECTED)) {
! 	    XFillRectangle(menuPtr->display, d, indicatorGC, left, top,
! 		    (unsigned int) dim, (unsigned int) dim);
! 	}
      }
  
      /*
--- 590,615 ----
  	int dim, top, left;
  	int activeBorderWidth;
  	Tk_3DBorder border;
! 	XColor *bg;
! 	XColor *fg = Tk_GetColorFromObj(menuPtr->tkwin, mePtr->fgPtr ? mePtr->fgPtr : menuPtr->fgPtr);
! 	XColor *ind = Tk_GetColorFromObj(menuPtr->tkwin, 
! 					 mePtr->indicatorFgPtr ? mePtr->indicatorFgPtr : menuPtr->indicatorFgPtr);
! 	XColor *dis = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->disabledFgPtr);
  	dim = (int) mePtr->platformEntryData;
  	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
! 			    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
  	border = Tk_Get3DBorderFromObj(menuPtr->tkwin,
! 				       menuPtr->borderPtr);
! 	bg = Tk_3DBorderColor(border);
! 	top = y + height/2;
! 	left = x + activeBorderWidth + DECORATION_BORDER_WIDTH + mePtr->indicatorSpace/2;
! 	TkpDrawCheckButton(menuPtr->tkwin, menuPtr->display, d, 
! 			   left, top,
! 			   border, fg,
! 			   ind, bg, dis, 
! 			   (mePtr->entryFlags & ENTRY_SELECTED), 
! 			   (mePtr->state == ENTRY_DISABLED),
! 			   CHECK_MENU);
      }
  
      /*
*************** DrawMenuEntryIndicator(menuPtr, mePtr, d
*** 599,629 ****
       */
  
      if ((mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn) {
! 	XPoint points[4];
! 	int radius;
  	Tk_3DBorder border;
! 
! 	border = Tk_Get3DBorderFromObj(menuPtr->tkwin, 
! 		menuPtr->borderPtr);
! 	radius = ((int) mePtr->platformEntryData)/2;
! 	points[0].x = x + (mePtr->indicatorSpace
! 		- (int) mePtr->platformEntryData)/2;
! 	points[0].y = y + (height)/2;
! 	points[1].x = points[0].x + radius;
! 	points[1].y = points[0].y + radius;
! 	points[2].x = points[1].x + radius;
! 	points[2].y = points[0].y;
! 	points[3].x = points[1].x;
! 	points[3].y = points[0].y - radius;
! 	if (mePtr->entryFlags & ENTRY_SELECTED) {
! 	    XFillPolygon(menuPtr->display, d, indicatorGC, points, 4,
! 		    Convex, CoordModeOrigin);
! 	} else {
! 	    Tk_Fill3DPolygon(menuPtr->tkwin, d, border, points, 4,
! 		    DECORATION_BORDER_WIDTH, TK_RELIEF_FLAT);
! 	}
! 	Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 4,
! 		DECORATION_BORDER_WIDTH, TK_RELIEF_SUNKEN);
      }
  }
  
--- 617,645 ----
       */
  
      if ((mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn) {
! 	int dim, top, left;
! 	int activeBorderWidth;
  	Tk_3DBorder border;
! 	XColor *bg;
! 	XColor *fg = Tk_GetColorFromObj(menuPtr->tkwin, mePtr->fgPtr ? mePtr->fgPtr : menuPtr->fgPtr);
! 	XColor *ind = Tk_GetColorFromObj(menuPtr->tkwin, 
! 					 mePtr->indicatorFgPtr ? mePtr->indicatorFgPtr : menuPtr->indicatorFgPtr);
! 	XColor *dis = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->disabledFgPtr);
! 	dim = (int) mePtr->platformEntryData;
! 	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
! 			    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
! 	border = Tk_Get3DBorderFromObj(menuPtr->tkwin,
! 				       menuPtr->borderPtr);
! 	bg = Tk_3DBorderColor(border);
! 	top = y + height/2;
! 	left = x + activeBorderWidth + DECORATION_BORDER_WIDTH + mePtr->indicatorSpace/2;
! 	TkpDrawCheckButton(menuPtr->tkwin, menuPtr->display, d, 
! 			   left, top,
! 			   border, fg,
! 			   ind, bg, dis, 
! 			   (mePtr->entryFlags & ENTRY_SELECTED), 
! 			   (mePtr->state == ENTRY_DISABLED),
! 			   RADIO_MENU);
      }
  }