/* Checkbox Widget for XEmacs. Copyright (C) 1999 Edward A. Falk This file is part of XEmacs. XEmacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs. If not, see . */ /* Synched up with: Checkbox.c 1.1 */ /* * Checkbox.c - Checkbox button widget * * Author: Edward A. Falk * falk@falconer.vip.best.com * * Date: June 30, 1997 * * Overview: This widget is identical to the Radio widget in behavior, * except that the button is square and has a check mark. */ #include #include #include #include #include ATHENA_XawInit_h_ #include "xt-wrappers.h" #include "xlwcheckboxP.h" /* by using the same size for the checkbox as for the diamond box, * we can let the Radio widget do the vast majority of the work. */ #define BOX_SIZE 8 #define DRAW_CHECK 0 /* don't draw the check mark */ #define cclass(w) ((CheckboxWidgetClass)((w)->core.widget_class)) #ifdef _ThreeDP_h #define swid(cw) ((cw)->threeD.shadow_width) #else #define swid(cw) ((cw)->core.border_width) #endif #define bsize(cw) (cclass(cw)->radio_class.dsize) #define bs(cw) (bsize(cw) + 2*swid(cw)) #if DRAW_CHECK #define check_width 14 #define check_height 14 static unsigned char check_bits[] = { 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03, 0x8c, 0x03, 0xde, 0x01, 0xff, 0x01, 0xfe, 0x00, 0xfc, 0x00, 0x78, 0x00, 0x70, 0x00, 0x20, 0x00}; #endif /**************************************************************** * * Full class record constant * ****************************************************************/ #if DRAW_CHECK static char defaultTranslations[] = ": highlight()\n\ : unpress(draw) unhighlight()\n\ : press()\n\ ,: unpress(nodraw) toggle() notify()"; #endif #define offset(field) XtOffsetOf(CheckboxRec, checkbox.field) #define res(name,_class,intrepr,type,member,extrepr,value) \ Xt_RESOURCE (name, _class, intrepr, type, offset(member), extrepr, value) static XtResource resources[] = { res (XtNtristate, XtCTristate, XtRBoolean, Boolean, tristate, XtRImmediate, FALSE), } ; #undef offset /* Member functions */ static void CheckboxClassInit (void); static void CheckboxInit (Widget, Widget, ArgList, Cardinal *); #if DRAW_CHECK static void CheckboxRealize (Widget, Mask *, XSetWindowAttributes *); #endif static void DrawCheck (Widget); /* Action procs */ #if DRAW_CHECK static void CheckboxPress (Widget, XEvent *, String *, Cardinal *); static void CheckboxUnpress (Widget, XEvent *, String *, Cardinal *); #endif /* internal privates */ #if DRAW_CHECK static XtActionsRec actionsList[] = { {"press", CheckboxPress}, {"unpress", CheckboxUnpress}, } ; #endif #define SuperClass ((RadioWidgetClass)&radioClassRec) CheckboxClassRec checkboxClassRec = { { (WidgetClass) SuperClass, /* superclass */ (String) "Checkbox", /* class_name */ sizeof(CheckboxRec), /* size */ CheckboxClassInit, /* class_initialize */ NULL, /* class_part_initialize */ FALSE, /* class_inited */ CheckboxInit, /* initialize */ NULL, /* initialize_hook */ #if DRAW_CHECK CheckboxRealize, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ #else XtInheritRealize, /* realize */ NULL, /* actions */ 0, /* num_actions */ #endif resources, /* resources */ XtNumber(resources), /* resource_count */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ NULL, /* destroy */ XtInheritResize, /* resize */ XtInheritExpose, /* expose */ NULL, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_private */ #if DRAW_CHECK defaultTranslations, /* tm_table */ #else XtInheritTranslations, /* tm_table */ #endif XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display_accelerator */ NULL /* extension */ }, /* CoreClass fields initialization */ { XtInheritChangeSensitive /* change_sensitive */ }, /* SimpleClass fields initialization */ #ifdef _ThreeDP_h { XtInheritXaw3dShadowDraw /* field not used */ }, /* ThreeDClass fields initialization */ #endif { 0 /* field not used */ }, /* LabelClass fields initialization */ { 0 /* field not used */ }, /* CommandClass fields initialization */ { RadioSet, /* Set Procedure. */ RadioUnset, /* Unset Procedure. */ NULL /* extension. */ }, /* ToggleClass fields initialization */ { BOX_SIZE, DrawCheck, /* draw procedure */ NULL /* extension. */ }, /* RadioClass fields initialization */ { NULL /* extension. */ }, /* CheckboxClass fields initialization */ }; /* for public consumption */ WidgetClass checkboxWidgetClass = (WidgetClass) &checkboxClassRec; /**************************************************************** * * Class Methods * ****************************************************************/ static void CheckboxClassInit (void) { XawInitializeWidgetSet(); } /*ARGSUSED*/ static void CheckboxInit (Widget UNUSED (request), #if DRAW_CHECK Widget new, #else Widget UNUSED (new_), #endif ArgList UNUSED (args), Cardinal *UNUSED (num_args)) { #if DRAW_CHECK CheckboxWidget cw = (CheckboxWidget) new_; cw->checkbox.checkmark = None ; cw->checkbox.checkmark_GC = None ; #endif } #if DRAW_CHECK static void CheckboxRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) { CheckboxWidget cw = (CheckboxWidget) w; XtGCMask value_mask, dynamic_mask, dontcare_mask ; XGCValues values ; /* first, call superclass realize */ (*checkboxWidgetClass->core_class.superclass->core_class.realize) (w, valueMask, attributes); /* TODO: cache this via xmu */ if( cw->checkbox.checkmark == None ) cw->checkbox.checkmark = XCreateBitmapFromData( XtDisplay(w), XtWindow(w), check_bits,check_width,check_height); values.fill_style = FillStippled ; values.stipple = cw->checkbox.checkmark ; values.foreground = cw->label.foreground ; value_mask = GCFillStyle | GCStipple | GCForeground ; dynamic_mask = GCTileStipXOrigin | GCTileStipYOrigin ; dontcare_mask = GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFont | GCSubwindowMode | GCGraphicsExposures | GCDashOffset | GCDashList | GCArcMode ; cw->checkbox.checkmark_GC = XtAllocateGC(w, 0, value_mask, &values, dynamic_mask, dontcare_mask) ; } #endif /* Function Name: CheckboxDestroy * Description: Destroy Callback for checkbox widget. * Arguments: w - the checkbox widget that is being destroyed. * junk, garbage - not used. * Returns: none. */ /* ARGSUSED */ #if DRAW_CHECK static void CheckboxDestroy ( Widget w, XtPointer UNUSED (junk), XtPointer UNUSED (garbage)) { CheckboxWidget cw = (CheckboxWidget) w; /* TODO: cache this via xmu */ if( cw->checkbox.checkmark != None ) XFreePixmap( XtDisplay(w), cw->checkbox.checkmark ) ; if( cw->checkbox.checkmark_GC != None ) XtReleaseGC(w, cw->checkbox.checkmark_GC) ; } #endif /* DRAW_CHECK */ #if DRAW_CHECK /************************************************************ * * Actions Procedures * ************************************************************/ /* ARGSUSED */ static void CheckboxPress (Widget w, XEvent *event, String *params, /* unused */ Cardinal *num_params) /* unused */ { CheckboxWidget cw = (CheckboxWidget) w ; if( !cw->checkbox.pressed ) { cw->checkbox.pressed = TRUE ; ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w) ; } } static void CheckboxUnpress (Widget w, XEvent *event, String *params, /* unused */ Cardinal *num_params) /* unused */ { CheckboxWidget cw = (CheckboxWidget) w ; int i ; if( cw->checkbox.pressed ) { cw->checkbox.pressed = FALSE ; if( *num_params > 0 && **params == 'd' ) ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w); } } #endif /************************************************************ * * Internal Procedures * ************************************************************/ static void DrawCheck (Widget w) { CheckboxWidget cw = (CheckboxWidget) w ; Display *dpy = XtDisplay(w) ; Window win = XtWindow(w) ; GC gc ; #ifdef _ThreeDP_h XPoint pts[6] ; #endif Dimension s = swid(cw); Dimension bsz = bsize(cw); Position bx,by ; /* Check upper-left */ Dimension bh ; #ifdef _ThreeDP_h Dimension bw; GC top, bot; #endif GC ctr ; /* foreground GC */ gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC ; bh = bs(cw) ; bx = cw->label.internal_width ; by = cw->core.height/2 - bh/2 ; #ifdef _ThreeDP_h bw = bh ; if( !cw->command.set ) { top = cw->threeD.top_shadow_GC ; bot = cw->threeD.bot_shadow_GC ; } else { top = cw->threeD.bot_shadow_GC ; bot = cw->threeD.top_shadow_GC ; } ctr = cw->command.inverse_GC ; #else ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC ; #endif XFillRectangle(dpy,win,ctr, bx+s,by+s, bsz,bsz) ; #ifdef _ThreeDP_h /* top-left shadow */ pts[0].x = bx ; pts[0].y = by ; pts[1].x = bw ; pts[1].y = 0 ; pts[2].x = -s ; pts[2].y = s ; pts[3].x = -bsz ; pts[3].y = 0 ; pts[4].x = 0 ; pts[4].y = bsz ; pts[5].x = -s ; pts[5].y = s ; XFillPolygon(dpy,win,top, pts,6, Nonconvex,CoordModePrevious) ; /* bottom-right shadow */ pts[0].x = bx+bw ; pts[0].y = by+bh ; pts[1].x = -bw ; pts[1].y = 0 ; pts[2].x = s ; pts[2].y = -s ; pts[3].x = bsz ; pts[3].y = 0 ; pts[4].x = 0 ; pts[4].y = -bsz ; pts[5].x = s ; pts[5].y = -s ; XFillPolygon(dpy,win,bot, pts,6, Nonconvex,CoordModePrevious) ; #else XDrawRectangle(dpy,win,gc, bx+s,by+s, bsz,bsz) ; #endif #if DRAW_CHECK if( cw->command.set && cw->checkbox.checkmark_GC != None ) { XSetTSOrigin(dpy,cw->checkbox.checkmark_GC, bx+s, by+s) ; XFillRectangle(dpy,win,cw->checkbox.checkmark_GC, bx+s, by+s, check_width,check_height) ; } #endif }