Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_context_menu.cc
- This file was moved from source/blender/editors/interface/interface_context_menu.c.
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| /** \file | /** \file | ||||
| * \ingroup edinterface | * \ingroup edinterface | ||||
| * | * | ||||
| * Generic context popup menus. | * Generic context popup menus. | ||||
| */ | */ | ||||
| #include <string.h> | #include <cstring> | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "BLI_path_util.h" | #include "BLI_path_util.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| Show All 36 Lines | |||||
| static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but) | static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but) | ||||
| { | { | ||||
| /* Compute data path from context to property. */ | /* Compute data path from context to property. */ | ||||
| /* If this returns null, we won't be able to bind shortcuts to these RNA properties. | /* If this returns null, we won't be able to bind shortcuts to these RNA properties. | ||||
| * Support can be added at #wm_context_member_from_ptr. */ | * Support can be added at #wm_context_member_from_ptr. */ | ||||
| char *final_data_path = WM_context_path_resolve_property_full( | char *final_data_path = WM_context_path_resolve_property_full( | ||||
| C, &but->rnapoin, but->rnaprop, but->rnaindex); | C, &but->rnapoin, but->rnaprop, but->rnaindex); | ||||
| if (final_data_path == NULL) { | if (final_data_path == nullptr) { | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| /* Create ID property of data path, to pass to the operator. */ | /* Create ID property of data path, to pass to the operator. */ | ||||
| const IDPropertyTemplate val = {0}; | const IDPropertyTemplate val = {0}; | ||||
| IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__); | IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__); | ||||
| IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path", strlen(final_data_path) + 1)); | IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path", strlen(final_data_path) + 1)); | ||||
| MEM_freeN((void *)final_data_path); | MEM_freeN((void *)final_data_path); | ||||
| return prop; | return prop; | ||||
| } | } | ||||
| static const char *shortcut_get_operator_property(bContext *C, uiBut *but, IDProperty **r_prop) | static const char *shortcut_get_operator_property(bContext *C, uiBut *but, IDProperty **r_prop) | ||||
| { | { | ||||
| if (but->optype) { | if (but->optype) { | ||||
| /* Operator */ | /* Operator */ | ||||
| *r_prop = (but->opptr && but->opptr->data) ? IDP_CopyProperty(but->opptr->data) : NULL; | *r_prop = (but->opptr && but->opptr->data) ? | ||||
| IDP_CopyProperty(static_cast<IDProperty *>(but->opptr->data)) : | |||||
| nullptr; | |||||
| return but->optype->idname; | return but->optype->idname; | ||||
| } | } | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| const PropertyType rnaprop_type = RNA_property_type(but->rnaprop); | const PropertyType rnaprop_type = RNA_property_type(but->rnaprop); | ||||
| if (rnaprop_type == PROP_BOOLEAN) { | if (rnaprop_type == PROP_BOOLEAN) { | ||||
| /* Boolean */ | /* Boolean */ | ||||
| *r_prop = shortcut_property_from_rna(C, but); | *r_prop = shortcut_property_from_rna(C, but); | ||||
| if (*r_prop == NULL) { | if (*r_prop == nullptr) { | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| return "WM_OT_context_toggle"; | return "WM_OT_context_toggle"; | ||||
| } | } | ||||
| if (rnaprop_type == PROP_ENUM) { | if (rnaprop_type == PROP_ENUM) { | ||||
| /* Enum */ | /* Enum */ | ||||
| *r_prop = shortcut_property_from_rna(C, but); | *r_prop = shortcut_property_from_rna(C, but); | ||||
| if (*r_prop == NULL) { | if (*r_prop == nullptr) { | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| return "WM_OT_context_menu_enum"; | return "WM_OT_context_menu_enum"; | ||||
| } | } | ||||
| } | } | ||||
| *r_prop = NULL; | *r_prop = nullptr; | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| static void shortcut_free_operator_property(IDProperty *prop) | static void shortcut_free_operator_property(IDProperty *prop) | ||||
| { | { | ||||
| if (prop) { | if (prop) { | ||||
| IDP_FreeProperty(prop); | IDP_FreeProperty(prop); | ||||
| } | } | ||||
| } | } | ||||
| static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) | static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) | ||||
| { | { | ||||
| uiBut *but = (uiBut *)arg1; | uiBut *but = (uiBut *)arg1; | ||||
| char shortcut_str[128]; | char shortcut_str[128]; | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| if (idname == NULL) { | if (idname == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* complex code to change name of button */ | /* complex code to change name of button */ | ||||
| if (WM_key_event_operator_string( | if (WM_key_event_operator_string( | ||||
| C, idname, but->opcontext, prop, true, shortcut_str, sizeof(shortcut_str))) { | C, idname, but->opcontext, prop, true, shortcut_str, sizeof(shortcut_str))) { | ||||
| ui_but_add_shortcut(but, shortcut_str, true); | ui_but_add_shortcut(but, shortcut_str, true); | ||||
| } | } | ||||
| else { | else { | ||||
| /* simply strip the shortcut */ | /* simply strip the shortcut */ | ||||
| ui_but_add_shortcut(but, NULL, true); | ui_but_add_shortcut(but, nullptr, true); | ||||
| } | } | ||||
| shortcut_free_operator_property(prop); | shortcut_free_operator_property(prop); | ||||
| } | } | ||||
| static uiBlock *menu_change_shortcut(bContext *C, ARegion *region, void *arg) | static uiBlock *menu_change_shortcut(bContext *C, ARegion *region, void *arg) | ||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| uiBut *but = (uiBut *)arg; | uiBut *but = (uiBut *)arg; | ||||
| PointerRNA ptr; | PointerRNA ptr; | ||||
| const uiStyle *style = UI_style_get_dpi(); | const uiStyle *style = UI_style_get_dpi(); | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| wmKeyMap *km; | wmKeyMap *km; | ||||
| wmKeyMapItem *kmi = WM_key_event_operator(C, | wmKeyMapItem *kmi = WM_key_event_operator(C, | ||||
| idname, | idname, | ||||
| but->opcontext, | but->opcontext, | ||||
| prop, | prop, | ||||
| EVT_TYPE_MASK_HOTKEY_INCLUDE, | EVT_TYPE_MASK_HOTKEY_INCLUDE, | ||||
| EVT_TYPE_MASK_HOTKEY_EXCLUDE, | EVT_TYPE_MASK_HOTKEY_EXCLUDE, | ||||
| &km); | &km); | ||||
| U.runtime.is_dirty = true; | U.runtime.is_dirty = true; | ||||
| BLI_assert(kmi != NULL); | BLI_assert(kmi != nullptr); | ||||
| RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); | RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); | ||||
| uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS); | uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS); | ||||
| UI_block_func_handle_set(block, but_shortcut_name_func, but); | UI_block_func_handle_set(block, but_shortcut_name_func, but); | ||||
| UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); | UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); | ||||
| UI_block_direction_set(block, UI_DIR_CENTER_Y); | UI_block_direction_set(block, UI_DIR_CENTER_Y); | ||||
| uiLayout *layout = UI_block_layout(block, | uiLayout *layout = UI_block_layout(block, | ||||
| UI_LAYOUT_VERTICAL, | UI_LAYOUT_VERTICAL, | ||||
| UI_LAYOUT_PANEL, | UI_LAYOUT_PANEL, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| U.widget_unit * 10, | U.widget_unit * 10, | ||||
| U.widget_unit * 2, | U.widget_unit * 2, | ||||
| 0, | 0, | ||||
| style); | style); | ||||
| uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), ICON_HAND); | uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), ICON_HAND); | ||||
| uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); | uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); | ||||
| UI_block_bounds_set_popup( | const int bounds_offset[2] = {int(-100 * U.dpi_fac), int(36 * U.dpi_fac)}; | ||||
| block, 6 * U.dpi_fac, (const int[2]){-100 * U.dpi_fac, 36 * U.dpi_fac}); | UI_block_bounds_set_popup(block, 6 * U.dpi_fac, bounds_offset); | ||||
| shortcut_free_operator_property(prop); | shortcut_free_operator_property(prop); | ||||
| return block; | return block; | ||||
| } | } | ||||
| #ifdef USE_KEYMAP_ADD_HACK | #ifdef USE_KEYMAP_ADD_HACK | ||||
| static int g_kmi_id_hack; | static int g_kmi_id_hack; | ||||
| #endif | #endif | ||||
| static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg) | static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg) | ||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| uiBut *but = (uiBut *)arg; | uiBut *but = (uiBut *)arg; | ||||
| PointerRNA ptr; | PointerRNA ptr; | ||||
| const uiStyle *style = UI_style_get_dpi(); | const uiStyle *style = UI_style_get_dpi(); | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| /* XXX this guess_opname can potentially return a different keymap | /* XXX this guess_opname can potentially return a different keymap | ||||
| * than being found on adding later... */ | * than being found on adding later... */ | ||||
| wmKeyMap *km = WM_keymap_guess_opname(C, idname); | wmKeyMap *km = WM_keymap_guess_opname(C, idname); | ||||
| wmKeyMapItem *kmi = WM_keymap_add_item(km, | KeyMapItem_Params params{}; | ||||
| idname, | params.type = EVT_AKEY; | ||||
| &(const KeyMapItem_Params){ | params.value = KM_PRESS; | ||||
| .type = EVT_AKEY, | params.modifier = 0; | ||||
| .value = KM_PRESS, | params.direction = KM_ANY; | ||||
| .modifier = 0, | wmKeyMapItem *kmi = WM_keymap_add_item(km, idname, ¶ms); | ||||
| .direction = KM_ANY, | |||||
| }); | |||||
| const int kmi_id = kmi->id; | const int kmi_id = kmi->id; | ||||
| /* This takes ownership of prop, or prop can be NULL for reset. */ | /* This takes ownership of prop, or prop can be nullptr for reset. */ | ||||
| WM_keymap_item_properties_reset(kmi, prop); | WM_keymap_item_properties_reset(kmi, prop); | ||||
| /* update and get pointers again */ | /* update and get pointers again */ | ||||
| WM_keyconfig_update(wm); | WM_keyconfig_update(wm); | ||||
| U.runtime.is_dirty = true; | U.runtime.is_dirty = true; | ||||
| km = WM_keymap_guess_opname(C, idname); | km = WM_keymap_guess_opname(C, idname); | ||||
| kmi = WM_keymap_item_find_id(km, kmi_id); | kmi = WM_keymap_item_find_id(km, kmi_id); | ||||
| Show All 12 Lines | uiLayout *layout = UI_block_layout(block, | ||||
| U.widget_unit * 10, | U.widget_unit * 10, | ||||
| U.widget_unit * 2, | U.widget_unit * 2, | ||||
| 0, | 0, | ||||
| style); | style); | ||||
| uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"), ICON_HAND); | uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"), ICON_HAND); | ||||
| uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); | uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); | ||||
| UI_block_bounds_set_popup( | const int bounds_offset[2] = {int(-100 * U.dpi_fac), int(36 * U.dpi_fac)}; | ||||
| block, 6 * U.dpi_fac, (const int[2]){-100 * U.dpi_fac, 36 * U.dpi_fac}); | UI_block_bounds_set_popup(block, 6 * U.dpi_fac, bounds_offset); | ||||
| #ifdef USE_KEYMAP_ADD_HACK | #ifdef USE_KEYMAP_ADD_HACK | ||||
| g_kmi_id_hack = kmi_id; | g_kmi_id_hack = kmi_id; | ||||
| #endif | #endif | ||||
| return block; | return block; | ||||
| } | } | ||||
| static void menu_add_shortcut_cancel(struct bContext *C, void *arg1) | static void menu_add_shortcut_cancel(bContext *C, void *arg1) | ||||
| { | { | ||||
| uiBut *but = (uiBut *)arg1; | uiBut *but = (uiBut *)arg1; | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| #ifdef USE_KEYMAP_ADD_HACK | #ifdef USE_KEYMAP_ADD_HACK | ||||
| wmKeyMap *km = WM_keymap_guess_opname(C, idname); | wmKeyMap *km = WM_keymap_guess_opname(C, idname); | ||||
| const int kmi_id = g_kmi_id_hack; | const int kmi_id = g_kmi_id_hack; | ||||
| UNUSED_VARS(but); | UNUSED_VARS(but); | ||||
| #else | #else | ||||
| int kmi_id = WM_key_event_operator_id(C, idname, but->opcontext, prop, true, &km); | int kmi_id = WM_key_event_operator_id(C, idname, but->opcontext, prop, true, &km); | ||||
| #endif | #endif | ||||
| shortcut_free_operator_property(prop); | shortcut_free_operator_property(prop); | ||||
| wmKeyMapItem *kmi = WM_keymap_item_find_id(km, kmi_id); | wmKeyMapItem *kmi = WM_keymap_item_find_id(km, kmi_id); | ||||
| WM_keymap_remove_item(km, kmi); | WM_keymap_remove_item(km, kmi); | ||||
| } | } | ||||
| static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) | static void popup_change_shortcut_func(bContext *C, void *arg1, void * /*arg2*/) | ||||
| { | { | ||||
| uiBut *but = (uiBut *)arg1; | uiBut *but = (uiBut *)arg1; | ||||
| UI_popup_block_invoke(C, menu_change_shortcut, but, NULL); | UI_popup_block_invoke(C, menu_change_shortcut, but, nullptr); | ||||
| } | } | ||||
| static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) | static void remove_shortcut_func(bContext *C, void *arg1, void * /*arg2*/) | ||||
| { | { | ||||
| uiBut *but = (uiBut *)arg1; | uiBut *but = (uiBut *)arg1; | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| wmKeyMap *km; | wmKeyMap *km; | ||||
| wmKeyMapItem *kmi = WM_key_event_operator(C, | wmKeyMapItem *kmi = WM_key_event_operator(C, | ||||
| idname, | idname, | ||||
| but->opcontext, | but->opcontext, | ||||
| prop, | prop, | ||||
| EVT_TYPE_MASK_HOTKEY_INCLUDE, | EVT_TYPE_MASK_HOTKEY_INCLUDE, | ||||
| EVT_TYPE_MASK_HOTKEY_EXCLUDE, | EVT_TYPE_MASK_HOTKEY_EXCLUDE, | ||||
| &km); | &km); | ||||
| BLI_assert(kmi != NULL); | BLI_assert(kmi != nullptr); | ||||
| WM_keymap_remove_item(km, kmi); | WM_keymap_remove_item(km, kmi); | ||||
| U.runtime.is_dirty = true; | U.runtime.is_dirty = true; | ||||
| shortcut_free_operator_property(prop); | shortcut_free_operator_property(prop); | ||||
| but_shortcut_name_func(C, but, 0); | but_shortcut_name_func(C, but, 0); | ||||
| } | } | ||||
| static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) | static void popup_add_shortcut_func(bContext *C, void *arg1, void * /*arg2*/) | ||||
| { | { | ||||
| uiBut *but = (uiBut *)arg1; | uiBut *but = (uiBut *)arg1; | ||||
| UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL); | UI_popup_block_ex(C, menu_add_shortcut, nullptr, menu_add_shortcut_cancel, but, nullptr); | ||||
| } | } | ||||
| static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but) | static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but) | ||||
| { | { | ||||
| bool result = false; | bool result = false; | ||||
| if (but->optype) { | if (but->optype) { | ||||
| result = true; | result = true; | ||||
| } | } | ||||
| else if (but->rnaprop) { | else if (but->rnaprop) { | ||||
| if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) { | if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) { | ||||
| char *data_path = WM_context_path_resolve_full(C, &but->rnapoin); | char *data_path = WM_context_path_resolve_full(C, &but->rnapoin); | ||||
| if (data_path != NULL) { | if (data_path != nullptr) { | ||||
| MEM_freeN(data_path); | MEM_freeN(data_path); | ||||
| result = true; | result = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (UI_but_menutype_get(but)) { | else if (UI_but_menutype_get(but)) { | ||||
| result = true; | result = true; | ||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um) | static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um) | ||||
| { | { | ||||
| if (but->optype) { | if (but->optype) { | ||||
| IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; | IDProperty *prop = (but->opptr) ? static_cast<IDProperty *>(but->opptr->data) : nullptr; | ||||
| return (bUserMenuItem *)ED_screen_user_menu_item_find_operator( | return (bUserMenuItem *)ED_screen_user_menu_item_find_operator( | ||||
| &um->items, but->optype, prop, but->opcontext); | &um->items, but->optype, prop, but->opcontext); | ||||
| } | } | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); | char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); | ||||
| const char *prop_id = RNA_property_identifier(but->rnaprop); | const char *prop_id = RNA_property_identifier(but->rnaprop); | ||||
| bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop( | bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop( | ||||
| &um->items, member_id_data_path, prop_id, but->rnaindex); | &um->items, member_id_data_path, prop_id, but->rnaindex); | ||||
| MEM_freeN(member_id_data_path); | MEM_freeN(member_id_data_path); | ||||
| return umi; | return umi; | ||||
| } | } | ||||
| MenuType *mt = UI_but_menutype_get(but); | MenuType *mt = UI_but_menutype_get(but); | ||||
| if (mt != NULL) { | if (mt != nullptr) { | ||||
| return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt); | return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt); | ||||
| } | } | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um) | static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um) | ||||
| { | { | ||||
| BLI_assert(ui_but_is_user_menu_compatible(C, but)); | BLI_assert(ui_but_is_user_menu_compatible(C, but)); | ||||
| char drawstr[sizeof(but->drawstr)]; | char drawstr[sizeof(but->drawstr)]; | ||||
| ui_but_drawstr_without_sep_char(but, drawstr, sizeof(drawstr)); | ui_but_drawstr_without_sep_char(but, drawstr, sizeof(drawstr)); | ||||
| MenuType *mt = NULL; | MenuType *mt = nullptr; | ||||
| if (but->optype) { | if (but->optype) { | ||||
| if (drawstr[0] == '\0') { | if (drawstr[0] == '\0') { | ||||
| /* Hard code overrides for generic operators. */ | /* Hard code overrides for generic operators. */ | ||||
| if (UI_but_is_tool(but)) { | if (UI_but_is_tool(but)) { | ||||
| char idname[64]; | char idname[64]; | ||||
| RNA_string_get(but->opptr, "name", idname); | RNA_string_get(but->opptr, "name", idname); | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| { | { | ||||
| const char *expr_imports[] = {"bpy", "bl_ui", NULL}; | const char *expr_imports[] = {"bpy", "bl_ui", nullptr}; | ||||
| char expr[256]; | char expr[256]; | ||||
| SNPRINTF(expr, | SNPRINTF(expr, | ||||
| "bl_ui.space_toolsystem_common.item_from_id(" | "bl_ui.space_toolsystem_common.item_from_id(" | ||||
| "bpy.context, " | "bpy.context, " | ||||
| "bpy.context.space_data.type, " | "bpy.context.space_data.type, " | ||||
| "'%s').label", | "'%s').label", | ||||
| idname); | idname); | ||||
| char *expr_result = NULL; | char *expr_result = nullptr; | ||||
| if (BPY_run_string_as_string(C, expr_imports, expr, NULL, &expr_result)) { | if (BPY_run_string_as_string(C, expr_imports, expr, nullptr, &expr_result)) { | ||||
| STRNCPY(drawstr, expr_result); | STRNCPY(drawstr, expr_result); | ||||
| MEM_freeN(expr_result); | MEM_freeN(expr_result); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| STRNCPY(drawstr, idname); | STRNCPY(drawstr, idname); | ||||
| } | } | ||||
| } | } | ||||
| #else | #else | ||||
| STRNCPY(drawstr, idname); | STRNCPY(drawstr, idname); | ||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| ED_screen_user_menu_item_add_operator( | ED_screen_user_menu_item_add_operator( | ||||
| &um->items, drawstr, but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext); | &um->items, | ||||
| drawstr, | |||||
| but->optype, | |||||
| but->opptr ? static_cast<const IDProperty *>(but->opptr->data) : nullptr, | |||||
| but->opcontext); | |||||
| } | } | ||||
| else if (but->rnaprop) { | else if (but->rnaprop) { | ||||
| /* NOTE: 'member_id' may be a path. */ | /* NOTE: 'member_id' may be a path. */ | ||||
| char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); | char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); | ||||
| const char *prop_id = RNA_property_identifier(but->rnaprop); | const char *prop_id = RNA_property_identifier(but->rnaprop); | ||||
| /* NOTE: ignore 'drawstr', use property idname always. */ | /* NOTE: ignore 'drawstr', use property idname always. */ | ||||
| ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex); | ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex); | ||||
| MEM_freeN(member_id_data_path); | MEM_freeN(member_id_data_path); | ||||
| } | } | ||||
| else if ((mt = UI_but_menutype_get(but))) { | else if ((mt = UI_but_menutype_get(but))) { | ||||
| ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt); | ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt); | ||||
| } | } | ||||
| } | } | ||||
| static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2)) | static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void * /*arg2*/) | ||||
| { | { | ||||
| uiBut *but = arg1; | uiBut *but = static_cast<uiBut *>(arg1); | ||||
| bUserMenu *um = ED_screen_user_menu_ensure(C); | bUserMenu *um = ED_screen_user_menu_ensure(C); | ||||
| U.runtime.is_dirty = true; | U.runtime.is_dirty = true; | ||||
| ui_but_user_menu_add(C, but, um); | ui_but_user_menu_add(C, but, um); | ||||
| } | } | ||||
| static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2) | static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2) | ||||
| { | { | ||||
| bUserMenu *um = arg1; | bUserMenu *um = static_cast<bUserMenu *>(arg1); | ||||
| bUserMenuItem *umi = arg2; | bUserMenuItem *umi = static_cast<bUserMenuItem *>(arg2); | ||||
| U.runtime.is_dirty = true; | U.runtime.is_dirty = true; | ||||
| ED_screen_user_menu_item_remove(&um->items, umi); | ED_screen_user_menu_item_remove(&um->items, umi); | ||||
| } | } | ||||
| static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop) | static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop) | ||||
| { | { | ||||
| const PropertySubType subtype = RNA_property_subtype(prop); | const PropertySubType subtype = RNA_property_subtype(prop); | ||||
| wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); | wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); | ||||
| Show All 9 Lines | static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop) | ||||
| BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file)); | BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file)); | ||||
| if (file[0]) { | if (file[0]) { | ||||
| BLI_assert(subtype == PROP_FILEPATH); | BLI_assert(subtype == PROP_FILEPATH); | ||||
| uiItemFullO_ptr(layout, | uiItemFullO_ptr(layout, | ||||
| ot, | ot, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &props_ptr); | &props_ptr); | ||||
| RNA_string_set(&props_ptr, "filepath", filepath); | RNA_string_set(&props_ptr, "filepath", filepath); | ||||
| } | } | ||||
| uiItemFullO_ptr(layout, | uiItemFullO_ptr(layout, | ||||
| ot, | ot, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &props_ptr); | &props_ptr); | ||||
| RNA_string_set(&props_ptr, "filepath", dir); | RNA_string_set(&props_ptr, "filepath", dir); | ||||
| } | } | ||||
| bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *event) | bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *event) | ||||
| { | { | ||||
| /* ui_but_is_interactive() may let some buttons through that should not get a context menu - it | /* ui_but_is_interactive() may let some buttons through that should not get a context menu - it | ||||
| * doesn't make sense for them. */ | * doesn't make sense for them. */ | ||||
| if (ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_IMAGE)) { | if (ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_IMAGE)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| uiPopupMenu *pup; | uiPopupMenu *pup; | ||||
| uiLayout *layout; | uiLayout *layout; | ||||
| bContextStore *previous_ctx = CTX_store_get(C); | bContextStore *previous_ctx = CTX_store_get(C); | ||||
| { | { | ||||
| uiStringInfo label = {BUT_GET_LABEL, NULL}; | uiStringInfo label = {BUT_GET_LABEL, nullptr}; | ||||
| /* highly unlikely getting the label ever fails */ | /* highly unlikely getting the label ever fails */ | ||||
| UI_but_string_info_get(C, but, &label, NULL); | UI_but_string_info_get(C, but, &label, nullptr); | ||||
| pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE); | pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE); | ||||
| layout = UI_popup_menu_layout(pup); | layout = UI_popup_menu_layout(pup); | ||||
| if (label.strinfo) { | if (label.strinfo) { | ||||
| MEM_freeN(label.strinfo); | MEM_freeN(label.strinfo); | ||||
| } | } | ||||
| if (but->context) { | if (but->context) { | ||||
| ▲ Show 20 Lines • Show All 261 Lines • ▼ Show 20 Lines | if (is_overridable) { | ||||
| /* Override Operators */ | /* Override Operators */ | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| if (but->flag & UI_BUT_OVERRIDDEN) { | if (but->flag & UI_BUT_OVERRIDDEN) { | ||||
| if (is_array_component) { | if (is_array_component) { | ||||
| #if 0 /* Disabled for now. */ | #if 0 /* Disabled for now. */ | ||||
| ot = WM_operatortype_find("UI_OT_override_type_set_button", false); | ot = WM_operatortype_find("UI_OT_override_type_set_button", false); | ||||
| uiItemFullO_ptr( | uiItemFullO_ptr( | ||||
| layout, ot, "Overrides Type", ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); | layout, ot, "Overrides Type", ICON_NONE, nullptr, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", true); | RNA_boolean_set(&op_ptr, "all", true); | ||||
| uiItemFullO_ptr(layout, | uiItemFullO_ptr(layout, | ||||
| ot, | ot, | ||||
| "Single Override Type", | "Single Override Type", | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &op_ptr); | &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", false); | RNA_boolean_set(&op_ptr, "all", false); | ||||
| #endif | #endif | ||||
| uiItemBooleanO(layout, | uiItemBooleanO(layout, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"), | ||||
| ICON_X, | ICON_X, | ||||
| "UI_OT_override_remove_button", | "UI_OT_override_remove_button", | ||||
| "all", | "all", | ||||
| true); | true); | ||||
| uiItemBooleanO(layout, | uiItemBooleanO(layout, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"), | ||||
| ICON_X, | ICON_X, | ||||
| "UI_OT_override_remove_button", | "UI_OT_override_remove_button", | ||||
| "all", | "all", | ||||
| false); | false); | ||||
| } | } | ||||
| else { | else { | ||||
| #if 0 /* Disabled for now. */ | #if 0 /* Disabled for now. */ | ||||
| uiItemFullO(layout, | uiItemFullO(layout, | ||||
| "UI_OT_override_type_set_button", | "UI_OT_override_type_set_button", | ||||
| "Override Type", | "Override Type", | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &op_ptr); | &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", false); | RNA_boolean_set(&op_ptr, "all", false); | ||||
| #endif | #endif | ||||
| uiItemBooleanO(layout, | uiItemBooleanO(layout, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"), | ||||
| ICON_X, | ICON_X, | ||||
| "UI_OT_override_remove_button", | "UI_OT_override_remove_button", | ||||
| "all", | "all", | ||||
| true); | true); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (is_array_component) { | if (is_array_component) { | ||||
| ot = WM_operatortype_find("UI_OT_override_type_set_button", false); | ot = WM_operatortype_find("UI_OT_override_type_set_button", false); | ||||
| uiItemFullO_ptr(layout, | uiItemFullO_ptr(layout, | ||||
| ot, | ot, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Overrides"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Overrides"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &op_ptr); | &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", true); | RNA_boolean_set(&op_ptr, "all", true); | ||||
| uiItemFullO_ptr(layout, | uiItemFullO_ptr(layout, | ||||
| ot, | ot, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Single Override"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Single Override"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &op_ptr); | &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", false); | RNA_boolean_set(&op_ptr, "all", false); | ||||
| } | } | ||||
| else { | else { | ||||
| uiItemFullO(layout, | uiItemFullO(layout, | ||||
| "UI_OT_override_type_set_button", | "UI_OT_override_type_set_button", | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Override"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Define Override"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| &op_ptr); | &op_ptr); | ||||
| RNA_boolean_set(&op_ptr, "all", false); | RNA_boolean_set(&op_ptr, "all", false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | if (view_item_but) { | ||||
| BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM); | BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM); | ||||
| UI_view_item_context_menu_build(C, view_item_but->view_item, uiLayoutColumn(layout, false)); | UI_view_item_context_menu_build(C, view_item_but->view_item, uiLayoutColumn(layout, false)); | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| } | } | ||||
| } | } | ||||
| /* If the button represents an id, it can set the "id" context pointer. */ | /* If the button represents an id, it can set the "id" context pointer. */ | ||||
| if (ED_asset_can_mark_single_from_context(C)) { | if (ED_asset_can_mark_single_from_context(C)) { | ||||
| ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data; | const ID *id = static_cast<const ID *>(CTX_data_pointer_get_type(C, "id", &RNA_ID).data); | ||||
| /* Gray out items depending on if data-block is an asset. Preferably this could be done via | /* Gray out items depending on if data-block is an asset. Preferably this could be done via | ||||
| * operator poll, but that doesn't work since the operator also works with "selected_ids", | * operator poll, but that doesn't work since the operator also works with "selected_ids", | ||||
| * which isn't cheap to check. */ | * which isn't cheap to check. */ | ||||
| uiLayout *sub = uiLayoutColumn(layout, true); | uiLayout *sub = uiLayoutColumn(layout, true); | ||||
| uiLayoutSetEnabled(sub, !id->asset_data); | uiLayoutSetEnabled(sub, !id->asset_data); | ||||
| uiItemO(sub, NULL, ICON_NONE, "ASSET_OT_mark"); | uiItemO(sub, nullptr, ICON_NONE, "ASSET_OT_mark"); | ||||
| sub = uiLayoutColumn(layout, true); | sub = uiLayoutColumn(layout, true); | ||||
| uiLayoutSetEnabled(sub, id->asset_data); | uiLayoutSetEnabled(sub, id->asset_data); | ||||
| uiItemO(sub, NULL, ICON_NONE, "ASSET_OT_clear"); | uiItemO(sub, nullptr, ICON_NONE, "ASSET_OT_clear"); | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| } | } | ||||
| MenuType *mt_idtemplate_liboverride = WM_menutype_find("UI_MT_idtemplate_liboverride", true); | MenuType *mt_idtemplate_liboverride = WM_menutype_find("UI_MT_idtemplate_liboverride", true); | ||||
| if (mt_idtemplate_liboverride && mt_idtemplate_liboverride->poll(C, mt_idtemplate_liboverride)) { | if (mt_idtemplate_liboverride && mt_idtemplate_liboverride->poll(C, mt_idtemplate_liboverride)) { | ||||
| uiItemM_ptr(layout, mt_idtemplate_liboverride, IFACE_("Library Override"), ICON_NONE); | uiItemM_ptr(layout, mt_idtemplate_liboverride, IFACE_("Library Override"), ICON_NONE); | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| } | } | ||||
| Show All 19 Lines | if (ui_but_is_user_menu_compatible(C, but)) { | ||||
| uiBlock *block = uiLayoutGetBlock(layout); | uiBlock *block = uiLayoutGetBlock(layout); | ||||
| const int w = uiLayoutGetWidth(layout); | const int w = uiLayoutGetWidth(layout); | ||||
| bool item_found = false; | bool item_found = false; | ||||
| uint um_array_len; | uint um_array_len; | ||||
| bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len); | bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len); | ||||
| for (int um_index = 0; um_index < um_array_len; um_index++) { | for (int um_index = 0; um_index < um_array_len; um_index++) { | ||||
| bUserMenu *um = um_array[um_index]; | bUserMenu *um = um_array[um_index]; | ||||
| if (um == NULL) { | if (um == nullptr) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| bUserMenuItem *umi = ui_but_user_menu_find(C, but, um); | bUserMenuItem *umi = ui_but_user_menu_find(C, but, um); | ||||
| if (umi != NULL) { | if (umi != nullptr) { | ||||
| uiBut *but2 = uiDefIconTextBut( | uiBut *but2 = uiDefIconTextBut( | ||||
| block, | block, | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_MENU_PANEL, | ICON_MENU_PANEL, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Quick Favorites"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Quick Favorites"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_but_func_set(but2, popup_user_menu_remove_func, um, umi); | UI_but_func_set(but2, popup_user_menu_remove_func, um, umi); | ||||
| item_found = true; | item_found = true; | ||||
| } | } | ||||
| } | } | ||||
| if (um_array) { | if (um_array) { | ||||
| MEM_freeN(um_array); | MEM_freeN(um_array); | ||||
| } | } | ||||
| if (!item_found) { | if (!item_found) { | ||||
| uiBut *but2 = uiDefIconTextBut( | uiBut *but2 = uiDefIconTextBut( | ||||
| block, | block, | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_MENU_PANEL, | ICON_MENU_PANEL, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Quick Favorites"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Quick Favorites"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| "Add to a user defined context menu (stored in the user preferences)"); | "Add to a user defined context menu (stored in the user preferences)"); | ||||
| UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL); | UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, nullptr); | ||||
| } | } | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| } | } | ||||
| /* Shortcut menu */ | /* Shortcut menu */ | ||||
| IDProperty *prop; | IDProperty *prop; | ||||
| const char *idname = shortcut_get_operator_property(C, but, &prop); | const char *idname = shortcut_get_operator_property(C, but, &prop); | ||||
| if (idname != NULL) { | if (idname != nullptr) { | ||||
| uiBlock *block = uiLayoutGetBlock(layout); | uiBlock *block = uiLayoutGetBlock(layout); | ||||
| const int w = uiLayoutGetWidth(layout); | const int w = uiLayoutGetWidth(layout); | ||||
| /* We want to know if this op has a shortcut, be it hotkey or not. */ | /* We want to know if this op has a shortcut, be it hotkey or not. */ | ||||
| wmKeyMap *km; | wmKeyMap *km; | ||||
| wmKeyMapItem *kmi = WM_key_event_operator( | wmKeyMapItem *kmi = WM_key_event_operator( | ||||
| C, idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km); | C, idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km); | ||||
| Show All 17 Lines | #endif | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_HAND, | ICON_HAND, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_but_func_set(but2, popup_change_shortcut_func, but, NULL); | UI_but_func_set(but2, popup_change_shortcut_func, but, nullptr); | ||||
| } | } | ||||
| else { | else { | ||||
| uiBut *but2 = uiDefIconTextBut(block, | uiBut *but2 = uiDefIconTextBut(block, | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_HAND, | ICON_HAND, | ||||
| IFACE_("Non-Keyboard Shortcut"), | IFACE_("Non-Keyboard Shortcut"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| TIP_("Only keyboard shortcuts can be edited that way, " | TIP_("Only keyboard shortcuts can be edited that way, " | ||||
| "please use User Preferences otherwise")); | "please use User Preferences otherwise")); | ||||
| UI_but_flag_enable(but2, UI_BUT_DISABLED); | UI_but_flag_enable(but2, UI_BUT_DISABLED); | ||||
| } | } | ||||
| uiBut *but2 = uiDefIconTextBut( | uiBut *but2 = uiDefIconTextBut( | ||||
| block, | block, | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_BLANK1, | ICON_BLANK1, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_but_func_set(but2, remove_shortcut_func, but, NULL); | UI_but_func_set(but2, remove_shortcut_func, but, nullptr); | ||||
| } | } | ||||
| /* only show 'assign' if there's a suitable key map for it to go in */ | /* only show 'assign' if there's a suitable key map for it to go in */ | ||||
| else if (WM_keymap_guess_opname(C, idname)) { | else if (WM_keymap_guess_opname(C, idname)) { | ||||
| uiBut *but2 = uiDefIconTextBut( | uiBut *but2 = uiDefIconTextBut( | ||||
| block, | block, | ||||
| UI_BTYPE_BUT, | UI_BTYPE_BUT, | ||||
| 0, | 0, | ||||
| ICON_HAND, | ICON_HAND, | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"), | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| w, | w, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_but_func_set(but2, popup_add_shortcut_func, but, NULL); | UI_but_func_set(but2, popup_add_shortcut_func, but, nullptr); | ||||
| } | } | ||||
| shortcut_free_operator_property(prop); | shortcut_free_operator_property(prop); | ||||
| /* Set the operator pointer for python access */ | /* Set the operator pointer for python access */ | ||||
| uiLayoutSetContextFromBut(layout, but); | uiLayoutSetContextFromBut(layout, but); | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| Show All 9 Lines | if (UI_but_online_manual_id(but, buf, sizeof(buf))) { | ||||
| ICON_URL, | ICON_URL, | ||||
| "WM_OT_doc_view_manual_ui_context"); | "WM_OT_doc_view_manual_ui_context"); | ||||
| if (U.flag & USER_DEVELOPER_UI) { | if (U.flag & USER_DEVELOPER_UI) { | ||||
| uiItemFullO(layout, | uiItemFullO(layout, | ||||
| "WM_OT_doc_view", | "WM_OT_doc_view", | ||||
| CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"), | CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_EXEC_DEFAULT, | WM_OP_EXEC_DEFAULT, | ||||
| 0, | 0, | ||||
| &ptr_props); | &ptr_props); | ||||
| RNA_string_set(&ptr_props, "doc_id", buf); | RNA_string_set(&ptr_props, "doc_id", buf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (but->optype && U.flag & USER_DEVELOPER_UI) { | if (but->optype && U.flag & USER_DEVELOPER_UI) { | ||||
| uiItemO(layout, NULL, ICON_NONE, "UI_OT_copy_python_command_button"); | uiItemO(layout, nullptr, ICON_NONE, "UI_OT_copy_python_command_button"); | ||||
| } | } | ||||
| /* 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) { | ||||
| uiItemFullO( | uiItemFullO(layout, | ||||
| layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL); | "UI_OT_editsource", | ||||
| nullptr, | |||||
| ICON_NONE, | |||||
| nullptr, | |||||
| WM_OP_INVOKE_DEFAULT, | |||||
| 0, | |||||
| nullptr); | |||||
| } | } | ||||
| } | } | ||||
| if (BKE_addon_find(&U.addons, "ui_translate")) { | if (BKE_addon_find(&U.addons, "ui_translate")) { | ||||
| uiItemFullO(layout, | uiItemFullO(layout, | ||||
| "UI_OT_edittranslation_init", | "UI_OT_edittranslation_init", | ||||
| NULL, | nullptr, | ||||
| ICON_NONE, | ICON_NONE, | ||||
| NULL, | nullptr, | ||||
| WM_OP_INVOKE_DEFAULT, | WM_OP_INVOKE_DEFAULT, | ||||
| 0, | 0, | ||||
| NULL); | nullptr); | ||||
| } | } | ||||
| /* Show header tools for header buttons. */ | /* Show header tools for header buttons. */ | ||||
| if (ui_block_is_popup_any(but->block) == false) { | if (ui_block_is_popup_any(but->block) == false) { | ||||
| const ARegion *region = CTX_wm_region(C); | const ARegion *region = CTX_wm_region(C); | ||||
| if (!region) { | if (!region) { | ||||
| /* skip */ | /* skip */ | ||||
| } | } | ||||
| else if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { | else if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { | ||||
| 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, nullptr); | |||||
| } | } | ||||
| else if (region->regiontype == RGN_TYPE_NAV_BAR) { | else if (region->regiontype == RGN_TYPE_NAV_BAR) { | ||||
| uiItemMenuF(layout, | uiItemMenuF(layout, | ||||
| IFACE_("Navigation Bar"), | IFACE_("Navigation Bar"), | ||||
| ICON_NONE, | ICON_NONE, | ||||
| ED_screens_navigation_bar_tools_menu_create, | ED_screens_navigation_bar_tools_menu_create, | ||||
| NULL); | nullptr); | ||||
| } | } | ||||
| else if (region->regiontype == RGN_TYPE_FOOTER) { | else if (region->regiontype == RGN_TYPE_FOOTER) { | ||||
| uiItemMenuF(layout, IFACE_("Footer"), ICON_NONE, ED_screens_footer_tools_menu_create, NULL); | uiItemMenuF( | ||||
| layout, IFACE_("Footer"), ICON_NONE, ED_screens_footer_tools_menu_create, nullptr); | |||||
| } | } | ||||
| } | } | ||||
| /* UI List item context menu. Scripts can add items to it, by default there's nothing shown. */ | /* UI List item context menu. Scripts can add items to it, by default there's nothing shown. */ | ||||
| const ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); | const ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); | ||||
| const bool is_inside_listbox = ui_list_find_mouse_over(region, event) != NULL; | const bool is_inside_listbox = ui_list_find_mouse_over(region, event) != nullptr; | ||||
| const bool is_inside_listrow = is_inside_listbox ? | const bool is_inside_listrow = is_inside_listbox ? | ||||
| ui_list_row_find_mouse_over(region, event->xy) != NULL : | ui_list_row_find_mouse_over(region, event->xy) != nullptr : | ||||
| false; | false; | ||||
| if (is_inside_listrow) { | if (is_inside_listrow) { | ||||
| MenuType *mt = WM_menutype_find("UI_MT_list_item_context_menu", true); | MenuType *mt = WM_menutype_find("UI_MT_list_item_context_menu", true); | ||||
| if (mt) { | if (mt) { | ||||
| UI_menutype_draw(C, mt, uiLayoutColumn(layout, false)); | UI_menutype_draw(C, mt, uiLayoutColumn(layout, false)); | ||||
| } | } | ||||
| } | } | ||||
| Show All 19 Lines | |||||
| { | { | ||||
| bScreen *screen = CTX_wm_screen(C); | bScreen *screen = CTX_wm_screen(C); | ||||
| const bool has_panel_category = UI_panel_category_is_visible(region); | const bool has_panel_category = UI_panel_category_is_visible(region); | ||||
| const bool any_item_visible = has_panel_category; | const bool any_item_visible = has_panel_category; | ||||
| if (!any_item_visible) { | if (!any_item_visible) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (panel->type->parent != NULL) { | if (panel->type->parent != nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (!UI_panel_can_be_pinned(panel)) { | if (!UI_panel_can_be_pinned(panel)) { | ||||
| return; | return; | ||||
| } | } | ||||
| PointerRNA ptr; | PointerRNA ptr; | ||||
| RNA_pointer_create(&screen->id, &RNA_Panel, panel, &ptr); | RNA_pointer_create(&screen->id, &RNA_Panel, panel, &ptr); | ||||
| uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE); | uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE); | ||||
| uiLayout *layout = UI_popup_menu_layout(pup); | uiLayout *layout = UI_popup_menu_layout(pup); | ||||
| if (has_panel_category) { | if (has_panel_category) { | ||||
| char tmpstr[80]; | char tmpstr[80]; | ||||
| BLI_snprintf(tmpstr, | BLI_snprintf(tmpstr, | ||||
| sizeof(tmpstr), | sizeof(tmpstr), | ||||
| "%s" UI_SEP_CHAR_S "%s", | "%s" UI_SEP_CHAR_S "%s", | ||||
| IFACE_("Pin"), | IFACE_("Pin"), | ||||
| IFACE_("Shift Left Mouse")); | IFACE_("Shift Left Mouse")); | ||||
| uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE); | uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE); | ||||
| /* evil, force shortcut flag */ | /* evil, force shortcut flag */ | ||||
| { | { | ||||
| uiBlock *block = uiLayoutGetBlock(layout); | uiBlock *block = uiLayoutGetBlock(layout); | ||||
| uiBut *but = block->buttons.last; | uiBut *but = static_cast<uiBut *>(block->buttons.last); | ||||
| but->flag |= UI_BUT_HAS_SEP_CHAR; | but->flag |= UI_BUT_HAS_SEP_CHAR; | ||||
| } | } | ||||
| } | } | ||||
| UI_popup_menu_end(C, pup); | UI_popup_menu_end(C, pup); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||