summaryrefslogtreecommitdiff
path: root/iup/src/iup_hbox.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_hbox.c
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/iup_hbox.c')
-rwxr-xr-xiup/src/iup_hbox.c309
1 files changed, 309 insertions, 0 deletions
diff --git a/iup/src/iup_hbox.c b/iup/src/iup_hbox.c
new file mode 100755
index 0000000..e790636
--- /dev/null
+++ b/iup/src/iup_hbox.c
@@ -0,0 +1,309 @@
+/** \file
+ * \brief Hbox 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"
+#include "iup_box.h"
+
+
+static int iHboxSetRasterSizeAttrib(Ihandle* ih, const char* value)
+{
+ if (!value)
+ {
+ ih->userwidth = 0;
+ ih->userheight = 0;
+ }
+ else
+ {
+ int s = 0;
+ iupStrToInt(value, &s);
+ if (s > 0)
+ {
+ ih->userheight = 0;
+ ih->userwidth = s;
+ }
+ }
+ iupAttribSetStr(ih, "SIZE", NULL); /* clear SIZE in hash table */
+ return 0;
+}
+
+static int iHboxSetSizeAttrib(Ihandle* ih, const char* value)
+{
+ if (!value)
+ {
+ ih->userwidth = 0;
+ ih->userheight = 0;
+ }
+ else
+ {
+ int s = 0;
+ iupStrToInt(value, &s);
+ if (s > 0)
+ {
+ int charwidth, charheight;
+ iupdrvFontGetCharSize(ih, &charwidth, &charheight);
+ ih->userheight = 0;
+ ih->userwidth = iupWIDTH2RASTER(s, charwidth);
+ }
+ }
+ return 1;
+}
+
+static int iHboxSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+ if (iupStrEqualNoCase(value, "ABOTTOM"))
+ ih->data->alignment = IUP_ALIGN_ABOTTOM;
+ else if (iupStrEqualNoCase(value, "ACENTER"))
+ ih->data->alignment = IUP_ALIGN_ACENTER;
+ else if (iupStrEqualNoCase(value, "ATOP"))
+ ih->data->alignment = IUP_ALIGN_ATOP;
+ return 0;
+}
+
+static char* iHboxGetAlignmentAttrib(Ihandle* ih)
+{
+ static char* align2str[3] = {"ATOP", "ACENTER", "ABOTTOM"};
+ return align2str[ih->data->alignment];
+}
+
+static void iHboxComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *expand)
+{
+ Ihandle* child;
+ int children_naturalwidth, children_naturalheight;
+
+ /* calculate total children natural size */
+ int children_expand = 0;
+ int children_count = 0;
+ int children_natural_totalwidth = 0;
+ int children_natural_maxwidth = 0;
+ int children_natural_maxheight = 0;
+
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ /* update child natural size first */
+ iupBaseComputeNaturalSize(child);
+
+ if (!child->is_floating)
+ {
+ children_expand |= child->expand;
+ children_natural_maxwidth = iupMAX(children_natural_maxwidth, child->naturalwidth);
+ children_natural_maxheight = iupMAX(children_natural_maxheight, child->naturalheight);
+ children_count++;
+ }
+ }
+
+ /* reset to max natural width and/or height if NORMALIZESIZE is defined */
+ if (ih->data->normalize_size)
+ iupNormalizeSizeBoxChild(ih, ih->data->normalize_size, children_natural_maxwidth, children_natural_maxheight);
+
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ if (!child->is_floating)
+ children_natural_totalwidth += child->naturalwidth;
+ }
+
+ /* leave room at the element for the maximum natural size of the children when is_homogeneous */
+ if (ih->data->is_homogeneous)
+ children_natural_totalwidth = children_natural_maxwidth*children_count;
+
+ /* compute the Hbox contents natural size */
+ children_naturalwidth = children_natural_totalwidth + (children_count-1)*ih->data->gap + 2*ih->data->margin_x;
+ children_naturalheight = children_natural_maxheight + 2*ih->data->margin_y;
+
+ /* Store to be used in iHboxCalcEmptyWidth */
+ ih->data->children_naturalsize = children_naturalwidth;
+
+ *expand = children_expand;
+ *w = children_naturalwidth;
+ *h = children_naturalheight;
+}
+
+static int iHboxCalcHomogeneousWidth(Ihandle *ih)
+{
+ Ihandle* child;
+ int homogeneous_width;
+
+ int children_count=0;
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ if (!child->is_floating)
+ children_count++;
+ }
+ if (children_count == 0)
+ return 0;
+
+ /* equal spaces for all elements */
+ homogeneous_width = (ih->currentwidth - (children_count-1)*ih->data->gap - 2*ih->data->margin_x)/children_count;
+ if (homogeneous_width<0) homogeneous_width = 0;
+ return homogeneous_width;
+}
+
+static int iHboxCalcEmptyWidth(Ihandle *ih, int expand)
+{
+ /* This is the space that the child can be expanded. */
+ Ihandle* child;
+ int empty_width;
+
+ int expand_count=0;
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ if (!child->is_floating && child->expand & expand)
+ expand_count++;
+ }
+ if (expand_count == 0)
+ return 0;
+
+ /* equal spaces for all expandable elements */
+ empty_width = (ih->currentwidth - ih->data->children_naturalsize)/expand_count;
+ if (empty_width < 0) empty_width = 0;
+ return empty_width;
+}
+
+static void iHboxSetChildrenCurrentSizeMethod(Ihandle* ih, int shrink)
+{
+ /* update children */
+ Ihandle* child;
+ int empty_w0 = 0, empty_w1 = 0, client_height;
+
+ if (ih->data->expand_children)
+ ih->expand |= ih->data->expand_children;
+
+ if (ih->data->is_homogeneous)
+ ih->data->homogeneous_size = iHboxCalcHomogeneousWidth(ih);
+ else
+ {
+ ih->data->homogeneous_size = 0;
+
+ /* must calculate the space left for each control to grow inside the container */
+ /* W1 means there is an EXPAND enabled inside */
+ if (ih->expand & IUP_EXPAND_W1)
+ empty_w1 = iHboxCalcEmptyWidth(ih, IUP_EXPAND_W1);
+ /* Not W1 and W0 means that EXPAND is not enabled but there are some IupFill inside */
+ else if (ih->expand & IUP_EXPAND_W0)
+ empty_w0 = iHboxCalcEmptyWidth(ih, IUP_EXPAND_W0);
+ }
+
+ client_height = ih->currentheight - 2*ih->data->margin_y;
+ if (client_height<0) client_height=0;
+
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ if (!child->is_floating)
+ {
+ int old_expand = child->expand;
+ if (ih->data->expand_children)
+ child->expand |= ih->data->expand_children;
+
+ if (ih->data->homogeneous_size)
+ iupBaseSetCurrentSize(child, ih->data->homogeneous_size, client_height, shrink);
+ else
+ {
+ int empty = (child->expand & IUP_EXPAND_W1)? empty_w1: ((child->expand & IUP_EXPAND_W0)? empty_w0: 0);
+ iupBaseSetCurrentSize(child, child->naturalwidth+empty, client_height, shrink);
+ }
+
+ if (ih->data->expand_children)
+ child->expand = old_expand;
+ }
+ else
+ {
+ /* update children to their own natural size */
+ iupBaseSetCurrentSize(child, child->naturalwidth, child->naturalheight, shrink);
+ }
+ }
+}
+
+static void iHboxSetChildrenPositionMethod(Ihandle* ih, int x, int y)
+{
+ int dy, client_height;
+ Ihandle* child;
+
+ x += ih->data->margin_x;
+ y += ih->data->margin_y;
+
+ client_height = ih->currentheight - 2*ih->data->margin_y;
+ if (client_height<0) client_height=0;
+
+ for (child = ih->firstchild; child; child = child->brother)
+ {
+ if (!child->is_floating)
+ {
+ if (ih->data->alignment == IUP_ALIGN_ACENTER)
+ dy = (client_height - child->currentheight)/2;
+ else if (ih->data->alignment == IUP_ALIGN_ABOTTOM)
+ dy = client_height - child->currentheight;
+ else /* IUP_ALIGN_ATOP */
+ dy = 0;
+ if (dy<0) dy = 0;
+
+ /* update child */
+ iupBaseSetPosition(child, x, y+dy);
+
+ /* calculate next */
+ if (ih->data->homogeneous_size)
+ x += ih->data->homogeneous_size + ih->data->gap;
+ else
+ x += child->currentwidth + ih->data->gap;
+ }
+ }
+}
+
+
+/******************************************************************************/
+
+
+Ihandle *IupHboxv(Ihandle **children)
+{
+ return IupCreatev("hbox", (void**)children);
+}
+
+Ihandle *IupHbox(Ihandle* child, ...)
+{
+ Ihandle **children;
+ Ihandle *ih;
+
+ va_list arglist;
+ va_start(arglist, child);
+ children = (Ihandle **)iupObjectGetParamList(child, arglist);
+ va_end(arglist);
+
+ ih = IupCreatev("hbox", (void**)children);
+ free(children);
+
+ return ih;
+}
+
+Iclass* iupHboxGetClass(void)
+{
+ Iclass* ic = iupBoxClassBase();
+
+ ic->name = "hbox";
+
+ /* Class functions */
+ ic->ComputeNaturalSize = iHboxComputeNaturalSizeMethod;
+ ic->SetChildrenCurrentSize = iHboxSetChildrenCurrentSizeMethod;
+ ic->SetChildrenPosition = iHboxSetChildrenPositionMethod;
+
+ /* Overwrite Common */
+ iupClassRegisterAttribute(ic, "SIZE", iupBaseGetSizeAttrib, iHboxSetSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "RASTERSIZE", iupBaseGetRasterSizeAttrib, iHboxSetRasterSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+ /* Hbox only */
+ iupClassRegisterAttribute(ic, "ALIGNMENT", iHboxGetAlignmentAttrib, iHboxSetAlignmentAttrib, IUPAF_SAMEASSYSTEM, "ATOP", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+ return ic;
+}