Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_utils.c
| Show First 20 Lines • Show All 708 Lines • ▼ Show 20 Lines | |||||
| bool UI_butstore_is_valid(uiButStore *bs) | bool UI_butstore_is_valid(uiButStore *bs) | ||||
| { | { | ||||
| return (bs->block != NULL); | return (bs->block != NULL); | ||||
| } | } | ||||
| bool UI_butstore_is_registered(uiBlock *block, uiBut *but) | bool UI_butstore_is_registered(uiBlock *block, uiBut *but) | ||||
| { | { | ||||
| uiButStore *bs_handle; | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | |||||
| for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { | |||||
| uiButStoreElem *bs_elem; | |||||
| for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { | |||||
| if (*bs_elem->but_p == but) { | if (*bs_elem->but_p == but) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p) | void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p) | ||||
| { | { | ||||
| uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__); | uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__); | ||||
| BLI_assert(*but_p); | BLI_assert(*but_p); | ||||
| bs_elem->but_p = but_p; | bs_elem->but_p = but_p; | ||||
| BLI_addtail(&bs_handle->items, bs_elem); | BLI_addtail(&bs_handle->items, bs_elem); | ||||
| } | } | ||||
| void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) | void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) | ||||
| { | { | ||||
| uiButStoreElem *bs_elem, *bs_elem_next; | LISTBASE_FOREACH_MUTABLE (uiButStoreElem *, bs_elem, &bs_handle->items) { | ||||
| for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) { | |||||
| bs_elem_next = bs_elem->next; | |||||
| if (bs_elem->but_p == but_p) { | 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. | * 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) | ||||
| { | { | ||||
| uiButStore *bs_handle; | |||||
| bool found = false; | bool found = false; | ||||
| for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| uiButStoreElem *bs_elem; | LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | ||||
| for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { | |||||
| 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. | * 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) | ||||
| { | { | ||||
| uiButStore *bs_handle; | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { | |||||
| uiButStoreElem *bs_elem; | |||||
| bs_handle->block = NULL; | bs_handle->block = NULL; | ||||
| LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | |||||
| for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { | |||||
| *bs_elem->but_p = NULL; | *bs_elem->but_p = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Map freed buttons from the old block and update pointers. | * Map freed buttons from the old block and update pointers. | ||||
| */ | */ | ||||
| void UI_butstore_update(uiBlock *block) | void UI_butstore_update(uiBlock *block) | ||||
| { | { | ||||
| uiButStore *bs_handle; | |||||
| /* 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); | ||||
| } | } | ||||
| } | } | ||||
| if (LIKELY(block->butstore.first == NULL)) { | if (LIKELY(block->butstore.first == NULL)) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* warning, loop-in-loop, in practice we only store <10 buttons at a time, | /* warning, loop-in-loop, in practice we only store <10 buttons at a time, | ||||
| * so this isn't going to be a problem, if that changes old-new mapping can be cached first */ | * so this isn't going to be a problem, if that changes old-new mapping can be cached first */ | ||||
| for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { | LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { | ||||
| BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) || | BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) || | ||||
| (block->oldblock && block->oldblock == bs_handle->block)); | (block->oldblock && block->oldblock == bs_handle->block)); | ||||
| if (bs_handle->block == block->oldblock) { | if (bs_handle->block == block->oldblock) { | ||||
| uiButStoreElem *bs_elem; | |||||
| bs_handle->block = block; | bs_handle->block = block; | ||||
| for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { | LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { | ||||
| if (*bs_elem->but_p) { | if (*bs_elem->but_p) { | ||||
| uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p); | uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p); | ||||
| /* can be NULL if the buttons removed, | /* can be NULL if the buttons removed, | ||||
| * note: we could allow passing in a callback when buttons are removed | * note: we could allow passing in a callback when buttons are removed | ||||
| * so the caller can cleanup */ | * so the caller can cleanup */ | ||||
| *bs_elem->but_p = but_new; | *bs_elem->but_p = but_new; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||