WIP: UI: Icon Overlays #121138

Draft
Harley Acheson wants to merge 1 commits from Harley/blender:IconOverlays into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 65 additions and 37 deletions

View File

@ -28,9 +28,11 @@ struct IconFile {
int index;
};
struct IconTextOverlay {
struct IconOverlay {
char text[5];
uchar color[4] = {0};
uchar text_color[4] = {0};
int icon = 0;
uchar icon_color[4] = {0};
};
#define UI_NO_ICON_OVERLAY_TEXT NULL
@ -111,7 +113,7 @@ void UI_icon_draw_ex(float x,
float desaturate,
const uchar mono_color[4],
bool mono_border,
const IconTextOverlay *text_overlay);
const IconOverlay *icon_overlay);
/**
* Draw an monochrome icon into a given coordinate rectangle. The rectangle is used as-is,
@ -138,5 +140,5 @@ int UI_icon_from_library(const ID *id);
int UI_icon_from_object_mode(int mode);
int UI_icon_color_from_collection(const Collection *collection);
void UI_icon_text_overlay_init_from_count(IconTextOverlay *text_overlay,
void UI_icon_text_overlay_init_from_count(IconOverlay *icon_overlay,
const int icon_indicator_number);

View File

@ -6255,17 +6255,17 @@ void UI_but_hint_drawstr_set(uiBut *but, const char *string)
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);
UI_icon_text_overlay_init_from_count(&but->icon_overlay, indicator_number);
}
void UI_but_icon_indicator_set(uiBut *but, const char *string)
{
STRNCPY(but->icon_overlay_text.text, string);
STRNCPY(but->icon_overlay.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);
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])

View File

@ -1868,20 +1868,20 @@ static void icon_draw_texture(float x,
float alpha,
const float rgb[3],
bool with_border,
const IconTextOverlay *text_overlay)
const IconOverlay *icon_overlay)
{
const float zoom_factor = w / UI_ICON_SIZE;
float text_width = 0.0f;
/* No need to show if too zoomed out, otherwise it just adds noise. */
const bool show_indicator = (text_overlay && text_overlay->text[0] != '\0') &&
const bool show_indicator = (icon_overlay && icon_overlay->text[0] != '\0') &&
(zoom_factor > 0.7f);
if (show_indicator) {
/* Handle the little numbers on top of the icon. */
uchar text_color[4];
if (text_overlay->color[3]) {
copy_v4_v4_uchar(text_color, text_overlay->color);
if (icon_overlay->text_color[3]) {
copy_v4_v4_uchar(text_color, icon_overlay->text_color);
}
else {
UI_GetThemeColor4ubv(TH_TEXT, text_color);
@ -1901,11 +1901,11 @@ static void icon_draw_texture(float x,
params.align = UI_STYLE_TEXT_RIGHT;
UI_fontstyle_draw(&fstyle_small,
&text_rect,
text_overlay->text,
sizeof(text_overlay->text),
icon_overlay->text,
sizeof(icon_overlay->text),
text_color,
&params);
text_width = float(UI_fontstyle_string_width(&fstyle_small, text_overlay->text)) / UI_UNIT_X /
text_width = float(UI_fontstyle_string_width(&fstyle_small, icon_overlay->text)) / UI_UNIT_X /
zoom_factor;
}
@ -1985,7 +1985,7 @@ static void icon_draw_size(float x,
const float desaturate,
const uchar mono_rgba[4],
const bool mono_border,
const IconTextOverlay *text_overlay)
const IconOverlay *icon_overlay)
{
bTheme *btheme = UI_GetTheme();
const float fdraw_size = float(draw_size);
@ -2074,10 +2074,11 @@ static void icon_draw_size(float x,
alpha,
nullptr,
false,
text_overlay);
icon_overlay);
}
else if (di->type == ICON_TYPE_MONO_TEXTURE) {
/* Monochrome icon that uses text or theme color. */
GPU_blend(GPU_BLEND_ALPHA);
const bool with_border = mono_border && (btheme->tui.icon_border_intensity > 0.0f);
float color[4];
if (mono_rgba) {
@ -2109,9 +2110,37 @@ static void icon_draw_size(float x,
color[3],
color,
with_border,
text_overlay);
}
icon_overlay);
if (icon_overlay && icon_overlay->icon) {
float color[4];
/* 60% of main icon width. */
float overlay_w = fdraw_size / aspect * 0.6f;
float overlay_h = fdraw_size / aspect * 0.6f;
float h_offset = w - (0.6f * overlay_w);
float v_offset = h - (0.9f * overlay_h);
if (icon_overlay->icon_color[3]) {
rgba_uchar_to_float(color, icon_overlay->icon_color);
}
else {
UI_GetThemeColor4fv(TH_TEXT, color);
}
Icon *overlay = BKE_icon_get(icon_overlay->icon);
DrawInfo *di = icon_ensure_drawinfo(overlay);
icon_draw_texture(x + h_offset,
y + v_offset,
float(overlay_w),
float(overlay_h),
di->data.texture.x,
di->data.texture.y,
di->data.texture.w,
di->data.texture.h,
color[3],
color,
false,
nullptr);
}
}
else if (di->type == ICON_TYPE_BUFFER) {
/* it is a builtin icon */
IconImage *iimg = di->data.buffer.image;
@ -2676,7 +2705,7 @@ void UI_icon_draw_ex(float x,
float desaturate,
const uchar mono_color[4],
const bool mono_border,
const IconTextOverlay *text_overlay)
const IconOverlay *icon_overlay)
{
const int draw_size = get_draw_size(ICON_SIZE_ICON);
icon_draw_size(x,
@ -2689,7 +2718,7 @@ void UI_icon_draw_ex(float x,
desaturate,
mono_color,
mono_border,
text_overlay);
icon_overlay);
}
void UI_icon_draw_mono_rect(
@ -2721,15 +2750,15 @@ void UI_icon_draw_mono_rect(
nullptr);
}
void UI_icon_text_overlay_init_from_count(IconTextOverlay *text_overlay,
void UI_icon_text_overlay_init_from_count(IconOverlay *icon_overlay,
const int icon_indicator_number)
{
/* The icon indicator is used as an aggregator, no need to show if it is 1. */
if (icon_indicator_number < 2) {
text_overlay->text[0] = '\0';
icon_overlay->text[0] = '\0';
return;
}
BLI_str_format_integer_unit(text_overlay->text, icon_indicator_number);
BLI_str_format_integer_unit(icon_overlay->text, icon_indicator_number);
}
/* ********** Alert Icons ********** */

View File

@ -31,7 +31,7 @@ struct CurveProfile;
namespace blender::gpu {
class Batch;
}
struct IconTextOverlay;
struct IconOverlay;
struct ID;
struct ImBuf;
struct Main;
@ -293,7 +293,7 @@ struct uiBut {
std::function<bool(const uiBut &)> pushed_state_func;
/** Little indicator (e.g., counter) displayed on top of some icons. */
IconTextOverlay icon_overlay_text = {};
IconOverlay icon_overlay = {};
/* pointer back */
uiBlock *block = nullptr;

View File

@ -1356,25 +1356,22 @@ static void widget_draw_icon(
/* to indicate draggable */
if (ui_but_drag_is_draggable(but) && (but->flag & UI_HOVER)) {
UI_icon_draw_ex(
xs, ys, icon, aspect, 1.25f, 0.0f, color, has_theme, &but->icon_overlay_text);
UI_icon_draw_ex(xs, ys, icon, aspect, 1.25f, 0.0f, color, has_theme, &but->icon_overlay);
}
else if (but->flag & (UI_HOVER | UI_SELECT | UI_SELECT_DRAW)) {
UI_icon_draw_ex(
xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay_text);
UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay);
}
else if (!((but->icon != ICON_NONE) && UI_but_is_tool(but))) {
if (has_theme) {
alpha *= 0.8f;
}
UI_icon_draw_ex(
xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay_text);
UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay);
}
else {
const bTheme *btheme = UI_GetTheme();
const float desaturate = 1.0 - btheme->tui.icon_saturation;
UI_icon_draw_ex(
xs, ys, icon, aspect, alpha, desaturate, color, has_theme, &but->icon_overlay_text);
xs, ys, icon, aspect, alpha, desaturate, color, has_theme, &but->icon_overlay);
}
}

View File

@ -2966,8 +2966,8 @@ static bool tselem_draw_icon(uiBlock *block,
}
const bool is_collection = outliner_is_collection_tree_element(te);
IconTextOverlay text_overlay;
UI_icon_text_overlay_init_from_count(&text_overlay, num_elements);
IconOverlay icon_overlay;
UI_icon_text_overlay_init_from_count(&icon_overlay, num_elements);
/* Collection colors and icons covered by restrict buttons. */
if (!is_clickable || x >= xmax || is_collection) {
@ -2988,7 +2988,7 @@ static bool tselem_draw_icon(uiBlock *block,
0.0f,
btheme->collection_color[collection->color_tag].color,
true,
&text_overlay);
&icon_overlay);
return true;
}
}
@ -2999,11 +2999,11 @@ static bool tselem_draw_icon(uiBlock *block,
/* Restrict column clip. it has been coded by simply overdrawing, doesn't work for buttons. */
uchar color[4];
if (UI_icon_get_theme_color(data.icon, color)) {
UI_icon_draw_ex(x, y, data.icon, UI_INV_SCALE_FAC, alpha, 0.0f, color, true, &text_overlay);
UI_icon_draw_ex(x, y, data.icon, UI_INV_SCALE_FAC, alpha, 0.0f, color, true, &icon_overlay);
}
else {
UI_icon_draw_ex(
x, y, data.icon, UI_INV_SCALE_FAC, alpha, 0.0f, nullptr, false, &text_overlay);
x, y, data.icon, UI_INV_SCALE_FAC, alpha, 0.0f, nullptr, false, &icon_overlay);
}
}
else {