Add new parameter to reverse UIList items
authorAntonioya <blendergit@gmail.com>
Thu, 11 Oct 2018 15:47:46 +0000 (17:47 +0200)
committerAntonioya <blendergit@gmail.com>
Thu, 11 Oct 2018 16:30:09 +0000 (18:30 +0200)
Now, it was possible to invert the order of the UIlist using the filter, but it was impossible to know if the list was inverted or not.

The problem with this is that any other element depending of this value could not be adjusted.

See https://devtalk.blender.org/t/how-to-access-uilist-properties/2268

The new parameter allows to set the reverse order by default. When the list is set as reverse, it cannot be inverted again, so the invert button is removed of the filter.

This change is needed to fix a requested feature for Grease Pencil (T56985) and because a lot of 2D softwares use the drawing layers in the inverse order used in Blender.

source/blender/blenkernel/BKE_screen.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_buttons.c
source/blender/makesrna/intern/rna_ui.c
source/blender/makesrna/intern/rna_ui_api.c

index aaaaf620afad9b8eeff17b86fe35089fdcb673d5..58058d1e1344062855fdf855b9f9654a0feedbeb 100644 (file)
@@ -238,7 +238,7 @@ typedef void (*uiListDrawItemFunc)(
 
 /* Draw the filtering part of an uiList */
 typedef void (*uiListDrawFilterFunc)(
-        struct uiList *ui_list, struct bContext *C, struct uiLayout *layout);
+        struct uiList *ui_list, struct bContext *C, struct uiLayout *layout, bool reverse);
 
 /* Filter items of an uiList */
 typedef void (*uiListFilterItemsFunc)(
index 13d1c2b89161f39149f507e62351c1ece1901209..92423d84c3f2e3aaaef213ddc3af04a9386ff61a 100644 (file)
@@ -1120,7 +1120,7 @@ void uiTemplateList(
         uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id,
         struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr,
         const char *active_propname, const char *item_dyntip_propname,
-        int rows, int maxrows, int layout_type, int columns);
+        int rows, int maxrows, int layout_type, int columns, bool reverse);
 void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
 void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
 void uiTemplateTextureUser(uiLayout *layout, struct bContext *C);
index 67ab9aa7f44dae47c8d94b18b52a0a3fd8c2d3ea..aee426280c24cd4c5e52d355daf1cef0a62291c6 100644 (file)
@@ -3474,7 +3474,7 @@ static void uilist_draw_item_default(
        }
 }
 
-static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout)
+static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout, bool reverse)
 {
        PointerRNA listptr;
        uiLayout *row, *subrow;
@@ -3488,10 +3488,13 @@ static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *
        uiItemR(subrow, &listptr, "use_filter_invert", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "",
                (ui_list->filter_flag & UILST_FLT_EXCLUDE) ? ICON_ZOOM_OUT : ICON_ZOOM_IN);
 
-       subrow = uiLayoutRow(row, true);
-       uiItemR(subrow, &listptr, "use_filter_sort_alpha", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-       uiItemR(subrow, &listptr, "use_filter_sort_reverse", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "",
-               (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
+       /* a reverse list, cannot sort or invert order in filter */
+       if (!reverse) {
+               subrow = uiLayoutRow(row, true);
+               uiItemR(subrow, &listptr, "use_filter_sort_alpha", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+               uiItemR(subrow, &listptr, "use_filter_sort_reverse", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "",
+                       (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
+       }
 }
 
 typedef struct {
@@ -3714,7 +3717,7 @@ static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const cha
 void uiTemplateList(
         uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
         PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
-        const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns)
+        const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, bool reverse)
 {
        uiListType *ui_list_type;
        uiList *ui_list = NULL;
@@ -3835,6 +3838,11 @@ void uiTemplateList(
        MEM_SAFE_FREE(dyn_data->items_filter_neworder);
        dyn_data->items_len = dyn_data->items_shown = -1;
 
+       /* if reverse, enable reverse flag */
+       if (reverse) {
+               ui_list->filter_sort_flag |= UILST_FLT_SORT_REVERSE;
+       }
+
        /* When active item changed since last draw, scroll to it. */
        if (activei != ui_list->list_last_activei) {
                ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
@@ -4112,7 +4120,7 @@ void uiTemplateList(
                        subblock = uiLayoutGetBlock(col);
                        uiDefBut(subblock, UI_BTYPE_SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, "");
 
-                       draw_filter(ui_list, C, col);
+                       draw_filter(ui_list, C, col, reverse);
                }
                else {
                        but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0,
index fa2fc44645acf5a69d49995ce6b7da2f5259d020..65170c7c203c9a20a53d95bbfb1861e34ec34038 100644 (file)
@@ -1795,13 +1795,13 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
        /* using different collection properties if multilayer format is enabled */
        if (multilayer) {
                uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index",
-                              NULL, 0, 0, 0, 0);
+                              NULL, 0, 0, 0, 0, false);
                RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"),
                                                   active_index, &active_input_ptr);
        }
        else {
                uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index",
-                              NULL, 0, 0, 0, 0);
+                              NULL, 0, 0, 0, 0, false);
                RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"),
                                                   active_index, &active_input_ptr);
        }
index c2efc548c30eff271b186289f02cb9b2b56f1f90..0a913bcbea8f92840b6e9ccbdb224bd88b855a09 100644 (file)
@@ -150,14 +150,14 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
        ot = WM_operatortype_find("NODE_OT_tree_socket_add", false);
        uiItemL(col, IFACE_("Inputs:"), ICON_NONE);
        uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input",
-                      NULL, 0, 0, 0, 0);
+                      NULL, 0, 0, 0, 0, false);
        uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
        RNA_enum_set(&opptr, "in_out", SOCK_IN);
 
        col = uiLayoutColumn(split, true);
        uiItemL(col, IFACE_("Outputs:"), ICON_NONE);
        uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output",
-                      NULL, 0, 0, 0, 0);
+                      NULL, 0, 0, 0, 0, false);
        uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
        RNA_enum_set(&opptr, "in_out", SOCK_OUT);
 
index 333181b35930a86ae2e5839e8cf25818c335bcbe..0756d5e39eed970bd0c3c786680a5415d0ea054b 100644 (file)
@@ -378,7 +378,7 @@ static void uilist_draw_item(uiList *ui_list, bContext *C, uiLayout *layout, Poi
        RNA_parameter_list_free(&list);
 }
 
-static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout)
+static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout, bool reverse)
 {
        extern FunctionRNA rna_UIList_draw_filter_func;
 
@@ -392,6 +392,7 @@ static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout)
        RNA_parameter_list_create(&list, &ul_ptr, func);
        RNA_parameter_set_lookup(&list, "context", &C);
        RNA_parameter_set_lookup(&list, "layout", &layout);
+       RNA_parameter_set_lookup(&list, "reverse", &reverse);
        ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
 
        RNA_parameter_list_free(&list);
@@ -1307,6 +1308,7 @@ static void rna_def_uilist(BlenderRNA *brna)
        RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
        parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
        RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+       RNA_def_boolean(func, "reverse", false, "", "Display items in reverse order");
 
        /* filter */
        func = RNA_def_function(srna, "filter_items", NULL);
index f2d97833bd9052ad39f62708d8bad3e2538b9a6e..4adf10fedee87cba8a405399d38f9e7789b1cd1e 100644 (file)
@@ -1024,7 +1024,8 @@ void RNA_api_ui_layout(StructRNA *srna)
        RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Default maximum number of rows to display", 0, INT_MAX);
        RNA_def_enum(func, "type", rna_enum_uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use");
        RNA_def_int(func, "columns", 9, 0, INT_MAX, "", "Number of items to display per row, for GRID layout", 0, INT_MAX);
-
+       RNA_def_boolean(func, "reverse", false, "", "Display items in reverse order");
+       
        func = RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
        RNA_def_function_flag(func, FUNC_USE_CONTEXT);