Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-08-23 17:13:52 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-09-11 13:43:28 +0300
commite1178266e713ae7184fc60c3ecb93d42d8b28a53 (patch)
tree5cea7a841344925a7423a3b50205c0acfbd08074 /source/blender/blenkernel
parent6acf8642e5c464a0879cf37e3f39cd3e526a2019 (diff)
Workspace: support reordering of workspaces from RMB menu.
Drag and drop will follow later, it's a bit complicated to make this work reliable in the current UI code.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_library.h3
-rw-r--r--source/blender/blenkernel/intern/library.c95
2 files changed, 98 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 50447e02fe5..050e9368a43 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -214,6 +214,9 @@ void BKE_id_tag_clear_atomic(struct ID *id, int tag);
bool BKE_id_is_in_gobal_main(struct ID *id);
+void BKE_id_ordered_list(struct ListBase *ordered_lb, const struct ListBase *lb);
+void BKE_id_reorder(const struct ListBase *lb, struct ID *id, struct ID *relative, bool after);
+
/* use when "" is given to new_id() */
#define ID_FALLBACK_NAME N_("Untitled")
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 04ebaaf80b7..84aa75abc72 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -2596,3 +2596,98 @@ bool BKE_id_is_in_gobal_main(ID *id)
/* We do not want to fail when id is NULL here, even though this is a bit strange behavior... */
return (id == NULL || BLI_findindex(which_libbase(G_MAIN, GS(id->name)), id) != -1);
}
+
+/************************* Datablock order in UI **************************/
+
+static int *id_order_get(ID *id)
+{
+ /* Only for workspace tabs currently. */
+ switch (GS(id->name)) {
+ case ID_WS:
+ return &((WorkSpace *)id)->order;
+ default:
+ return NULL;
+ }
+}
+
+static int id_order_compare(const void *a, const void *b)
+{
+ ID *id_a = ((LinkData *)a)->data;
+ ID *id_b = ((LinkData *)b)->data;
+
+ int *order_a = id_order_get(id_a);
+ int *order_b = id_order_get(id_b);
+
+ if (order_a && order_b) {
+ if (*order_a < *order_b) {
+ return -1;
+ }
+ else if (*order_a > *order_b) {
+ return 1;
+ }
+ }
+
+ return strcmp(id_a->name, id_b->name);
+}
+
+/**
+ * Returns ordered list of datablocks 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)
+{
+ BLI_listbase_clear(ordered_lb);
+
+ for (ID *id = lb->first; id; id = id->next) {
+ BLI_addtail(ordered_lb, BLI_genericNodeN(id));
+ }
+
+ BLI_listbase_sort(ordered_lb, id_order_compare);
+
+ int num = 0;
+ for (LinkData *link = ordered_lb->first; link; link = link->next) {
+ int *order = id_order_get(link->data);
+ if (order) {
+ *order = num++;
+ }
+ }
+}
+
+/**
+ * Reorder ID in the list, before or after the "relative" ID.
+ */
+void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
+{
+ int *id_order = id_order_get(id);
+ int relative_order;
+
+ if (relative) {
+ relative_order = *id_order_get(relative);
+ }
+ else {
+ relative_order = (after) ? BLI_listbase_count(lb) : 0;
+ }
+
+ if (after) {
+ /* Insert after. */
+ for (ID *other = lb->first; other; other = other->next) {
+ int *order = id_order_get(other);
+ if (*order > relative_order) {
+ (*order)++;
+ }
+ }
+
+ *id_order = relative_order + 1;
+ }
+ else {
+ /* Insert before. */
+ for (ID *other = lb->first; other; other = other->next) {
+ int *order = id_order_get(other);
+ if (*order < relative_order) {
+ (*order)--;
+ }
+ }
+
+ *id_order = relative_order - 1;
+ }
+}