summaryrefslogtreecommitdiff
path: root/iup/src/iup_fill.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/src/iup_fill.c')
-rwxr-xr-xiup/src/iup_fill.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/iup/src/iup_fill.c b/iup/src/iup_fill.c
new file mode 100755
index 0000000..4cad3c0
--- /dev/null
+++ b/iup/src/iup_fill.c
@@ -0,0 +1,242 @@
+/** \file
+ * \brief Fill Control.
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "iup.h"
+#include "iupcbs.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"
+
+
+enum {IUP_FILL_NONE, IUP_FILL_HORIZ, IUP_FILL_VERT};
+
+struct _IcontrolData
+{
+ int dir;
+};
+
+static int iFillGetDir(Ihandle* ih)
+{
+ if (!ih->parent)
+ return IUP_FILL_NONE;
+
+ if (ih->data->dir != IUP_FILL_NONE)
+ return ih->data->dir;
+
+ /* Its parent must be an IupHbox or an IupVbox. */
+ if (ih->parent->iclass->nativetype == IUP_TYPEVOID)
+ {
+ if (iupStrEqual(ih->parent->iclass->name, "hbox"))
+ ih->data->dir = IUP_FILL_HORIZ;
+ else if (iupStrEqual(ih->parent->iclass->name, "vbox"))
+ ih->data->dir = IUP_FILL_VERT;
+ }
+
+ return ih->data->dir;
+}
+
+static int iFillMapMethod(Ihandle* ih)
+{
+ iFillGetDir(ih);
+ return iupBaseTypeVoidMapMethod(ih);
+}
+
+static void iFillUnMapMethod(Ihandle* ih)
+{
+ ih->data->dir = IUP_FILL_NONE;
+}
+
+static int iFillSetRasterSizeAttrib(Ihandle* ih, const char* value)
+{
+ if (!value)
+ {
+ ih->userwidth = 0;
+ ih->userheight = 0;
+ }
+ else
+ {
+ int s = 0;
+ if (iFillGetDir(ih) == IUP_FILL_NONE) /* if Fill is not yet a child of a Vbox or Hbox */
+ {
+ iupAttribSetStr(ih, "SIZE", NULL);
+ return 1;
+ }
+
+ iupStrToInt(value, &s);
+ if (s > 0)
+ {
+ if (iFillGetDir(ih) == IUP_FILL_HORIZ)
+ {
+ ih->userwidth = s; /* inside HBOX */
+ ih->userheight = 0;
+ }
+ else
+ {
+ ih->userheight = s; /* inside VBOX */
+ ih->userwidth = 0;
+ }
+ }
+ }
+ iupAttribSetStr(ih, "SIZE", NULL);
+ return 0;
+}
+
+static int iFillSetSizeAttrib(Ihandle* ih, const char* value)
+{
+ if (!value)
+ {
+ ih->userwidth = 0;
+ ih->userheight = 0;
+ }
+ else
+ {
+ int s = 0;
+ if (iFillGetDir(ih) == IUP_FILL_NONE) /* if Fill is not yet a child of a Vbox or Hbox */
+ {
+ iupAttribSetStr(ih, "RASTERSIZE", NULL);
+ return 1;
+ }
+
+ iupStrToInt(value, &s);
+ if (s > 0)
+ {
+ int charwidth, charheight;
+ iupdrvFontGetCharSize(ih, &charwidth, &charheight);
+ if (iFillGetDir(ih) == IUP_FILL_HORIZ)
+ {
+ ih->userwidth = iupWIDTH2RASTER(s, charwidth); /* inside HBOX */
+ ih->userheight = 0;
+ }
+ else
+ {
+ ih->userheight = iupHEIGHT2RASTER(s, charheight); /* inside VBOX */
+ ih->userwidth = 0;
+ }
+ }
+ }
+ iupAttribSetStr(ih, "RASTERSIZE", NULL);
+ return 1;
+}
+
+static char* iFillGetExpandAttrib(Ihandle* ih)
+{
+ if (iFillGetDir(ih) == IUP_FILL_NONE) /* if Fill is not yet a child of a Vbox or Hbox */
+ return "NO";
+
+ /* if size is not defined, then expansion on that direction is permited */
+ if (iFillGetDir(ih) == IUP_FILL_HORIZ)
+ {
+ if (ih->userwidth <= 0)
+ return "HORIZONTAL";
+ }
+ else
+ {
+ if (ih->userheight <= 0)
+ return "VERTICAL";
+ }
+
+ return "NO";
+}
+
+static void iFillUpdateSize(Ihandle* ih)
+{
+ char* value = iupAttribGet(ih, "SIZE");
+ if (value)
+ {
+ iFillSetSizeAttrib(ih, value);
+ iupAttribSetStr(ih, "SIZE", NULL);
+ }
+ value = iupAttribGet(ih, "RASTERSIZE");
+ if (value)
+ {
+ iFillSetRasterSizeAttrib(ih, value);
+ iupAttribSetStr(ih, "RASTERSIZE", NULL);
+ }
+}
+
+static void iFillComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *expand)
+{
+ (void)expand; /* unset if not a container */
+
+ /* EXPAND is initialized as none for FILL */
+ ih->expand = IUP_EXPAND_NONE;
+
+ iFillUpdateSize(ih);
+
+ /* always initialize the natural size using the user size,
+ must do this again because of iFillUpdateSize */
+ ih->naturalwidth = ih->userwidth;
+ ih->naturalheight = ih->userheight;
+
+ if (iFillGetDir(ih) == IUP_FILL_NONE) /* if Fill is not a child of a Vbox or Hbox */
+ return;
+
+ /* if size is NOT defined, then expansion on that direction is permited */
+ if (iFillGetDir(ih) == IUP_FILL_HORIZ)
+ {
+ if (ih->naturalwidth <= 0)
+ ih->expand = IUP_EXPAND_W0;
+ }
+ else
+ {
+ if (ih->naturalheight <= 0)
+ ih->expand = IUP_EXPAND_H0;
+ }
+
+ *w = ih->naturalwidth;
+ *h = ih->naturalheight;
+}
+
+static int iFillCreateMethod(Ihandle* ih, void** params)
+{
+ (void)params;
+ ih->data = iupALLOCCTRLDATA();
+ return IUP_NOERROR;
+}
+
+/******************************************************************************/
+
+Ihandle* IupFill(void)
+{
+ return IupCreate("fill");
+}
+
+Iclass* iupFillGetClass(void)
+{
+ Iclass* ic = iupClassNew(NULL);
+
+ ic->name = "fill";
+ ic->format = NULL; /* no parameters */
+ ic->nativetype = IUP_TYPEVOID;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 0;
+
+ /* Class functions */
+ ic->Create = iFillCreateMethod;
+ ic->Map = iFillMapMethod;
+ ic->UnMap = iFillUnMapMethod;
+ ic->ComputeNaturalSize = iFillComputeNaturalSizeMethod;
+
+ /* Common */
+ iupBaseRegisterCommonAttrib(ic);
+
+ /* Overwrite Common */
+ iupClassRegisterAttribute(ic, "SIZE", iupBaseGetSizeAttrib, iFillSetSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "RASTERSIZE", iupBaseGetRasterSizeAttrib, iFillSetRasterSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+ /* Base */
+ iupClassRegisterAttribute(ic, "EXPAND", iFillGetExpandAttrib, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+ return ic;
+}