Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_layout.c
| Show First 20 Lines • Show All 447 Lines • ▼ Show 20 Lines | static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, bool align) | ||||
| sub->space = 0; | sub->space = 0; | ||||
| return sub; | return sub; | ||||
| } | } | ||||
| static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) | static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| uiBut *but = arg_but, *cbut; | uiBut *but = arg_but; | ||||
| PointerRNA *ptr = &but->rnapoin; | PointerRNA *ptr = &but->rnapoin; | ||||
| PropertyRNA *prop = but->rnaprop; | PropertyRNA *prop = but->rnaprop; | ||||
| int i, index = POINTER_AS_INT(arg_index); | int i, index = POINTER_AS_INT(arg_index); | ||||
| int shift = win->eventstate->shift; | int shift = win->eventstate->shift; | ||||
| int len = RNA_property_array_length(ptr, prop); | int len = RNA_property_array_length(ptr, prop); | ||||
| if (!shift) { | if (!shift) { | ||||
| RNA_property_boolean_set_index(ptr, prop, index, true); | RNA_property_boolean_set_index(ptr, prop, index, true); | ||||
| for (i = 0; i < len; i++) { | for (i = 0; i < len; i++) { | ||||
| if (i != index) { | if (i != index) { | ||||
| RNA_property_boolean_set_index(ptr, prop, i, 0); | RNA_property_boolean_set_index(ptr, prop, i, 0); | ||||
| } | } | ||||
| } | } | ||||
| RNA_property_update(C, ptr, prop); | RNA_property_update(C, ptr, prop); | ||||
| for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) { | LISTBASE_FOREACH (uiBut *, cbut, &but->block->buttons) { | ||||
| ui_but_update(cbut); | ui_but_update(cbut); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* create buttons for an item with an RNA array */ | /* create buttons for an item with an RNA array */ | ||||
| static void ui_item_array(uiLayout *layout, | static void ui_item_array(uiLayout *layout, | ||||
| uiBlock *block, | uiBlock *block, | ||||
| ▲ Show 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | |||||
| void UI_context_active_but_prop_get_filebrowser(const bContext *C, | void UI_context_active_but_prop_get_filebrowser(const bContext *C, | ||||
| PointerRNA *r_ptr, | PointerRNA *r_ptr, | ||||
| PropertyRNA **r_prop, | PropertyRNA **r_prop, | ||||
| bool *r_is_undo, | bool *r_is_undo, | ||||
| bool *r_is_userdef) | bool *r_is_userdef) | ||||
| { | { | ||||
| ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); | ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); | ||||
| uiBlock *block; | uiBut *prevbut = NULL; | ||||
| uiBut *but, *prevbut = NULL; | |||||
| memset(r_ptr, 0, sizeof(*r_ptr)); | memset(r_ptr, 0, sizeof(*r_ptr)); | ||||
| *r_prop = NULL; | *r_prop = NULL; | ||||
| *r_is_undo = false; | *r_is_undo = false; | ||||
| *r_is_userdef = false; | *r_is_userdef = false; | ||||
| if (!region) { | if (!region) { | ||||
| return; | return; | ||||
| } | } | ||||
| for (block = region->uiblocks.first; block; block = block->next) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| for (but = block->buttons.first; but; but = but->next) { | LISTBASE_FOREACH (uiBut *, but, &block->buttons) { | ||||
| if (but && but->rnapoin.data) { | if (but && but->rnapoin.data) { | ||||
| if (RNA_property_type(but->rnaprop) == PROP_STRING) { | if (RNA_property_type(but->rnaprop) == PROP_STRING) { | ||||
| prevbut = but; | prevbut = but; | ||||
| } | } | ||||
| } | } | ||||
| /* find the button before the active one */ | /* find the button before the active one */ | ||||
| if ((but->flag & UI_BUT_LAST_ACTIVE) && prevbut) { | if ((but->flag & UI_BUT_LAST_ACTIVE) && prevbut) { | ||||
| ▲ Show 20 Lines • Show All 2,413 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Layout Items | /** \name Layout Items | ||||
| * \{ */ | * \{ */ | ||||
| /* single-row layout */ | /* single-row layout */ | ||||
| static void ui_litem_estimate_row(uiLayout *litem) | static void ui_litem_estimate_row(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemw, itemh; | int itemw, itemh; | ||||
| bool min_size_flag = true; | bool min_size_flag = true; | ||||
| litem->w = 0; | litem->w = 0; | ||||
| litem->h = 0; | litem->h = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); | min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); | ||||
| litem->w += itemw; | litem->w += itemw; | ||||
| litem->h = MAX2(itemh, litem->h); | litem->h = MAX2(itemh, litem->h); | ||||
| if (item->next) { | if (item->next) { | ||||
| litem->w += litem->space; | litem->w += litem->space; | ||||
| } | } | ||||
| } | } | ||||
| if (min_size_flag) { | if (min_size_flag) { | ||||
| litem->item.flag |= UI_ITEM_FIXED_SIZE; | litem->item.flag |= UI_ITEM_FIXED_SIZE; | ||||
| } | } | ||||
| } | } | ||||
| static int ui_litem_min_width(int itemw) | static int ui_litem_min_width(int itemw) | ||||
| { | { | ||||
| return MIN2(2 * UI_UNIT_X, itemw); | return MIN2(2 * UI_UNIT_X, itemw); | ||||
| } | } | ||||
| static void ui_litem_layout_row(uiLayout *litem) | static void ui_litem_layout_row(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item, *last_free_item = NULL; | uiItem *last_free_item = NULL; | ||||
| int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; | int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; | ||||
| int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; | int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; | ||||
| float extra_pixel; | float extra_pixel; | ||||
| /* x = litem->x; */ /* UNUSED */ | /* x = litem->x; */ /* UNUSED */ | ||||
| y = litem->y; | y = litem->y; | ||||
| w = litem->w; | w = litem->w; | ||||
| totw = 0; | totw = 0; | ||||
| tot = 0; | tot = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| totw += itemw; | totw += itemw; | ||||
| tot++; | tot++; | ||||
| } | } | ||||
| if (totw == 0) { | if (totw == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (w != 0) { | if (w != 0) { | ||||
| w -= (tot - 1) * litem->space; | w -= (tot - 1) * litem->space; | ||||
| } | } | ||||
| fixedw = 0; | fixedw = 0; | ||||
| /* keep clamping items to fixed minimum size until all are done */ | /* keep clamping items to fixed minimum size until all are done */ | ||||
| do { | do { | ||||
| freew = 0; | freew = 0; | ||||
| x = 0; | x = 0; | ||||
| flag = 0; | flag = 0; | ||||
| newtotw = totw; | newtotw = totw; | ||||
| extra_pixel = 0.0f; | extra_pixel = 0.0f; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| minw = ui_litem_min_width(itemw); | minw = ui_litem_min_width(itemw); | ||||
| if (w - lastw > 0) { | if (w - lastw > 0) { | ||||
| Show All 35 Lines | do { | ||||
| lastw = fixedw; | lastw = fixedw; | ||||
| } while (flag); | } while (flag); | ||||
| freex = 0; | freex = 0; | ||||
| fixedx = 0; | fixedx = 0; | ||||
| extra_pixel = 0.0f; | extra_pixel = 0.0f; | ||||
| x = litem->x; | x = litem->x; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| minw = ui_litem_min_width(itemw); | minw = ui_litem_min_width(itemw); | ||||
| if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | ||||
| /* fixed minimum size items */ | /* fixed minimum size items */ | ||||
| if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_FIXED_SIZE) { | if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_FIXED_SIZE) { | ||||
| minw = itemw; | minw = itemw; | ||||
| } | } | ||||
| Show All 32 Lines | static void ui_litem_layout_row(uiLayout *litem) | ||||
| } | } | ||||
| /* add extra pixel */ | /* add extra pixel */ | ||||
| uiItem *last_item = litem->items.last; | uiItem *last_item = litem->items.last; | ||||
| extra_pixel = litem->w - (x - litem->x); | extra_pixel = litem->w - (x - litem->x); | ||||
| if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item && | if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item && | ||||
| last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) { | ||||
| ui_item_move(last_free_item, 0, extra_pixel); | ui_item_move(last_free_item, 0, extra_pixel); | ||||
| for (item = last_free_item->next; item; item = item->next) { | for (uiItem *item = last_free_item->next; item; item = item->next) { | ||||
| ui_item_move(item, extra_pixel, extra_pixel); | ui_item_move(item, extra_pixel, extra_pixel); | ||||
| } | } | ||||
| } | } | ||||
| litem->w = x - litem->x; | litem->w = x - litem->x; | ||||
| litem->h = litem->y - y; | litem->h = litem->y - y; | ||||
| litem->x = x; | litem->x = x; | ||||
| litem->y = y; | litem->y = y; | ||||
| } | } | ||||
| /* single-column layout */ | /* single-column layout */ | ||||
| static void ui_litem_estimate_column(uiLayout *litem, bool is_box) | static void ui_litem_estimate_column(uiLayout *litem, bool is_box) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemw, itemh; | int itemw, itemh; | ||||
| bool min_size_flag = true; | bool min_size_flag = true; | ||||
| litem->w = 0; | litem->w = 0; | ||||
| litem->h = 0; | litem->h = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); | min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); | ||||
| litem->w = MAX2(litem->w, itemw); | litem->w = MAX2(litem->w, itemw); | ||||
| litem->h += itemh; | litem->h += itemh; | ||||
| if (item->next && (!is_box || item != litem->items.first)) { | if (item->next && (!is_box || item != litem->items.first)) { | ||||
| litem->h += litem->space; | litem->h += litem->space; | ||||
| } | } | ||||
| } | } | ||||
| if (min_size_flag) { | if (min_size_flag) { | ||||
| litem->item.flag |= UI_ITEM_FIXED_SIZE; | litem->item.flag |= UI_ITEM_FIXED_SIZE; | ||||
| } | } | ||||
| } | } | ||||
| static void ui_litem_layout_column(uiLayout *litem, bool is_box) | static void ui_litem_layout_column(uiLayout *litem, bool is_box) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemh, x, y; | int itemh, x, y; | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y; | y = litem->y; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, NULL, &itemh); | ui_item_size(item, NULL, &itemh); | ||||
| y -= itemh; | y -= itemh; | ||||
| ui_item_position(item, x, y, litem->w, itemh); | ui_item_position(item, x, y, litem->w, itemh); | ||||
| if (item->next && (!is_box || item != litem->items.first)) { | if (item->next && (!is_box || item != litem->items.first)) { | ||||
| y -= litem->space; | y -= litem->space; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (ELEM(bitem->but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void ui_litem_layout_radial(uiLayout *litem) | static void ui_litem_layout_radial(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemh, itemw, x, y; | int itemh, itemw, x, y; | ||||
| int itemnum = 0; | int itemnum = 0; | ||||
| int totitems = 0; | int totitems = 0; | ||||
| /* For the radial layout we will use Matt Ebb's design | /* For the radial layout we will use Matt Ebb's design | ||||
| * for radiation, see http://mattebb.com/weblog/radiation/ | * for radiation, see http://mattebb.com/weblog/radiation/ | ||||
| * also the old code at http://developer.blender.org/T5103 | * also the old code at http://developer.blender.org/T5103 | ||||
| */ | */ | ||||
| int pie_radius = U.pie_menu_radius * UI_DPI_FAC; | int pie_radius = U.pie_menu_radius * UI_DPI_FAC; | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y; | y = litem->y; | ||||
| int minx = x, miny = y, maxx = x, maxy = y; | int minx = x, miny = y, maxx = x, maxy = y; | ||||
| /* first count total items */ | /* first count total items */ | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| totitems++; | totitems++; | ||||
| } | } | ||||
| if (totitems < 5) { | if (totitems < 5) { | ||||
| litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE; | litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE; | ||||
| } | } | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| /* not all button types are drawn in a radial menu, do filtering here */ | /* not all button types are drawn in a radial menu, do filtering here */ | ||||
| if (ui_item_is_radial_displayable(item)) { | if (ui_item_is_radial_displayable(item)) { | ||||
| RadialDirection dir; | RadialDirection dir; | ||||
| float vec[2]; | float vec[2]; | ||||
| float factor[2]; | float factor[2]; | ||||
| dir = ui_get_radialbut_vec(vec, itemnum); | dir = ui_get_radialbut_vec(vec, itemnum); | ||||
| factor[0] = (vec[0] > 0.01f) ? 0.0f : ((vec[0] < -0.01f) ? -1.0f : -0.5f); | factor[0] = (vec[0] > 0.01f) ? 0.0f : ((vec[0] < -0.01f) ? -1.0f : -0.5f); | ||||
| ▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | static void ui_litem_layout_box(uiLayout *litem) | ||||
| but->rect.ymax = litem->y + litem->h; | but->rect.ymax = litem->y + litem->h; | ||||
| } | } | ||||
| /* multi-column layout, automatically flowing to the next */ | /* multi-column layout, automatically flowing to the next */ | ||||
| static void ui_litem_estimate_column_flow(uiLayout *litem) | static void ui_litem_estimate_column_flow(uiLayout *litem) | ||||
| { | { | ||||
| const uiStyle *style = litem->root->style; | const uiStyle *style = litem->root->style; | ||||
| uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; | uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; | ||||
| uiItem *item; | |||||
| int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; | int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; | ||||
| int toth, totitem; | int toth, totitem; | ||||
| /* compute max needed width and total height */ | /* compute max needed width and total height */ | ||||
| toth = 0; | toth = 0; | ||||
| totitem = 0; | totitem = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| maxw = MAX2(maxw, itemw); | maxw = MAX2(maxw, itemw); | ||||
| toth += itemh; | toth += itemh; | ||||
| totitem++; | totitem++; | ||||
| } | } | ||||
| if (flow->number <= 0) { | if (flow->number <= 0) { | ||||
| /* auto compute number of columns, not very good */ | /* auto compute number of columns, not very good */ | ||||
| Show All 15 Lines | static void ui_litem_estimate_column_flow(uiLayout *litem) | ||||
| emy = 0; | emy = 0; | ||||
| miny = 0; | miny = 0; | ||||
| maxw = 0; | maxw = 0; | ||||
| emh = toth / flow->totcol; | emh = toth / flow->totcol; | ||||
| /* create column per column */ | /* create column per column */ | ||||
| col = 0; | col = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| y -= itemh + style->buttonspacey; | y -= itemh + style->buttonspacey; | ||||
| miny = min_ii(miny, y); | miny = min_ii(miny, y); | ||||
| emy -= itemh; | emy -= itemh; | ||||
| maxw = max_ii(itemw, maxw); | maxw = max_ii(itemw, maxw); | ||||
| /* decide to go to next one */ | /* decide to go to next one */ | ||||
| Show All 9 Lines | static void ui_litem_estimate_column_flow(uiLayout *litem) | ||||
| litem->w = x; | litem->w = x; | ||||
| litem->h = litem->y - miny; | litem->h = litem->y - miny; | ||||
| } | } | ||||
| static void ui_litem_layout_column_flow(uiLayout *litem) | static void ui_litem_layout_column_flow(uiLayout *litem) | ||||
| { | { | ||||
| const uiStyle *style = litem->root->style; | const uiStyle *style = litem->root->style; | ||||
| uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; | uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; | ||||
| uiItem *item; | |||||
| int col, x, y, w, emh, emy, miny, itemw, itemh; | int col, x, y, w, emh, emy, miny, itemw, itemh; | ||||
| int toth, totitem; | int toth, totitem; | ||||
| /* compute max needed width and total height */ | /* compute max needed width and total height */ | ||||
| toth = 0; | toth = 0; | ||||
| totitem = 0; | totitem = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| toth += itemh; | toth += itemh; | ||||
| totitem++; | totitem++; | ||||
| } | } | ||||
| /* compute sizes */ | /* compute sizes */ | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y; | y = litem->y; | ||||
| emy = 0; | emy = 0; | ||||
| miny = 0; | miny = 0; | ||||
| w = litem->w - (flow->totcol - 1) * style->columnspace; | w = litem->w - (flow->totcol - 1) * style->columnspace; | ||||
| emh = toth / flow->totcol; | emh = toth / flow->totcol; | ||||
| /* create column per column */ | /* create column per column */ | ||||
| col = 0; | col = 0; | ||||
| w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol; | w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw); | itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw); | ||||
| y -= itemh; | y -= itemh; | ||||
| emy -= itemh; | emy -= itemh; | ||||
| ui_item_position(item, x, y, itemw, itemh); | ui_item_position(item, x, y, itemw, itemh); | ||||
| y -= style->buttonspacey; | y -= style->buttonspacey; | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | typedef struct UILayoutGridFlowOutput { | ||||
| int *heights_array; /* Computed height of each column. */ | int *heights_array; /* Computed height of each column. */ | ||||
| int *tot_h; /* Computed total height. */ | int *tot_h; /* Computed total height. */ | ||||
| } UILayoutGridFlowOutput; | } UILayoutGridFlowOutput; | ||||
| static void ui_litem_grid_flow_compute(ListBase *items, | static void ui_litem_grid_flow_compute(ListBase *items, | ||||
| UILayoutGridFlowInput *parameters, | UILayoutGridFlowInput *parameters, | ||||
| UILayoutGridFlowOutput *results) | UILayoutGridFlowOutput *results) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int i; | |||||
| float tot_w = 0.0f, tot_h = 0.0f; | float tot_w = 0.0f, tot_h = 0.0f; | ||||
| float global_avg_w = 0.0f, global_totweight_w = 0.0f; | float global_avg_w = 0.0f, global_totweight_w = 0.0f; | ||||
| int global_max_h = 0; | int global_max_h = 0; | ||||
| float *avg_w = NULL, *totweight_w = NULL; | float *avg_w = NULL, *totweight_w = NULL; | ||||
| int *max_h = NULL; | int *max_h = NULL; | ||||
| BLI_assert( | BLI_assert( | ||||
| Show All 23 Lines | if (parameters->tot_columns != 0) { | ||||
| memset(avg_w, 0, sizeof(*avg_w) * parameters->tot_columns); | memset(avg_w, 0, sizeof(*avg_w) * parameters->tot_columns); | ||||
| memset(totweight_w, 0, sizeof(*totweight_w) * parameters->tot_columns); | memset(totweight_w, 0, sizeof(*totweight_w) * parameters->tot_columns); | ||||
| } | } | ||||
| if (parameters->tot_rows != 0) { | if (parameters->tot_rows != 0) { | ||||
| max_h = BLI_array_alloca(max_h, parameters->tot_rows); | max_h = BLI_array_alloca(max_h, parameters->tot_rows); | ||||
| memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows); | memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows); | ||||
| } | } | ||||
| for (i = 0, item = items->first; item; item = item->next, i++) { | int i = 0; | ||||
| LISTBASE_FOREACH (uiItem *, item, items) { | |||||
| int item_w, item_h; | int item_w, item_h; | ||||
| ui_item_size(item, &item_w, &item_h); | ui_item_size(item, &item_w, &item_h); | ||||
| global_avg_w += (float)(item_w * item_w); | global_avg_w += (float)(item_w * item_w); | ||||
| global_totweight_w += (float)item_w; | global_totweight_w += (float)item_w; | ||||
| global_max_h = max_ii(global_max_h, item_h); | global_max_h = max_ii(global_max_h, item_h); | ||||
| if (parameters->tot_rows != 0 && parameters->tot_columns != 0) { | if (parameters->tot_rows != 0 && parameters->tot_columns != 0) { | ||||
| const int index_col = parameters->row_major ? i % parameters->tot_columns : | const int index_col = parameters->row_major ? i % parameters->tot_columns : | ||||
| i / parameters->tot_rows; | i / parameters->tot_rows; | ||||
| const int index_row = parameters->row_major ? i / parameters->tot_columns : | const int index_row = parameters->row_major ? i / parameters->tot_columns : | ||||
| i % parameters->tot_rows; | i % parameters->tot_rows; | ||||
| avg_w[index_col] += (float)(item_w * item_w); | avg_w[index_col] += (float)(item_w * item_w); | ||||
| totweight_w[index_col] += (float)item_w; | totweight_w[index_col] += (float)item_w; | ||||
| max_h[index_row] = max_ii(max_h[index_row], item_h); | max_h[index_row] = max_ii(max_h[index_row], item_h); | ||||
| } | } | ||||
| if (results->tot_items) { | if (results->tot_items) { | ||||
| (*results->tot_items)++; | (*results->tot_items)++; | ||||
| } | } | ||||
| i++; | |||||
| } | } | ||||
| /* Finalize computing of column average sizes */ | /* Finalize computing of column average sizes */ | ||||
| global_avg_w /= global_totweight_w; | global_avg_w /= global_totweight_w; | ||||
| if (parameters->tot_columns != 0) { | if (parameters->tot_columns != 0) { | ||||
| for (i = 0; i < parameters->tot_columns; i++) { | for (i = 0; i < parameters->tot_columns; i++) { | ||||
| avg_w[i] /= totweight_w[i]; | avg_w[i] /= totweight_w[i]; | ||||
| tot_w += avg_w[i]; | tot_w += avg_w[i]; | ||||
| ▲ Show 20 Lines • Show All 192 Lines • ▼ Show 20 Lines | * we can compute actual needed space for non-evenly sized axes. */ | ||||
| litem->w = tot_w; | litem->w = tot_w; | ||||
| litem->h = tot_h; | litem->h = tot_h; | ||||
| } | } | ||||
| } | } | ||||
| static void ui_litem_layout_grid_flow(uiLayout *litem) | static void ui_litem_layout_grid_flow(uiLayout *litem) | ||||
| { | { | ||||
| int i; | |||||
| const uiStyle *style = litem->root->style; | const uiStyle *style = litem->root->style; | ||||
| uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; | uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; | ||||
| uiItem *item; | |||||
| if (gflow->tot_items == 0) { | if (gflow->tot_items == 0) { | ||||
| litem->w = litem->h = 0; | litem->w = litem->h = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| BLI_assert(gflow->tot_columns > 0); | BLI_assert(gflow->tot_columns > 0); | ||||
| BLI_assert(gflow->tot_rows > 0); | BLI_assert(gflow->tot_rows > 0); | ||||
| Show All 22 Lines | ui_litem_grid_flow_compute(&litem->items, | ||||
| }), | }), | ||||
| &((UILayoutGridFlowOutput){ | &((UILayoutGridFlowOutput){ | ||||
| .cos_x_array = cos_x, | .cos_x_array = cos_x, | ||||
| .cos_y_array = cos_y, | .cos_y_array = cos_y, | ||||
| .widths_array = widths, | .widths_array = widths, | ||||
| .heights_array = heights, | .heights_array = heights, | ||||
| })); | })); | ||||
| for (item = litem->items.first, i = 0; item; item = item->next, i++) { | int i; | ||||
| LISTBASE_FOREACH_INDEX (uiItem *, item, &litem->items, i) { | |||||
| const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows; | const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows; | ||||
| const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows; | const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows; | ||||
| int item_w, item_h; | int item_w, item_h; | ||||
| ui_item_size(item, &item_w, &item_h); | ui_item_size(item, &item_w, &item_h); | ||||
| const int w = widths[col]; | const int w = widths[col]; | ||||
| const int h = heights[row]; | const int h = heights[row]; | ||||
| item_w = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, item_w); | item_w = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, item_w); | ||||
| item_h = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? h : min_ii(h, item_h); | item_h = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? h : min_ii(h, item_h); | ||||
| ui_item_position(item, cos_x[col], cos_y[row], item_w, item_h); | ui_item_position(item, cos_x[col], cos_y[row], item_w, item_h); | ||||
| } | } | ||||
campbellbarton: Using the `for` loop for the counters is less error prone, as using `continue` here will skip… | |||||
Done Inline ActionsNote that it's possible to forward extra arguments to LISTBASE_FOREACH into the end of the for-loop using __VA_ARGS__, although this can get a bit involved, since in most cases we only want an extra counter, it's probably not such an advantage. campbellbarton: Note that it's possible to forward extra arguments to `LISTBASE_FOREACH` into the end of the… | |||||
Done Inline ActionsI like the idea of having a LISTBASE_FOREACH_INDEX macro, but I think to keep the scope of the index variable confined to the loop we would need a LISTBASE_FOREACH_INDEX_END macro to close off the scope. Unless the macro doesn't declare the index variable. Then we could use this: #define LISTBASE_FOREACH_INDEX(type, var, list, index_var) \
for (type var = (type)((list)->first); var != NULL; \
var = (type)(((Link *)(var))->next), index_var++) \HooglyBoogly: I like the idea of having a `LISTBASE_FOREACH_INDEX` macro, but I think to keep the scope of… | |||||
| litem->h = litem->y - cos_y[gflow->tot_rows - 1]; | litem->h = litem->y - cos_y[gflow->tot_rows - 1]; | ||||
| litem->x = (cos_x[gflow->tot_columns - 1] - litem->x) + widths[gflow->tot_columns - 1]; | litem->x = (cos_x[gflow->tot_columns - 1] - litem->x) + widths[gflow->tot_columns - 1]; | ||||
| litem->y = litem->y - litem->h; | litem->y = litem->y - litem->h; | ||||
| } | } | ||||
| /* free layout */ | /* free layout */ | ||||
| static void ui_litem_estimate_absolute(uiLayout *litem) | static void ui_litem_estimate_absolute(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemx, itemy, itemw, itemh, minx, miny; | int itemx, itemy, itemw, itemh, minx, miny; | ||||
| minx = 1e6; | minx = 1e6; | ||||
| miny = 1e6; | miny = 1e6; | ||||
| litem->w = 0; | litem->w = 0; | ||||
| litem->h = 0; | litem->h = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_offset(item, &itemx, &itemy); | ui_item_offset(item, &itemx, &itemy); | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| minx = min_ii(minx, itemx); | minx = min_ii(minx, itemx); | ||||
| miny = min_ii(miny, itemy); | miny = min_ii(miny, itemy); | ||||
| litem->w = MAX2(litem->w, itemx + itemw); | litem->w = MAX2(litem->w, itemx + itemw); | ||||
| litem->h = MAX2(litem->h, itemy + itemh); | litem->h = MAX2(litem->h, itemy + itemh); | ||||
| } | } | ||||
| litem->w -= minx; | litem->w -= minx; | ||||
| litem->h -= miny; | litem->h -= miny; | ||||
| } | } | ||||
| static void ui_litem_layout_absolute(uiLayout *litem) | static void ui_litem_layout_absolute(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| float scalex = 1.0f, scaley = 1.0f; | float scalex = 1.0f, scaley = 1.0f; | ||||
| int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; | int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; | ||||
| minx = 1e6; | minx = 1e6; | ||||
| miny = 1e6; | miny = 1e6; | ||||
| totw = 0; | totw = 0; | ||||
| toth = 0; | toth = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_offset(item, &itemx, &itemy); | ui_item_offset(item, &itemx, &itemy); | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| minx = min_ii(minx, itemx); | minx = min_ii(minx, itemx); | ||||
| miny = min_ii(miny, itemy); | miny = min_ii(miny, itemy); | ||||
| totw = max_ii(totw, itemx + itemw); | totw = max_ii(totw, itemx + itemw); | ||||
| toth = max_ii(toth, itemy + itemh); | toth = max_ii(toth, itemy + itemh); | ||||
| } | } | ||||
| totw -= minx; | totw -= minx; | ||||
| toth -= miny; | toth -= miny; | ||||
| if (litem->w && totw > 0) { | if (litem->w && totw > 0) { | ||||
| scalex = (float)litem->w / (float)totw; | scalex = (float)litem->w / (float)totw; | ||||
| } | } | ||||
| if (litem->h && toth > 0) { | if (litem->h && toth > 0) { | ||||
| scaley = (float)litem->h / (float)toth; | scaley = (float)litem->h / (float)toth; | ||||
| } | } | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y - scaley * toth; | y = litem->y - scaley * toth; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_offset(item, &itemx, &itemy); | ui_item_offset(item, &itemx, &itemy); | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| if (scalex != 1.0f) { | if (scalex != 1.0f) { | ||||
| newx = (itemx - minx) * scalex; | newx = (itemx - minx) * scalex; | ||||
| itemw = (itemx - minx + itemw) * scalex - newx; | itemw = (itemx - minx + itemw) * scalex - newx; | ||||
| itemx = minx + newx; | itemx = minx + newx; | ||||
| } | } | ||||
| Show All 18 Lines | |||||
| { | { | ||||
| ui_litem_estimate_row(litem); | ui_litem_estimate_row(litem); | ||||
| litem->item.flag &= ~UI_ITEM_FIXED_SIZE; | litem->item.flag &= ~UI_ITEM_FIXED_SIZE; | ||||
| } | } | ||||
| static void ui_litem_layout_split(uiLayout *litem) | static void ui_litem_layout_split(uiLayout *litem) | ||||
| { | { | ||||
| uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; | uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; | ||||
| uiItem *item; | |||||
| float percentage, extra_pixel = 0.0f; | float percentage, extra_pixel = 0.0f; | ||||
| const int tot = BLI_listbase_count(&litem->items); | const int tot = BLI_listbase_count(&litem->items); | ||||
| int itemh, x, y, w, colw = 0; | int itemh, x, y, w, colw = 0; | ||||
| if (tot == 0) { | if (tot == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y; | y = litem->y; | ||||
| percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage; | percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage; | ||||
| w = (litem->w - (tot - 1) * litem->space); | w = (litem->w - (tot - 1) * litem->space); | ||||
| colw = w * percentage; | colw = w * percentage; | ||||
| colw = MAX2(colw, 0); | colw = MAX2(colw, 0); | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, NULL, &itemh); | ui_item_size(item, NULL, &itemh); | ||||
| ui_item_position(item, x, y - itemh, colw, itemh); | ui_item_position(item, x, y - itemh, colw, itemh); | ||||
| x += colw; | x += colw; | ||||
| if (item->next) { | if (item->next) { | ||||
| const float width = extra_pixel + (w - (int)(w * percentage)) / ((float)tot - 1); | const float width = extra_pixel + (w - (int)(w * percentage)) / ((float)tot - 1); | ||||
| extra_pixel = width - (int)width; | extra_pixel = width - (int)width; | ||||
| colw = (int)width; | colw = (int)width; | ||||
| colw = MAX2(colw, 0); | colw = MAX2(colw, 0); | ||||
| x += litem->space; | x += litem->space; | ||||
| } | } | ||||
| } | } | ||||
| litem->w = x - litem->x; | litem->w = x - litem->x; | ||||
| litem->h = litem->y - y; | litem->h = litem->y - y; | ||||
| litem->x = x; | litem->x = x; | ||||
| litem->y = y; | litem->y = y; | ||||
| } | } | ||||
| /* overlap layout */ | /* overlap layout */ | ||||
| static void ui_litem_estimate_overlap(uiLayout *litem) | static void ui_litem_estimate_overlap(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemw, itemh; | int itemw, itemh; | ||||
| litem->w = 0; | litem->w = 0; | ||||
| litem->h = 0; | litem->h = 0; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| litem->w = MAX2(itemw, litem->w); | litem->w = MAX2(itemw, litem->w); | ||||
| litem->h = MAX2(itemh, litem->h); | litem->h = MAX2(itemh, litem->h); | ||||
| } | } | ||||
| } | } | ||||
| static void ui_litem_layout_overlap(uiLayout *litem) | static void ui_litem_layout_overlap(uiLayout *litem) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int itemw, itemh, x, y; | int itemw, itemh, x, y; | ||||
| x = litem->x; | x = litem->x; | ||||
| y = litem->y; | y = litem->y; | ||||
| for (item = litem->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &litem->items) { | ||||
| ui_item_size(item, &itemw, &itemh); | ui_item_size(item, &itemw, &itemh); | ||||
| ui_item_position(item, x, y - itemh, litem->w, itemh); | ui_item_position(item, x, y - itemh, litem->w, itemh); | ||||
| litem->h = MAX2(litem->h, itemh); | litem->h = MAX2(litem->h, itemh); | ||||
| } | } | ||||
| litem->x = x; | litem->x = x; | ||||
| litem->y = y - litem->h; | litem->y = y - litem->h; | ||||
| ▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) | ||||
| box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, ""); | box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, ""); | ||||
| return box; | return box; | ||||
| } | } | ||||
| uiLayout *uiLayoutRadial(uiLayout *layout) | uiLayout *uiLayoutRadial(uiLayout *layout) | ||||
| { | { | ||||
| uiLayout *litem; | uiLayout *litem; | ||||
| uiItem *item; | |||||
| /* radial layouts are only valid for radial menus */ | /* radial layouts are only valid for radial menus */ | ||||
| if (layout->root->type != UI_LAYOUT_PIEMENU) { | if (layout->root->type != UI_LAYOUT_PIEMENU) { | ||||
| return ui_item_local_sublayout(layout, layout, 0); | return ui_item_local_sublayout(layout, layout, 0); | ||||
| } | } | ||||
| /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ | /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ | ||||
| for (item = layout->root->layout->items.first; item; item = item->next) { | LISTBASE_FOREACH (uiItem *, item, &layout->root->layout->items) { | ||||
| litem = (uiLayout *)item; | litem = (uiLayout *)item; | ||||
| if (litem->item.type == ITEM_LAYOUT_RADIAL) { | if (litem->item.type == ITEM_LAYOUT_RADIAL) { | ||||
| UI_block_layout_set_current(layout->root->block, litem); | UI_block_layout_set_current(layout->root->block, litem); | ||||
| return litem; | return litem; | ||||
| } | } | ||||
| } | } | ||||
| litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial"); | litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial"); | ||||
| Show All 13 Lines | |||||
| /** | /** | ||||
| * Check all buttons defined in this layout, | * Check all buttons defined in this layout, | ||||
| * and set any button flagged as UI_BUT_LIST_ITEM as active/selected. | * and set any button flagged as UI_BUT_LIST_ITEM as active/selected. | ||||
| * Needed to handle correctly text colors of active (selected) list item. | * Needed to handle correctly text colors of active (selected) list item. | ||||
| */ | */ | ||||
| void ui_layout_list_set_labels_active(uiLayout *layout) | void ui_layout_list_set_labels_active(uiLayout *layout) | ||||
| { | { | ||||
| uiButtonItem *bitem; | LISTBASE_FOREACH (uiButtonItem *, bitem, &layout->items) { | ||||
| for (bitem = layout->items.first; bitem; bitem = bitem->item.next) { | |||||
| if (bitem->item.type != ITEM_BUTTON) { | if (bitem->item.type != ITEM_BUTTON) { | ||||
| ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); | ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); | ||||
| } | } | ||||
| else if (bitem->but->flag & UI_BUT_LIST_ITEM) { | else if (bitem->but->flag & UI_BUT_LIST_ITEM) { | ||||
| UI_but_flag_enable(bitem->but, UI_SELECT); | UI_but_flag_enable(bitem->but, UI_SELECT); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Layout | /** \name Layout | ||||
| * \{ */ | * \{ */ | ||||
| static void ui_item_scale(uiLayout *litem, const float scale[2]) | static void ui_item_scale(uiLayout *litem, const float scale[2]) | ||||
| { | { | ||||
| uiItem *item; | |||||
| int x, y, w, h; | int x, y, w, h; | ||||
| for (item = litem->items.last; item; item = item->prev) { | LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { | ||||
| if (item->type != ITEM_BUTTON) { | if (item->type != ITEM_BUTTON) { | ||||
| uiLayout *subitem = (uiLayout *)item; | uiLayout *subitem = (uiLayout *)item; | ||||
| ui_item_scale(subitem, scale); | ui_item_scale(subitem, scale); | ||||
| } | } | ||||
| ui_item_size(item, &w, &h); | ui_item_size(item, &w, &h); | ||||
| ui_item_offset(item, &x, &y); | ui_item_offset(item, &x, &y); | ||||
| if (scale[0] != 0.0f) { | if (scale[0] != 0.0f) { | ||||
| x *= scale[0]; | x *= scale[0]; | ||||
| w *= scale[0]; | w *= scale[0]; | ||||
| } | } | ||||
| if (scale[1] != 0.0f) { | if (scale[1] != 0.0f) { | ||||
| y *= scale[1]; | y *= scale[1]; | ||||
| h *= scale[1]; | h *= scale[1]; | ||||
| } | } | ||||
| ui_item_position(item, x, y, w, h); | ui_item_position(item, x, y, w, h); | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_estimate(uiItem *item) | static void ui_item_estimate(uiItem *item) | ||||
| { | { | ||||
| uiItem *subitem; | |||||
| if (item->type != ITEM_BUTTON) { | if (item->type != ITEM_BUTTON) { | ||||
| uiLayout *litem = (uiLayout *)item; | uiLayout *litem = (uiLayout *)item; | ||||
| for (subitem = litem->items.first; subitem; subitem = subitem->next) { | LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { | ||||
| ui_item_estimate(subitem); | ui_item_estimate(subitem); | ||||
| } | } | ||||
| if (BLI_listbase_is_empty(&litem->items)) { | if (BLI_listbase_is_empty(&litem->items)) { | ||||
| litem->w = 0; | litem->w = 0; | ||||
| litem->h = 0; | litem->h = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if (item->type != ITEM_BUTTON) { | ||||
| if (litem->units[1] > 0) { | if (litem->units[1] > 0) { | ||||
| litem->h = UI_UNIT_Y * litem->units[1]; | litem->h = UI_UNIT_Y * litem->units[1]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_align(uiLayout *litem, short nr) | static void ui_item_align(uiLayout *litem, short nr) | ||||
| { | { | ||||
| uiItem *item; | |||||
| uiButtonItem *bitem; | uiButtonItem *bitem; | ||||
| uiLayoutItemBx *box; | uiLayoutItemBx *box; | ||||
| for (item = litem->items.last; item; item = item->prev) { | LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { | ||||
| if (item->type == ITEM_BUTTON) { | if (item->type == ITEM_BUTTON) { | ||||
| bitem = (uiButtonItem *)item; | bitem = (uiButtonItem *)item; | ||||
| #ifndef USE_UIBUT_SPATIAL_ALIGN | #ifndef USE_UIBUT_SPATIAL_ALIGN | ||||
| if (ui_but_can_align(bitem->but)) | if (ui_but_can_align(bitem->but)) | ||||
| #endif | #endif | ||||
| { | { | ||||
| if (!bitem->but->alignnr) { | if (!bitem->but->alignnr) { | ||||
| bitem->but->alignnr = nr; | bitem->but->alignnr = nr; | ||||
| Show All 15 Lines | #endif | ||||
| else if (((uiLayout *)item)->align) { | else if (((uiLayout *)item)->align) { | ||||
| ui_item_align((uiLayout *)item, nr); | ui_item_align((uiLayout *)item, nr); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_flag(uiLayout *litem, int flag) | static void ui_item_flag(uiLayout *litem, int flag) | ||||
| { | { | ||||
| uiItem *item; | |||||
| uiButtonItem *bitem; | uiButtonItem *bitem; | ||||
| for (item = litem->items.last; item; item = item->prev) { | LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { | ||||
| if (item->type == ITEM_BUTTON) { | if (item->type == ITEM_BUTTON) { | ||||
| bitem = (uiButtonItem *)item; | bitem = (uiButtonItem *)item; | ||||
| bitem->but->flag |= flag; | bitem->but->flag |= flag; | ||||
| } | } | ||||
| else { | else { | ||||
| ui_item_flag((uiLayout *)item, flag); | ui_item_flag((uiLayout *)item, flag); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_layout(uiItem *item) | static void ui_item_layout(uiItem *item) | ||||
| { | { | ||||
| uiItem *subitem; | |||||
| if (item->type != ITEM_BUTTON) { | if (item->type != ITEM_BUTTON) { | ||||
| uiLayout *litem = (uiLayout *)item; | uiLayout *litem = (uiLayout *)item; | ||||
| if (BLI_listbase_is_empty(&litem->items)) { | if (BLI_listbase_is_empty(&litem->items)) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (litem->align) { | if (litem->align) { | ||||
| Show All 36 Lines | switch (litem->item.type) { | ||||
| break; | break; | ||||
| case ITEM_LAYOUT_RADIAL: | case ITEM_LAYOUT_RADIAL: | ||||
| ui_litem_layout_radial(litem); | ui_litem_layout_radial(litem); | ||||
| break; | break; | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| for (subitem = litem->items.first; subitem; subitem = subitem->next) { | LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { | ||||
| if (item->flag & UI_ITEM_BOX_ITEM) { | if (item->flag & UI_ITEM_BOX_ITEM) { | ||||
| subitem->flag |= UI_ITEM_BOX_ITEM; | subitem->flag |= UI_ITEM_BOX_ITEM; | ||||
| } | } | ||||
| ui_item_layout(subitem); | ui_item_layout(subitem); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (item->flag & UI_ITEM_BOX_ITEM) { | if (item->flag & UI_ITEM_BOX_ITEM) { | ||||
| Show All 17 Lines | static void ui_layout_end(uiBlock *block, uiLayout *layout, int *r_x, int *r_y) | ||||
| } | } | ||||
| if (r_y) { | if (r_y) { | ||||
| *r_y = layout->y; | *r_y = layout->y; | ||||
| } | } | ||||
| } | } | ||||
| static void ui_layout_free(uiLayout *layout) | static void ui_layout_free(uiLayout *layout) | ||||
| { | { | ||||
| uiItem *item, *next; | LISTBASE_FOREACH_MUTABLE (uiItem *, item, &layout->items) { | ||||
| for (item = layout->items.first; item; item = next) { | |||||
| next = item->next; | |||||
| if (item->type == ITEM_BUTTON) { | if (item->type == ITEM_BUTTON) { | ||||
| MEM_freeN(item); | MEM_freeN(item); | ||||
| } | } | ||||
| else { | else { | ||||
| ui_layout_free((uiLayout *)item); | ui_layout_free((uiLayout *)item); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | |||||
| void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) | void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) | ||||
| { | { | ||||
| layout->root->handlefunc = handlefunc; | layout->root->handlefunc = handlefunc; | ||||
| layout->root->argv = argv; | layout->root->argv = argv; | ||||
| } | } | ||||
| void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) | void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) | ||||
| { | { | ||||
| uiLayoutRoot *root; | |||||
| BLI_assert(block->active); | BLI_assert(block->active); | ||||
| if (r_x) { | if (r_x) { | ||||
| *r_x = 0; | *r_x = 0; | ||||
| } | } | ||||
| if (r_y) { | if (r_y) { | ||||
| *r_y = 0; | *r_y = 0; | ||||
| } | } | ||||
| block->curlayout = NULL; | block->curlayout = NULL; | ||||
| for (root = block->layouts.first; root; root = root->next) { | LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) { | ||||
| ui_layout_add_padding_button(root); | ui_layout_add_padding_button(root); | ||||
| /* NULL in advance so we don't interfere when adding button */ | /* NULL in advance so we don't interfere when adding button */ | ||||
| ui_layout_end(block, root->layout, r_x, r_y); | ui_layout_end(block, root->layout, r_x, r_y); | ||||
| ui_layout_free(root->layout); | ui_layout_free(root->layout); | ||||
| } | } | ||||
| BLI_freelistN(&block->layouts); | BLI_freelistN(&block->layouts); | ||||
| ▲ Show 20 Lines • Show All 161 Lines • Show Last 20 Lines | |||||
Using the for loop for the counters is less error prone, as using continue here will skip the counter (while not an issue in this case, I don't think it's a good convention).
We could have LISTBASE_FOREACH_INDEX macro for this, as we have for BMesh iterators.