To make your composite widget available to EZ_CreateWidget
, you
need to
EZ_Widget *create(EZ_Widget *parent, char *inst_name, char *class_name);
EZ_RegisterCompositeWidget
to register
your widget.
After a widget has been registered, it can be instantiatd
by calling EZ_CreateWidgetXrm
with the registered
type.
In this section, we implement a counter widget. Our counter
has three private resources, value
(an integer),
increment
(a pair of integers) and counterWidth
(an integer specifies the width of the counter label).
We implement two interface procedures; ez_GetCounter
and ez_SetCounter
.
/************************* Counter Widget *******************************/
#include "EZ.h"
int ez_GetCounter (EZ_Widget *widget);
void ez_SetCounter (EZ_Widget *widget, int value);
/*********************************************************************/
#define Counter_TYPE 65538
static EZ_Widget *CounterCreate(EZ_Widget *parent, char *iname, char *cname);
/*********************************************************************/
typedef struct counter_ {
EZ_Widget *frame, *label;
EZ_Widget *btnLL, *btnL, *btnR, *btnRR;
int type, value;
int increment1, increment2;
} ez_counter;
/*********************************************************************/
int ez_GetCounter(EZ_Widget *widget)
{
/* return counter value */
ez_counter *ptr = (ez_counter *)EZ_GetWidgetPtrData(widget);
return(ptr->value);
}
/*********************************************************************/
void ez_SetCounter(EZ_Widget *widget, int value)
{
/* set counter value and update display */
ez_counter *ptr = (ez_counter *)EZ_GetWidgetPtrData(widget);
if(ptr->value != value)
{
char str[64];
ptr->value = value;
sprintf(str, "%d", value);
EZ_ConfigureWidget(ptr->label, EZ_LABEL_STRING, str, 0);
if(EZ_WidgetIsViewable(ptr->label)) EZ_DrawWidget(ptr->label);
}
}
/*********************************************************************/
static void btnEHandle(EZ_Widget *btn, void *data, int etype, XEvent *xev)
{
/* the arrow buttons are labels, this event handler replaces
* the default event handler
*/
switch(xev->type)
{
case Expose: EZ_DrawWidget(btn); break;
case EnterNotify: EZ_HighlightWidget(btn, 1); break;
case LeaveNotify: EZ_HighlightWidget(btn, 0); break;
case ButtonPress:
{
if(xev->xbutton.button == EZ_Btn1)
{
Display *dpy = EZ_GetDisplay();
XEvent xevent;
ez_counter *ptr = (ez_counter *)data;
int whichBtn = EZ_GetWidgetIntData(btn);
int nnn = 10;
int increment, done = 0;
switch(whichBtn)
{
case -2: increment = - ptr->increment2; break;
case -1: increment = - ptr->increment1; break;
case 1: increment = ptr->increment1; break;
case 2: increment = ptr->increment2; break;
default: break;
}
/* wait for btn release */
while( !done )
{
/* increment counter */
ez_SetCounter(btn, ptr->value + increment);
XSync(dpy, False);
if(--nnn > 0) EZ_SitForALittleBit(30000 * nnn);
else EZ_SitForALittleBit(30000);
while(XPending(dpy))
{
XNextEvent(dpy, &xevent);
if(xevent.type == ButtonRelease && xevent.xbutton.button == EZ_Btn1) done = 1;
if(xevent.type == Expose)
{
EZ_WidgetDispatchEvent(&xevent);
EZ_RemoveEvent(&xevent);
}
if(done) break;
}
}
}
}
break;
case KeyPress: /* may be ... */
break;
default:
break;
}
xev->type = 0; /* disable the default event handler */
}
/*********************************************************************/
static void freeCounter(EZ_Widget *w, void *data) { free(data);}
/*********************************************************************/
static EZ_Widget *CounterCreate(EZ_Widget *parent, char *iname, char *cname)
{
ez_counter *record = (ez_counter *)malloc(sizeof(ez_counter));
memset(record, 0, sizeof(ez_counter));
record->value = 0; record->increment1 = 1; record->increment2 = 10;
record->frame = EZ_CreateWidgetXrm(EZ_WIDGET_FRAME, parent,
iname, cname,
EZ_PADX, 0,
EZ_PADY, 0,
EZ_IPADX, 2,
EZ_HEIGHT, 0,
EZ_FILL_MODE, EZ_FILL_BOTH,
EZ_DESTROY_CALLBACK, freeCounter, record,
EZ_CLIENT_PTR_DATA, record,
0);
record->btnLL = EZ_CreateWidget(EZ_WIDGET_LABEL, record->frame,
EZ_ARROW_LABEL, EZ_DOUBLE_LEFT_TRIANGLE,
EZ_CLIENT_PTR_DATA, record,
EZ_CLIENT_INT_DATA, -2,
EZ_EVENT_HANDLER, btnEHandle, record,
EZ_BORDER_WIDTH, 2,
EZ_BORDER_TYPE, EZ_BORDER_RAISED,
EZ_WIDTH, 0,
0);
record->btnL = EZ_CreateWidget(EZ_WIDGET_LABEL, record->frame,
EZ_ARROW_LABEL, EZ_LEFT_TRIANGLE,
EZ_CLIENT_PTR_DATA, record,
EZ_CLIENT_INT_DATA, -1,
EZ_EVENT_HANDLER, btnEHandle, record,
EZ_BORDER_WIDTH, 2,
EZ_BORDER_TYPE, EZ_BORDER_RAISED,
EZ_WIDTH, 0,
0);
record->label = EZ_CreateWidgetXrm(EZ_WIDGET_LABEL, record->frame,
"counter", "Counter",
EZ_BORDER_TYPE, EZ_BORDER_SUNKEN,
EZ_BORDER_WIDTH, 2,
EZ_WIDTH, 80,
EZ_LABEL_POSITION, EZ_CENTER,
EZ_CLIENT_PTR_DATA, record,
EZ_PROPAGATE, False,
0);
record->btnR = EZ_CreateWidget(EZ_WIDGET_LABEL, record->frame,
EZ_ARROW_LABEL, EZ_RIGHT_TRIANGLE,
EZ_CLIENT_PTR_DATA, record,
EZ_CLIENT_INT_DATA, 1,
EZ_EVENT_HANDLER, btnEHandle, record,
EZ_BORDER_WIDTH, 2,
EZ_BORDER_TYPE, EZ_BORDER_RAISED,
EZ_WIDTH, 0,
0);
record->btnRR = EZ_CreateWidget(EZ_WIDGET_LABEL, record->frame,
EZ_ARROW_LABEL, EZ_DOUBLE_RIGHT_TRIANGLE,
EZ_CLIENT_PTR_DATA, record,
EZ_CLIENT_INT_DATA, 2,
EZ_EVENT_HANDLER, btnEHandle, record,
EZ_BORDER_WIDTH, 2,
EZ_BORDER_TYPE, EZ_BORDER_RAISED,
EZ_WIDTH, 0,
0);
/* set up: parse resources 'value', 'increment' and 'counterWidth */
{
char str[64], *value; int a, b;
if(EZ_GetWidgetResource(record->frame, "value", &value))
if(sscanf(value, "%d", &a) == 1) record->value = a;
if(EZ_GetWidgetResource(record->frame, "increment", &value))
if(sscanf(value, "%d %d", &a, &b) == 2)
{ record->increment1 = a; record->increment2 = b;}
if(EZ_GetWidgetResource(record->frame, "counterWidth", &value))
if(sscanf(value, "%d", &a) == 1 && a > 0)
{ EZ_ConfigureWidget(record->label, EZ_WIDTH, a, 0); }
sprintf(str, "%d", record->value);
EZ_ConfigureWidget(record->label, EZ_LABEL_STRING, str, 0);
}
return(record->frame);
}
/*********************************************************************/
/* TEST */
main(int ac, char **av)
{
EZ_Widget *counter;
EZ_Initialize(ac,av,0);
EZ_RegisterCompositeWidget(Counter_TYPE, "counter", "Counter",
CounterCreate);
counter = EZ_CreateWidgetXrm(Counter_TYPE, NULL,
"counter1", "Counter1",
0);
EZ_DisplayWidget(counter);
EZ_EventMainLoop();
}
/*********************************************************************/