UI: Show library status icons in search menus, rather than letter prefix
Rather than a `L` (linked), `O` (overridden) or `M` (missing) prefix for the name, show the existing library status icons. See D7999 for screenshots. Note that when using preview icons, or if the search menu contains items with own icons (e.g. brush icons), we still fallback to the prefix solution. Zero or fake user is still indicated with a prefix. Differential Revision: https://developer.blender.org/D7999 Reviewed by: Bastien Montagne, William Reynish
This commit is contained in:
parent
5024c54271
commit
937d89afba
Notes:
blender-bot
2024-03-22 15:57:27 +01:00
Referenced by commit 26d5c24f0a
, Fix T80258: UILayout.prop_search() issues with datablock names
Referenced by issue #78588, Material preview not visible in selection list
|
@ -267,6 +267,7 @@ void BKE_main_id_repair_duplicate_names_listbase(struct ListBase *lb);
|
|||
void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const struct ID *id, char separator_str);
|
||||
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
|
||||
const struct ID *id,
|
||||
const bool add_lib_hint,
|
||||
char separator_char);
|
||||
|
||||
char *BKE_id_to_unique_string_key(const struct ID *id);
|
||||
|
|
|
@ -2175,13 +2175,18 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
|
|||
*/
|
||||
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
|
||||
const ID *id,
|
||||
const bool add_lib_hint,
|
||||
char separator_char)
|
||||
{
|
||||
name[0] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' ';
|
||||
name[1] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' ');
|
||||
name[2] = ' ';
|
||||
int i = 0;
|
||||
|
||||
BKE_id_full_name_get(name + 3, id, separator_char);
|
||||
if (add_lib_hint) {
|
||||
name[i++] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' ';
|
||||
}
|
||||
name[i++] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' ');
|
||||
name[i++] = ' ';
|
||||
|
||||
BKE_id_full_name_get(name + i, id, separator_char);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -106,6 +106,7 @@ struct PreviewImage *UI_icon_to_preview(int icon_id);
|
|||
|
||||
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big);
|
||||
int UI_idcode_icon_get(const int idcode);
|
||||
int UI_library_icon_get(const struct ID *id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -2192,6 +2192,26 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
|
|||
return iconid;
|
||||
}
|
||||
|
||||
int UI_library_icon_get(const ID *id)
|
||||
{
|
||||
if (ID_IS_LINKED(id)) {
|
||||
if (id->tag & LIB_TAG_MISSING) {
|
||||
return ICON_LIBRARY_DATA_BROKEN;
|
||||
}
|
||||
else if (id->tag & LIB_TAG_INDIRECT) {
|
||||
return ICON_LIBRARY_DATA_INDIRECT;
|
||||
}
|
||||
else {
|
||||
return ICON_LIBRARY_DATA_DIRECT;
|
||||
}
|
||||
}
|
||||
else if (ID_IS_OVERRIDE_LIBRARY(id)) {
|
||||
return ICON_LIBRARY_DATA_OVERRIDE;
|
||||
}
|
||||
|
||||
return ICON_NONE;
|
||||
}
|
||||
|
||||
int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, const bool big)
|
||||
{
|
||||
ID *id = NULL;
|
||||
|
|
|
@ -77,6 +77,9 @@ struct uiSearchItems {
|
|||
int *icons;
|
||||
int *states;
|
||||
|
||||
/** Is there any item with an icon? */
|
||||
bool has_icon;
|
||||
|
||||
AutoComplete *autocpl;
|
||||
void *active;
|
||||
};
|
||||
|
@ -122,6 +125,10 @@ bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int
|
|||
return true;
|
||||
}
|
||||
|
||||
if (iconid) {
|
||||
items->has_icon = true;
|
||||
}
|
||||
|
||||
/* hijack for finding active item */
|
||||
if (items->active) {
|
||||
if (poin == items->active) {
|
||||
|
@ -562,6 +569,10 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
|
|||
/* widget itself */
|
||||
if ((search_sep_len == 0) ||
|
||||
!(name_sep_test = strstr(data->items.names[a], data->sep_string))) {
|
||||
if (!icon && data->items.has_icon) {
|
||||
/* If there is any icon item, make sure all items line up. */
|
||||
icon = ICON_BLANK1;
|
||||
}
|
||||
|
||||
/* Simple menu item. */
|
||||
ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, use_sep_char, NULL);
|
||||
|
|
|
@ -361,11 +361,16 @@ static bool id_search_add(const bContext *C,
|
|||
* followed by ID_NAME-2 characters from id->name
|
||||
*/
|
||||
char name_ui[MAX_ID_FULL_NAME_UI];
|
||||
BKE_id_full_name_ui_prefix_get(name_ui, id, UI_SEP_CHAR);
|
||||
|
||||
int iconid = ui_id_icon_get(C, id, template_ui->preview);
|
||||
bool has_sep_char = (id->lib != NULL);
|
||||
|
||||
/* When using previews, the library hint (linked, overriden, missing) is added with a
|
||||
* character prefix, otherwise we can use a icon. */
|
||||
BKE_id_full_name_ui_prefix_get(name_ui, id, template_ui->preview, UI_SEP_CHAR);
|
||||
if (!template_ui->preview) {
|
||||
iconid = UI_library_icon_get(id);
|
||||
}
|
||||
|
||||
if (!UI_search_item_add(
|
||||
items, name_ui, id, iconid, has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
|
||||
return false;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface_icons.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
@ -384,6 +385,7 @@ typedef struct CollItemSearch {
|
|||
char *name;
|
||||
int index;
|
||||
int iconid;
|
||||
bool is_id;
|
||||
uint has_sep_char : 1;
|
||||
} CollItemSearch;
|
||||
|
||||
|
@ -418,6 +420,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
|||
const bool skip_filter = data->search_but && !data->search_but->changed;
|
||||
char name_buf[UI_MAX_DRAW_STR];
|
||||
char *name;
|
||||
bool has_id_icon = false;
|
||||
|
||||
/* build a temporary list of relevant items first */
|
||||
RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop) {
|
||||
|
@ -437,16 +440,20 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
|||
|
||||
int iconid = ICON_NONE;
|
||||
bool has_sep_char = false;
|
||||
bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
|
||||
|
||||
if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
|
||||
if (is_id) {
|
||||
iconid = ui_id_icon_get(C, itemptr.data, false);
|
||||
if (!ELEM(iconid, 0, ICON_BLANK1)) {
|
||||
has_id_icon = true;
|
||||
}
|
||||
|
||||
if (requires_exact_data_name) {
|
||||
name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), NULL);
|
||||
}
|
||||
else {
|
||||
const ID *id = itemptr.data;
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, id, UI_SEP_CHAR);
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, itemptr.data, true, UI_SEP_CHAR);
|
||||
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
|
||||
"Name string buffer should be big enough to hold full UI ID name");
|
||||
name = name_buf;
|
||||
|
@ -464,6 +471,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
|||
cis->name = BLI_strdup(name);
|
||||
cis->index = i;
|
||||
cis->iconid = iconid;
|
||||
cis->is_id = is_id;
|
||||
cis->has_sep_char = has_sep_char;
|
||||
BLI_addtail(items_list, cis);
|
||||
}
|
||||
|
@ -480,6 +488,17 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
|||
|
||||
/* add search items from temporary list */
|
||||
for (cis = items_list->first; cis; cis = cis->next) {
|
||||
/* If no item has an own icon to display, libraries can use the library icons rather than the
|
||||
* name prefix for showing the library status. */
|
||||
if (!has_id_icon && cis->is_id) {
|
||||
cis->iconid = UI_library_icon_get(cis->data);
|
||||
/* No need to re-allocate, string should be shorter than before (lib status prefix is
|
||||
* removed). */
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR);
|
||||
BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
|
||||
strcpy(cis->name, name_buf);
|
||||
}
|
||||
|
||||
if (!UI_search_item_add(items,
|
||||
cis->name,
|
||||
cis->data,
|
||||
|
|
|
@ -3108,33 +3108,13 @@ static void outliner_draw_tree_element(bContext *C,
|
|||
offsx += 2 * ufac;
|
||||
}
|
||||
|
||||
if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_LINKED(tselem->id)) {
|
||||
if (tselem->id->tag & LIB_TAG_MISSING) {
|
||||
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
|
||||
(float)*starty + 2 * ufac,
|
||||
ICON_LIBRARY_DATA_BROKEN,
|
||||
alpha_fac);
|
||||
if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
|
||||
const BIFIconID lib_icon = UI_library_icon_get(tselem->id);
|
||||
if (lib_icon != ICON_NONE) {
|
||||
UI_icon_draw_alpha(
|
||||
(float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, lib_icon, alpha_fac);
|
||||
offsx += UI_UNIT_X + 4 * ufac;
|
||||
}
|
||||
else if (tselem->id->tag & LIB_TAG_INDIRECT) {
|
||||
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
|
||||
(float)*starty + 2 * ufac,
|
||||
ICON_LIBRARY_DATA_INDIRECT,
|
||||
alpha_fac);
|
||||
}
|
||||
else {
|
||||
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
|
||||
(float)*starty + 2 * ufac,
|
||||
ICON_LIBRARY_DATA_DIRECT,
|
||||
alpha_fac);
|
||||
}
|
||||
offsx += UI_UNIT_X + 4 * ufac;
|
||||
}
|
||||
else if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_OVERRIDE_LIBRARY(tselem->id)) {
|
||||
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
|
||||
(float)*starty + 2 * ufac,
|
||||
ICON_LIBRARY_DATA_OVERRIDE,
|
||||
alpha_fac);
|
||||
offsx += UI_UNIT_X + 4 * ufac;
|
||||
}
|
||||
GPU_blend(false);
|
||||
|
||||
|
|
Loading…
Reference in New Issue