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_hbox.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100755 iup/src/iup_hbox.c (limited to 'iup/src/iup_hbox.c') 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 +#include + +#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; +} -- cgit v1.2.3