1 /* Checkbox Widget for XEmacs.
2 Copyright (C) 1999 Edward A. Falk
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Synched up with: Checkbox.c 1.1 */
24 * Checkbox.c - Checkbox button widget
26 * Author: Edward A. Falk
27 * falk@falconer.vip.best.com
31 * Overview: This widget is identical to the Radio widget in behavior,
32 * except that the button is square and has a check mark.
39 #include <X11/IntrinsicP.h>
40 #include <X11/StringDefs.h>
41 #include ATHENA_XawInit_h_
42 #include "../src/xmu.h"
43 #include "xlwcheckboxP.h"
46 /* by using the same size for the checkbox as for the diamond box,
47 * we can let the Radio widget do the vast majority of the work.
51 #define DRAW_CHECK 0 /* don't draw the check mark */
53 #define cclass(w) ((CheckboxWidgetClass)((w)->core.widget_class))
56 #define swid(cw) ((cw)->threeD.shadow_width)
58 #define swid(cw) ((cw)->core.border_width)
61 #define bsize(cw) (cclass(cw)->radio_class.dsize)
62 #define bs(cw) (bsize(cw) + 2*swid(cw))
66 #define check_width 14
67 #define check_height 14
68 static unsigned char check_bits[] = {
69 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03,
70 0x8c, 0x03, 0xde, 0x01, 0xff, 0x01, 0xfe, 0x00, 0xfc, 0x00, 0x78, 0x00,
71 0x70, 0x00, 0x20, 0x00};
75 /****************************************************************
77 * Full class record constant
79 ****************************************************************/
83 static char defaultTranslations[] =
84 "<EnterWindow>: highlight()\n\
85 <LeaveWindow>: unpress(draw) unhighlight()\n\
86 <Btn1Down>: press()\n\
87 <Btn1Down>,<Btn1Up>: unpress(nodraw) toggle() notify()";
92 #define offset(field) XtOffsetOf(CheckboxRec, field)
93 static XtResource resources[] = {
94 {XtNtristate, XtCTristate, XtRBoolean, sizeof(Boolean),
95 offset(checkbox.tristate), XtRImmediate, (XtPointer)FALSE},
99 /* Member functions */
101 static void CheckboxClassInit (void);
102 static void CheckboxInit (Widget, Widget, ArgList, Cardinal *);
104 static void CheckboxRealize (Widget, Mask *, XSetWindowAttributes *);
106 static void DrawCheck (Widget);
111 static void CheckboxPress (Widget, XEvent *, String *, Cardinal *);
112 static void CheckboxUnpress (Widget, XEvent *, String *, Cardinal *);
115 /* internal privates */
118 static XtActionsRec actionsList[] =
120 {"press", CheckboxPress},
121 {"unpress", CheckboxUnpress},
125 #define SuperClass ((RadioWidgetClass)&radioClassRec)
127 CheckboxClassRec checkboxClassRec = {
129 (WidgetClass) SuperClass, /* superclass */
130 "Checkbox", /* class_name */
131 sizeof(CheckboxRec), /* size */
132 CheckboxClassInit, /* class_initialize */
133 NULL, /* class_part_initialize */
134 FALSE, /* class_inited */
135 CheckboxInit, /* initialize */
136 NULL, /* initialize_hook */
138 CheckboxRealize, /* realize */
139 actionsList, /* actions */
140 XtNumber(actionsList), /* num_actions */
142 XtInheritRealize, /* realize */
146 resources, /* resources */
147 XtNumber(resources), /* resource_count */
148 NULLQUARK, /* xrm_class */
149 TRUE, /* compress_motion */
150 TRUE, /* compress_exposure */
151 TRUE, /* compress_enterleave */
152 FALSE, /* visible_interest */
154 XtInheritResize, /* resize */
155 XtInheritExpose, /* expose */
156 NULL, /* set_values */
157 NULL, /* set_values_hook */
158 XtInheritSetValuesAlmost, /* set_values_almost */
159 NULL, /* get_values_hook */
160 NULL, /* accept_focus */
161 XtVersion, /* version */
162 NULL, /* callback_private */
164 defaultTranslations, /* tm_table */
166 XtInheritTranslations, /* tm_table */
168 XtInheritQueryGeometry, /* query_geometry */
169 XtInheritDisplayAccelerator, /* display_accelerator */
171 }, /* CoreClass fields initialization */
173 XtInheritChangeSensitive /* change_sensitive */
174 }, /* SimpleClass fields initialization */
177 XtInheritXaw3dShadowDraw /* field not used */
178 }, /* ThreeDClass fields initialization */
181 0 /* field not used */
182 }, /* LabelClass fields initialization */
184 0 /* field not used */
185 }, /* CommandClass fields initialization */
187 RadioSet, /* Set Procedure. */
188 RadioUnset, /* Unset Procedure. */
189 NULL /* extension. */
190 }, /* ToggleClass fields initialization */
193 DrawCheck, /* draw procedure */
194 NULL /* extension. */
195 }, /* RadioClass fields initialization */
197 NULL /* extension. */
198 }, /* CheckboxClass fields initialization */
201 /* for public consumption */
202 WidgetClass checkboxWidgetClass = (WidgetClass) &checkboxClassRec;
209 /****************************************************************
213 ****************************************************************/
216 CheckboxClassInit (void)
218 XawInitializeWidgetSet();
224 CheckboxInit (Widget request,
230 CheckboxWidget cw = (CheckboxWidget) new;
231 cw->checkbox.checkmark = None ;
232 cw->checkbox.checkmark_GC = None ;
239 CheckboxRealize(Widget w,
241 XSetWindowAttributes *attributes)
243 CheckboxWidget cw = (CheckboxWidget) w;
244 XtGCMask value_mask, dynamic_mask, dontcare_mask ;
247 /* first, call superclass realize */
248 (*checkboxWidgetClass->core_class.superclass->core_class.realize)
249 (w, valueMask, attributes);
251 /* TODO: cache this via xmu */
252 if( cw->checkbox.checkmark == None )
253 cw->checkbox.checkmark =
254 XCreateBitmapFromData( XtDisplay(w), XtWindow(w),
255 check_bits,check_width,check_height);
257 values.fill_style = FillStippled ;
258 values.stipple = cw->checkbox.checkmark ;
259 values.foreground = cw->label.foreground ;
260 value_mask = GCFillStyle | GCStipple | GCForeground ;
261 dynamic_mask = GCTileStipXOrigin | GCTileStipYOrigin ;
262 dontcare_mask = GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
263 GCFont | GCSubwindowMode | GCGraphicsExposures |
264 GCDashOffset | GCDashList | GCArcMode ;
265 cw->checkbox.checkmark_GC =
266 XtAllocateGC(w, 0, value_mask, &values, dynamic_mask, dontcare_mask) ;
271 /* Function Name: CheckboxDestroy
272 * Description: Destroy Callback for checkbox widget.
273 * Arguments: w - the checkbox widget that is being destroyed.
274 * junk, garbage - not used.
280 CheckboxDestroy (Widget w,
285 CheckboxWidget cw = (CheckboxWidget) w;
287 /* TODO: cache this via xmu */
288 if( cw->checkbox.checkmark != None )
289 XFreePixmap( XtDisplay(w), cw->checkbox.checkmark ) ;
290 if( cw->checkbox.checkmark_GC != None )
291 XtReleaseGC(w, cw->checkbox.checkmark_GC) ;
298 /************************************************************
302 ************************************************************/
306 CheckboxPress (Widget w,
308 String *params, /* unused */
309 Cardinal *num_params) /* unused */
311 CheckboxWidget cw = (CheckboxWidget) w ;
312 if( !cw->checkbox.pressed ) {
313 cw->checkbox.pressed = TRUE ;
314 ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w) ;
319 CheckboxUnpress (Widget w,
321 String *params, /* unused */
322 Cardinal *num_params) /* unused */
324 CheckboxWidget cw = (CheckboxWidget) w ;
327 if( cw->checkbox.pressed ) {
328 cw->checkbox.pressed = FALSE ;
329 if( *num_params > 0 && **params == 'd' )
330 ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w);
339 /************************************************************
341 * Internal Procedures
343 ************************************************************/
348 CheckboxWidget cw = (CheckboxWidget) w ;
349 Display *dpy = XtDisplay(w) ;
350 Window win = XtWindow(w) ;
356 Dimension s = swid(cw);
357 Dimension bsz = bsize(cw);
358 Position bx,by ; /* Check upper-left */
366 gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC ;
369 bx = cw->label.internal_width ;
370 by = cw->core.height/2 - bh/2 ;
373 if( !cw->command.set ) {
374 top = cw->threeD.top_shadow_GC ;
375 bot = cw->threeD.bot_shadow_GC ;
377 top = cw->threeD.bot_shadow_GC ;
378 bot = cw->threeD.top_shadow_GC ;
380 ctr = cw->command.inverse_GC ;
382 ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC ;
385 XFillRectangle(dpy,win,ctr, bx+s,by+s, bsz,bsz) ;
388 /* top-left shadow */
389 pts[0].x = bx ; pts[0].y = by ;
390 pts[1].x = bw ; pts[1].y = 0 ;
391 pts[2].x = -s ; pts[2].y = s ;
392 pts[3].x = -bsz ; pts[3].y = 0 ;
393 pts[4].x = 0 ; pts[4].y = bsz ;
394 pts[5].x = -s ; pts[5].y = s ;
395 XFillPolygon(dpy,win,top, pts,6, Nonconvex,CoordModePrevious) ;
396 /* bottom-right shadow */
397 pts[0].x = bx+bw ; pts[0].y = by+bh ;
398 pts[1].x = -bw ; pts[1].y = 0 ;
399 pts[2].x = s ; pts[2].y = -s ;
400 pts[3].x = bsz ; pts[3].y = 0 ;
401 pts[4].x = 0 ; pts[4].y = -bsz ;
402 pts[5].x = s ; pts[5].y = -s ;
403 XFillPolygon(dpy,win,bot, pts,6, Nonconvex,CoordModePrevious) ;
405 XDrawRectangle(dpy,win,gc, bx+s,by+s, bsz,bsz) ;
409 if( cw->command.set && cw->checkbox.checkmark_GC != None ) {
410 XSetTSOrigin(dpy,cw->checkbox.checkmark_GC, bx+s, by+s) ;
411 XFillRectangle(dpy,win,cw->checkbox.checkmark_GC,
412 bx+s, by+s, check_width,check_height) ;