Files
test/source/blender/editors/interface/templates/interface_template_icon.cc
Guillermo Venegas a46e3d2e78 Refactor: UI: Replace uiLayoutAbsolute and uiLayoutAbsoluteBlock with uiLayout class methods
This converts the public `uiLayoutAbsolute ` and `uiLayoutAbsoluteBlock`
functions to an object oriented API (an `uiLayout::absolute` and
`uiLayout::absolute_block` respectively), following recent changes.

`uiLayout::absolute` now returns an uiLayout reference instead of a
pointer. New calls to this method should use references too.

Part of: #117604

Pull Request: https://projects.blender.org/blender/blender/pulls/138546
2025-05-07 17:03:15 +02:00

182 lines
5.4 KiB
C++

/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edinterface
*/
#include "BLI_string_ref.hh"
#include "RNA_access.hh"
#include "UI_interface.hh"
#include "interface_intern.hh"
using blender::StringRefNull;
struct IconViewMenuArgs {
PointerRNA ptr;
PropertyRNA *prop;
bool show_labels;
float icon_scale;
};
/* ID Search browse menu, open */
static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_litem)
{
static IconViewMenuArgs args;
/* arg_litem is malloced, can be freed by parent button */
args = *((IconViewMenuArgs *)arg_litem);
const int w = UI_UNIT_X * (args.icon_scale);
const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
uiBlock *block = UI_block_begin(C, region, "_popup", blender::ui::EmbossType::Pulldown);
UI_block_flag_enable(block, UI_BLOCK_LOOP);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
bool free;
const EnumPropertyItem *item;
RNA_property_enum_items(C, &args.ptr, args.prop, &item, nullptr, &free);
for (int a = 0; item[a].identifier; a++) {
const int x = (a % 8) * w;
const int y = -(a / 8) * h;
const int icon = item[a].icon;
const int value = item[a].value;
uiBut *but;
if (args.show_labels) {
but = uiDefIconTextButR_prop(block,
UI_BTYPE_ROW,
0,
icon,
item[a].name,
x,
y,
w,
h,
&args.ptr,
args.prop,
-1,
0,
value,
std::nullopt);
}
else {
but = uiDefIconButR_prop(block,
UI_BTYPE_ROW,
0,
icon,
x,
y,
w,
h,
&args.ptr,
args.prop,
-1,
0,
value,
std::nullopt);
}
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
UI_block_direction_set(block, UI_DIR_DOWN);
if (free) {
MEM_freeN(item);
}
return block;
}
void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
{
uiBlock *block = layout->absolute_block();
uiBut *but = uiDefIconBut(block,
UI_BTYPE_LABEL,
0,
ICON_X,
0,
0,
UI_UNIT_X * icon_scale,
UI_UNIT_Y * icon_scale,
nullptr,
0.0,
0.0,
"");
ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
void uiTemplateIconView(uiLayout *layout,
PointerRNA *ptr,
const StringRefNull propname,
bool show_labels,
float icon_scale,
float icon_scale_popup)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname.c_str());
if (!prop || RNA_property_type(prop) != PROP_ENUM) {
RNA_warning("property of type Enum not found: %s.%s",
RNA_struct_identifier(ptr->type),
propname.c_str());
return;
}
uiBlock *block = layout->absolute_block();
int tot_items;
bool free_items;
const EnumPropertyItem *items;
RNA_property_enum_items(
static_cast<bContext *>(block->evil_C), ptr, prop, &items, &tot_items, &free_items);
const int value = RNA_property_enum_get(ptr, prop);
int icon = ICON_NONE;
RNA_enum_icon_from_value(items, value, &icon);
uiBut *but;
if (RNA_property_editable(ptr, prop)) {
IconViewMenuArgs *cb_args = MEM_new<IconViewMenuArgs>(__func__);
cb_args->ptr = *ptr;
cb_args->prop = prop;
cb_args->show_labels = show_labels;
cb_args->icon_scale = icon_scale_popup;
but = uiDefBlockButN(block,
ui_icon_view_menu_cb,
cb_args,
"",
0,
0,
UI_UNIT_X * icon_scale,
UI_UNIT_Y * icon_scale,
"",
but_func_argN_free<IconViewMenuArgs>,
but_func_argN_copy<IconViewMenuArgs>);
}
else {
but = uiDefIconBut(block,
UI_BTYPE_LABEL,
0,
ICON_X,
0,
0,
UI_UNIT_X * icon_scale,
UI_UNIT_Y * icon_scale,
nullptr,
0.0,
0.0,
"");
}
ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if (free_items) {
MEM_freeN(items);
}
}