diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index 8f515ec7707..29197c67045 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -1686,6 +1686,8 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name); */ void UI_but_hint_drawstr_set(uiBut *but, const char *string); void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number); +void UI_but_icon_indicator_set(uiBut *but, const char *string); +void UI_but_icon_indicator_color_set(uiBut *but, const uchar color[4]); void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4]); diff --git a/source/blender/editors/include/UI_interface_icons.hh b/source/blender/editors/include/UI_interface_icons.hh index d31f1a12660..3741ab9e24e 100644 --- a/source/blender/editors/include/UI_interface_icons.hh +++ b/source/blender/editors/include/UI_interface_icons.hh @@ -30,6 +30,7 @@ struct IconFile { struct IconTextOverlay { char text[5]; + uchar color[4] = {0}; }; #define UI_NO_ICON_OVERLAY_TEXT NULL diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 4538e84207f..6e5401ba2a4 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -6258,6 +6258,16 @@ void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number) UI_icon_text_overlay_init_from_count(&but->icon_overlay_text, indicator_number); } +void UI_but_icon_indicator_set(uiBut *but, const char *string) +{ + STRNCPY(but->icon_overlay_text.text, string); +} + +void UI_but_icon_indicator_color_set(uiBut *but, const uchar color[4]) +{ + copy_v4_v4_uchar(but->icon_overlay_text.color, color); +} + void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4]) { but->flag |= UI_BUT_NODE_LINK; diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index f8c8dffe419..26e75e3453a 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -1883,8 +1883,12 @@ static void icon_draw_texture(float x, if (show_indicator) { /* Handle the little numbers on top of the icon. */ uchar text_color[4]; - UI_GetThemeColor3ubv(TH_TEXT, text_color); - text_color[3] = 255; + if (text_overlay->color[3]) { + copy_v4_v4_uchar(text_color, text_overlay->color); + } + else { + UI_GetThemeColor4ubv(TH_TEXT, text_color); + } uiFontStyle fstyle_small = *UI_FSTYLE_WIDGET; fstyle_small.points *= zoom_factor; diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 189b25ead2f..2f8568b21c1 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -1761,56 +1761,83 @@ static void outliner_draw_userbuts(uiBlock *block, } const TreeStoreElem *tselem = TREESTORE(te); - if (tselem->type != TSE_SOME_ID) { + ID *id = tselem->id; + + if (tselem->type != TSE_SOME_ID || id->tag & LIB_TAG_EXTRAUSER) { return; } uiBut *bt; - ID *id = tselem->id; const char *tip = nullptr; - char buf[BLI_STR_FORMAT_INT32_GROUPED_SIZE] = ""; - int but_flag = UI_BUT_DRAG_LOCK; + const int real_users = id->us - ID_FAKE_USERS(id); + const bool has_fake_user = id->flag & LIB_FAKEUSER; + const bool is_linked = ID_IS_LINKED(id); + const bool is_object = GS(id->name) == ID_OB; + char overlay[5]; + BLI_str_format_integer_unit(overlay, id->us); - if (ID_IS_LINKED(id)) { - but_flag |= UI_BUT_DISABLED; - } - - BLI_str_format_int_grouped(buf, id->us); - bt = uiDefBut(block, - UI_BTYPE_BUT, - 1, - buf, - int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS), - te->ys, - UI_UNIT_X, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - TIP_("Number of users of this data-block")); - UI_but_flag_enable(bt, but_flag); - - if (id->flag & LIB_FAKEUSER) { - tip = TIP_("Data-block will be retained using a fake user"); + if (is_object) { + bt = uiDefBut(block, + UI_BTYPE_BUT, + 0, + overlay, + int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + TIP_("Number of users")); } else { - tip = TIP_("Data-block has no users and will be deleted"); + + if (has_fake_user) { + tip = is_linked ? TIP_("Item is protected from deletion") : + TIP_("Click to remove protection from deletion"); + } + else { + if (real_users) { + tip = is_linked ? TIP_("Item is not protected from deletion") : + TIP_("Click to add protection from deletion"); + } + else { + tip = is_linked ? + TIP_("Item has no users and will be removed") : + TIP_("Item has no users and will be removed.\nClick to protect from deletion"); + } + } + + bt = uiDefIconButBitS(block, + UI_BTYPE_ICON_TOGGLE, + LIB_FAKEUSER, + 1, + ICON_FAKE_USER_OFF, + int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &id->flag, + 0, + 0, + tip); + + if (is_linked) { + UI_but_flag_enable(bt, UI_BUT_DISABLED); + } + else { + UI_but_func_set(bt, restrictbutton_id_user_toggle, id, nullptr); + /* Allow _inaccurate_ dragging over multiple toggles. */ + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + } + + if (!real_users && !has_fake_user) { + uchar overlay_color[4]; + UI_GetThemeColor4ubv(TH_REDALERT, overlay_color); + UI_but_icon_indicator_color_set(bt, overlay_color); + } + UI_but_icon_indicator_set(bt, overlay); } - bt = uiDefIconButBitS(block, - UI_BTYPE_ICON_TOGGLE, - LIB_FAKEUSER, - 1, - ICON_FAKE_USER_OFF, - int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS), - te->ys, - UI_UNIT_X, - UI_UNIT_Y, - &id->flag, - 0, - 0, - tip); - UI_but_func_set(bt, restrictbutton_id_user_toggle, id, nullptr); - UI_but_flag_enable(bt, but_flag); }); } @@ -4040,8 +4067,7 @@ void draw_outliner(const bContext *C) outliner_draw_rnabuts(block, region, space_outliner, buttons_start_x); UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); } - else if (space_outliner->outlinevis == SO_ID_ORPHANS) { - /* draw user toggle columns */ + else if (ELEM(space_outliner->outlinevis, SO_ID_ORPHANS, SO_LIBRARIES)) { outliner_draw_userbuts(block, region, space_outliner); } else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) { diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh index 7e7204eaadf..681bb659bec 100644 --- a/source/blender/editors/space_outliner/outliner_intern.hh +++ b/source/blender/editors/space_outliner/outliner_intern.hh @@ -203,8 +203,7 @@ enum eOLSetState { /* size constants */ #define OL_Y_OFFSET 2 -#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH) -#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X + V2D_SCROLL_WIDTH) +#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 1.2f + V2D_SCROLL_WIDTH) #define OL_RNA_COLX (UI_UNIT_X * 15) #define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)