diff --git a/source/blender/blenkernel/BKE_lib_id.hh b/source/blender/blenkernel/BKE_lib_id.hh index 2076eb6485d..78e1172f15c 100644 --- a/source/blender/blenkernel/BKE_lib_id.hh +++ b/source/blender/blenkernel/BKE_lib_id.hh @@ -31,9 +31,9 @@ */ #include "BLI_compiler_attrs.h" -#include "BLI_utildefines.h" - #include "BLI_set.hh" +#include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "DNA_userdef_enums.h" @@ -662,9 +662,8 @@ bool BKE_id_is_editable(const Main *bmain, const ID *id); /** * Returns ordered list of data-blocks for display in the UI. - * Result is list of #LinkData of IDs that must be freed. */ -void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb); +blender::Vector BKE_id_ordered_list(const ListBase *lb); /** * Reorder ID in the list, before or after the "relative" ID. */ diff --git a/source/blender/blenkernel/intern/lib_id.cc b/source/blender/blenkernel/intern/lib_id.cc index 0d5d467a67e..70bbcb57df7 100644 --- a/source/blender/blenkernel/intern/lib_id.cc +++ b/source/blender/blenkernel/intern/lib_id.cc @@ -77,6 +77,8 @@ # include "BLI_time_utildefines.h" #endif +using blender::Vector; + using namespace blender::bke::id; static CLG_LogRef LOG = {"bke.lib_id"}; @@ -2165,43 +2167,40 @@ static int *id_order_get(ID *id) } } -static int id_order_compare(const void *a, const void *b) +static bool id_order_compare(ID *a, ID *b) { - ID *id_a = static_cast(((LinkData *)a)->data); - ID *id_b = static_cast(((LinkData *)b)->data); - - int *order_a = id_order_get(id_a); - int *order_b = id_order_get(id_b); + int *order_a = id_order_get(a); + int *order_b = id_order_get(b); if (order_a && order_b) { if (*order_a < *order_b) { - return -1; + return true; } if (*order_a > *order_b) { - return 1; + return false; } } - return strcmp(id_a->name, id_b->name); + return strcmp(a->name, b->name) <= 0; } -void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb) +Vector BKE_id_ordered_list(const ListBase *lb) { - BLI_listbase_clear(ordered_lb); + Vector ordered; LISTBASE_FOREACH (ID *, id, lb) { - BLI_addtail(ordered_lb, BLI_genericNodeN(id)); + ordered.append(id); } - BLI_listbase_sort(ordered_lb, id_order_compare); + std::sort(ordered.begin(), ordered.end(), id_order_compare); - int num = 0; - LISTBASE_FOREACH (LinkData *, link, ordered_lb) { - int *order = id_order_get(static_cast(link->data)); - if (order) { - *order = num++; + for (const int i : ordered.index_range()) { + if (int *order = id_order_get(ordered[i])) { + *order = i; } } + + return ordered; } void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after) diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 7999207842b..17b9035cfac 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -97,6 +97,8 @@ #include "UI_string_search.hh" #include "interface_intern.hh" +using blender::Vector; + /* we may want to make this optional, disable for now. */ // #define USE_OP_RESET_BUT @@ -1659,11 +1661,7 @@ static void template_ID_tabs(const bContext *C, uiBlock *block = uiLayoutGetBlock(layout); const uiStyle *style = UI_style_get_dpi(); - ListBase ordered; - BKE_id_ordered_list(&ordered, template_id->idlb); - - LISTBASE_FOREACH (LinkData *, link, &ordered) { - ID *id = static_cast(link->data); + for (ID *id : BKE_id_ordered_list(template_id->idlb)) { const int name_width = UI_fontstyle_string_width(&style->widget, id->name + 2); const int but_width = name_width + UI_UNIT_X; @@ -1689,8 +1687,6 @@ static void template_ID_tabs(const bContext *C, UI_but_drawflag_enable(tab, but_align); } - BLI_freelistN(&ordered); - if (flag & UI_ID_ADD_NEW) { const bool editable = RNA_property_editable(&template_id->ptr, template_id->prop); uiBut *but; diff --git a/source/blender/editors/screen/screen_ops.cc b/source/blender/editors/screen/screen_ops.cc index e9ac556a7cf..652b47f2257 100644 --- a/source/blender/editors/screen/screen_ops.cc +++ b/source/blender/editors/screen/screen_ops.cc @@ -76,6 +76,8 @@ #include "screen_intern.h" /* own module include */ +using blender::Vector; + #define KM_MODAL_CANCEL 1 #define KM_MODAL_APPLY 2 #define KM_MODAL_SNAP_ON 3 @@ -5788,34 +5790,26 @@ static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEve Main *bmain = CTX_data_main(C); const eScreenCycle direction = eScreenCycle(RNA_enum_get(op->ptr, "direction")); WorkSpace *workspace_src = WM_window_get_active_workspace(win); - WorkSpace *workspace_dst = nullptr; - ListBase ordered; - BKE_id_ordered_list(&ordered, &bmain->workspaces); - - LISTBASE_FOREACH (LinkData *, link, &ordered) { - if (link->data == workspace_src) { - if (direction == SPACE_CONTEXT_CYCLE_PREV) { - workspace_dst = static_cast((link->prev) ? link->prev->data : nullptr); - } - else { - workspace_dst = static_cast((link->next) ? link->next->data : nullptr); - } - } - } - - if (workspace_dst == nullptr) { - LinkData *link = static_cast( - (direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first); - workspace_dst = static_cast(link->data); - } - - BLI_freelistN(&ordered); - - if (workspace_src == workspace_dst) { + Vector ordered = BKE_id_ordered_list(&bmain->workspaces); + if (ordered.size() == 1) { return OPERATOR_CANCELLED; } + const int index = ordered.first_index_of(&workspace_src->id); + + WorkSpace *workspace_dst = nullptr; + switch (direction) { + case SPACE_CONTEXT_CYCLE_PREV: + workspace_dst = reinterpret_cast(index == 0 ? ordered.last() : + ordered[index - 1]); + break; + case SPACE_CONTEXT_CYCLE_NEXT: + workspace_dst = reinterpret_cast( + index == ordered.index_range().last() ? ordered.first() : ordered[index + 1]); + break; + } + win->workspace_hook->temp_workspace_store = workspace_dst; WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst); win->workspace_hook->temp_workspace_store = nullptr; diff --git a/source/blender/editors/screen/workspace_edit.cc b/source/blender/editors/screen/workspace_edit.cc index a3b52f6d479..766d762f4d5 100644 --- a/source/blender/editors/screen/workspace_edit.cc +++ b/source/blender/editors/screen/workspace_edit.cc @@ -45,6 +45,8 @@ #include "screen_intern.h" +using blender::Vector; + /* -------------------------------------------------------------------- */ /** \name Workspace API * @@ -242,23 +244,16 @@ bool ED_workspace_delete(WorkSpace *workspace, Main *bmain, bContext *C, wmWindo return false; } - ListBase ordered; - BKE_id_ordered_list(&ordered, &bmain->workspaces); - WorkSpace *prev = nullptr, *next = nullptr; - LISTBASE_FOREACH (LinkData *, link, &ordered) { - if (link->data == workspace) { - prev = static_cast(link->prev ? link->prev->data : nullptr); - next = static_cast(link->next ? link->next->data : nullptr); - break; - } - } - BLI_freelistN(&ordered); - BLI_assert((prev != nullptr) || (next != nullptr)); + Vector ordered = BKE_id_ordered_list(&bmain->workspaces); + const int index = ordered.first_index_of(&workspace->id); + + WorkSpace *new_active = reinterpret_cast(index == 0 ? ordered[1] : + ordered[index - 1]); LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { WorkSpace *workspace_active = WM_window_get_active_workspace(win); if (workspace_active == workspace) { - ED_workspace_change((prev != nullptr) ? prev : next, C, wm, win); + ED_workspace_change(new_active, C, wm, win); } }