Refactor: UI: Use unique_ptr for tooltip data management

Mostly to allow leak-free early exiting from functions generating the
tooltip data, otherwise cleanups have to be duplicated. But using smart
pointers is good practice in general. Also use references instead of
pointers, to indicate that null is not an expected value.
This commit is contained in:
Julian Eisel
2024-07-26 12:24:33 +02:00
parent ddbc34829f
commit 2100623a96
4 changed files with 103 additions and 118 deletions

View File

@@ -614,7 +614,7 @@ using uiButSearchListenFn = void (*)(const wmRegionListenerParams *params, void
/** Must return an allocated string. */
using uiButToolTipFunc = std::string (*)(bContext *C, void *argN, const char *tip);
using uiButToolTipCustomFunc = void (*)(bContext *C, uiTooltipData *data, void *argN);
using uiButToolTipCustomFunc = void (*)(bContext &C, uiTooltipData &data, void *argN);
using uiBlockHandleFunc = void (*)(bContext *C, void *arg, int event);
@@ -1851,7 +1851,7 @@ void UI_but_func_tooltip_custom_set(uiBut *but,
* \param text: Allocated text (transfer ownership to `data`) or null.
* \param suffix: Allocated text (transfer ownership to `data`) or null.
*/
void UI_tooltip_text_field_add(uiTooltipData *data,
void UI_tooltip_text_field_add(uiTooltipData &data,
std::string text,
std::string suffix,
const uiTooltipStyle style,
@@ -1862,7 +1862,7 @@ 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 uiTooltipImage &image_data);
void UI_tooltip_image_field_add(uiTooltipData &data, const uiTooltipImage &image_data);
/**
* Recreate tool-tip (use to update dynamic tips)

View File

@@ -21,6 +21,7 @@
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <fmt/format.h>
@@ -111,7 +112,7 @@ struct uiTooltipData {
BLI_STATIC_ASSERT(int(UI_TIP_LC_MAX) == int(UI_TIP_LC_ALERT) + 1, "invalid lc-max");
void UI_tooltip_text_field_add(uiTooltipData *data,
void UI_tooltip_text_field_add(uiTooltipData &data,
std::string text,
std::string suffix,
const uiTooltipStyle style,
@@ -128,16 +129,16 @@ void UI_tooltip_text_field_add(uiTooltipData *data,
field.format.color_id = color_id;
field.text = std::move(text);
field.text_suffix = std::move(suffix);
data->fields.append(std::move(field));
data.fields.append(std::move(field));
}
void UI_tooltip_image_field_add(uiTooltipData *data, const uiTooltipImage &image_data)
void UI_tooltip_image_field_add(uiTooltipData &data, const uiTooltipImage &image_data)
{
uiTooltipField field{};
field.format.style = UI_TIP_STYLE_IMAGE;
field.image = image_data;
field.image->ibuf = IMB_dupImBuf(image_data.ibuf);
data->fields.append(std::move(field));
data.fields.append(std::move(field));
}
/* -------------------------------------------------------------------- */
@@ -350,13 +351,13 @@ static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
static void ui_tooltip_region_free_cb(ARegion *region)
{
uiTooltipData *data = static_cast<uiTooltipData *>(region->regiondata);
/* Put ownership back into a unique pointer. */
std::unique_ptr<uiTooltipData> data{static_cast<uiTooltipData *>(region->regiondata)};
for (uiTooltipField &field : data->fields) {
if (field.image && field.image->ibuf) {
IMB_freeImBuf(field.image->ibuf);
}
}
MEM_delete(data);
region->regiondata = nullptr;
}
@@ -384,9 +385,9 @@ static std::string ui_tooltip_text_python_from_op(bContext *C,
#ifdef WITH_PYTHON
static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data, wmKeyMap *keymap)
static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData &data, wmKeyMap *keymap)
{
const int fields_len_init = data->fields.size();
const int fields_len_init = data.fields.size();
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
wmOperatorType *ot = WM_operatortype_find(kmi->idname, true);
@@ -417,7 +418,7 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data,
}
}
return (fields_len_init != data->fields.size());
return (fields_len_init != data.fields.size());
}
#endif /* WITH_PYTHON */
@@ -425,7 +426,9 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data,
/**
* Special tool-system exception.
*/
static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is_label)
static std::unique_ptr<uiTooltipData> ui_tooltip_data_from_tool(bContext *C,
uiBut *but,
bool is_label)
{
if (but->optype == nullptr) {
return nullptr;
@@ -472,7 +475,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
/* We have a tool, now extract the info. */
uiTooltipData *data = MEM_new<uiTooltipData>(__func__);
std::unique_ptr<uiTooltipData> data = std::make_unique<uiTooltipData>();
#ifdef WITH_PYTHON
/* It turns out to be most simple to do this via Python since C
@@ -520,7 +523,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
expr_result = BLI_strdup(label_str);
}
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
expr_result,
{},
UI_TIP_STYLE_NORMAL,
@@ -561,7 +564,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
if (expr_result != nullptr) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
expr_result,
{},
UI_TIP_STYLE_NORMAL,
@@ -630,7 +633,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
if (!shortcut.empty()) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Shortcut: {}"), shortcut),
{},
UI_TIP_STYLE_NORMAL,
@@ -702,7 +705,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
MEM_freeN(expr_result);
if (shortcut) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Shortcut Cycle: {}"), *shortcut),
{},
UI_TIP_STYLE_NORMAL,
@@ -715,7 +718,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
/* Python */
if ((is_label == false) && (U.flag & USER_TOOLTIPS_PYTHON)) {
std::string str = ui_tooltip_text_python_from_op(C, but->optype, but->opptr);
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Python: {}"), str),
{},
UI_TIP_STYLE_NORMAL,
@@ -746,9 +749,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
else if (BPY_run_string_as_intptr(C, expr_imports, expr, nullptr, &expr_result)) {
if (expr_result != 0) {
UI_tooltip_text_field_add(
data, TIP_("Tool Keymap:"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL, true);
*data, TIP_("Tool Keymap:"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL, true);
wmKeyMap *keymap = (wmKeyMap *)expr_result;
ui_tooltip_data_append_from_keymap(C, data, keymap);
ui_tooltip_data_append_from_keymap(C, *data, keymap);
}
}
else {
@@ -759,17 +762,11 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
UNUSED_VARS(is_label, has_valid_context, has_valid_context_error);
#endif /* WITH_PYTHON */
if (data->fields.is_empty()) {
MEM_delete(data);
return nullptr;
}
return data;
return data->fields.is_empty() ? nullptr : std::move(data);
}
static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
uiBut *but,
uiButExtraOpIcon *extra_icon,
const bool is_label)
static std::unique_ptr<uiTooltipData> ui_tooltip_data_from_button_or_extra_icon(
bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, const bool is_label)
{
char buf[512];
@@ -777,7 +774,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
but->optype;
PropertyRNA *rnaprop = extra_icon ? nullptr : but->rnaprop;
uiTooltipData *data = MEM_new<uiTooltipData>(__func__);
std::unique_ptr<uiTooltipData> data = std::make_unique<uiTooltipData>();
/* Menus already show shortcuts, don't show them in the tool-tips. */
const bool is_menu = ui_block_is_menu(but->block) && !ui_block_is_pie_menu(but->block);
@@ -830,7 +827,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Label: If there is a custom tooltip label, use that to override the label to display.
* Otherwise fallback to the regular label. */
if (!but_tip_label.empty()) {
UI_tooltip_text_field_add(data, but_tip_label, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(*data, but_tip_label, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* Regular (non-custom) label. Only show when the button doesn't already show the label. Check
* prefix instead of comparing because the button may include the shortcut. Buttons with dynamic
@@ -839,23 +836,23 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
else if (!but_label.empty() && !blender::StringRef(but->drawstr).startswith(but_label) &&
!but->tip_func)
{
UI_tooltip_text_field_add(data, but_label, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(*data, but_label, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* Tip */
if (!but_tip.empty()) {
if (!enum_label.empty()) {
UI_tooltip_text_field_add(
data, fmt::format("{}: ", but_tip), enum_label, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
*data, fmt::format("{}: ", but_tip), enum_label, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
else {
UI_tooltip_text_field_add(
data, fmt::format("{}.", but_tip), {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
*data, fmt::format("{}.", but_tip), {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* special case enum rna buttons */
if ((but->type & UI_BTYPE_ROW) && rnaprop && RNA_property_flag(rnaprop) & PROP_ENUM_FLAG) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
TIP_("(Shift-Click/Drag to select multiple)"),
{},
UI_TIP_STYLE_NORMAL,
@@ -865,17 +862,18 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* When there is only an enum label (no button label or tip), draw that as header. */
else if (!enum_label.empty() && but_label.empty()) {
UI_tooltip_text_field_add(
data, std::move(enum_label), {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
*data, std::move(enum_label), {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL);
}
/* Enum field label & tip. */
if (!enum_tip.empty()) {
UI_tooltip_text_field_add(data, std::move(enum_tip), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE);
UI_tooltip_text_field_add(
*data, std::move(enum_tip), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE);
}
/* Operator shortcut. */
if (!op_keymap.empty()) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Shortcut: {}"), op_keymap),
{},
UI_TIP_STYLE_NORMAL,
@@ -885,7 +883,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Property context-toggle shortcut. */
if (!prop_keymap.empty()) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Shortcut: {}"), prop_keymap),
{},
UI_TIP_STYLE_NORMAL,
@@ -899,7 +897,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Full string. */
ui_but_string_get(but, buf, sizeof(buf));
if (buf[0]) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Value: {}"), buf),
{},
UI_TIP_STYLE_NORMAL,
@@ -917,7 +915,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
float value = RNA_property_array_check(rnaprop) ?
RNA_property_float_get_index(&but->rnapoin, rnaprop, but->rnaindex) :
RNA_property_float_get(&but->rnapoin, rnaprop);
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Radians: {}"), value),
{},
UI_TIP_STYLE_NORMAL,
@@ -927,7 +925,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
if (but->flag & UI_BUT_DRIVEN) {
if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Expression: {}"), buf),
{},
UI_TIP_STYLE_NORMAL,
@@ -938,7 +936,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
if (but->rnapoin.owner_id) {
const ID *id = but->rnapoin.owner_id;
if (ID_IS_LINKED(id)) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Library: {}"), id->lib->filepath),
{},
UI_TIP_STYLE_NORMAL,
@@ -958,7 +956,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
/* Operator info. */
if (U.flag & USER_TOOLTIPS_PYTHON) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Python: {}"), str),
{},
UI_TIP_STYLE_MONO,
@@ -991,7 +989,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
}
if (disabled_msg && disabled_msg[0]) {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Disabled: {}"), disabled_msg),
{},
UI_TIP_STYLE_NORMAL,
@@ -1004,7 +1002,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && !rna_struct.empty()) {
{
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
rna_prop.empty() ?
fmt::format(TIP_("Python: {}"), rna_struct) :
fmt::format(TIP_("Python: {}.{}"), rna_struct, rna_prop),
@@ -1018,7 +1016,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
std::optional<std::string> str = rnaprop ? RNA_path_full_property_py_ex(
&but->rnapoin, rnaprop, but->rnaindex, true) :
RNA_path_full_struct_py(&but->rnapoin);
UI_tooltip_text_field_add(data, str.value_or(""), {}, UI_TIP_STYLE_MONO, UI_TIP_LC_PYTHON);
UI_tooltip_text_field_add(*data, str.value_or(""), {}, UI_TIP_STYLE_MONO, UI_TIP_LC_PYTHON);
}
}
@@ -1093,29 +1091,25 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
image_data.ibuf, color, 1, 1, image_data.width / 2, image_data.height, display);
}
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_image_field_add(data, image_data);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(data, hex_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(data, rgba_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(data, hsva_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_image_field_add(*data, image_data);
UI_tooltip_text_field_add(*data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, hex_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, rgba_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
UI_tooltip_text_field_add(*data, hsva_st, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_NORMAL, false);
/* Tooltip now owns a copy of the ImBuf, so we can delete ours.*/
IMB_freeImBuf(image_data.ibuf);
}
if (data->fields.is_empty()) {
MEM_delete(data);
return nullptr;
}
return data;
return data->fields.is_empty() ? nullptr : std::move(data);
}
static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
static std::unique_ptr<uiTooltipData> ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
{
uiTooltipData *data = MEM_new<uiTooltipData>(__func__);
std::unique_ptr<uiTooltipData> data = std::make_unique<uiTooltipData>();
/* TODO(@ideasman42): a way for gizmos to have their own descriptions (low priority). */
@@ -1147,7 +1141,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
if (!info.empty()) {
UI_tooltip_text_field_add(
data,
*data,
gzop_actions[i].prefix ? fmt::format("{}: {}", gzop_actions[i].prefix, info) : info,
{},
UI_TIP_STYLE_HEADER,
@@ -1161,7 +1155,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
if (std::optional<std::string> shortcut_str = WM_key_event_operator_string(
C, gzop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true))
{
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Shortcut: {}"), *shortcut_str),
{},
UI_TIP_STYLE_NORMAL,
@@ -1182,36 +1176,28 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
if (gz_prop->prop != nullptr) {
const char *info = RNA_property_ui_description(gz_prop->prop);
if (info && info[0]) {
UI_tooltip_text_field_add(data, info, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, true);
UI_tooltip_text_field_add(*data, info, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, true);
}
}
}
}
if (data->fields.is_empty()) {
MEM_delete(data);
return nullptr;
}
return data;
return data->fields.is_empty() ? nullptr : std::move(data);
}
static uiTooltipData *ui_tooltip_data_from_custom_func(bContext *C, uiBut *but)
static std::unique_ptr<uiTooltipData> ui_tooltip_data_from_custom_func(bContext *C, uiBut *but)
{
/* Create tooltip data. */
uiTooltipData *data = MEM_new<uiTooltipData>(__func__);
std::unique_ptr<uiTooltipData> data = std::make_unique<uiTooltipData>();
/* Create fields from custom callback. */
but->tip_custom_func(C, data, but->tip_arg);
but->tip_custom_func(*C, *data, but->tip_arg);
if (data->fields.is_empty()) {
MEM_delete(data);
return nullptr;
}
return data;
return data->fields.is_empty() ? nullptr : std::move(data);
}
static ARegion *ui_tooltip_create_with_data(bContext *C,
uiTooltipData *data,
std::unique_ptr<uiTooltipData> data_uptr,
const float init_position[2],
const rcti *init_rect_overlap)
{
@@ -1232,6 +1218,11 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
type.free = ui_tooltip_region_free_cb;
type.regionid = RGN_TYPE_TEMPORARY;
region->type = &type;
/* Move ownership to region data. The region type free callback puts it back into a unique
* pointer for save freeing. */
region->regiondata = data_uptr.release();
uiTooltipData *data = static_cast<uiTooltipData *>(region->regiondata);
/* Set font, get bounding-box. */
data->fstyle = style->tooltip; /* copy struct */
@@ -1299,8 +1290,6 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
BLF_disable(data->fstyle.uifont_id, font_flag);
BLF_disable(blf_mono_font, font_flag);
region->regiondata = data;
data->toth = fonth;
data->lineh = h;
@@ -1473,7 +1462,7 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon(
if (but->drawflag & UI_BUT_NO_TOOLTIP) {
return nullptr;
}
uiTooltipData *data = nullptr;
std::unique_ptr<uiTooltipData> data = nullptr;
if (but->tip_custom_func) {
data = ui_tooltip_data_from_custom_func(C, but);
@@ -1525,7 +1514,7 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon(
}
ARegion *region = ui_tooltip_create_with_data(
C, data, init_position, is_no_overlap ? &init_rect : nullptr);
C, std::move(data), init_position, is_no_overlap ? &init_rect : nullptr);
return region;
}
@@ -1540,7 +1529,7 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
wmWindow *win = CTX_wm_window(C);
float init_position[2] = {float(win->eventstate->xy[0]), float(win->eventstate->xy[1])};
uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
std::unique_ptr<uiTooltipData> data = ui_tooltip_data_from_gizmo(C, gz);
if (data == nullptr) {
return nullptr;
}
@@ -1555,7 +1544,7 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
}
}
return ui_tooltip_create_with_data(C, data, init_position, nullptr);
return ui_tooltip_create_with_data(C, std::move(data), init_position, nullptr);
}
static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
@@ -1563,7 +1552,7 @@ static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
if (ima.filepath[0]) {
char root[FILE_MAX];
BLI_path_split_dir_part(ima.filepath, root, FILE_MAX);
UI_tooltip_text_field_add(&data, root, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, root, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
}
std::string image_type;
@@ -1587,7 +1576,7 @@ static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
image_type = TIP_("UDIM Tiles");
break;
}
UI_tooltip_text_field_add(&data, image_type, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, image_type, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
short w;
short h;
@@ -1595,7 +1584,7 @@ static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
if (ibuf) {
UI_tooltip_text_field_add(
&data, fmt::format("{} \u00D7 {}", w, h), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
data, fmt::format("{} \u00D7 {}", w, h), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
}
if (BKE_image_has_anim(&ima)) {
@@ -1603,15 +1592,15 @@ static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
if (anim) {
int duration = IMB_anim_get_duration(anim, IMB_TC_RECORD_RUN);
UI_tooltip_text_field_add(
&data, fmt::format("Frames: {}", duration), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
data, fmt::format("Frames: {}", duration), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
}
}
UI_tooltip_text_field_add(
&data, ima.colorspace_settings.name, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
data, ima.colorspace_settings.name, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(
&data, fmt::format(TIP_("Users: {}"), ima.id.us), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
data, fmt::format(TIP_("Users: {}"), ima.id.us), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
if (ibuf) {
uiTooltipImage image_data;
@@ -1621,9 +1610,9 @@ static void ui_tooltip_from_image(Image &ima, uiTooltipData &data)
image_data.border = true;
image_data.background = uiTooltipImageBackground::Checkerboard_Themed;
image_data.premultiplied = true;
UI_tooltip_text_field_add(&data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(&data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_image_field_add(&data, image_data);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_image_field_add(data, image_data);
IMB_freeImBuf(ibuf);
}
}
@@ -1633,7 +1622,7 @@ static void ui_tooltip_from_clip(MovieClip &clip, uiTooltipData &data)
if (clip.filepath[0]) {
char root[FILE_MAX];
BLI_path_split_dir_part(clip.filepath, root, FILE_MAX);
UI_tooltip_text_field_add(&data, root, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, root, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
}
std::string image_type;
@@ -1645,12 +1634,12 @@ static void ui_tooltip_from_clip(MovieClip &clip, uiTooltipData &data)
image_type = TIP_("Movie");
break;
}
UI_tooltip_text_field_add(&data, image_type, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, image_type, {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_NORMAL);
if (clip.anim) {
ImBufAnim *anim = clip.anim;
UI_tooltip_text_field_add(&data,
UI_tooltip_text_field_add(data,
fmt::format("{} \u00D7 {}",
IMB_anim_get_image_width(anim),
IMB_anim_get_image_height(anim)),
@@ -1659,7 +1648,7 @@ static void ui_tooltip_from_clip(MovieClip &clip, uiTooltipData &data)
UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(
&data,
data,
fmt::format("Frames: {}", IMB_anim_get_duration(anim, IMB_TC_RECORD_RUN)),
{},
UI_TIP_STYLE_NORMAL,
@@ -1680,9 +1669,9 @@ static void ui_tooltip_from_clip(MovieClip &clip, uiTooltipData &data)
image_data.border = true;
image_data.background = uiTooltipImageBackground::Checkerboard_Themed;
image_data.premultiplied = true;
UI_tooltip_text_field_add(&data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(&data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_image_field_add(&data, image_data);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_text_field_add(data, {}, {}, UI_TIP_STYLE_SPACER, UI_TIP_LC_NORMAL);
UI_tooltip_image_field_add(data, image_data);
IMB_freeImBuf(ibuf);
}
}
@@ -1697,7 +1686,7 @@ static void ui_tooltip_from_vfont(const VFont &font, uiTooltipData &data)
if (!BLI_exists(font.filepath)) {
UI_tooltip_text_field_add(
&data, TIP_("File not found"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_ALERT);
data, TIP_("File not found"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_ALERT);
return;
}
@@ -1714,17 +1703,17 @@ static void ui_tooltip_from_vfont(const VFont &font, uiTooltipData &data)
image_data.background = uiTooltipImageBackground::None;
image_data.premultiplied = false;
image_data.text_color = true;
UI_tooltip_image_field_add(&data, image_data);
UI_tooltip_image_field_add(data, image_data);
IMB_freeImBuf(ibuf);
}
}
static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(ID *id)
static std::unique_ptr<uiTooltipData> ui_tooltip_data_from_search_item_tooltip_data(ID *id)
{
uiTooltipData *data = MEM_new<uiTooltipData>(__func__);
std::unique_ptr<uiTooltipData> data = std::make_unique<uiTooltipData>();
const ID_Type type_id = GS(id->name);
UI_tooltip_text_field_add(data, id->name + 2, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_MAIN);
UI_tooltip_text_field_add(*data, id->name + 2, {}, UI_TIP_STYLE_HEADER, UI_TIP_LC_MAIN);
if (type_id == ID_IM) {
ui_tooltip_from_image(*reinterpret_cast<Image *>(id), *data);
@@ -1736,7 +1725,7 @@ static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(ID *id)
ui_tooltip_from_vfont(*reinterpret_cast<VFont *>(id), *data);
}
else {
UI_tooltip_text_field_add(data,
UI_tooltip_text_field_add(*data,
fmt::format(TIP_("Choose {} data-block to be assigned to this user"),
BKE_idtype_idcode_to_name(GS(id->name))),
{},
@@ -1747,18 +1736,14 @@ static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(ID *id)
/** Additional info about the item (e.g. library name of a linked data-block). */
if (ID_IS_LINKED(id)) {
UI_tooltip_text_field_add(
data,
*data,
fmt::format(TIP_("Source library: {}\n{}"), id->lib->id.name + 2, id->lib->filepath),
{},
UI_TIP_STYLE_NORMAL,
UI_TIP_LC_NORMAL);
}
if (data->fields.is_empty()) {
MEM_delete(data);
return nullptr;
}
return data;
return data->fields.is_empty() ? nullptr : std::move(data);
}
ARegion *UI_tooltip_create_from_search_item_generic(bContext *C,
@@ -1766,7 +1751,7 @@ ARegion *UI_tooltip_create_from_search_item_generic(bContext *C,
const rcti *item_rect,
ID *id)
{
uiTooltipData *data = ui_tooltip_data_from_search_item_tooltip_data(id);
std::unique_ptr<uiTooltipData> data = ui_tooltip_data_from_search_item_tooltip_data(id);
if (data == nullptr) {
return nullptr;
}
@@ -1776,7 +1761,7 @@ ARegion *UI_tooltip_create_from_search_item_generic(bContext *C,
init_position[0] = win->eventstate->xy[0];
init_position[1] = item_rect->ymin + searchbox_region->winrct.ymin - (UI_POPUP_MARGIN / 2);
return ui_tooltip_create_with_data(C, data, init_position, nullptr);
return ui_tooltip_create_with_data(C, std::move(data), init_position, nullptr);
}
void UI_tooltip_free(bContext *C, bScreen *screen, ARegion *region)

View File

@@ -7295,7 +7295,7 @@ void uiTemplateCacheFile(uiLayout *layout,
/* -------------------------------------------------------------------- */
/** \name Recent Files Template
* \{ */
static void uiTemplateRecentFiles_tooltip_func(bContext * /*C*/, uiTooltipData *tip, void *argN)
static void uiTemplateRecentFiles_tooltip_func(bContext & /*C*/, uiTooltipData &tip, void *argN)
{
char *path = (char *)argN;

View File

@@ -127,7 +127,7 @@ static FileTooltipData *file_tooltip_data_create(const SpaceFile *sfile, const F
return data;
}
static void file_draw_tooltip_custom_func(bContext * /*C*/, uiTooltipData *tip, void *argN)
static void file_draw_tooltip_custom_func(bContext & /*C*/, uiTooltipData &tip, void *argN)
{
FileTooltipData *file_data = static_cast<FileTooltipData *>(argN);
const SpaceFile *sfile = file_data->sfile;