forked from bartvdbraak/blender
UI: alternate fix for empty context menu
block and layout could be NULL and checking this everywhere wasn't practical. Instead of lazy initializing, add UI_popup_menu_end_or_cancel which cancels empty popup menus.
This commit is contained in:
parent
6cd0484de8
commit
f8a3636374
@ -395,6 +395,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(
|
|||||||
struct bContext *C, const char *title, const char *block_name,
|
struct bContext *C, const char *title, const char *block_name,
|
||||||
int icon) ATTR_NONNULL();
|
int icon) ATTR_NONNULL();
|
||||||
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
|
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
|
||||||
|
bool UI_popup_menu_end_or_cancel(struct bContext *C, struct uiPopupMenu *head);
|
||||||
struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
|
struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
|
||||||
|
|
||||||
void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
|
void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
|
||||||
@ -497,6 +498,8 @@ void UI_block_order_flip(uiBlock *block);
|
|||||||
void UI_block_flag_enable(uiBlock *block, int flag);
|
void UI_block_flag_enable(uiBlock *block, int flag);
|
||||||
void UI_block_flag_disable(uiBlock *block, int flag);
|
void UI_block_flag_disable(uiBlock *block, int flag);
|
||||||
|
|
||||||
|
bool UI_block_is_empty(const uiBlock *block);
|
||||||
|
|
||||||
int UI_but_return_value_get(uiBut *but);
|
int UI_but_return_value_get(uiBut *but);
|
||||||
|
|
||||||
void UI_but_drag_set_id(uiBut *but, struct ID *id);
|
void UI_but_drag_set_id(uiBut *but, struct ID *id);
|
||||||
|
@ -4007,6 +4007,16 @@ int UI_blocklist_min_y_get(ListBase *lb)
|
|||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UI_block_is_empty(const uiBlock *block)
|
||||||
|
{
|
||||||
|
for (const uiBut *but = block->buttons.first; but; but = but->next) {
|
||||||
|
if (!ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void UI_block_direction_set(uiBlock *block, char direction)
|
void UI_block_direction_set(uiBlock *block, char direction)
|
||||||
{
|
{
|
||||||
block->direction = direction;
|
block->direction = direction;
|
||||||
@ -4753,4 +4763,3 @@ void UI_exit(void)
|
|||||||
ui_resources_free();
|
ui_resources_free();
|
||||||
ui_but_clipboard_free();
|
ui_but_clipboard_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6837,45 +6837,34 @@ static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, Pr
|
|||||||
RNA_string_set(&props_ptr, "filepath", dir);
|
RNA_string_set(&props_ptr, "filepath", dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_but_menu_lazy_init(
|
|
||||||
bContext *C, uiBut *but,
|
|
||||||
uiPopupMenu **pup_p, uiLayout **layout_p)
|
|
||||||
{
|
|
||||||
if (*pup_p != NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiStringInfo label = {BUT_GET_LABEL, NULL};
|
|
||||||
|
|
||||||
/* highly unlikely getting the label ever fails */
|
|
||||||
UI_but_string_info_get(C, but, &label, NULL);
|
|
||||||
|
|
||||||
*pup_p = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
|
|
||||||
*layout_p = UI_popup_menu_layout(*pup_p);
|
|
||||||
if (label.strinfo) {
|
|
||||||
MEM_freeN(label.strinfo);
|
|
||||||
}
|
|
||||||
uiLayoutSetOperatorContext(*layout_p, WM_OP_INVOKE_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ui_but_menu(bContext *C, uiBut *but)
|
static bool ui_but_menu(bContext *C, uiBut *but)
|
||||||
{
|
{
|
||||||
uiPopupMenu *pup = NULL;
|
|
||||||
uiLayout *layout = NULL;
|
|
||||||
MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
|
MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
|
||||||
bool is_array, is_array_component;
|
bool is_array, is_array_component;
|
||||||
|
|
||||||
/* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/
|
|
||||||
/* return 0;*/
|
|
||||||
|
|
||||||
/* having this menu for some buttons makes no sense */
|
/* having this menu for some buttons makes no sense */
|
||||||
if (but->type == UI_BTYPE_IMAGE) {
|
if (but->type == UI_BTYPE_IMAGE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (but->rnapoin.data && but->rnaprop) {
|
uiPopupMenu *pup;
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
uiLayout *layout;
|
||||||
|
|
||||||
|
{
|
||||||
|
uiStringInfo label = {BUT_GET_LABEL, NULL};
|
||||||
|
|
||||||
|
/* highly unlikely getting the label ever fails */
|
||||||
|
UI_but_string_info_get(C, but, &label, NULL);
|
||||||
|
|
||||||
|
pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
|
||||||
|
layout = UI_popup_menu_layout(pup);
|
||||||
|
if (label.strinfo) {
|
||||||
|
MEM_freeN(label.strinfo);
|
||||||
|
}
|
||||||
|
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (but->rnapoin.data && but->rnaprop) {
|
||||||
PointerRNA *ptr = &but->rnapoin;
|
PointerRNA *ptr = &but->rnapoin;
|
||||||
PropertyRNA *prop = but->rnaprop;
|
PropertyRNA *prop = but->rnaprop;
|
||||||
const PropertyType type = RNA_property_type(prop);
|
const PropertyType type = RNA_property_type(prop);
|
||||||
@ -7074,8 +7063,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
|
|
||||||
/* We do have a shortcut, but only keyboard ones are editbale that way... */
|
/* We do have a shortcut, but only keyboard ones are editbale that way... */
|
||||||
if (kmi) {
|
if (kmi) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
|
|
||||||
if (ISKEYBOARD(kmi->type)) {
|
if (ISKEYBOARD(kmi->type)) {
|
||||||
#if 0 /* would rather use a block but, but gets weirdly positioned... */
|
#if 0 /* would rather use a block but, but gets weirdly positioned... */
|
||||||
uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut",
|
uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut",
|
||||||
@ -7102,8 +7089,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
}
|
}
|
||||||
/* only show 'add' if there's a suitable key map for it to go in */
|
/* only show 'add' if there's a suitable key map for it to go in */
|
||||||
else if (WM_keymap_guess_opname(C, but->optype->idname)) {
|
else if (WM_keymap_guess_opname(C, but->optype->idname)) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
|
|
||||||
but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND,
|
but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND,
|
||||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
|
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
|
||||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||||
@ -7120,7 +7105,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
if (ui_block_is_menu(but->block) == false) {
|
if (ui_block_is_menu(but->block) == false) {
|
||||||
ARegion *ar = CTX_wm_region(C);
|
ARegion *ar = CTX_wm_region(C);
|
||||||
if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
|
if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
|
uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
|
||||||
uiItemS(layout);
|
uiItemS(layout);
|
||||||
}
|
}
|
||||||
@ -7130,8 +7114,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
|
if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
|
|
||||||
PointerRNA ptr_props;
|
PointerRNA ptr_props;
|
||||||
uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
|
uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
|
||||||
ICON_URL, "WM_OT_doc_view_manual_ui_context");
|
ICON_URL, "WM_OT_doc_view_manual_ui_context");
|
||||||
@ -7154,7 +7136,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (but->optype) {
|
if (but->optype) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
uiItemO(layout, NULL,
|
uiItemO(layout, NULL,
|
||||||
ICON_NONE, "UI_OT_copy_python_command_button");
|
ICON_NONE, "UI_OT_copy_python_command_button");
|
||||||
}
|
}
|
||||||
@ -7162,27 +7143,20 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||||||
/* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
|
/* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
|
||||||
if (U.flag & USER_DEVELOPER_UI) {
|
if (U.flag & USER_DEVELOPER_UI) {
|
||||||
if (ui_block_is_menu(but->block) == false) {
|
if (ui_block_is_menu(but->block) == false) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
|
uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BKE_addon_find(&U.addons, "ui_translate")) {
|
if (BKE_addon_find(&U.addons, "ui_translate")) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
|
uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mt = WM_menutype_find("WM_MT_button_context", true);
|
mt = WM_menutype_find("WM_MT_button_context", true);
|
||||||
if (mt) {
|
if (mt) {
|
||||||
ui_but_menu_lazy_init(C, but, &pup, &layout);
|
|
||||||
UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
|
UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pup != NULL) {
|
return UI_popup_menu_end_or_cancel(C, pup);
|
||||||
UI_popup_menu_end(C, pup);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (pup != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
|
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
|
||||||
|
@ -454,6 +454,21 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
|
|||||||
MEM_freeN(pup);
|
MEM_freeN(pup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
|
||||||
|
{
|
||||||
|
if (!UI_block_is_empty(pup->block)) {
|
||||||
|
UI_popup_menu_end(C, pup);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UI_block_layout_resolve(pup->block, NULL, NULL);
|
||||||
|
MEM_freeN(pup->block->handle);
|
||||||
|
UI_block_free(C, pup->block);
|
||||||
|
MEM_freeN(pup);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
|
uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
|
||||||
{
|
{
|
||||||
return pup->layout;
|
return pup->layout;
|
||||||
|
Loading…
Reference in New Issue
Block a user