- oui: callbacks for appending new items - oui: more API changespull/1/head
@@ -30,6 +30,10 @@ typedef enum { | |||
ST_RADIO = 2, | |||
// progress slider | |||
ST_SLIDER = 3, | |||
// column | |||
ST_COLUMN = 4, | |||
// row | |||
ST_ROW = 5, | |||
} SubType; | |||
typedef struct { | |||
@@ -66,26 +70,39 @@ void init(NVGcontext *vg) { | |||
// the container the item is in has negative spacing, and the item | |||
// is first or last element in a sequence of 2 or more elements. | |||
int cornerFlags(int item) { | |||
/* | |||
int parent = uiParent(item); | |||
int spacing = uiGetSpacing(parent); | |||
if (spacing >= 0) return BND_CORNER_NONE; | |||
int numkids = uiGetChildCount(parent); | |||
int numid = uiGetChildId(item); | |||
if (numkids < 2) return BND_CORNER_NONE; | |||
UIuvec2 flags = uiGetLayoutFlags(parent); | |||
if (flags.x & UI_LAYOUT_PACK) { | |||
if (!numid) return BND_CORNER_RIGHT; | |||
else if (numid == numkids-1) return BND_CORNER_LEFT; | |||
else return BND_CORNER_ALL; | |||
} else if (flags.y & UI_LAYOUT_PACK) { | |||
if (!numid) return BND_CORNER_DOWN; | |||
else if (numid == numkids-1) return BND_CORNER_TOP; | |||
else return BND_CORNER_ALL; | |||
}*/ | |||
const UIData *head = (const UIData *)uiGetData(parent); | |||
if (head) { | |||
int numid = uiGetChildId(item); | |||
switch(head->subtype) { | |||
case ST_COLUMN: { | |||
if (!numid) return BND_CORNER_DOWN; | |||
else if (numid == numkids-1) return BND_CORNER_TOP; | |||
else return BND_CORNER_ALL; | |||
} break; | |||
case ST_ROW: { | |||
if (!numid) return BND_CORNER_RIGHT; | |||
else if (numid == numkids-1) return BND_CORNER_LEFT; | |||
else return BND_CORNER_ALL; | |||
} break; | |||
default: break; | |||
} | |||
} | |||
return BND_CORNER_NONE; | |||
} | |||
void testrect(NVGcontext *vg, UIrect rect) { | |||
#if 0 | |||
nvgBeginPath(vg); | |||
nvgRect(vg,rect.x+0.5,rect.y+0.5,rect.w-1,rect.h-1); | |||
nvgStrokeColor(vg,nvgRGBf(1,0,0)); | |||
nvgStrokeWidth(vg,1); | |||
nvgStroke(vg); | |||
#endif | |||
} | |||
void drawUI(NVGcontext *vg, int item, int x, int y) { | |||
const UIData *head = (const UIData *)uiGetData(item); | |||
UIrect rect = uiGetRect(item); | |||
@@ -93,7 +110,9 @@ void drawUI(NVGcontext *vg, int item, int x, int y) { | |||
rect.y += y; | |||
if (head) { | |||
switch(head->subtype) { | |||
default: | |||
default: { | |||
testrect(vg,rect); | |||
} break; | |||
case ST_LABEL: { | |||
assert(head); | |||
const UIButtonData *data = (UIButtonData*)head; | |||
@@ -126,11 +145,7 @@ void drawUI(NVGcontext *vg, int item, int x, int y) { | |||
} break; | |||
} | |||
} else { | |||
nvgBeginPath(vg); | |||
nvgRect(vg,rect.x+0.5,rect.y+0.5,rect.w-1,rect.h-1); | |||
nvgStrokeColor(vg,nvgRGBf(1,0,0)); | |||
nvgStrokeWidth(vg,1); | |||
nvgStroke(vg); | |||
testrect(vg,rect); | |||
} | |||
int kid = uiFirstChild(item); | |||
@@ -140,58 +155,92 @@ void drawUI(NVGcontext *vg, int item, int x, int y) { | |||
} | |||
} | |||
int label(int iconid, const char *label) { | |||
int label(int parent, int iconid, const char *label) { | |||
int item = uiItem(); | |||
uiSetSize(item, 0, BND_WIDGET_HEIGHT); | |||
UIButtonData *data = (UIButtonData *)uiAllocData(item, sizeof(UIButtonData)); | |||
data->head.subtype = ST_LABEL; | |||
data->iconid = iconid; | |||
data->label = label; | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
int button(UIhandle handle, int iconid, const char *label, | |||
void demohandler(int item, UIevent event) { | |||
const UIButtonData *data = (const UIButtonData *)uiGetData(item); | |||
printf("clicked: %lld %s\n", uiGetHandle(item), data->label); | |||
} | |||
int button(int parent, UIhandle handle, int iconid, const char *label, | |||
UIhandler handler) { | |||
int item = uiItem(); | |||
// create new ui item | |||
int item = uiItem(); | |||
// set persistent handle for item that is used | |||
// to track activity over time | |||
uiSetHandle(item, handle); | |||
// set size of wiget; horizontal size is dynamic, vertical is fixed | |||
uiSetSize(item, 0, BND_WIDGET_HEIGHT); | |||
// attach event handler e.g. demohandler above | |||
uiSetHandler(item, handler, UI_BUTTON0_HOT_UP); | |||
// store some custom data with the button that we use for styling | |||
UIButtonData *data = (UIButtonData *)uiAllocData(item, sizeof(UIButtonData)); | |||
data->head.subtype = ST_BUTTON; | |||
data->iconid = iconid; | |||
data->label = label; | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
// simple logic for a slider | |||
// starting offset of the currently active slider | |||
static float sliderstart = 0.0; | |||
// event handler for slider (same handler for all sliders) | |||
void sliderhandler(int item, UIevent event) { | |||
// retrieve the custom data we saved with the slider | |||
UISliderData *data = (UISliderData *)uiGetData(item); | |||
switch(event) { | |||
default: break; | |||
case UI_BUTTON0_DOWN: { | |||
// button was pressed for the first time; capture initial | |||
// slider value. | |||
sliderstart = *data->progress; | |||
} break; | |||
case UI_BUTTON0_CAPTURE: { | |||
// called for every frame that the button is pressed. | |||
// get the delta between the click point and the current | |||
// mouse position | |||
UIvec2 pos = uiGetCursorStartDelta(); | |||
// get the items layouted rectangle | |||
UIrect rc = uiGetRect(item); | |||
// calculate our new offset and clamp | |||
float value = sliderstart + ((float)pos.x / (float)rc.w); | |||
value = (value<0)?0:(value>1)?1:value; | |||
// assign the new value | |||
*data->progress = value; | |||
} break; | |||
} | |||
} | |||
int slider(UIhandle handle, const char *label, float *progress) { | |||
int slider(int parent, UIhandle handle, const char *label, float *progress) { | |||
// create new ui item | |||
int item = uiItem(); | |||
// set persistent handle for item that is used | |||
// to track activity over time | |||
uiSetHandle(item, handle); | |||
// set size of wiget; horizontal size is dynamic, vertical is fixed | |||
uiSetSize(item, 0, BND_WIDGET_HEIGHT); | |||
// attach our slider event handler and capture two classes of events | |||
uiSetHandler(item, sliderhandler, | |||
UI_BUTTON0_DOWN | UI_BUTTON0_CAPTURE); | |||
// store some custom data with the button that we use for styling | |||
// and logic, e.g. the pointer to the data we want to alter. | |||
UISliderData *data = (UISliderData *)uiAllocData(item, sizeof(UISliderData)); | |||
data->head.subtype = ST_SLIDER; | |||
data->label = label; | |||
data->progress = progress; | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
@@ -201,7 +250,7 @@ void radiohandler(int item, UIevent event) { | |||
*data->value = uiGetChildId(item); | |||
} | |||
int radio(UIhandle handle, int iconid, const char *label, int *value) { | |||
int radio(int parent, UIhandle handle, int iconid, const char *label, int *value) { | |||
int item = uiItem(); | |||
uiSetHandle(item, handle); | |||
uiSetSize(item, label?0:BND_TOOL_WIDTH, BND_WIDGET_HEIGHT); | |||
@@ -211,30 +260,82 @@ int radio(UIhandle handle, int iconid, const char *label, int *value) { | |||
data->label = label; | |||
data->value = value; | |||
uiSetHandler(item, radiohandler, UI_BUTTON0_DOWN); | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
int addVList(int parent, int item) { | |||
int last = uiLastChild(parent); | |||
uiSetRelativeTo(item, -1, last, -1, -1); | |||
void columnhandler(int parent, UIevent event) { | |||
int item = uiLastChild(parent); | |||
int last = uiPrevSibling(item); | |||
// mark the new item as positioned under the previous item | |||
uiSetRelToTop(item, last); | |||
// fill parent horizontally, anchor to previous item vertically | |||
uiSetLayout(item, UI_HFILL|UI_TOP); | |||
uiSetParent(item, parent); | |||
// if not the first item, add a margin of 1 | |||
uiSetMargins(item, 0, (last < 0)?0:1, 0, 0); | |||
} | |||
int column(int parent) { | |||
int item = uiItem(); | |||
uiSetHandler(item, columnhandler, UI_APPEND); | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
void vgrouphandler(int parent, UIevent event) { | |||
int item = uiLastChild(parent); | |||
int last = uiPrevSibling(item); | |||
// mark the new item as positioned under the previous item | |||
uiSetRelToTop(item, last); | |||
// fill parent horizontally, anchor to previous item vertically | |||
uiSetLayout(item, UI_HFILL|UI_TOP); | |||
// if not the first item, add a margin | |||
uiSetMargins(item, 0, (last < 0)?0:-2, 0, 0); | |||
} | |||
int vgroup(int parent) { | |||
int item = uiItem(); | |||
UIData *data = (UIData *)uiAllocData(item, sizeof(UIData)); | |||
data->subtype = ST_COLUMN; | |||
uiSetHandler(item, vgrouphandler, UI_APPEND); | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
int addHGroup(int parent, int item) { | |||
int last = uiLastChild(parent); | |||
uiSetRelativeTo(item, last, -1, -1, -1); | |||
uiSetLayout(item, UI_LEFT); | |||
uiSetParent(item, parent); | |||
void hgrouphandler(int parent, UIevent event) { | |||
int item = uiLastChild(parent); | |||
int last = uiPrevSibling(item); | |||
uiSetRelToLeft(item, last); | |||
if (last > 0) | |||
uiSetRelToRight(last, item); | |||
uiSetLayout(item, UI_LEFT|UI_RIGHT); | |||
uiSetMargins(item, (last < 0)?0:-1, 0, 0, 0); | |||
} | |||
int hgroup(int parent) { | |||
int item = uiItem(); | |||
UIData *data = (UIData *)uiAllocData(item, sizeof(UIData)); | |||
data->subtype = ST_ROW; | |||
uiSetHandler(item, hgrouphandler, UI_APPEND); | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
void demohandler(int item, UIevent event) { | |||
const UIButtonData *data = (const UIButtonData *)uiGetData(item); | |||
printf("clicked: %lld %s\n", uiGetHandle(item), data->label); | |||
void rowhandler(int parent, UIevent event) { | |||
int item = uiLastChild(parent); | |||
int last = uiPrevSibling(item); | |||
uiSetRelToLeft(item, last); | |||
if (last > 0) | |||
uiSetRelToRight(last, item); | |||
uiSetLayout(item, UI_LEFT|UI_RIGHT); | |||
uiSetMargins(item, (last < 0)?0:8, 0, 0, 0); | |||
} | |||
int row(int parent) { | |||
int item = uiItem(); | |||
uiSetHandler(item, rowhandler, UI_APPEND); | |||
uiAppend(parent, item); | |||
return item; | |||
} | |||
void draw(NVGcontext *vg, float w, float h) { | |||
@@ -427,31 +528,28 @@ void draw(NVGcontext *vg, float w, float h) { | |||
uiClear(); | |||
int root = uiItem(); | |||
// position root element | |||
uiSetLayout(0,UI_LEFT|UI_TOP); | |||
uiSetMargins(0,600,10,0,0); | |||
uiSetSize(0,250,400); | |||
int c = button(1, BND_ICONID(6,3), "Item 1", demohandler); | |||
uiSetParent(c, 0); | |||
uiSetSize(c, 100, 100); | |||
uiSetLayout(c, UI_CENTER); | |||
int col = column(0); | |||
uiSetLayout(col, UI_TOP|UI_HFILL); | |||
addVList(0, button(1, BND_ICONID(6,3), "Item 1", demohandler)); | |||
addVList(0, button(2, BND_ICONID(6,3), "Item 2", demohandler)); | |||
button(col, 1, BND_ICONID(6,3), "Item 1", demohandler); | |||
button(col, 2, BND_ICONID(6,3), "Item 2", demohandler); | |||
static int enum1 = 0; | |||
{ | |||
int h = addVList(0, uiItem()); | |||
addHGroup(h, radio(3, BND_ICONID(6,3), "Item 3.0", &enum1)); | |||
addHGroup(h, radio(4, BND_ICONID(0,10), NULL, &enum1)); | |||
addHGroup(h, radio(5, BND_ICONID(1,10), NULL, &enum1)); | |||
addHGroup(h, radio(6, BND_ICONID(6,3), "Item 3.3", &enum1)); | |||
int h = hgroup(col); | |||
radio(h, 3, BND_ICONID(6,3), "Item 3.0", &enum1); | |||
radio(h, 4, BND_ICONID(0,10), NULL, &enum1); | |||
radio(h, 5, BND_ICONID(1,10), NULL, &enum1); | |||
radio(h, 6, BND_ICONID(6,3), "Item 3.3", &enum1); | |||
} | |||
/* | |||
static float progress1 = 0.25f; | |||
static float progress2 = 0.75f; | |||
@@ -470,7 +568,6 @@ void draw(NVGcontext *vg, float w, float h) { | |||
} | |||
button(col, 11, BND_ICONID(6,3), "Item 5", NULL); | |||
*/ | |||
uiProcess(); | |||
@@ -93,6 +93,8 @@ typedef enum UIevent { | |||
UI_BUTTON0_HOT_UP = 0x04, | |||
// item is being captured (button 0 constantly pressed) | |||
UI_BUTTON0_CAPTURE = 0x08, | |||
// item has been added to container | |||
UI_APPEND = 0x10, | |||
} UIevent; | |||
// handler callback; event is one of UI_EVENT_* | |||
@@ -164,10 +166,9 @@ void uiClear(); | |||
int uiItem(); | |||
// assign an item to a container. | |||
// parent is the item ID of the containing item; an item ID of 0 refers to the | |||
// root item. | |||
// if item is already assigned to a parent, an assertion will be thrown. | |||
void uiSetParent(int item, int parent); | |||
// an item ID of 0 refers to the root item. | |||
// if child is already assigned to a parent, an assertion will be thrown. | |||
int uiAppend(int item, int child); | |||
// layout all added items and update the internal state according to the | |||
// current cursor position and button states. | |||
@@ -203,11 +204,29 @@ int uiGetChildId(int item); | |||
// returns an items next sibling in the list of the parent containers children. | |||
// if item is 0 or the item is the last child item, -1 will be returned. | |||
int uiNextSibling(int item); | |||
// returns an items previous sibling in the list of the parent containers | |||
// children. | |||
// if item is 0 or the item is the first child item, -1 will be returned. | |||
int uiPrevSibling(int item); | |||
void uiSetSize(int item, int w, int h); | |||
int uiGetWidth(int item); | |||
int uiGetHeight(int item); | |||
void uiSetLayout(int item, int flags); | |||
int uiGetLayout(int item); | |||
void uiSetMargins(int item, int t, int r, int b, int l); | |||
void uiSetRelativeTo(int item, int titem, int ritem, int bitem, int litem); | |||
int uiGetMarginLeft(int item); | |||
int uiGetMarginTop(int item); | |||
int uiGetMarginRight(int item); | |||
int uiGetMarginDown(int item); | |||
void uiSetRelToLeft(int item, int other); | |||
int uiGetRelToLeft(int item); | |||
void uiSetRelToTop(int item, int other); | |||
int uiGetRelToTop(int item); | |||
void uiSetRelToRight(int item, int other); | |||
int uiGetRelToRight(int item); | |||
void uiSetRelToDown(int item, int other); | |||
int uiGetRelToDown(int item); | |||
// returns the items layout rectangle relative to the parent. If uiGetRect() | |||
// is called before uiProcess(), the values of the returned rectangle are | |||
@@ -293,6 +312,8 @@ typedef struct UIitem { | |||
int kidid; | |||
// index of next sibling with same parent | |||
int nextitem; | |||
// index of previous sibling with same parent | |||
int previtem; | |||
// one or multiple of UIlayoutFlags | |||
int layout_flags; | |||
@@ -303,6 +324,9 @@ typedef struct UIitem { | |||
int margins[4]; | |||
// neighbors to position borders to | |||
int relto[4]; | |||
// computed size | |||
UIvec2 computed_size; | |||
// relative rect | |||
UIrect rect; | |||
@@ -439,20 +463,10 @@ UIitem *uiItemPtr(int item) { | |||
void uiClear() { | |||
assert(ui_context); | |||
ui_context->count = 1; | |||
ui_context->count = 0; | |||
ui_context->datasize = 0; | |||
ui_context->hot_item = -1; | |||
ui_context->active_item = -1; | |||
// init root object | |||
UIitem *item = ui_context->items; | |||
memset(item, 0, sizeof(UIitem)); | |||
item->parent = -1; | |||
item->firstkid = -1; | |||
item->lastkid = -1; | |||
item->nextitem = -1; | |||
item->data = -1; | |||
} | |||
int uiItem() { | |||
@@ -464,26 +478,37 @@ int uiItem() { | |||
item->firstkid = -1; | |||
item->lastkid = -1; | |||
item->nextitem = -1; | |||
item->previtem = -1; | |||
item->data = -1; | |||
for (int i = 0; i < 4; ++i) | |||
item->relto[i] = -1; | |||
return idx; | |||
} | |||
void uiSetParent(int item, int parent) { | |||
assert(item > 0); | |||
assert(uiParent(item) == -1); | |||
void uiNotifyItem(int item, UIevent event) { | |||
UIitem *pitem = uiItemPtr(item); | |||
UIitem *pparent = uiItemPtr(parent); | |||
pitem->parent = parent; | |||
if (pitem->handler && (pitem->event_flags & event)) { | |||
pitem->handler(item, event); | |||
} | |||
} | |||
int uiAppend(int item, int child) { | |||
assert(child > 0); | |||
assert(uiParent(child) == -1); | |||
UIitem *pitem = uiItemPtr(child); | |||
UIitem *pparent = uiItemPtr(item); | |||
pitem->parent = item; | |||
pitem->kidid = pparent->numkids++; | |||
if (pparent->lastkid < 0) { | |||
pparent->firstkid = item; | |||
pparent->lastkid = item; | |||
pparent->firstkid = child; | |||
pparent->lastkid = child; | |||
} else { | |||
uiItemPtr(pparent->lastkid)->nextitem = item; | |||
pparent->lastkid = item; | |||
pitem->previtem = pparent->lastkid; | |||
uiItemPtr(pparent->lastkid)->nextitem = child; | |||
pparent->lastkid = child; | |||
} | |||
uiNotifyItem(item, UI_APPEND); | |||
return child; | |||
} | |||
void uiSetSize(int item, int w, int h) { | |||
@@ -492,9 +517,20 @@ void uiSetSize(int item, int w, int h) { | |||
pitem->size.y = h; | |||
} | |||
int uiGetWidth(int item) { | |||
return uiItemPtr(item)->size.x; | |||
} | |||
int uiGetHeight(int item) { | |||
return uiItemPtr(item)->size.y; | |||
} | |||
void uiSetLayout(int item, int flags) { | |||
UIitem *pitem = uiItemPtr(item); | |||
pitem->layout_flags = flags; | |||
uiItemPtr(item)->layout_flags = flags; | |||
} | |||
int uiGetLayout(int item) { | |||
return uiItemPtr(item)->layout_flags; | |||
} | |||
void uiSetMargins(int item, int l, int t, int r, int b) { | |||
@@ -505,14 +541,54 @@ void uiSetMargins(int item, int l, int t, int r, int b) { | |||
pitem->margins[3] = b; | |||
} | |||
void uiSetRelativeTo(int item, int litem, int titem, int ritem, int bitem) { | |||
UIitem *pitem = uiItemPtr(item); | |||
pitem->relto[0] = litem; | |||
pitem->relto[1] = titem; | |||
pitem->relto[2] = ritem; | |||
pitem->relto[3] = bitem; | |||
int uiGetMarginLeft(int item) { | |||
return uiItemPtr(item)->margins[0]; | |||
} | |||
int uiGetMarginTop(int item) { | |||
return uiItemPtr(item)->margins[1]; | |||
} | |||
int uiGetMarginRight(int item) { | |||
return uiItemPtr(item)->margins[2]; | |||
} | |||
int uiGetMarginDown(int item) { | |||
return uiItemPtr(item)->margins[3]; | |||
} | |||
void uiSetRelToLeft(int item, int other) { | |||
assert((other < 0) || (uiParent(other) == uiParent(item))); | |||
uiItemPtr(item)->relto[0] = other; | |||
} | |||
int uiGetRelToLeft(int item) { | |||
return uiItemPtr(item)->relto[0]; | |||
} | |||
void uiSetRelToTop(int item, int other) { | |||
assert((other < 0) || (uiParent(other) == uiParent(item))); | |||
uiItemPtr(item)->relto[1] = other; | |||
} | |||
int uiGetRelToTop(int item) { | |||
return uiItemPtr(item)->relto[1]; | |||
} | |||
void uiSetRelToRight(int item, int other) { | |||
assert((other < 0) || (uiParent(other) == uiParent(item))); | |||
uiItemPtr(item)->relto[2] = other; | |||
} | |||
int uiGetRelToRight(int item) { | |||
return uiItemPtr(item)->relto[2]; | |||
} | |||
void uiSetRelToDown(int item, int other) { | |||
assert((other < 0) || (uiParent(other) == uiParent(item))); | |||
uiItemPtr(item)->relto[3] = other; | |||
} | |||
int uiGetRelToDown(int item) { | |||
return uiItemPtr(item)->relto[3]; | |||
} | |||
UI_INLINE int uiComputeChainSize(UIitem *pkid, int dim) { | |||
UIitem *pitem = pkid; | |||
int wdim = dim+2; | |||
@@ -560,6 +636,7 @@ UI_INLINE void uiComputeSizeDim(UIitem *pitem, int dim) { | |||
} | |||
pitem->rect.v[wdim] = size; | |||
pitem->computed_size.v[dim] = size; | |||
} | |||
} | |||
@@ -577,28 +654,35 @@ static void uiComputeBestSize(int item) { | |||
uiComputeSizeDim(pitem, 1); | |||
} | |||
static void uiLayoutChildItem(UIitem *pparent, UIitem *pitem, int dim) { | |||
static void uiLayoutChildItem(UIitem *pparent, UIitem *pitem, int *dyncount, int dim) { | |||
if (pitem->visited & (4<<dim)) return; | |||
pitem->visited |= (4<<dim); | |||
if (!pitem->size.v[dim]) { | |||
*dyncount = (*dyncount)+1; | |||
} | |||
int wdim = dim+2; | |||
int wl = 0; | |||
int wr = pparent->rect.v[wdim]; | |||
int flags = pitem->layout_flags>>dim; | |||
if ((flags & UI_LEFT) && (pitem->relto[dim] > 0)) { | |||
int hasl = (flags & UI_LEFT) && (pitem->relto[dim] > 0); | |||
int hasr = (flags & UI_RIGHT) && (pitem->relto[wdim] > 0); | |||
if (hasl) { | |||
UIitem *pl = uiItemPtr(pitem->relto[dim]); | |||
uiLayoutChildItem(pparent, pl, dim); | |||
wl = pl->rect.v[dim]+pl->rect.v[wdim]; | |||
uiLayoutChildItem(pparent, pl, dyncount, dim); | |||
wl = pl->rect.v[dim]+pl->rect.v[wdim]+pl->margins[wdim]; | |||
wr -= wl; | |||
} | |||
if ((flags & UI_RIGHT) && (pitem->relto[wdim] > 0)) { | |||
if (hasr) { | |||
UIitem *pl = uiItemPtr(pitem->relto[wdim]); | |||
uiLayoutChildItem(pparent, pl, dim); | |||
wr = pl->rect.v[dim]-wl; | |||
uiLayoutChildItem(pparent, pl, dyncount, dim); | |||
wr = pl->rect.v[dim]-pl->margins[dim]-wl; | |||
} | |||
switch(flags & UI_HFILL) { | |||
default: | |||
case UI_HCENTER: { | |||
@@ -611,8 +695,28 @@ static void uiLayoutChildItem(UIitem *pparent, UIitem *pitem, int dim) { | |||
pitem->rect.v[dim] = wl+wr-pitem->rect.v[wdim]-pitem->margins[wdim]; | |||
} break; | |||
case UI_HFILL: { | |||
pitem->rect.v[dim] = wl+pitem->margins[dim]; | |||
pitem->rect.v[wdim] = wr-pitem->margins[dim]-pitem->margins[wdim]; | |||
if (pitem->size.v[dim]) { // hard maximum size; can't stretch | |||
if (hasl) | |||
pitem->rect.v[dim] = wl+wr-pitem->rect.v[wdim]-pitem->margins[wdim]; | |||
else | |||
pitem->rect.v[dim] = wl+pitem->margins[dim]; | |||
} else { | |||
if (1) { //!pitem->rect.v[wdim]) { | |||
int width = (pparent->rect.v[wdim] - pparent->computed_size.v[dim]); | |||
int space = width / (*dyncount); | |||
//int rest = width - space*(*dyncount); | |||
if (!hasl) { | |||
pitem->rect.v[dim] = wl+pitem->margins[dim]; | |||
pitem->rect.v[wdim] = wr-pitem->margins[dim]-pitem->margins[wdim]; | |||
} else { | |||
pitem->rect.v[wdim] = space-pitem->margins[dim]-pitem->margins[wdim]; | |||
pitem->rect.v[dim] = wl+wr-pitem->rect.v[wdim]-pitem->margins[wdim]; | |||
} | |||
} else { | |||
pitem->rect.v[dim] = wl+pitem->margins[dim]; | |||
pitem->rect.v[wdim] = wr-pitem->margins[dim]-pitem->margins[wdim]; | |||
} | |||
} | |||
} break; | |||
} | |||
} | |||
@@ -621,7 +725,8 @@ UI_INLINE void uiLayoutItemDim(UIitem *pitem, int dim) { | |||
int kid = pitem->firstkid; | |||
while (kid > 0) { | |||
UIitem *pkid = uiItemPtr(kid); | |||
uiLayoutChildItem(pitem, pkid, dim); | |||
int dyncount = 0; | |||
uiLayoutChildItem(pitem, pkid, &dyncount, dim); | |||
kid = uiNextSibling(kid); | |||
} | |||
} | |||
@@ -655,6 +760,10 @@ int uiNextSibling(int item) { | |||
return uiItemPtr(item)->nextitem; | |||
} | |||
int uiPrevSibling(int item) { | |||
return uiItemPtr(item)->previtem; | |||
} | |||
int uiParent(int item) { | |||
return uiItemPtr(item)->parent; | |||
} | |||
@@ -730,14 +839,8 @@ int uiFindItem(int item, int x, int y) { | |||
return -1; | |||
} | |||
void uiNotifyItem(int item, UIevent event) { | |||
UIitem *pitem = uiItemPtr(item); | |||
if (pitem->handler && (pitem->event_flags & event)) { | |||
pitem->handler(item, event); | |||
} | |||
} | |||
void uiProcess() { | |||
if (!ui_context->count) return; | |||
uiComputeBestSize(0); | |||
// position root element rect | |||
uiItemPtr(0)->rect.x = uiItemPtr(0)->margins[0]; | |||