/* 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
}