UI: Add Optional Flags for Tooltip Image Fields #119437
|
@ -1722,6 +1722,21 @@ enum uiTooltipColorID {
|
|||
UI_TIP_LC_MAX
|
||||
};
|
||||
|
||||
enum uiTooltipFlag {
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
UI_TIP_FLAG_NONE = 0,
|
||||
/* Regular checkerboard pattern, with themed colors. */
|
||||
UI_TIP_FLAG_IMAGE_CHECKER = 1 << 0,
|
||||
/* Checkerboard pattern with fixed colors used for themes. */
|
||||
UI_TIP_FLAG_IMAGE_CHECKER_FIXED = 1 << 1,
|
||||
/* Border around the image. */
|
||||
UI_TIP_FLAG_IMAGE_BORDER = 1 << 2,
|
||||
/* Blend as premultiplied alpha. */
|
||||
UI_TIP_FLAG_IMAGE_PREMULTIPLIED = 1 << 3,
|
||||
/* Recolor the image with text color. */
|
||||
UI_TIP_FLAG_IMAGE_TEXTCOLOR = 1 << 4,
|
||||
};
|
||||
ENUM_OPERATORS(uiTooltipFlag, UI_TIP_FLAG_IMAGE_TEXTCOLOR)
|
||||
|
||||
void UI_but_func_tooltip_custom_set(uiBut *but,
|
||||
uiButToolTipCustomFunc func,
|
||||
void *arg,
|
||||
|
@ -1742,8 +1757,10 @@ void UI_tooltip_text_field_add(uiTooltipData *data,
|
|||
* \param image: Image buffer (duplicated, ownership is *not* transferred to `data`).
|
||||
* \param image_size: Display size for the image (pixels without UI scale applied).
|
||||
*/
|
||||
void UI_tooltip_image_field_add(uiTooltipData *data, const ImBuf *image, const short image_size[2])
|
||||
ATTR_NONNULL(1, 2, 3);
|
||||
void UI_tooltip_image_field_add(uiTooltipData *data,
|
||||
const ImBuf *image,
|
||||
const short image_size[2],
|
||||
uiTooltipFlag flag = UI_TIP_FLAG_NONE) ATTR_NONNULL(1, 2, 3);
|
||||
|
||||
/**
|
||||
* Recreate tool-tip (use to update dynamic tips)
|
||||
|
|
|
@ -92,6 +92,7 @@ struct uiTooltipField {
|
|||
uiTooltipFormat format;
|
||||
ImBuf *image;
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
`std::optional` seems simpler here than allocating a struct. I don't see a matching `delete` in this PR, so I'd expect a memory leak currently.
|
||||
short image_size[2];
|
||||
uiTooltipFlag flag = UI_TIP_FLAG_NONE;
|
||||
};
|
||||
|
||||
struct uiTooltipData {
|
||||
|
@ -124,13 +125,17 @@ void UI_tooltip_text_field_add(uiTooltipData *data,
|
|||
data->fields.append(std::move(field));
|
||||
}
|
||||
Harley marked this conversation as resolved
Outdated
Hans Goudey
commented
Think I'd pass this by const reference, it's not a small struct and it's not being Think I'd pass this by const reference, it's not a small struct and it's not being `std::move`d here
|
||||
|
||||
void UI_tooltip_image_field_add(uiTooltipData *data, const ImBuf *image, const short image_size[2])
|
||||
void UI_tooltip_image_field_add(uiTooltipData *data,
|
||||
const ImBuf *image,
|
||||
const short image_size[2],
|
||||
uiTooltipFlag flag)
|
||||
{
|
||||
uiTooltipField field{};
|
||||
field.format.style = UI_TIP_STYLE_IMAGE;
|
||||
field.image = IMB_dupImBuf(image);
|
||||
field.image_size[0] = std::min(image_size[0], short(UI_TIP_MAXIMAGEWIDTH * UI_SCALE_FAC));
|
||||
field.image_size[1] = std::min(image_size[1], short(UI_TIP_MAXIMAGEHEIGHT * UI_SCALE_FAC));
|
||||
field.flag = flag;
|
||||
data->fields.append(std::move(field));
|
||||
}
|
||||
|
||||
|
@ -259,13 +264,28 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
|
|||
|
||||
bbox.ymax -= field->image_size[1];
|
||||
|
||||
/* Draw checker pattern behind the image in case is has transparency. */
|
||||
imm_draw_box_checker_2d(float(bbox.xmin),
|
||||
float(bbox.ymax),
|
||||
float(bbox.xmin + field->image_size[0]),
|
||||
float(bbox.ymax + field->image_size[1]));
|
||||
if (field->flag & UI_TIP_FLAG_IMAGE_CHECKER) {
|
||||
imm_draw_box_checker_2d(float(bbox.xmin),
|
||||
float(bbox.ymax),
|
||||
float(bbox.xmin + field->image_size[0]),
|
||||
float(bbox.ymax + field->image_size[1]));
|
||||
}
|
||||
else if (field->flag & UI_TIP_FLAG_IMAGE_CHECKER_FIXED) {
|
||||
const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f;
|
||||
const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f;
|
||||
const float color1[4] = {checker_dark, checker_dark, checker_dark, 1.0f};
|
||||
const float color2[4] = {checker_light, checker_light, checker_light, 1.0f};
|
||||
imm_draw_box_checker_2d_ex(float(bbox.xmin + U.pixelsize),
|
||||
float(bbox.ymax + U.pixelsize),
|
||||
float(bbox.xmin + field->image_size[0]),
|
||||
float(bbox.ymax + field->image_size[1]),
|
||||
color1,
|
||||
color2,
|
||||
8);
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
|
||||
GPU_blend((field->flag & UI_TIP_FLAG_IMAGE_PREMULTIPLIED) ? GPU_BLEND_ALPHA_PREMULT :
|
||||
GPU_BLEND_ALPHA);
|
||||
|
||||
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
|
||||
immDrawPixelsTexScaledFullSize(&state,
|
||||
|
@ -280,30 +300,31 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
|
|||
1.0f,
|
||||
float(field->image_size[0]) / float(field->image->x),
|
||||
float(field->image_size[1]) / float(field->image->y),
|
||||
nullptr);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
(field->flag & UI_TIP_FLAG_IMAGE_TEXTCOLOR) ? main_color :
|
||||
nullptr);
|
||||
|
||||
/* Draw border around it. */
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
float border_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
|
||||
float bgcolor[4];
|
||||
UI_GetThemeColor4fv(TH_BACK, bgcolor);
|
||||
if (rgb_to_grayscale(bgcolor) > 0.5f) {
|
||||
border_color[0] = 0.0f;
|
||||
border_color[1] = 0.0f;
|
||||
border_color[2] = 0.0f;
|
||||
if (field->flag & UI_TIP_FLAG_IMAGE_BORDER) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
float border_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
|
||||
float bgcolor[4];
|
||||
UI_GetThemeColor4fv(TH_BACK, bgcolor);
|
||||
if (rgb_to_grayscale(bgcolor) > 0.5f) {
|
||||
border_color[0] = 0.0f;
|
||||
border_color[1] = 0.0f;
|
||||
border_color[2] = 0.0f;
|
||||
}
|
||||
immUniformColor4fv(border_color);
|
||||
imm_draw_box_wire_2d(pos,
|
||||
float(bbox.xmin),
|
||||
float(bbox.ymax),
|
||||
float(bbox.xmin + field->image_size[0]),
|
||||
float(bbox.ymax + field->image_size[1]));
|
||||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
immUniformColor4fv(border_color);
|
||||
imm_draw_box_wire_2d(pos,
|
||||
float(bbox.xmin),
|
||||
float(bbox.ymax),
|
||||
float(bbox.xmin + field->image_size[0]),
|
||||
float(bbox.ymax + field->image_size[1]));
|
||||
immUnbindProgram();
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
else if (field->format.style == UI_TIP_STYLE_SPACER) {
|
||||
bbox.ymax -= data->lineh * UI_TIP_SPACER;
|
||||
|
|
|
@ -6899,7 +6899,11 @@ static void uiTemplateRecentFiles_tooltip_func(bContext * /*C*/, uiTooltipData *
|
|||
short size[2] = {short(float(thumb->x) * scale), short(float(thumb->y) * scale)};
|
||||
UI_tooltip_text_field_add(tip, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
|
||||
UI_tooltip_text_field_add(tip, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
|
||||
UI_tooltip_image_field_add(tip, thumb, size);
|
||||
UI_tooltip_image_field_add(tip,
|
||||
thumb,
|
||||
size,
|
||||
UI_TIP_FLAG_IMAGE_CHECKER | UI_TIP_FLAG_IMAGE_PREMULTIPLIED |
|
||||
UI_TIP_FLAG_IMAGE_BORDER);
|
||||
IMB_freeImBuf(thumb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,11 @@ static void file_draw_tooltip_custom_func(bContext * /*C*/, uiTooltipData *tip,
|
|||
short size[2] = {short(float(thumb->x) * scale), short(float(thumb->y) * scale)};
|
||||
UI_tooltip_text_field_add(tip, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
|
||||
UI_tooltip_text_field_add(tip, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
|
||||
UI_tooltip_image_field_add(tip, thumb, size);
|
||||
UI_tooltip_image_field_add(tip,
|
||||
thumb,
|
||||
size,
|
||||
UI_TIP_FLAG_IMAGE_CHECKER | UI_TIP_FLAG_IMAGE_PREMULTIPLIED |
|
||||
UI_TIP_FLAG_IMAGE_BORDER);
|
||||
}
|
||||
|
||||
if (thumb && free_imbuf) {
|
||||
|
|
Loading…
Reference in New Issue
How about this :)