Control Creation Guide

IUP - Portable User Interface

Control Creation Guide

Introduction

All the IUP controls use the same internal API to implement their functionalities.

Each control, needs to export only one function that register the control so it can be used by IupCreate and other functions. Actually another utility function is exported to simplify the creation of the control.

Internally the control must implement the methods of the IUP class, and create functions that handle attributes.

Control Class Registration

The new control must export function to register the control. This function is quite simple and it is just a call to iupRegisterClass. For example:

void IupXxxOpen(void)
{
  iupRegisterClass(iupXxxClass());
}

The function iupXxxClass is internal to the control and it creates the control class.

Control Class Implementation

The function that creates the class will (1) initialize a base class, then (2) fill its configuration parameters, (3) set the class methods, (4) register the callbacks and (5) register the attributes. For example:

Iclass* iupXxxClass(void)
{
  /* (1) - initialize a base class */
  Iclass* ic = iupClassCreateBase(NULL); 

  /* (2) - configuration parameters */
  ic->name = "xxx";
  ic->format = ""; /* no creation parameters */
  ic->nativetype = IUP_TYPECONTROL;
  ic->childtype = IUP_CHILDNONE;
  ic->interactive = 1;

  /* (3) - class methods */
  ic->Create = iXxxCreateMeth;
  ic->Map = iXxxMapMeth;
  ic->Destroy = iXxxDestroyMeth;
  ic->ComputeNaturalSize = iXxxComputeNaturalSizeMeth;
  ic->SetCurrentSize = iXxxSetCurrentSizeMeth; 
  ic->LayoutUpdate = iXxxLayoutUpdateMeth;
  ic->DisplayUpdate = iXxxDisplayUpdateMeth;
  ic->SetPosition = iXxxSetPositionMeth;

  /* (4) - callbacks */
  iupClassRegisterCallback(ic, "XXX_CB", "i");
  iupClassRegisterCallback(ic, "MAP_CB", "");
  iupClassRegisterCallback(ic, "HELP_CB", "");
  iupClassRegisterCallback(ic, "GETFOCUS_CB", "");
  iupClassRegisterCallback(ic, "KILLFOCUS_CB", "");
  iupClassRegisterCallback(ic, "ENTERWINDOW_CB", "");
  iupClassRegisterCallback(ic, "LEAVEWINDOW_CB", "");
  iupClassRegisterCallback(ic, "K_ANY", "i"); 

  /* (5) - attributes */

  /* Common */
  iupClassRegisterAttribute(ic, "SIZE", iupGetSizeAttrib, iupDlgSetSizeAttrib, 0, 1, 0);
  iupClassRegisterAttribute(ic, "RASTERSIZE", iupGetRasterSizeAttrib, iupDlgSetRastersizeAttrib, 0, 1, 0);
  iupClassRegisterAttribute(ic, "WID", iupGetWidAttrib, iupNoSetAttrib, 0, 1, 0);
  iupClassRegisterAttribute(ic, "FONT", 0, iupdrvSetFontAttrib, IupGetGlobal("DEFAULTFONT"), 1, 0); 

  /* Common, but only after Map */
  iupClassRegisterAttribute(ic, "ACTIVE", iupGetActiveAttrib, iupSetActiveAttrib, "YES", 0, 0);
  iupClassRegisterAttribute(ic, "VISIBLE", iupGetVisibleAttrib, iupSetVisibleAttrib, "YES", 0, 0);
  iupClassRegisterAttribute(ic, "ZORDER", 0, iupdrvSetZorderAttrib, 0, 0, 0); 

  /* only the default value. */
  iupClassRegisterAttribute(ic, "BORDER", 0, 0, "YES", 0, 0); 

  return ic;
}

You can use the iupXxxClass equivalent function of other controls to initialize a new base class for a new control that inherits the functionalities of the base class.

If the control is a native control then it usually will have separate modules for each driver. The iupXxxClass function could call a iupdrvXxxClassInit(ic) function to initialize methods and attributes that are driver dependent.

Control Creation

All controls can be created using the IupCreate functions. But it is a common pratice to have a convenience function to create the control:

Ihandle* IupXxx(void)
{
  return IupCreate("xxx");
}

Control Exported Functions

The file header with the exported functions should look like this:

#ifndef __IUPGL_H 
#define __IUPGL_H

#ifdef __cplusplus
extern "C" {
#endif 

void IupXxxOpen(void); 

Ihandle* IupXxx(void);

#ifdef __cplusplus
}
#endif 

#endif