summaryrefslogtreecommitdiff
path: root/iup/src/iup_classattrib.c
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/src/iup_classattrib.c
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/iup_classattrib.c')
-rwxr-xr-xiup/src/iup_classattrib.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/iup/src/iup_classattrib.c b/iup/src/iup_classattrib.c
new file mode 100755
index 0000000..df8f873
--- /dev/null
+++ b/iup/src/iup_classattrib.c
@@ -0,0 +1,508 @@
+/** \file
+ * \brief Ihandle Class Attribute Management
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_str.h"
+#include "iup_attrib.h"
+#include "iup_assert.h"
+#include "iup_register.h"
+#include "iup_globalattrib.h"
+
+
+typedef struct _IattribFunc
+{
+ IattribGetFunc get;
+ IattribSetFunc set;
+ const char* default_value;
+ const char* system_default;
+ int call_global_default;
+ int flags;
+} IattribFunc;
+
+
+static int iClassIsGlobalDefault(const char* name)
+{
+ if (iupStrEqual(name, "DEFAULTFONT"))
+ return 1;
+ if (iupStrEqual(name, "DLGBGCOLOR"))
+ return 1;
+ if (iupStrEqual(name, "DLGFGCOLOR"))
+ return 1;
+ if (iupStrEqual(name, "TXTBGCOLOR"))
+ return 1;
+ if (iupStrEqual(name, "TXTFGCOLOR"))
+ return 1;
+ if (iupStrEqual(name, "MENUBGCOLOR"))
+ return 1;
+ return 0;
+}
+
+static const char* iClassFindId(const char* name)
+{
+ while(*name)
+ {
+ if (*name >= '0' && *name <= '9')
+ return name;
+ if (*name == '*' || *name == ':')
+ return name;
+
+ name++;
+ }
+ return NULL;
+}
+
+static const char* iClassCutNameId(const char* name, const char* name_id)
+{
+ char* str;
+ int len = name_id - name;
+ if (len == 0)
+ return NULL;
+
+ str = iupStrGetMemory(len+1);
+ memcpy(str, name, len);
+ str[len] = 0;
+ return str;
+}
+
+
+static char* iClassGetDefaultValue(IattribFunc* afunc)
+{
+ if (afunc->call_global_default)
+ return IupGetGlobal(afunc->default_value);
+ else
+ return (char*)afunc->default_value;
+}
+
+int iupClassObjectSetAttribute(Ihandle* ih, const char* name, const char * value, int *inherit)
+{
+ IattribFunc* afunc;
+
+ if (ih->iclass->has_attrib_id)
+ {
+ const char* name_id = iClassFindId(name);
+ if (name_id)
+ {
+ IattribFunc* afunc;
+ const char* partial_name = iClassCutNameId(name, name_id);
+ if (!partial_name)
+ partial_name = "IDVALUE"; /* pure numbers are used as attributes in IupList and IupMatrix,
+ translate them into IDVALUE. */
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, partial_name);
+ if (afunc)
+ {
+ *inherit = 0; /* id numbered attributes are NON inheritable always */
+
+ if (afunc->flags & IUPAF_READONLY)
+ {
+ if (afunc->flags & IUPAF_NO_STRING)
+ return -1; /* value is NOT a string, can NOT call iupAttribStoreStr */
+ return 0;
+ }
+
+ if (afunc->set && (ih->handle || afunc->flags & IUPAF_NOT_MAPPED))
+ {
+ /* id numbered attributes have default value NULL always */
+ IattribSetIdFunc id_set = (IattribSetIdFunc)afunc->set;
+ return id_set(ih, name_id, value);
+ }
+
+ if (afunc->flags & IUPAF_NO_STRING)
+ return -1; /* value is NOT a string, can NOT call iupAttribStoreStr */
+
+ return 1; /* if the function exists, then must return here */
+ }
+ }
+ }
+
+ /* if not has_attrib_id, or not found an ID, or not found the partial name, check using the full name */
+
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, name);
+ *inherit = 1; /* default is inheritable */
+ if (afunc)
+ {
+ *inherit = !(afunc->flags & IUPAF_NO_INHERIT) && !(afunc->flags & IUPAF_NO_STRING);
+
+ if (afunc->flags & IUPAF_READONLY)
+ {
+ if (afunc->flags & IUPAF_NO_STRING)
+ return -1; /* value is NOT a string, can NOT call iupAttribStoreStr */
+ return 0;
+ }
+
+ if (afunc->set && (ih->handle || afunc->flags & IUPAF_NOT_MAPPED))
+ {
+ int ret;
+ if (!value)
+ {
+ /* inheritable attributes when reset must check the parent value */
+ if (*inherit && ih->parent)
+ value = iupAttribGetInherit(ih->parent, name);
+
+ if (!value)
+ value = iClassGetDefaultValue(afunc);
+ }
+
+ if (afunc->flags & IUPAF_HAS_ID)
+ {
+ IattribSetIdFunc id_set = (IattribSetIdFunc)afunc->set;
+ return id_set(ih, "", value); /* empty Id */
+ }
+ else
+ ret = afunc->set(ih, value);
+
+ if (ret == 1 && afunc->flags & IUPAF_NO_STRING)
+ return -1; /* value is NOT a string, can NOT call iupAttribStoreStr */
+
+ if (*inherit)
+ return 1; /* inheritable attributes are always stored in the hash table, */
+ else /* to indicate that they are set at the control. */
+ return ret;
+ }
+ }
+
+ return 1;
+}
+
+char* iupClassObjectGetAttribute(Ihandle* ih, const char* name, char* *def_value, int *inherit)
+{
+ IattribFunc* afunc;
+
+ if (ih->iclass->has_attrib_id)
+ {
+ const char* name_id = iClassFindId(name);
+ if (name_id)
+ {
+ IattribFunc* afunc;
+ const char* partial_name = iClassCutNameId(name, name_id);
+ if (!partial_name)
+ partial_name = "IDVALUE"; /* pure numbers are used as attributes in IupList and IupMatrix,
+ translate them into IDVALUE. */
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, partial_name);
+ if (afunc)
+ {
+ *def_value = NULL; /* id numbered attributes have default value NULL always */
+ *inherit = 0; /* id numbered attributes are NON inheritable always */
+
+ if (afunc->flags & IUPAF_WRITEONLY)
+ return NULL;
+
+ if (afunc->get && (ih->handle || afunc->flags & IUPAF_NOT_MAPPED))
+ {
+ IattribGetIdFunc id_get = (IattribGetIdFunc)afunc->get;
+ return id_get(ih, name_id);
+ }
+ else
+ return NULL; /* if the function exists, then must return here */
+ }
+ }
+ }
+
+ /* if not has_attrib_id, or not found an ID, or not found the partial name, check using the full name */
+
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, name);
+ *def_value = NULL;
+ *inherit = 1; /* default is inheritable */
+ if (afunc)
+ {
+ *def_value = iClassGetDefaultValue(afunc);
+ *inherit = !(afunc->flags & IUPAF_NO_INHERIT) && !(afunc->flags & IUPAF_NO_STRING);
+
+ if (afunc->flags & IUPAF_WRITEONLY)
+ return NULL;
+
+ if (afunc->get && (ih->handle || afunc->flags & IUPAF_NOT_MAPPED))
+ {
+ if (afunc->flags & IUPAF_HAS_ID)
+ {
+ IattribGetIdFunc id_get = (IattribGetIdFunc)afunc->get;
+ return id_get(ih, ""); /* empty Id */
+ }
+ else
+ return afunc->get(ih);
+ }
+ }
+ return NULL;
+}
+
+void iupClassObjectGetAttributeInfo(Ihandle* ih, const char* name, char* *def_value, int *inherit)
+{
+ IattribFunc* afunc;
+
+ if (ih->iclass->has_attrib_id)
+ {
+ const char* name_id = iClassFindId(name);
+ if (name_id)
+ {
+ IattribFunc* afunc;
+ const char* partial_name = iClassCutNameId(name, name_id);
+ if (!partial_name)
+ partial_name = "IDVALUE"; /* pure numbers are used as attributes in IupList and IupMatrix,
+ translate them into IDVALUE. */
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, partial_name);
+ if (afunc)
+ {
+ *def_value = NULL; /* id numbered attributes have default value NULL always */
+ *inherit = 0; /* id numbered attributes are NON inheritable always */
+ return; /* if the function exists, then must return here */
+ }
+ }
+ }
+
+ /* if not has_attrib_id, or not found an ID, or not found the partial name, check using the full name */
+
+ afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, name);
+ *def_value = NULL;
+ *inherit = 1; /* default is inheritable */
+ if (afunc)
+ {
+ *def_value = iClassGetDefaultValue(afunc);
+ *inherit = !(afunc->flags & IUPAF_NO_INHERIT) && !(afunc->flags & IUPAF_NO_STRING);
+ }
+}
+
+int iupClassObjectCurAttribIsInherit(Iclass* ic)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGetCurr(ic->attrib_func);
+ if (afunc && !(afunc->flags & IUPAF_NO_INHERIT))
+ return 1;
+ return 0;
+}
+
+int iupClassObjectAttribIsNotString(Ihandle* ih, const char* name)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, name);
+ if (afunc && afunc->flags & IUPAF_NO_STRING)
+ return 1;
+ return 0;
+}
+
+void iupClassRegisterAttribute(Iclass* ic, const char* name,
+ IattribGetFunc _get, IattribSetFunc _set,
+ const char* _default_value, const char* _system_default, int _flags)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ic->attrib_func, name);
+ if (afunc)
+ free(afunc); /* overwrite a previous registration */
+
+ afunc = (IattribFunc*)malloc(sizeof(IattribFunc));
+ afunc->get = _get;
+ afunc->set = _set;
+ if (_default_value == IUPAF_SAMEASSYSTEM)
+ afunc->default_value = _system_default;
+ else
+ afunc->default_value = _default_value;
+ afunc->system_default = _system_default;
+ afunc->flags = _flags;
+
+ if (iClassIsGlobalDefault(afunc->default_value))
+ afunc->call_global_default = 1;
+ else
+ afunc->call_global_default = 0;
+
+ iupTableSet(ic->attrib_func, name, (void*)afunc, IUPTABLE_POINTER);
+}
+
+void iupClassRegisterAttributeId(Iclass* ic, const char* name,
+ IattribGetIdFunc _get, IattribSetIdFunc _set,
+ int _flags)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ic->attrib_func, name);
+ if (afunc)
+ free(afunc); /* overwrite a previous registration */
+
+ afunc = (IattribFunc*)malloc(sizeof(IattribFunc));
+ afunc->get = (IattribGetFunc)_get;
+ afunc->set = (IattribSetFunc)_set;
+ afunc->default_value = NULL;
+ afunc->system_default = NULL;
+ afunc->flags = _flags|IUPAF_HAS_ID|IUPAF_NO_INHERIT|IUPAF_NO_DEFAULTVALUE;
+ afunc->call_global_default = 0;
+
+ iupTableSet(ic->attrib_func, name, (void*)afunc, IUPTABLE_POINTER);
+}
+
+void iupClassRegisterGetAttribute(Iclass* ic, const char* name,
+ IattribGetFunc *_get, IattribSetFunc *_set,
+ const char* *_default_value, const char* *_system_default, int *_flags)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ic->attrib_func, name);
+ if (afunc)
+ {
+ if (_get) *_get = afunc->get;
+ if (_set) *_set = afunc->set;
+ if (_default_value) *_default_value = afunc->default_value;
+ if (_system_default) *_system_default = afunc->system_default;
+ if (_flags) *_flags = afunc->flags;
+ }
+}
+
+void iupClassRegisterCallback(Iclass* ic, const char* name, const char* format)
+{
+ /* Since attributes and callbacks do not conflict
+ we can use the same structure to store the callback format using the default_value. */
+ iupClassRegisterAttribute(ic, name, NULL, NULL, format, NULL, IUPAF_NO_INHERIT);
+}
+
+char* iupClassCallbackGetFormat(Iclass* ic, const char* name)
+{
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ic->attrib_func, name);
+ if (afunc)
+ return (char*)afunc->default_value;
+ return NULL;
+}
+
+int IupGetClassAttributes(const char* classname, char** names, int n)
+{
+ Iclass* ic;
+ int i = 0;
+ char* name;
+
+ iupASSERT(classname!=NULL);
+ if (!classname)
+ return 0;
+
+ ic = iupRegisterFindClass(classname);
+ if (!ic)
+ return -1;
+
+ if (!names || !n)
+ return iupTableCount(ic->attrib_func);
+
+ name = iupTableFirst(ic->attrib_func);
+ while (name)
+ {
+ names[i] = name;
+ i++;
+ if (i == n)
+ break;
+
+ name = iupTableNext(ic->attrib_func);
+ }
+
+ return i;
+}
+
+void IupSetClassDefaultAttribute(const char* classname, const char *name, const char* default_value)
+{
+ Iclass* ic;
+ IattribFunc* afunc;
+
+ iupASSERT(classname!=NULL);
+ if (!classname)
+ return;
+
+ iupASSERT(name!=NULL);
+ if (!name)
+ return;
+
+ ic = iupRegisterFindClass(name);
+ if (!ic)
+ return;
+
+ afunc = (IattribFunc*)iupTableGet(ic->attrib_func, name);
+ if (afunc && (!(afunc->flags & IUPAF_NO_DEFAULTVALUE) || !(afunc->flags & IUPAF_NO_STRING) || !(afunc->flags & IUPAF_HAS_ID)))
+ {
+ if (default_value == IUPAF_SAMEASSYSTEM)
+ afunc->default_value = afunc->system_default;
+ else
+ afunc->default_value = default_value;
+
+ if (iClassIsGlobalDefault(afunc->default_value))
+ afunc->call_global_default = 1;
+ else
+ afunc->call_global_default = 0;
+ }
+ else if (default_value)
+ iupClassRegisterAttribute(ic, name, NULL, NULL, default_value, NULL, IUPAF_DEFAULT);
+}
+
+void IupSaveClassAttributes(Ihandle* ih)
+{
+ Iclass* ic;
+ char *name;
+
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ ic = ih->iclass;
+
+ name = iupTableFirst(ic->attrib_func);
+ while (name)
+ {
+ IattribFunc* afunc = (IattribFunc*)iupTableGet(ih->iclass->attrib_func, name);
+ if (afunc && !(afunc->flags & IUPAF_NO_STRING))
+ {
+ int inherit;
+ char *def_value;
+ char *value = iupClassObjectGetAttribute(ih, name, &def_value, &inherit);
+ if (value && value != iupAttribGet(ih, name))
+ iupAttribStoreStr(ih, name, value);
+ }
+
+ name = iupTableNext(ic->attrib_func);
+ }
+}
+
+void iupClassObjectEnsureDefaultAttributes(Ihandle* ih)
+{
+ Iclass* ic;
+ char *name;
+
+ ic = ih->iclass;
+
+ name = iupTableFirst(ic->attrib_func);
+ while (name)
+ {
+ IattribFunc* afunc = (IattribFunc*)iupTableGetCurr(ic->attrib_func);
+ if (afunc && afunc->set && (afunc->default_value || afunc->system_default) &&
+ (!(afunc->flags & IUPAF_NO_DEFAULTVALUE) || !(afunc->flags & IUPAF_NO_STRING) || !(afunc->flags & IUPAF_HAS_ID)))
+ {
+ if ((!iupStrEqualNoCase(afunc->default_value, afunc->system_default)) ||
+ (afunc->call_global_default && iupGlobalDefaultColorChanged(afunc->default_value)))
+ {
+ if ((!ih->handle && (afunc->flags & IUPAF_NOT_MAPPED)) ||
+ (ih->handle && !(afunc->flags & IUPAF_NOT_MAPPED) && !iupAttribGet(ih, name)))
+ afunc->set(ih, iClassGetDefaultValue(afunc));
+ }
+ }
+
+ name = iupTableNext(ic->attrib_func);
+ }
+}
+
+char* iupClassGetDefaultAttribute(const char* classname, const char *attrib_name)
+{
+ Iclass* ic;
+ IattribFunc* afunc;
+
+ iupASSERT(classname!=NULL);
+ if (!classname)
+ return NULL;
+
+ iupASSERT(attrib_name!=NULL);
+ if (!attrib_name)
+ return NULL;
+
+ ic = iupRegisterFindClass(classname);
+ if (!ic)
+ return NULL;
+
+ afunc = (IattribFunc*)iupTableGet(ic->attrib_func, attrib_name);
+ if (afunc)
+ return (char*)afunc->default_value;
+ else
+ return NULL;
+}