Cleanup: Use Vector instead of linked list for data-block sorting utility
This commit is contained in:
@@ -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<ID *> BKE_id_ordered_list(const ListBase *lb);
|
||||
/**
|
||||
* Reorder ID in the list, before or after the "relative" ID.
|
||||
*/
|
||||
|
||||
@@ -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<ID *>(((LinkData *)a)->data);
|
||||
ID *id_b = static_cast<ID *>(((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<ID *> BKE_id_ordered_list(const ListBase *lb)
|
||||
{
|
||||
BLI_listbase_clear(ordered_lb);
|
||||
Vector<ID *> 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<ID *>(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)
|
||||
|
||||
@@ -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<ID *>(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;
|
||||
|
||||
@@ -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<WorkSpace *>((link->prev) ? link->prev->data : nullptr);
|
||||
}
|
||||
else {
|
||||
workspace_dst = static_cast<WorkSpace *>((link->next) ? link->next->data : nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (workspace_dst == nullptr) {
|
||||
LinkData *link = static_cast<LinkData *>(
|
||||
(direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first);
|
||||
workspace_dst = static_cast<WorkSpace *>(link->data);
|
||||
}
|
||||
|
||||
BLI_freelistN(&ordered);
|
||||
|
||||
if (workspace_src == workspace_dst) {
|
||||
Vector<ID *> 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<WorkSpace *>(index == 0 ? ordered.last() :
|
||||
ordered[index - 1]);
|
||||
break;
|
||||
case SPACE_CONTEXT_CYCLE_NEXT:
|
||||
workspace_dst = reinterpret_cast<WorkSpace *>(
|
||||
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;
|
||||
|
||||
@@ -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<WorkSpace *>(link->prev ? link->prev->data : nullptr);
|
||||
next = static_cast<WorkSpace *>(link->next ? link->next->data : nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&ordered);
|
||||
BLI_assert((prev != nullptr) || (next != nullptr));
|
||||
Vector<ID *> ordered = BKE_id_ordered_list(&bmain->workspaces);
|
||||
const int index = ordered.first_index_of(&workspace->id);
|
||||
|
||||
WorkSpace *new_active = reinterpret_cast<WorkSpace *>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user