Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface.c
| Show First 20 Lines • Show All 766 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (uiButExtraOpIcon *, new_extra_icon, &new_but->extra_op_icons) { | ||||
| /* Keep the highlighting state, and let handling update it later. */ | /* Keep the highlighting state, and let handling update it later. */ | ||||
| if (old_extra_icon) { | if (old_extra_icon) { | ||||
| new_extra_icon->highlighted = old_extra_icon->highlighted; | new_extra_icon->highlighted = old_extra_icon->highlighted; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * \return true when \a but_p is set (only done for active buttons). | * Update pointers and other information in the old active button from the last layout | ||||
| * pass based on information from the new button added in the current layout pass. | |||||
| * | |||||
| * \param oldbut: The button from the last layout pass that will be moved to the new block. | |||||
| * \param but: The newly added button with much of the up to date information. | |||||
| */ | */ | ||||
| static bool ui_but_update_from_old_block(const bContext *C, | static void ui_but_update_old_active_from_new(uiBut *oldbut, const uiBut *but) | ||||
| uiBlock *block, | |||||
| uiBut **but_p, | |||||
| uiBut **but_old_p) | |||||
| { | { | ||||
| const int drawflag_copy = 0; /* None currently. */ | BLI_assert(oldbut->active); | ||||
| uiBlock *oldblock = block->oldblock; | |||||
| uiBut *oldbut = NULL, *but = *but_p; | |||||
| bool found_active = false; | |||||
| #if 0 | |||||
| /* simple/stupid - search every time */ | |||||
| oldbut = ui_but_find_old(oldblock, but); | |||||
| (void)but_old_p; | |||||
| #else | |||||
| BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1); | |||||
| /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old | |||||
| * as long as old/new buttons are aligned. */ | |||||
| if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) { | |||||
| oldbut = *but_old_p; | |||||
| } | |||||
| else { | |||||
| /* fallback to block search */ | |||||
| oldbut = ui_but_find_old(oldblock, but); | |||||
| } | |||||
| (*but_old_p) = oldbut ? oldbut->next : NULL; | |||||
| #endif | |||||
| if (!oldbut) { | |||||
| return found_active; | |||||
| } | |||||
| if (oldbut->active) { | |||||
| /* flags from the buttons we want to refresh, may want to add more here... */ | /* flags from the buttons we want to refresh, may want to add more here... */ | ||||
| const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON; | const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON; | ||||
| const int drawflag_copy = 0; /* None currently. */ | |||||
| found_active = true; | |||||
| #if 0 | |||||
| but->flag = oldbut->flag; | |||||
| but->active = oldbut->active; | |||||
| but->pos = oldbut->pos; | |||||
| but->ofs = oldbut->ofs; | |||||
| but->editstr = oldbut->editstr; | |||||
| but->editval = oldbut->editval; | |||||
| but->editvec = oldbut->editvec; | |||||
| but->selsta = oldbut->selsta; | |||||
| but->selend = oldbut->selend; | |||||
| but->softmin = oldbut->softmin; | |||||
| but->softmax = oldbut->softmax; | |||||
| oldbut->active = NULL; | |||||
| #endif | |||||
| /* move button over from oldblock to new block */ | |||||
| BLI_remlink(&oldblock->buttons, oldbut); | |||||
| BLI_insertlinkafter(&block->buttons, but, oldbut); | |||||
| oldbut->block = block; | |||||
| *but_p = oldbut; | |||||
| /* still stuff needs to be copied */ | /* still stuff needs to be copied */ | ||||
| oldbut->rect = but->rect; | oldbut->rect = but->rect; | ||||
| oldbut->context = but->context; /* set by Layout */ | oldbut->context = but->context; /* set by Layout */ | ||||
| /* drawing */ | /* drawing */ | ||||
| oldbut->icon = but->icon; | oldbut->icon = but->icon; | ||||
| oldbut->iconadd = but->iconadd; | oldbut->iconadd = but->iconadd; | ||||
| oldbut->alignnr = but->alignnr; | oldbut->alignnr = but->alignnr; | ||||
| /* typically the same pointers, but not on undo/redo */ | /* typically the same pointers, but not on undo/redo */ | ||||
| /* XXX some menu buttons store button itself in but->poin. Ugly */ | /* XXX some menu buttons store button itself in but->poin. Ugly */ | ||||
| if (oldbut->poin != (char *)oldbut) { | if (oldbut->poin != (char *)oldbut) { | ||||
| SWAP(char *, oldbut->poin, but->poin); | oldbut->poin = but->poin; | ||||
| SWAP(void *, oldbut->func_argN, but->func_argN); | oldbut->func_argN = but->func_argN; | ||||
| } | } | ||||
| /* Move tooltip from new to old. */ | /* Move tooltip from new to old. */ | ||||
| SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func); | oldbut->tip_func = but->tip_func; | ||||
| SWAP(void *, oldbut->tip_argN, but->tip_argN); | oldbut->tip_argN = but->tip_argN; | ||||
| oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); | oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); | ||||
| oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); | oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); | ||||
| ui_but_extra_icons_update_from_old_but(but, oldbut); | ui_but_extra_icons_update_from_old_but(but, oldbut); | ||||
| SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons); | oldbut->extra_op_icons = but->extra_op_icons; | ||||
| if (oldbut->type == UI_BTYPE_SEARCH_MENU) { | if (oldbut->type == UI_BTYPE_SEARCH_MENU) { | ||||
| uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; | uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; | ||||
| SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn); | search_oldbut->arg_free_fn = search_but->arg_free_fn; | ||||
| SWAP(void *, search_oldbut->arg, search_but->arg); | search_oldbut->arg = search_but->arg; | ||||
| } | } | ||||
| /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position | /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position | ||||
| * when scrolling without moving mouse (see T28432) */ | * when scrolling without moving mouse (see T28432) */ | ||||
| if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { | if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { | ||||
| oldbut->hardmax = but->hardmax; | oldbut->hardmax = but->hardmax; | ||||
| } | } | ||||
| if (oldbut->type == UI_BTYPE_PROGRESS_BAR) { | if (oldbut->type == UI_BTYPE_PROGRESS_BAR) { | ||||
| uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut; | uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut; | ||||
| uiButProgressbar *progress_but = (uiButProgressbar *)but; | uiButProgressbar *progress_but = (uiButProgressbar *)but; | ||||
| progress_oldbut->progress = progress_but->progress; | progress_oldbut->progress = progress_but->progress; | ||||
| } | } | ||||
| if (!BLI_listbase_is_empty(&block->butstore)) { | |||||
| UI_butstore_register_update(block, oldbut, but); | |||||
| } | |||||
| /* move/copy string from the new button to the old */ | /* move/copy string from the new button to the old */ | ||||
| /* needed for alt+mouse wheel over enums */ | /* needed for alt+mouse wheel over enums */ | ||||
| if (but->str != but->strdata) { | if (but->str != but->strdata) { | ||||
| if (oldbut->str != oldbut->strdata) { | |||||
| SWAP(char *, but->str, oldbut->str); | |||||
| } | |||||
| else { | |||||
| oldbut->str = but->str; | oldbut->str = but->str; | ||||
| but->str = but->strdata; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| if (oldbut->str != oldbut->strdata) { | if (oldbut->str != oldbut->strdata) { | ||||
| MEM_freeN(oldbut->str); | MEM_freeN(oldbut->str); | ||||
| oldbut->str = oldbut->strdata; | oldbut->str = oldbut->strdata; | ||||
| } | } | ||||
| BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); | BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); | ||||
| } | } | ||||
| if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) { | if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) { | ||||
| SWAP(void *, but->dragpoin, oldbut->dragpoin); | oldbut->dragpoin = but->dragpoin; | ||||
| } | |||||
| /* note: if layout hasn't been applied yet, it uses old button pointers... */ | |||||
| } | |||||
| /** | |||||
| * \return true when \a but_p is set (only done for active buttons). | |||||
| */ | |||||
| static bool ui_but_update_from_old_block(const bContext *C, | |||||
| uiBlock *block, | |||||
| uiBut **but_p, | |||||
| uiBut **but_old_p) | |||||
| { | |||||
| uiBlock *oldblock = block->oldblock; | |||||
| uiBut *but = *but_p; | |||||
| #if 0 | |||||
| /* simple/stupid - search every time */ | |||||
| uiBut *oldbut = ui_but_find_old(oldblock, but); | |||||
| UNUSED_VARS(but_old_p); | |||||
| #else | |||||
| BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1); | |||||
| /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old | |||||
| * as long as old/new buttons are aligned. */ | |||||
| uiBut *oldbut; | |||||
| if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) { | |||||
| oldbut = *but_old_p; | |||||
| } | |||||
| else { | |||||
| /* fallback to block search */ | |||||
| oldbut = ui_but_find_old(oldblock, but); | |||||
| } | |||||
| (*but_old_p) = oldbut ? oldbut->next : NULL; | |||||
| #endif | |||||
| if (!oldbut) { | |||||
| return false; | |||||
| } | |||||
| if (oldbut->active) { | |||||
| /* move button over from oldblock to new block */ | |||||
| BLI_remlink(&oldblock->buttons, oldbut); | |||||
| BLI_insertlinkafter(&block->buttons, but, oldbut); | |||||
| oldbut->block = block; | |||||
| *but_p = oldbut; | |||||
| ui_but_update_old_active_from_new(oldbut, but); | |||||
| if (!BLI_listbase_is_empty(&block->butstore)) { | |||||
| UI_butstore_register_update(block, oldbut, but); | |||||
| } | } | ||||
| BLI_remlink(&block->buttons, but); | BLI_remlink(&block->buttons, but); | ||||
| ui_but_free(C, but); | ui_but_free(C, but); | ||||
| /* note: if layout hasn't been applied yet, it uses old button pointers... */ | return true; | ||||
| } | } | ||||
| else { | |||||
| const int flag_copy = UI_BUT_DRAG_MULTI; | const int flag_copy = UI_BUT_DRAG_MULTI; | ||||
| but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy); | but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy); | ||||
| /* ensures one button can get activated, and in case the buttons | /* ensures one button can get activated, and in case the buttons | ||||
| * draw are the same this gives O(1) lookup for each button */ | * draw are the same this gives O(1) lookup for each button */ | ||||
| BLI_remlink(&oldblock->buttons, oldbut); | BLI_remlink(&oldblock->buttons, oldbut); | ||||
| ui_but_free(C, oldbut); | ui_but_free(C, oldbut); | ||||
| } | |||||
| return found_active; | return false; | ||||
| } | } | ||||
campbellbarton: I'd rather avoid using early returns when free functions are involved, it makes it harder to… | |||||
| /* needed for temporarily rename buttons, such as in outliner or file-select, | /* needed for temporarily rename buttons, such as in outliner or file-select, | ||||
| * they should keep calling uiDefButs to keep them alive */ | * they should keep calling uiDefButs to keep them alive */ | ||||
| /* returns 0 when button removed */ | /* returns 0 when button removed */ | ||||
| bool UI_but_active_only_ex( | bool UI_but_active_only_ex( | ||||
| const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure) | const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure) | ||||
| { | { | ||||
| bool activate = false, found = false, isactive = false; | bool activate = false, found = false, isactive = false; | ||||
| ▲ Show 20 Lines • Show All 6,151 Lines • Show Last 20 Lines | |||||
I'd rather avoid using early returns when free functions are involved, it makes it harder to reason about changes when freeing. AFAICS this part can be left as-is.