From d577d991b97ae2b5ee1af23641bcffc3f83af5b2 Mon Sep 17 00:00:00 2001 From: Pixel Date: Wed, 4 Nov 2009 11:56:41 -0800 Subject: Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux. --- iup/src/iup_list.c | 711 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 711 insertions(+) create mode 100755 iup/src/iup_list.c (limited to 'iup/src/iup_list.c') diff --git a/iup/src/iup_list.c b/iup/src/iup_list.c new file mode 100755 index 0000000..5965665 --- /dev/null +++ b/iup/src/iup_list.c @@ -0,0 +1,711 @@ +/** \file + * \brief List Control + * + * See Copyright Notice in "iup.h" + */ + +#include +#include +#include + +#include "iup.h" +#include "iupcbs.h" + +#include "iup_assert.h" +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_drv.h" +#include "iup_drvfont.h" +#include "iup_stdcontrols.h" +#include "iup_layout.h" +#include "iup_mask.h" +#include "iup_list.h" + + +void iupListSingleCallDblClickCallback(Ihandle* ih, IFnis cb, int pos) +{ + char *text; + char str[30]; + + if (pos<=0) + return; + + sprintf(str, "%d", pos); + text = IupGetAttribute(ih, str); + + if (cb(ih, pos, text) == IUP_CLOSE) + IupExitLoop(); +} + +static void iListCallActionCallback(Ihandle* ih, IFnsii cb, int pos, int state) +{ + char *text; + char str[30]; + + if (pos<=0) + return; + + sprintf(str, "%d", pos); + text = IupGetAttribute(ih, str); + + if (cb(ih, text, pos, state) == IUP_CLOSE) + IupExitLoop(); +} + +void iupListSingleCallActionCallback(Ihandle* ih, IFnsii cb, int pos) +{ + char* old_str = iupAttribGet(ih, "_IUPLIST_OLDVALUE"); + if (old_str) + { + int oldpos = atoi(old_str); + if (oldpos != pos) + { + iListCallActionCallback(ih, cb, oldpos, 0); + iListCallActionCallback(ih, cb, pos, 1); + } + } + else + iListCallActionCallback(ih, cb, pos, 1); + iupAttribSetInt(ih, "_IUPLIST_OLDVALUE", pos); +} + +void iupListMultipleCallActionCallback(Ihandle* ih, IFnsii cb, IFns multi_cb, int* pos, int sel_count) +{ + int i, count = iupdrvListGetCount(ih); + + char* old_str = iupAttribGet(ih, "_IUPLIST_OLDVALUE"); + int old_count = old_str? strlen(old_str): 0; + + char* str = iupStrGetMemory(count+1); + memset(str, '-', count); + str[count]=0; + for (i=0; i= old_count) /* new items, if selected then call the callback */ + { + if (str[i] == '+') + iListCallActionCallback(ih, cb, i+1, 1); + } + else if (str[i] != old_str[i]) + { + if (str[i] == '+') + iListCallActionCallback(ih, cb, i+1, 1); + else + iListCallActionCallback(ih, cb, i+1, 0); + } + } + } + + iupAttribStoreStr(ih, "_IUPLIST_OLDVALUE", str); +} + +int iupListGetPos(Ihandle* ih, const char* name_id) +{ + int pos; + if (iupStrToInt(name_id, &pos)) + { + int count = iupdrvListGetCount(ih); + + pos--; /* IUP items start at 1 */ + + if (pos < 0) return -1; + if (pos > count-1) return -1; + + return pos; + } + return -1; +} + +void iupListSetInitialItems(Ihandle* ih) +{ + char str[20], *value; + int i = 1; + sprintf(str, "%d", i); + while ((value = iupAttribGet(ih, str))!=NULL) + { + iupdrvListAppendItem(ih, value); + iupAttribSetStr(ih, str, NULL); + + i++; + sprintf(str, "%d", i); + } +} + +char* iupListGetSpacingAttrib(Ihandle* ih) +{ + if (!ih->data->is_dropdown) + { + char *str = iupStrGetMemory(50); + sprintf(str, "%d", ih->data->spacing); + return str; + } + else + return NULL; +} + +char* iupListGetPaddingAttrib(Ihandle* ih) +{ + if (ih->data->has_editbox) + { + char *str = iupStrGetMemory(50); + sprintf(str, "%dx%d", ih->data->horiz_padding, ih->data->vert_padding); + return str; + } + else + return NULL; +} + +char* iupListGetNCAttrib(Ihandle* ih) +{ + if (ih->data->has_editbox) + { + char* str = iupStrGetMemory(100); + sprintf(str, "%d", ih->data->nc); + return str; + } + else + return NULL; +} + +int iupListSetIdValueAttrib(Ihandle* ih, const char* name_id, const char* value) +{ + int pos; + if (iupStrToInt(name_id, &pos)) + { + int count = iupdrvListGetCount(ih); + + pos--; /* IUP starts at 1 */ + + if (!value) + { + if (pos >= 0 && pos <= count-1) + { + if (pos == 0) + iupdrvListRemoveAllItems(ih); + else + { + int i = pos; + while (i < count) + { + iupdrvListRemoveItem(ih, pos); + i++; + } + } + } + } + else + { + if (pos >= 0 && pos <= count-1) + { + iupdrvListRemoveItem(ih, pos); + iupdrvListInsertItem(ih, pos, value); + } + else if (pos == count) + iupdrvListAppendItem(ih, value); + } + } + return 1; +} + +static int iListSetAppendItemAttrib(Ihandle* ih, const char* value) +{ + if (!ih->handle) /* do not store the action before map */ + return 0; + if (value) + iupdrvListAppendItem(ih, value); + return 0; +} + +static int iListSetInsertItemAttrib(Ihandle* ih, const char* name_id, const char* value) +{ + if (!ih->handle) /* do not store the action before map */ + return 0; + if (value) + { + int pos = iupListGetPos(ih, name_id); + if (pos!=-1) + iupdrvListInsertItem(ih, pos, value); + } + return 0; +} + +static int iListSetRemoveItemAttrib(Ihandle* ih, const char* value) +{ + if (!ih->handle) /* do not store the action before map */ + return 0; + if (!value) + iupdrvListRemoveAllItems(ih); + else + { + int pos = iupListGetPos(ih, value); + if (pos!=-1) + iupdrvListRemoveItem(ih, pos); + } + return 0; +} + +static int iListGetCount(Ihandle* ih) +{ + int count; + if (ih->handle) + count = iupdrvListGetCount(ih); + else + { + char str[20]; + count = 0; + sprintf(str, "%d", count+1); + while (iupAttribGet(ih, str)) + { + count++; + sprintf(str, "%d", count+1); + } + } + return count; +} + +static char* iListGetCountAttrib(Ihandle* ih) +{ + char* str = iupStrGetMemory(50); + sprintf(str, "%d", iListGetCount(ih)); + return str; +} + +static int iListSetDropdownAttrib(Ihandle* ih, const char* value) +{ + /* valid only before map */ + if (ih->handle) + return 0; + + if (iupStrBoolean(value)) + { + ih->data->is_dropdown = 1; + ih->data->is_multiple = 0; + } + else + ih->data->is_dropdown = 0; + + return 0; +} + +static char* iListGetDropdownAttrib(Ihandle* ih) +{ + if (ih->data->is_dropdown) + return "YES"; + else + return "NO"; +} + +static int iListSetMultipleAttrib(Ihandle* ih, const char* value) +{ + /* valid only before map */ + if (ih->handle) + return 0; + + if (iupStrBoolean(value)) + { + ih->data->is_multiple = 1; + ih->data->is_dropdown = 0; + ih->data->has_editbox = 0; + } + else + ih->data->is_multiple = 0; + + return 0; +} + +static char* iListGetMultipleAttrib(Ihandle* ih) +{ + if (ih->data->is_multiple) + return "YES"; + else + return "NO"; +} + +static int iListSetEditboxAttrib(Ihandle* ih, const char* value) +{ + /* valid only before map */ + if (ih->handle) + return 0; + + if (iupStrBoolean(value)) + { + ih->data->has_editbox = 1; + ih->data->is_multiple = 0; + } + else + ih->data->has_editbox = 0; + + return 0; +} + +static char* iListGetEditboxAttrib(Ihandle* ih) +{ + if (ih->data->has_editbox) + return "YES"; + else + return "NO"; +} + +static int iListSetScrollbarAttrib(Ihandle* ih, const char* value) +{ + /* valid only before map */ + if (ih->handle) + return 0; + + else if (iupStrBoolean(value)) + ih->data->sb = 1; + else + ih->data->sb = 0; + + return 0; +} + +static char* iListGetScrollbarAttrib(Ihandle* ih) +{ + if (ih->data->sb) + return "YES"; + else + return "NO"; +} + +static char* iListGetMaskDataAttrib(Ihandle* ih) +{ + if (!ih->data->has_editbox) + return NULL; + + /* Used only by the OLD iupmask API */ + return (char*)ih->data->mask; +} + +static int iListSetMaskAttrib(Ihandle* ih, const char* value) +{ + if (!ih->data->has_editbox) + return 0; + + if (!value) + { + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + } + else + { + int casei = iupAttribGetInt(ih, "MASKCASEI"); + Imask* mask = iupMaskCreate(value,casei); + if (mask) + { + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + + ih->data->mask = mask; + return 1; + } + } + + return 0; +} + +static int iListSetMaskIntAttrib(Ihandle* ih, const char* value) +{ + if (!ih->data->has_editbox) + return 0; + + if (!value) + { + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + + iupAttribSetStr(ih, "MASK", NULL); + } + else + { + Imask* mask; + int min, max; + + if (iupStrToIntInt(value, &min, &max, ':')!=2) + return 0; + + mask = iupMaskCreateInt(min,max); + + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + + ih->data->mask = mask; + + if (min < 0) + iupAttribSetStr(ih, "MASK", IUP_MASK_INT); + else + iupAttribSetStr(ih, "MASK", IUP_MASK_UINT); + } + + return 0; +} + +static int iListSetMaskFloatAttrib(Ihandle* ih, const char* value) +{ + if (!ih->data->has_editbox) + return 0; + + if (!value) + { + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + + iupAttribSetStr(ih, "MASK", NULL); + } + else + { + Imask* mask; + float min, max; + + if (iupStrToFloatFloat(value, &min, &max, ':')!=2) + return 0; + + mask = iupMaskCreateFloat(min,max); + + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); + + ih->data->mask = mask; + + if (min < 0) + iupAttribSetStr(ih, "MASK", IUP_MASK_FLOAT); + else + iupAttribSetStr(ih, "MASK", IUP_MASK_UFLOAT); + } + + return 0; +} + + +/*****************************************************************************************/ + + +static int iListCreateMethod(Ihandle* ih, void** params) +{ + if (params && params[0]) + iupAttribStoreStr(ih, "ACTION", (char*)(params[0])); + + ih->data = iupALLOCCTRLDATA(); + ih->data->sb = 1; + + return IUP_NOERROR; +} + +static void iListGetNaturalItemsSize(Ihandle *ih, int *w, int *h) +{ + char *value; + int visiblecolumns, + count = iListGetCount(ih); + + *w = 0; + *h = 0; + + iupdrvFontGetCharSize(ih, w, h); /* one line height, and one character width */ + + visiblecolumns = iupAttribGetInt(ih, "VISIBLECOLUMNS"); + if (visiblecolumns) + { + *w = iupdrvFontGetStringWidth(ih, "WWWWWWWWWW"); + *w = (visiblecolumns*(*w))/10; + } + else + { + int item_w, i; + char str[20]; + + for (i=1; i<=count; i++) + { + sprintf(str, "%d", i); + value = IupGetAttribute(ih, str); /* must use IupGetAttribute to check the native system */ + if (value) + { + item_w = iupdrvFontGetStringWidth(ih, value); + if (item_w > *w) + *w = item_w; + } + } + + if (*w == 0) /* default is 5 characters in 1 item */ + *w = iupdrvFontGetStringWidth(ih, "WWWWW"); + } + + /* compute height for multiple lines, drodown is just 1 line */ + if (!ih->data->is_dropdown) + { + int visiblelines, num_lines, line_size = *h; + + iupdrvListAddItemSpace(ih, h); /* this independs from spacing */ + + *h += 2*ih->data->spacing; /* this will be multiplied by the number of lines */ + *w += 2*ih->data->spacing; /* include also horizontal spacing */ + + num_lines = count; + if (num_lines == 0) num_lines = 1; + + visiblelines = iupAttribGetInt(ih, "VISIBLELINES"); + if (visiblelines) + num_lines = visiblelines; + + *h = *h * num_lines; + + if (ih->data->has_editbox) + *h += line_size; + } +} + +static void iListComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *expand) +{ + int natural_w, natural_h; + int sb_size = iupdrvGetScrollbarSize(); + (void)expand; /* unset if not a container */ + + iListGetNaturalItemsSize(ih, &natural_w, &natural_h); + + /* compute the borders space */ + iupdrvListAddBorders(ih, &natural_w, &natural_h); + + if (ih->data->is_dropdown) + { + /* add room for dropdown box */ + natural_w += sb_size; + + if (natural_h < sb_size) + natural_h = sb_size; + } + else + { + /* add room for scrollbar */ + if (ih->data->sb) + { + natural_h += sb_size; + natural_w += sb_size; + } + } + + if (ih->data->has_editbox) + { + natural_w += 2*ih->data->horiz_padding; + natural_h += 2*ih->data->vert_padding; + } + + *w = natural_w; + *h = natural_h; +} + +static void iListDestroyMethod(Ihandle* ih) +{ + if (ih->data->mask) + iupMaskDestroy(ih->data->mask); +} + + +/******************************************************************************/ + + +Ihandle* IupList(const char* action) +{ + void *params[2]; + params[0] = (void*)action; + params[1] = NULL; + return IupCreatev("list", params); +} + +Iclass* iupListGetClass(void) +{ + Iclass* ic = iupClassNew(NULL); + + ic->name = "list"; + ic->format = "A"; /* one optional callback name */ + ic->nativetype = IUP_TYPECONTROL; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 1; + ic->has_attrib_id = 1; + + /* Class functions */ + ic->Create = iListCreateMethod; + ic->Destroy = iListDestroyMethod; + ic->ComputeNaturalSize = iListComputeNaturalSizeMethod; + + ic->LayoutUpdate = iupdrvBaseLayoutUpdateMethod; + ic->UnMap = iupdrvBaseUnMapMethod; + + /* Callbacks */ + iupClassRegisterCallback(ic, "ACTION", "sii"); + iupClassRegisterCallback(ic, "MULTISELECT_CB", "s"); + iupClassRegisterCallback(ic, "DROPFILES_CB", "siii"); + iupClassRegisterCallback(ic, "DROPDOWN_CB", "i"); + iupClassRegisterCallback(ic, "DBLCLICK_CB", "is"); + iupClassRegisterCallback(ic, "VALUECHANGED_CB", ""); + + iupClassRegisterCallback(ic, "EDIT_CB", "is"); + iupClassRegisterCallback(ic, "CARET_CB", "iii"); + + /* Common Callbacks */ + iupBaseRegisterCommonCallbacks(ic); + + /* Common */ + iupBaseRegisterCommonAttrib(ic); + + /* Visual */ + iupBaseRegisterVisualAttrib(ic); + + /* IupList only */ + iupClassRegisterAttribute(ic, "SCROLLBAR", iListGetScrollbarAttrib, iListSetScrollbarAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "MULTIPLE", iListGetMultipleAttrib, iListSetMultipleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "DROPDOWN", iListGetDropdownAttrib, iListSetDropdownAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "EDITBOX", iListGetEditboxAttrib, iListSetEditboxAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "COUNT", iListGetCountAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttributeId(ic, "INSERTITEM", NULL, iListSetInsertItemAttrib, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "APPENDITEM", NULL, iListSetAppendItemAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "REMOVEITEM", NULL, iListSetRemoveItemAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "AUTOHIDE", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "MASKCASEI", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "MASK", NULL, iListSetMaskAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "MASKINT", NULL, iListSetMaskIntAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "MASKFLOAT", NULL, iListSetMaskFloatAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "OLD_MASK_DATA", iListGetMaskDataAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "VISIBLECOLUMNS", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "VISIBLELINES", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + iupdrvListInitClass(ic); + + return ic; +} -- cgit v1.2.3