EZ
Up Prev Next Contents


5.2 Write Composite Widgets

To make your composite widget available to EZ_CreateWidget, you need to

After a widget has been registered, it can be instantiatd by calling EZ_CreateWidgetXrm with the registered type.

5.2.1 Example: Counter

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();
}
/*********************************************************************/


Up Prev Next Contents

HTML Documentation Maintainance:Arturo Espinosa <arturo@nuclecu.unam.mx>