Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_utils.c
| Show First 20 Lines • Show All 348 Lines • ▼ Show 20 Lines | switch (RNA_property_type(prop)) { | ||||
| default: | default: | ||||
| but = NULL; | but = NULL; | ||||
| break; | break; | ||||
| } | } | ||||
| return but; | return but; | ||||
| } | } | ||||
| /** | |||||
| * \a check_prop callback filters functions to avoid drawing certain properties, | |||||
| * in cases where PROP_HIDDEN flag can't be used for a property. | |||||
| * | |||||
| * \param prop_activate_init: Property to activate on initial popup (#UI_BUT_ACTIVATE_ON_INIT). | |||||
| */ | |||||
| eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout, | eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout, | ||||
| PointerRNA *ptr, | PointerRNA *ptr, | ||||
| bool (*check_prop)(PointerRNA *ptr, | bool (*check_prop)(PointerRNA *ptr, | ||||
| PropertyRNA *prop, | PropertyRNA *prop, | ||||
| void *user_data), | void *user_data), | ||||
| void *user_data, | void *user_data, | ||||
| PropertyRNA *prop_activate_init, | PropertyRNA *prop_activate_init, | ||||
| const eButLabelAlign label_align, | const eButLabelAlign label_align, | ||||
| ▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | void ui_rna_collection_search_update_fn(const struct bContext *C, | ||||
| LISTBASE_FOREACH (CollItemSearch *, cis, items_list) { | LISTBASE_FOREACH (CollItemSearch *, cis, items_list) { | ||||
| MEM_freeN(cis->name); | MEM_freeN(cis->name); | ||||
| } | } | ||||
| BLI_freelistN(items_list); | BLI_freelistN(items_list); | ||||
| MEM_freeN(items_list); | MEM_freeN(items_list); | ||||
| } | } | ||||
| /***************************** ID Utilities *******************************/ | |||||
| int UI_icon_from_id(const ID *id) | int UI_icon_from_id(const ID *id) | ||||
| { | { | ||||
| if (id == NULL) { | if (id == NULL) { | ||||
| return ICON_NONE; | return ICON_NONE; | ||||
| } | } | ||||
| /* exception for objects */ | /* exception for objects */ | ||||
| if (GS(id->name) == ID_OB) { | if (GS(id->name) == ID_OB) { | ||||
| Object *ob = (Object *)id; | Object *ob = (Object *)id; | ||||
| if (ob->type == OB_EMPTY) { | if (ob->type == OB_EMPTY) { | ||||
| return ICON_EMPTY_DATA; | return ICON_EMPTY_DATA; | ||||
| } | } | ||||
| return UI_icon_from_id(ob->data); | return UI_icon_from_id(ob->data); | ||||
| } | } | ||||
| /* otherwise get it through RNA, creating the pointer | /* otherwise get it through RNA, creating the pointer | ||||
| * will set the right type, also with subclassing */ | * will set the right type, also with subclassing */ | ||||
| PointerRNA ptr; | PointerRNA ptr; | ||||
| RNA_id_pointer_create((ID *)id, &ptr); | RNA_id_pointer_create((ID *)id, &ptr); | ||||
| return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE; | return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE; | ||||
| } | } | ||||
| /* see: report_type_str */ | |||||
| int UI_icon_from_report_type(int type) | int UI_icon_from_report_type(int type) | ||||
| { | { | ||||
| if (type & RPT_ERROR_ALL) { | if (type & RPT_ERROR_ALL) { | ||||
| return ICON_CANCEL; | return ICON_CANCEL; | ||||
| } | } | ||||
| if (type & RPT_WARNING_ALL) { | if (type & RPT_WARNING_ALL) { | ||||
| return ICON_ERROR; | return ICON_ERROR; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | int UI_text_colorid_from_report_type(int type) | ||||
| if (type & RPT_OPERATOR) { | if (type & RPT_OPERATOR) { | ||||
| return TH_INFO_OPERATOR_TEXT; | return TH_INFO_OPERATOR_TEXT; | ||||
| } | } | ||||
| return TH_INFO_WARNING_TEXT; | return TH_INFO_WARNING_TEXT; | ||||
| } | } | ||||
| /********************************** Misc **************************************/ | /********************************** Misc **************************************/ | ||||
| /** | |||||
| * Returns the best "UI" precision for given floating value, | |||||
| * so that e.g. 10.000001 rather gets drawn as '10'... | |||||
| */ | |||||
| int UI_calc_float_precision(int prec, double value) | int UI_calc_float_precision(int prec, double value) | ||||
| { | { | ||||
| static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = { | static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = { | ||||
| 1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6}; | 1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6}; | ||||
| static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */ | static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */ | ||||
| BLI_assert(prec <= UI_PRECISION_FLOAT_MAX); | BLI_assert(prec <= UI_PRECISION_FLOAT_MAX); | ||||
| BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16); | BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16); | ||||
| ▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | static bool ui_view2d_cur_ensure_rect_in_view(View2D *v2d, const rctf *rect) | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(BLI_rctf_inside_rctf(cur, rect)); | BLI_assert(BLI_rctf_inside_rctf(cur, rect)); | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| /** | |||||
| * Adjust the view so the rectangle of \a but is in view, with some extra margin. | |||||
| * | |||||
| * It's important that this is only executed after buttons received their final #uiBut.rect. E.g. | |||||
| * #UI_panels_end() modifies them, so if that is executed, this function must not be called before | |||||
| * it. | |||||
| * | |||||
| * \param region: The region the button is placed in. Make sure this is actually the one the button | |||||
| * is placed in, not just the context region. | |||||
| */ | |||||
| void UI_but_ensure_in_view(const bContext *C, ARegion *region, const uiBut *but) | void UI_but_ensure_in_view(const bContext *C, ARegion *region, const uiBut *but) | ||||
| { | { | ||||
| View2D *v2d = ®ion->v2d; | View2D *v2d = ®ion->v2d; | ||||
| /* Uninitialized view or region that doesn't use View2D. */ | /* Uninitialized view or region that doesn't use View2D. */ | ||||
| if ((v2d->flag & V2D_IS_INIT) == 0) { | if ((v2d->flag & V2D_IS_INIT) == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| Show All 27 Lines | struct uiButStore { | ||||
| ListBase items; | ListBase items; | ||||
| }; | }; | ||||
| struct uiButStoreElem { | struct uiButStoreElem { | ||||
| struct uiButStoreElem *next, *prev; | struct uiButStoreElem *next, *prev; | ||||
| uiBut **but_p; | uiBut **but_p; | ||||
| }; | }; | ||||
| /** | |||||
| * Create a new button store, the caller must manage and run #UI_butstore_free | |||||
| */ | |||||
| uiButStore *UI_butstore_create(uiBlock *block) | uiButStore *UI_butstore_create(uiBlock *block) | ||||
| { | { | ||||
| uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__); | uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__); | ||||
| bs_handle->block = block; | bs_handle->block = block; | ||||
| BLI_addtail(&block->butstore, bs_handle); | BLI_addtail(&block->butstore, bs_handle); | ||||
| return bs_handle; | return bs_handle; | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | if (bs_elem->but_p == but_p) { | ||||
| BLI_remlink(&bs_handle->items, bs_elem); | BLI_remlink(&bs_handle->items, bs_elem); | ||||
| MEM_freeN(bs_elem); | MEM_freeN(bs_elem); | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| /** | |||||
| * Update the pointer for a registered button. | |||||
| */ | |||||
| bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src) | bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src) | ||||
| { | { | ||||
| bool found = false; | bool found = false; | ||||
| LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | ||||
| if (*bs_elem->but_p == but_src) { | if (*bs_elem->but_p == but_src) { | ||||
| *bs_elem->but_p = but_dst; | *bs_elem->but_p = but_dst; | ||||
| found = true; | found = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return found; | return found; | ||||
| } | } | ||||
| /** | |||||
| * NULL all pointers, don't free since the owner needs to be able to inspect. | |||||
| */ | |||||
| void UI_butstore_clear(uiBlock *block) | void UI_butstore_clear(uiBlock *block) | ||||
| { | { | ||||
| LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| bs_handle->block = NULL; | bs_handle->block = NULL; | ||||
| LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | ||||
| *bs_elem->but_p = NULL; | *bs_elem->but_p = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Map freed buttons from the old block and update pointers. | |||||
| */ | |||||
| void UI_butstore_update(uiBlock *block) | void UI_butstore_update(uiBlock *block) | ||||
| { | { | ||||
| /* move this list to the new block */ | /* move this list to the new block */ | ||||
| if (block->oldblock) { | if (block->oldblock) { | ||||
| if (block->oldblock->butstore.first) { | if (block->oldblock->butstore.first) { | ||||
| BLI_movelisttolist(&block->butstore, &block->oldblock->butstore); | BLI_movelisttolist(&block->butstore, &block->oldblock->butstore); | ||||
| } | } | ||||
| } | } | ||||
| Show All 29 Lines | |||||