42#include "RNA_prototypes.hh"
142 const uint str_size = strlen(
str) + 1;
144 memcpy(str_dst,
str, str_size);
167 std::string drawstr_override;
170 const bool drawstr_is_empty = sep_index == 0 || but->
drawstr.empty();
172 if (but->
optype !=
nullptr) {
173 if (drawstr_is_empty) {
185 but->
opptr =
nullptr;
187 else if (but->
rnaprop !=
nullptr) {
190 if (drawstr_is_empty) {
200 drawstr_override = enum_item.
name;
204 drawstr_override =
"Unknown";
215 printf(
"Button '%s' in menu '%s' is a menu item with unsupported RNA type %d\n",
235 if (item !=
nullptr) {
237 if (!drawstr_override.empty()) {
238 const StringRef drawstr_suffix = sep_index == std::string::npos ?
241 std::string drawstr = std::string(
"(") + drawstr_override +
")" + drawstr_suffix;
268 bool changed =
false;
269 switch (item->
type) {
297 if (sep_index != std::string::npos) {
298 but->
drawstr.resize(sep_index);
328 region ? ®ion->handlers :
nullptr,
329 area ? &area->handlers :
nullptr,
333 for (
int handler_index = 0; handler_index <
ARRAY_SIZE(handlers); handler_index++) {
334 if (handlers[handler_index] ==
nullptr) {
346 if (handler_base->poll ==
nullptr || handler_base->poll(region, win->
eventstate)) {
350 for (
int km_index = 0; km_index < km_result.
keymaps_len; km_index++) {
357 if (
STR_ELEM(kmi->idname,
"WM_OT_call_menu",
"WM_OT_call_menu_pie")) {
362 if (mt && menu_tagged.
add(mt)) {
364 menu_stack.
push({mt});
365 menu_to_kmi.
add(mt, kmi);
382 ListBase operator_items = {
nullptr,
nullptr};
384 MemArena *memarena = data->memarena;
431 bool include_all_areas,
432 const char *single_menu_idname)
453 const char *idname_array[] = {
455 (single_menu_idname &&
STREQ(single_menu_idname,
"TOPBAR_MT_file_open_recent")) ?
457 "TOPBAR_MT_file_open_recent",
460 "TOPBAR_MT_undo_history",
462 for (
int i = 0; i <
ARRAY_SIZE(idname_array); i++) {
463 if (!idname_array[i]) {
473 if (!single_menu_idname) {
488 const char *idname_array[] = {
490 "OUTLINER_MT_context_menu",
492 for (
int i = 0; i <
ARRAY_SIZE(idname_array); i++) {
504 int space_type_ui_items_len = 0;
505 bool space_type_ui_items_free =
false;
508 const char *global_menu_prefix =
nullptr;
510 if (include_all_areas) {
526 &space_type_ui_items,
527 &space_type_ui_items_len,
528 &space_type_ui_items_free);
531 memarena,
sizeof(*wm_contexts) * space_type_ui_items_len);
532 for (
int i = 0; i < space_type_ui_items_len; i++) {
539 if (region !=
nullptr) {
544 if (space_type_ui_index == -1) {
548 if (wm_contexts[space_type_ui_index].space_type_ui_index != -1) {
549 ScrArea *area_best = wm_contexts[space_type_ui_index].
area;
551 const uint value_test =
uint(area->winx) *
uint(area->winy);
552 if (value_best > value_test) {
558 wm_contexts[space_type_ui_index].
area = area;
559 wm_contexts[space_type_ui_index].
region = region;
566 for (
int space_type_ui_index = -1; space_type_ui_index < space_type_ui_items_len;
567 space_type_ui_index += 1)
574 if (include_all_areas) {
575 if (space_type_ui_index == -1) {
577 wm_context =
nullptr;
582 wm_context = &wm_contexts[space_type_ui_index];
587 area = wm_context->
area;
588 region = wm_context->
region;
596 region = region_init;
599 if (single_menu_idname) {
601 if (menu_tagged.
add(mt)) {
602 menu_stack.
push({mt});
611 const char *idname_array[2] = {
nullptr};
612 int idname_array_len = 0;
615 if (space_type_ui_index == -1) {
616 idname_array[idname_array_len++] =
"TOPBAR_MT_editor_menus";
619#define SPACE_MENU_MAP(space_type, menu_id) \
621 idname_array[idname_array_len++] = menu_id; \
623#define SPACE_MENU_NOP(space_type) \
627 if (area !=
nullptr) {
641 "TIME_MT_editor_menus" :
642 "DOPESHEET_MT_editor_menus");
649 "CLIP_MT_tracking_editor_menus" :
650 "CLIP_MT_masking_editor_menus");
658 for (
int i = 0; i < idname_array_len; i++) {
662 if (menu_tagged.
add(mt)) {
663 menu_stack.
push({mt});
671 bool has_keymap_menu_items =
false;
686 if (current_menu.
context.has_value()) {
703 but_test = but_test->
prev;
706 if (but_test ==
nullptr) {
711 data, memarena, mt, but, wm_context, current_menu.
self_as_parent))
716 const bool uses_context = but->context &&
718 const bool tagged_first_time = menu_tagged.
add(mt_from_but);
719 const bool scan_submenu = tagged_first_time || uses_context;
723 memarena,
sizeof(*menu_parent));
732 bool drawstr_is_empty =
false;
733 if (drawstr_sep !=
nullptr) {
736 const char *drawstr = but->drawstr.c_str();
737 int drawstr_len = drawstr_sep - but->drawstr.c_str();
740 drawstr_len = strlen(drawstr);
741 if (drawstr[0] ==
'\0') {
742 drawstr_is_empty =
true;
751 const char *drawstr = but->drawstr.c_str();
754 if (drawstr[0] ==
'\0') {
755 drawstr_is_empty =
true;
762 if (drawstr_is_empty) {
763 printf(
"Warning: '%s' menu has empty 'bl_label'.\n", mt_from_but->
idname);
767 menu_stack.
push({mt_from_but, menu_parent, *but->context});
770 menu_stack.
push({mt_from_but, menu_parent});
774 else if (but->menu_create_func !=
nullptr) {
786 but->menu_create_func(C, sub_layout, but->poin);
791 memarena,
sizeof(*menu_parent));
797 data, memarena, mt, sub_but, wm_context, menu_parent);
802 region->runtime.block_name_map, sub_block->
name.c_str(),
nullptr,
nullptr);
814 if (single_menu_idname ==
nullptr) {
817 if (menu_stack.
is_empty() && (has_keymap_menu_items ==
false)) {
818 has_keymap_menu_items =
true;
820 C, win, area, region, menu_stack, menu_to_kmi, menu_tagged);
833 if (include_all_areas) {
836 (item->wm_context !=
nullptr) ?
837 space_type_ui_items[item->wm_context->space_type_ui_index].
name :
841 if (item->menu_parent !=
nullptr) {
844 while (menu_parent && menu_parent->
parent) {
846 menu_parent = menu_parent->
parent;
848 while (menu_parent) {
855 const char *drawstr = menu_display_name_map.
lookup_default(item->mt,
nullptr);
856 if (drawstr ==
nullptr) {
857 drawstr =
CTX_IFACE_(item->mt->translation_context, item->mt->label);
862 if (kmi !=
nullptr) {
882 data->memarena = memarena;
884 if (include_all_areas) {
888 if (space_type_ui_items_free) {
915 switch (item->type) {
917 if (item->op.opptr !=
nullptr) {
919 MEM_delete(item->op.opptr);
921 MEM_delete(item->op.context);
938 if (item ==
nullptr) {
953 switch (item->
type) {
966 bool changed =
false;
1009 search.
add(item->drawwstr_full, item, item->weight);
1015 if (!
UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state, 0)) {
1038 bool has_menu =
false;
1040 new (&data->context_menu_data.but)
uiBut();
1041 new (&data->context_menu_data.block)
uiBlock();
1042 uiBut *but = &data->context_menu_data.but;
1043 uiBlock *block = &data->context_menu_data.block;
1081 new (&data->context_menu_data.but)
uiBut();
1082 new (&data->context_menu_data.block)
uiBlock();
1083 uiBut *but = &data->context_menu_data.but;
1084 uiBlock *block = &data->context_menu_data.block;
1093 tip_init[0] =
event->
xy[0];
1094 tip_init[1] =
event->xy[1] - (
UI_UNIT_Y / 2);
1136 const bool include_all_areas = (area && (area->spacetype ==
SPACE_TOPBAR)) &&
1137 !single_menu_idname;
1139 C, win, area, region, include_all_areas, single_menu_idname);
1159 static char search[256] =
"";
1165 block, search, 0, ICON_VIEWZOOM,
sizeof(search), 0, 0,
UI_UNIT_X * 6,
UI_UNIT_Y,
"");
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
void CTX_store_set(bContext *C, const bContextStore *store)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
A dynamically sized string ADT.
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL()
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new_memarena(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_clear(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
void BLI_ghashIterator_step(GHashIterator *ghi)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define LISTBASE_FOREACH(type, var, list)
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void unit_m4(float m[4][4])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void * BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
#define SNPRINTF(dst, format,...)
int bool bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(1
#define CTX_IFACE_(context, msgid)
Read Guarded memory(de)allocation.
@ UI_BLOCK_SHOW_SHORTCUT_ALWAYS
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int but_flag, uint8_t name_prefix_offset)
MenuType * UI_but_menutype_get(const uiBut *but)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const uiStyle *style)
const uiStyle * UI_style_get_dpi()
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout)
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn)
uiBut * uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxncpy, int x, int y, short width, short height, const char *tip)
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
void UI_block_free(const bContext *C, uiBlock *block)
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
ARegion * UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label)
void UI_block_flag_enable(uiBlock *block, int flag)
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
void UI_block_end(const bContext *C, uiBlock *block)
void uiLayoutContextCopy(uiLayout *layout, const bContextStore *context)
@ WM_OP_INVOKE_REGION_WIN
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
ValueIterator values() const
bool remove(const Key &key)
void push(const T &value)
constexpr StringRef drop_prefix(int64_t n) const
void add(const StringRef str, T *user_data, const int weight=0)
Vector< T * > query(const StringRef query) const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void ui_window_to_block_fl(const ARegion *region, const uiBlock *block, float *x, float *y)
ARegion * ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
int ui_but_icon(const uiBut *but)
void MEM_freeN(void *vmemh)
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
bool RNA_property_array_check(PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PropertyType RNA_property_type(PropertyRNA *prop)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_property_translation_context(const PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
bool RNA_property_enum_item_from_value_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
const char * RNA_property_ui_name(const PropertyRNA *prop)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
#define UI_MENU_ARROW_SEP
wmOperatorCallContext opcontext
const bContextStore * context
const char * translation_context
struct wmEvent * eventstate
bool WM_operator_poll(bContext *C, wmOperatorType *ot)
void WM_event_get_keymaps_from_handler(wmWindowManager *wm, wmWindow *win, wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result)
void WM_operator_name_call_ptr_with_depends_on_cursor(bContext *C, wmOperatorType *ot, wmOperatorCallContext opcontext, PointerRNA *properties, const wmEvent *event, const char *drawstr)
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
std::optional< std::string > WM_keymap_item_to_string(const wmKeyMapItem *kmi, const bool compact)
std::string WM_operatortype_name(wmOperatorType *ot, PointerRNA *properties)
const wmOperatorTypeMap & WM_operatortype_map()
size_t WM_operator_py_idname(char *dst, const char *src)
void WM_operator_properties_free(PointerRNA *ptr)
bScreen * WM_window_get_active_screen(const wmWindow *win)