/* $Id: Checkbox.c,v 1.4 1997/04/28 15:52:06 archer Exp $
 *	CHECKBOX.C - Handle CheckBox/Radiobox objects
 */
#include <Widget/CheckBoxP.h>
#include <Widget/drawP.h>
#include <Widget/IconP.h>


/**
 ** Internal: CHECK_BOX_GEOMETRY
 **	Recompute the geometry needed by CheckBox
 **/
static void checkbox_geometry(X11_widget wdg, XEvent *dummy)
{
unsigned int	h;
/*
 * Label is the main governor
 */
	x11__label_size(W_LABEL);
/*
 * CheckBox size
 */
	h = 2 + 2 * wdg->shadow_thickness;
/*
 * Actual size
 */
	if (h < W_LABEL->h)
		h = W_LABEL->h;
/*
 * Dimensions are better known
 */
	W_CHECKBOX->box_width = h;
	wdg->w_min = W_LABEL->w + wdg->margin_inside + h + wdg->border2;
	wdg->h_min = h + wdg->border2;
	wdg->fixed_w = True;
	wdg->fixed_h = True;
	x11__widget_grow(wdg);
}


/**
 ** Internal: EXPOSE
 **/
static void checkbox_expose(X11_widget wdg, XEvent *dummy)
{
int	x, y;
boolean	down;
/*
 * Start drawing
 */
	x11__draw_start(wdg);
/*
 * Draw the box
 */
	x11__x_w = W_CHECKBOX->box_width;
	x11__x_right = x11__x_left + x11__x_w - 1;
	x = x11__x_right + 1 + wdg->margin_inside;
	y = x11__y_top;
	x11__draw_fit_h(x11__x_w);
/*
 * Style
 */
	x11__shadows_gc();
	down = W_CHECKBOX->checked;
	if (wdg->is_depressed && wdg->is_selected)
		if (down)
			down = False;
		else
			down = True;
	if (down) {
		x11__draw_downshadow(wdg->shadow_thickness);
		x11__draw_filled(wdg->active_bk);
	} else {
		x11__draw_upshadow(wdg->shadow_thickness);
		x11__draw_filled(wdg->background);
	}
/*
 * Now, the label
 */
	x11__x_left = x;
	x11__y_top  = y;
	x11__x_w    = 0;
	x11__y_h    = wdg->h - wdg->border2;
	x11__label_draw(W_LABEL, wdg->background, wdg->foreground);
}


/**
 ** Internal: CHECKBOX_RELEASE
 **	CheckBox changes its position
 **/
static void checkbox_release(X11_widget wdg, XEvent *event)
{
/*
 * Inside when released?
 */
	if (wdg->is_selected) {
		W_CHECKBOX->checked = W_CHECKBOX->checked ? False : True;
		if (W_CHECKBOX->on_toggle)
			(*W_CHECKBOX->on_toggle)(wdg, W_CHECKBOX->data);
	}
/*
 * Process the release itself
 */
	x11__core_release(wdg, event);
}


/**
 ** X11_CHECKBOX_VALUE
 **	Returns the value of the checkbox
 **/
boolean X11_CheckBoxValue(X11_widget wdg)
{
	return W_CHECKBOX->checked;
}


/**
 ** X11_CHECKBOX_SET
 **	Positions the value of the checkbox
 **/
void X11_CheckBoxSet(X11_widget wdg, boolean val)
{
	W_CHECKBOX->checked = val;
	if (wdg->w && !wdg->unmapped)
		(*wdg->on_expose)(wdg, (XEvent *)0);
}


/**
 ** X11_CHECKBOX
 **	Create a CheckBox window
 **/
X11_widget X11_CheckBox(X11_widget parent, char *name, char *title, boolean rad,
						X11_callback call, void *data)
{
x11__checkbox	*object;
/*
 * Get resource
 */
	object = allocator(x11__checkbox);
	x11__core_setup(&object->label.core, parent, "CheckBox", name);
/*
 * Initialize fields
 */
	object->label.core.event_mask  = ExposureMask|
					ButtonPressMask|ButtonReleaseMask|
					PointerMotionMask|PointerMotionHintMask|
					EnterWindowMask|LeaveWindowMask;
	object->label.core.on_button_press   = x11__core_press;
	object->label.core.on_button_release = checkbox_release;
	object->label.core.on_destruction    = x11__label_cleanup;
	object->label.core.on_expose         = checkbox_expose;
	object->label.core.on_enter_window   = x11__core_enter;
	object->label.core.on_exit_window    = x11__core_exit;
	object->label.core.on_geometry_check = checkbox_geometry;
	object->label.core.on_motion_notify  = x11__core_motion;
	object->label.core.on_resize_window  = x11__core_resize;
/*
 * Default values depend on the style
 */
	object->label.core.margin_inside    = 5;
	object->label.core.shadow_thickness = 2;
/*
 * Properties as specified by resources
 */
	if (!title)
		title = name;
	x11__label_resources(&object->label, x11__font_helvetica12, title);
	object->radio_look = rad;
	object->on_toggle  = call;
	object->data       = data;
/*
 * Finished
 */
	return OBJECT_P;
}
