diff options
Diffstat (limited to 'source/blender/editors/interface/interface_templates.c')
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 899 |
1 files changed, 9 insertions, 890 deletions
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5232d4310a3..766840909cc 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -877,7 +877,7 @@ static uiBut *template_id_def_new_but(uiBlock *block, BLT_I18NCONTEXT_ID_POINTCLOUD, BLT_I18NCONTEXT_ID_VOLUME, BLT_I18NCONTEXT_ID_SIMULATION, ); - /* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters, + /* NOTE: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters, * check the definition to see if a new call must be added when the limit * is exceeded. */ @@ -2399,8 +2399,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( op->type->ui((bContext *)C, op); op->layout = NULL; - /* UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. We could - * allow ot.ui callback to return this, but not needed right now. */ + /* #UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. + * We could allow #wmOperatorType.ui callback to return this, but not needed right now. */ } else { wmWindowManager *wm = CTX_wm_manager(C); @@ -2556,7 +2556,7 @@ void uiTemplateOperatorPropertyButs( wmWindowManager *wm = CTX_wm_manager(C); /* If there are only checkbox items, don't use split layout by default. It looks weird if the - * checkboxes only use half the width. */ + * check-boxes only use half the width. */ if (ui_layout_operator_properties_only_booleans(C, wm, op, flag)) { flag |= UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT; } @@ -4015,23 +4015,23 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) case UICURVE_FUNC_RESET_VIEW: BKE_curvemapping_reset_view(cumap); break; - case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */ + case UICURVE_FUNC_HANDLE_VECTOR: /* Set vector. */ BKE_curvemap_handle_set(cuma, HD_VECT); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_HANDLE_AUTO: /* set auto */ + case UICURVE_FUNC_HANDLE_AUTO: /* Set auto. */ BKE_curvemap_handle_set(cuma, HD_AUTO); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */ + case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* Set auto-clamped. */ BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */ + case UICURVE_FUNC_EXTEND_HOZ: /* Extend horizontal. */ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE; BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */ + case UICURVE_FUNC_EXTEND_EXP: /* Extend extrapolate. */ cumap->flag |= CUMA_EXTEND_EXTRAPOLATE; BKE_curvemapping_changed(cumap, false); break; @@ -5645,887 +5645,6 @@ void uiTemplateLayers(uiLayout *layout, /** \} */ /* -------------------------------------------------------------------- */ -/** \name List Template - * \{ */ - -static void uilist_draw_item_default(struct uiList *ui_list, - struct bContext *UNUSED(C), - struct uiLayout *layout, - struct PointerRNA *UNUSED(dataptr), - struct PointerRNA *itemptr, - int icon, - struct PointerRNA *UNUSED(active_dataptr), - const char *UNUSED(active_propname), - int UNUSED(index), - int UNUSED(flt_flag)) -{ - PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type); - - /* Simplest one! */ - switch (ui_list->layout_type) { - case UILST_LAYOUT_GRID: - uiItemL(layout, "", icon); - break; - case UILST_LAYOUT_DEFAULT: - case UILST_LAYOUT_COMPACT: - default: - if (nameprop) { - uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon); - } - else { - uiItemL(layout, "", icon); - } - break; - } -} - -static void uilist_draw_filter_default(struct uiList *ui_list, - struct bContext *UNUSED(C), - struct uiLayout *layout) -{ - PointerRNA listptr; - RNA_pointer_create(NULL, &RNA_UIList, ui_list, &listptr); - - uiLayout *row = uiLayoutRow(layout, false); - - uiLayout *subrow = uiLayoutRow(row, true); - uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE); - uiItemR(subrow, - &listptr, - "use_filter_invert", - UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, - "", - ICON_ARROW_LEFTRIGHT); - - if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) { - subrow = uiLayoutRow(row, true); - uiItemR(subrow, - &listptr, - "use_filter_sort_alpha", - UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, - "", - ICON_NONE); - uiItemR(subrow, - &listptr, - "use_filter_sort_reverse", - UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, - "", - (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC); - } -} - -typedef struct { - char name[MAX_IDPROP_NAME]; - int org_idx; -} StringCmp; - -static int cmpstringp(const void *p1, const void *p2) -{ - /* Case-insensitive comparison. */ - return BLI_strcasecmp(((StringCmp *)p1)->name, ((StringCmp *)p2)->name); -} - -static void uilist_filter_items_default(struct uiList *ui_list, - struct bContext *UNUSED(C), - struct PointerRNA *dataptr, - const char *propname) -{ - uiListDyn *dyn_data = ui_list->dyn_data; - PropertyRNA *prop = RNA_struct_find_property(dataptr, propname); - - const char *filter_raw = ui_list->filter_byname; - char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = NULL; - const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0; - const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) == - UILST_FLT_SORT_ALPHA; - const int len = RNA_property_collection_length(dataptr, prop); - - dyn_data->items_shown = dyn_data->items_len = len; - - if (len && (order_by_name || filter_raw[0])) { - StringCmp *names = NULL; - int order_idx = 0, i = 0; - - if (order_by_name) { - names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp"); - } - if (filter_raw[0]) { - const size_t slen = strlen(filter_raw); - - dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags"); - dyn_data->items_shown = 0; - - /* Implicitly add heading/trailing wildcards if needed. */ - if (slen + 3 <= sizeof(filter_buff)) { - filter = filter_buff; - } - else { - filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn"); - } - BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3); - } - - RNA_PROP_BEGIN (dataptr, itemptr, prop) { - bool do_order = false; - - char *namebuf = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); - const char *name = namebuf ? namebuf : ""; - - if (filter[0]) { - /* Case-insensitive! */ - if (fnmatch(filter, name, FNM_CASEFOLD) == 0) { - dyn_data->items_filter_flags[i] = UILST_FLT_ITEM; - if (!filter_exclude) { - dyn_data->items_shown++; - do_order = order_by_name; - } - // printf("%s: '%s' matches '%s'\n", __func__, name, filter); - } - else if (filter_exclude) { - dyn_data->items_shown++; - do_order = order_by_name; - } - } - else { - do_order = order_by_name; - } - - if (do_order) { - names[order_idx].org_idx = order_idx; - BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME); - } - - /* free name */ - if (namebuf) { - MEM_freeN(namebuf); - } - i++; - } - RNA_PROP_END; - - if (order_by_name) { - int new_idx; - /* note: order_idx equals either to ui_list->items_len if no filtering done, - * or to ui_list->items_shown if filter is enabled, - * or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded. - * This way, we only sort items we actually intend to draw! - */ - qsort(names, order_idx, sizeof(StringCmp), cmpstringp); - - dyn_data->items_filter_neworder = MEM_mallocN(sizeof(int) * order_idx, - "items_filter_neworder"); - for (new_idx = 0; new_idx < order_idx; new_idx++) { - dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx; - } - } - - if (filter_dyn) { - MEM_freeN(filter_dyn); - } - if (names) { - MEM_freeN(names); - } - } -} - -typedef struct { - PointerRNA item; - int org_idx; - int flt_flag; -} _uilist_item; - -typedef struct { - int visual_items; /* Visual number of items (i.e. number of items we have room to display). */ - int start_idx; /* Index of first item to display. */ - int end_idx; /* Index of last item to display + 1. */ -} uiListLayoutdata; - -static void uilist_prepare(uiList *ui_list, - int len, - int activei, - int rows, - int maxrows, - int columns, - uiListLayoutdata *layoutdata) -{ - uiListDyn *dyn_data = ui_list->dyn_data; - const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD)); - - /* default rows */ - if (rows <= 0) { - rows = 5; - } - dyn_data->visual_height_min = rows; - if (maxrows < rows) { - maxrows = max_ii(rows, 5); - } - if (columns <= 0) { - columns = 9; - } - - int activei_row; - if (columns > 1) { - dyn_data->height = (int)ceil((double)len / (double)columns); - activei_row = (int)floor((double)activei / (double)columns); - } - else { - dyn_data->height = len; - activei_row = activei; - } - - if (!use_auto_size) { - /* No auto-size, yet we clamp at min size! */ - maxrows = rows = max_ii(ui_list->list_grip, rows); - } - else if ((rows != maxrows) && (dyn_data->height > rows)) { - /* Expand size if needed and possible. */ - rows = min_ii(dyn_data->height, maxrows); - } - - /* If list length changes or list is tagged to check this, - * and active is out of view, scroll to it. */ - if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) { - if (activei_row < ui_list->list_scroll) { - ui_list->list_scroll = activei_row; - } - else if (activei_row >= ui_list->list_scroll + rows) { - ui_list->list_scroll = activei_row - rows + 1; - } - ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM; - } - - const int max_scroll = max_ii(0, dyn_data->height - rows); - CLAMP(ui_list->list_scroll, 0, max_scroll); - ui_list->list_last_len = len; - dyn_data->visual_height = rows; - layoutdata->visual_items = rows * columns; - layoutdata->start_idx = ui_list->list_scroll * columns; - layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len); -} - -static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2)) -{ - uiList *ui_list = arg1; - uiListDyn *dyn_data = ui_list->dyn_data; - - /* This way we get diff in number of additional items to show (positive) or hide (negative). */ - const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) / - (float)UI_UNIT_Y); - - if (diff != 0) { - ui_list->list_grip += diff; - dyn_data->resize_prev += diff * UI_UNIT_Y; - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; - } - - /* In case uilist is in popup, we need special refreshing */ - ED_region_tag_refresh_ui(CTX_wm_menu(C)); -} - -static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname) -{ - if (propname && propname[0] && itemptr && itemptr->data) { - PropertyRNA *prop = RNA_struct_find_property(itemptr, propname); - - if (prop && (RNA_property_type(prop) == PROP_STRING)) { - return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL); - } - } - return NULL; -} - -static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip) -{ - char *dyn_tooltip = argN; - return BLI_sprintfN("%s - %s", tip, dyn_tooltip); -} - -void uiTemplateList(uiLayout *layout, - bContext *C, - const char *listtype_name, - const char *list_id, - PointerRNA *dataptr, - const char *propname, - PointerRNA *active_dataptr, - const char *active_propname, - const char *item_dyntip_propname, - int rows, - int maxrows, - int layout_type, - int columns, - bool sort_reverse, - bool sort_lock) -{ - PropertyRNA *prop = NULL, *activeprop; - _uilist_item *items_ptr = NULL; - uiLayout *glob = NULL, *box, *row, *col, *subrow, *sub, *overlap; - uiBut *but; - - uiListLayoutdata layoutdata; - char ui_list_id[UI_MAX_NAME_STR]; - char numstr[32]; - int rnaicon = ICON_NONE, icon = ICON_NONE; - int i = 0, activei = 0; - int len = 0; - - /* validate arguments */ - /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */ - if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) { - RNA_warning("template_list using default '%s' UIList class must provide a custom list_id", - UI_UL_DEFAULT_CLASS_NAME); - return; - } - - uiBlock *block = uiLayoutGetBlock(layout); - - if (!active_dataptr->data) { - RNA_warning("No active data"); - return; - } - - if (dataptr->data) { - prop = RNA_struct_find_property(dataptr, propname); - if (!prop) { - RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname); - return; - } - } - - activeprop = RNA_struct_find_property(active_dataptr, active_propname); - if (!activeprop) { - RNA_warning( - "Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname); - return; - } - - if (prop) { - const PropertyType type = RNA_property_type(prop); - if (type != PROP_COLLECTION) { - RNA_warning("Expected a collection data property"); - return; - } - } - - const PropertyType activetype = RNA_property_type(activeprop); - if (activetype != PROP_INT) { - RNA_warning("Expected an integer active data property"); - return; - } - - /* get icon */ - if (dataptr->data && prop) { - StructRNA *ptype = RNA_property_pointer_type(dataptr, prop); - rnaicon = RNA_struct_ui_icon(ptype); - } - - /* get active data */ - activei = RNA_property_int_get(active_dataptr, activeprop); - - /* Find the uiList type. */ - uiListType *ui_list_type = WM_uilisttype_find(listtype_name, false); - - if (ui_list_type == NULL) { - RNA_warning("List type %s not found", listtype_name); - return; - } - - uiListDrawItemFunc draw_item = ui_list_type->draw_item ? ui_list_type->draw_item : - uilist_draw_item_default; - uiListDrawFilterFunc draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter : - uilist_draw_filter_default; - uiListFilterItemsFunc filter_items = ui_list_type->filter_items ? ui_list_type->filter_items : - uilist_filter_items_default; - - /* Find or add the uiList to the current Region. */ - /* We tag the list id with the list type... */ - BLI_snprintf( - ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : ""); - - /* Allows to work in popups. */ - ARegion *region = CTX_wm_menu(C); - if (region == NULL) { - region = CTX_wm_region(C); - } - uiList *ui_list = BLI_findstring(®ion->ui_lists, ui_list_id, offsetof(uiList, list_id)); - - if (!ui_list) { - ui_list = MEM_callocN(sizeof(uiList), "uiList"); - BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id)); - BLI_addtail(®ion->ui_lists, ui_list); - ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */ - if (sort_reverse) { - ui_list->filter_sort_flag |= UILST_FLT_SORT_REVERSE; - } - if (sort_lock) { - ui_list->filter_sort_flag |= UILST_FLT_SORT_LOCK; - } - } - - if (!ui_list->dyn_data) { - ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data"); - } - uiListDyn *dyn_data = ui_list->dyn_data; - - /* Because we can't actually pass type across save&load... */ - ui_list->type = ui_list_type; - ui_list->layout_type = layout_type; - - /* Reset filtering data. */ - MEM_SAFE_FREE(dyn_data->items_filter_flags); - MEM_SAFE_FREE(dyn_data->items_filter_neworder); - dyn_data->items_len = dyn_data->items_shown = -1; - - /* When active item changed since last draw, scroll to it. */ - if (activei != ui_list->list_last_activei) { - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; - ui_list->list_last_activei = activei; - } - - /* Filter list items! (not for compact layout, though) */ - if (dataptr->data && prop) { - const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE; - const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0; - int items_shown, idx = 0; -#if 0 - int prev_ii = -1, prev_i; -#endif - - if (layout_type == UILST_LAYOUT_COMPACT) { - dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(dataptr, prop); - } - else { - // printf("%s: filtering...\n", __func__); - filter_items(ui_list, C, dataptr, propname); - // printf("%s: filtering done.\n", __func__); - } - - items_shown = dyn_data->items_shown; - if (items_shown >= 0) { - bool activei_mapping_pending = true; - items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, __func__); - // printf("%s: items shown: %d.\n", __func__, items_shown); - RNA_PROP_BEGIN (dataptr, itemptr, prop) { - if (!dyn_data->items_filter_flags || - ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) { - int ii; - if (dyn_data->items_filter_neworder) { - ii = dyn_data->items_filter_neworder[idx++]; - ii = order_reverse ? items_shown - ii - 1 : ii; - } - else { - ii = order_reverse ? items_shown - ++idx : idx++; - } - // printf("%s: ii: %d\n", __func__, ii); - items_ptr[ii].item = itemptr; - items_ptr[ii].org_idx = i; - items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] : - 0; - - if (activei_mapping_pending && activei == i) { - activei = ii; - /* So that we do not map again activei! */ - activei_mapping_pending = false; - } -#if 0 /* For now, do not alter active element, even if it will be hidden... */ - else if (activei < i) { - /* We do not want an active but invisible item! - * Only exception is when all items are filtered out... - */ - if (prev_ii >= 0) { - activei = prev_ii; - RNA_property_int_set(active_dataptr, activeprop, prev_i); - } - else { - activei = ii; - RNA_property_int_set(active_dataptr, activeprop, i); - } - } - prev_i = i; - prev_ii = ii; -#endif - } - i++; - } - RNA_PROP_END; - - if (activei_mapping_pending) { - /* No active item found, set to 'invalid' -1 value... */ - activei = -1; - } - } - if (dyn_data->items_shown >= 0) { - len = dyn_data->items_shown; - } - else { - len = dyn_data->items_len; - } - } - - switch (layout_type) { - case UILST_LAYOUT_DEFAULT: - /* layout */ - box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop); - glob = uiLayoutColumn(box, true); - row = uiLayoutRow(glob, false); - col = uiLayoutColumn(row, true); - - /* init numbers */ - uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata); - - if (dataptr->data && prop) { - /* create list items */ - for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { - PointerRNA *itemptr = &items_ptr[i].item; - void *dyntip_data; - const int org_i = items_ptr[i].org_idx; - const int flt_flag = items_ptr[i].flt_flag; - uiBlock *subblock = uiLayoutGetBlock(col); - - overlap = uiLayoutOverlap(col); - - UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM); - - /* list item behind label & other buttons */ - sub = uiLayoutRow(overlap, false); - - but = uiDefButR_prop(subblock, - UI_BTYPE_LISTROW, - 0, - "", - 0, - 0, - UI_UNIT_X * 10, - UI_UNIT_Y, - active_dataptr, - activeprop, - 0, - 0, - org_i, - 0, - 0, - TIP_("Double click to rename")); - if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) { - UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data, MEM_freeN); - } - - sub = uiLayoutRow(overlap, false); - - icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false); - if (icon == ICON_DOT) { - icon = ICON_NONE; - } - draw_item(ui_list, - C, - sub, - dataptr, - itemptr, - icon, - active_dataptr, - active_propname, - org_i, - flt_flag); - - /* Items should be able to set context pointers for the layout. But the list-row button - * swallows events, so it needs the context storage too for handlers to see it. */ - but->context = uiLayoutGetContextStore(sub); - - /* If we are "drawing" active item, set all labels as active. */ - if (i == activei) { - ui_layout_list_set_labels_active(sub); - } - - UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM); - } - } - - /* add dummy buttons to fill space */ - for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) { - uiItemL(col, "", ICON_NONE); - } - - /* add scrollbar */ - if (len > layoutdata.visual_items) { - col = uiLayoutColumn(row, false); - uiDefButI(block, - UI_BTYPE_SCROLL, - 0, - "", - 0, - 0, - V2D_SCROLL_WIDTH, - UI_UNIT_Y * dyn_data->visual_height, - &ui_list->list_scroll, - 0, - dyn_data->height - dyn_data->visual_height, - dyn_data->visual_height, - 0, - ""); - } - break; - case UILST_LAYOUT_COMPACT: - row = uiLayoutRow(layout, true); - - if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && (activei >= 0) && - (activei < dyn_data->items_shown)) { - PointerRNA *itemptr = &items_ptr[activei].item; - const int org_i = items_ptr[activei].org_idx; - - icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false); - if (icon == ICON_DOT) { - icon = ICON_NONE; - } - draw_item( - ui_list, C, row, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, 0); - } - /* if list is empty, add in dummy button */ - else { - uiItemL(row, "", ICON_NONE); - } - - /* next/prev button */ - BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown); - but = uiDefIconTextButR_prop(block, - UI_BTYPE_NUM, - 0, - 0, - numstr, - 0, - 0, - UI_UNIT_X * 5, - UI_UNIT_Y, - active_dataptr, - activeprop, - 0, - 0, - 0, - 0, - 0, - ""); - if (dyn_data->items_shown == 0) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - break; - case UILST_LAYOUT_GRID: - box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop); - glob = uiLayoutColumn(box, true); - row = uiLayoutRow(glob, false); - col = uiLayoutColumn(row, true); - subrow = NULL; /* Quite gcc warning! */ - - uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata); - - if (dataptr->data && prop) { - /* create list items */ - for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { - PointerRNA *itemptr = &items_ptr[i].item; - const int org_i = items_ptr[i].org_idx; - const int flt_flag = items_ptr[i].flt_flag; - - /* create button */ - if (!(i % columns)) { - subrow = uiLayoutRow(col, false); - } - - uiBlock *subblock = uiLayoutGetBlock(subrow); - overlap = uiLayoutOverlap(subrow); - - UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM); - - /* list item behind label & other buttons */ - sub = uiLayoutRow(overlap, false); - - but = uiDefButR_prop(subblock, - UI_BTYPE_LISTROW, - 0, - "", - 0, - 0, - UI_UNIT_X * 10, - UI_UNIT_Y, - active_dataptr, - activeprop, - 0, - 0, - org_i, - 0, - 0, - NULL); - UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP); - - sub = uiLayoutRow(overlap, false); - - icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false); - draw_item(ui_list, - C, - sub, - dataptr, - itemptr, - icon, - active_dataptr, - active_propname, - org_i, - flt_flag); - - /* If we are "drawing" active item, set all labels as active. */ - if (i == activei) { - ui_layout_list_set_labels_active(sub); - } - - UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM); - } - } - - /* add dummy buttons to fill space */ - for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) { - if (!(i % columns)) { - subrow = uiLayoutRow(col, false); - } - uiItemL(subrow, "", ICON_NONE); - } - - /* add scrollbar */ - if (len > layoutdata.visual_items) { - /* col = */ uiLayoutColumn(row, false); - uiDefButI(block, - UI_BTYPE_SCROLL, - 0, - "", - 0, - 0, - V2D_SCROLL_WIDTH, - UI_UNIT_Y * dyn_data->visual_height, - &ui_list->list_scroll, - 0, - dyn_data->height - dyn_data->visual_height, - dyn_data->visual_height, - 0, - ""); - } - break; - } - - if (glob) { - /* About #UI_BTYPE_GRIP drag-resize: - * We can't directly use results from a grip button, since we have a - * rather complex behavior here (sizing by discrete steps and, overall, auto-size feature). - * Since we *never* know whether we are grip-resizing or not - * (because there is no callback for when a button enters/leaves its "edit mode"), - * we use the fact that grip-controlled value (dyn_data->resize) is completely handled - * by the grip during the grab resize, so settings its value here has no effect at all. - * - * It is only meaningful when we are not resizing, - * in which case this gives us the correct "init drag" value. - * Note we cannot affect `dyn_data->resize_prev here`, - * since this value is not controlled by the grip! - */ - dyn_data->resize = dyn_data->resize_prev + - (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y; - - row = uiLayoutRow(glob, true); - uiBlock *subblock = uiLayoutGetBlock(row); - UI_block_emboss_set(subblock, UI_EMBOSS_NONE); - - if (ui_list->filter_flag & UILST_FLT_SHOW) { - but = uiDefIconButBitI(subblock, - UI_BTYPE_TOGGLE, - UILST_FLT_SHOW, - 0, - ICON_DISCLOSURE_TRI_DOWN, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y * 0.5f, - &(ui_list->filter_flag), - 0, - 0, - 0, - 0, - TIP_("Hide filtering options")); - UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - - but = uiDefIconButI(subblock, - UI_BTYPE_GRIP, - 0, - ICON_GRIP, - 0, - 0, - UI_UNIT_X * 10.0f, - UI_UNIT_Y * 0.5f, - &dyn_data->resize, - 0.0, - 0.0, - 0, - 0, - ""); - UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL); - - UI_block_emboss_set(subblock, UI_EMBOSS); - - col = uiLayoutColumn(glob, false); - subblock = uiLayoutGetBlock(col); - uiDefBut(subblock, - UI_BTYPE_SEPR, - 0, - "", - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y * 0.05f, - NULL, - 0.0, - 0.0, - 0, - 0, - ""); - - draw_filter(ui_list, C, col); - } - else { - but = uiDefIconButBitI(subblock, - UI_BTYPE_TOGGLE, - UILST_FLT_SHOW, - 0, - ICON_DISCLOSURE_TRI_RIGHT, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y * 0.5f, - &(ui_list->filter_flag), - 0, - 0, - 0, - 0, - TIP_("Show filtering options")); - UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - - but = uiDefIconButI(subblock, - UI_BTYPE_GRIP, - 0, - ICON_GRIP, - 0, - 0, - UI_UNIT_X * 10.0f, - UI_UNIT_Y * 0.5f, - &dyn_data->resize, - 0.0, - 0.0, - 0, - 0, - ""); - UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL); - - UI_block_emboss_set(subblock, UI_EMBOSS); - } - } - - if (items_ptr) { - MEM_freeN(items_ptr); - } -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Running Jobs Template * \{ */ |