UI: Add user defined context menu
- Add/Remove from RMB context menu. - Stored in user preferences. - Access from Q key. See T55027.
This commit is contained in:
parent
2fa231a86b
commit
85c1e61375
Notes:
blender-bot
2023-02-14 08:42:53 +01:00
Referenced by issue #55027, 2.8 UI Tools: Favourites Bar / Specials Menu Design
|
@ -121,9 +121,6 @@ typedef struct SpaceType {
|
|||
/* region type definitions */
|
||||
ListBase regiontypes;
|
||||
|
||||
/* tool shelf definitions */
|
||||
ListBase toolshelf;
|
||||
|
||||
/* read and write... */
|
||||
|
||||
/* default keymaps to add */
|
||||
|
|
|
@ -241,6 +241,15 @@ void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
|
|||
BLI_freelistN(&userdef->uifonts);
|
||||
BLI_freelistN(&userdef->themes);
|
||||
|
||||
for (bUserMenuItem *umi = userdef->user_menu_items.first, *umi_next; umi; umi = umi_next) {
|
||||
umi_next = umi->next;
|
||||
if (umi->prop) {
|
||||
IDP_FreeProperty(umi->prop);
|
||||
MEM_freeN(umi->prop);
|
||||
}
|
||||
MEM_freeN(umi);
|
||||
}
|
||||
|
||||
#undef U
|
||||
}
|
||||
|
||||
|
|
|
@ -88,8 +88,6 @@ static void spacetype_free(SpaceType *st)
|
|||
}
|
||||
|
||||
BLI_freelistN(&st->regiontypes);
|
||||
BLI_freelistN(&st->toolshelf);
|
||||
|
||||
}
|
||||
|
||||
void BKE_spacetypes_free(void)
|
||||
|
|
|
@ -8713,6 +8713,12 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||
user->uifonts.first = user->uifonts.last= NULL;
|
||||
|
||||
link_list(fd, &user->uistyles);
|
||||
link_list(fd, &user->user_menu_items);
|
||||
|
||||
for (bUserMenuItem *umi = user->user_menu_items.first; umi; umi = umi->next) {
|
||||
umi->prop = newdataadr(fd, umi->prop);
|
||||
IDP_DirectLinkGroup_OrFree(&umi->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||
}
|
||||
|
||||
/* free fd->datamap again */
|
||||
oldnewmap_free_unused(fd->datamap);
|
||||
|
|
|
@ -1258,6 +1258,13 @@ static void write_userdef(WriteData *wd, const UserDef *userdef)
|
|||
for (const uiStyle *style = userdef->uistyles.first; style; style = style->next) {
|
||||
writestruct(wd, DATA, uiStyle, 1, style);
|
||||
}
|
||||
|
||||
for (const bUserMenuItem *umi = userdef->user_menu_items.first; umi; umi = umi->next) {
|
||||
writestruct(wd, DATA, bUserMenuItem, 1, umi);
|
||||
if (umi->prop) {
|
||||
IDP_WriteProperty(umi->prop, wd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_boid_state(WriteData *wd, BoidState *state)
|
||||
|
|
|
@ -60,6 +60,8 @@ struct Main;
|
|||
struct wmMsgBus;
|
||||
struct wmMsgSubscribeKey;
|
||||
struct wmMsgSubscribeValue;
|
||||
struct wmOperatorType;
|
||||
struct IDProperty;
|
||||
|
||||
/* regions */
|
||||
void ED_region_do_listen(
|
||||
|
@ -311,6 +313,16 @@ int ED_operator_posemode_local(struct bContext *C);
|
|||
int ED_operator_mask(struct bContext *C);
|
||||
int ED_operator_camera(struct bContext *C);
|
||||
|
||||
/* screen_user_menu.c */
|
||||
|
||||
void ED_screen_user_menu_add(
|
||||
struct bContext *C, const char *ui_name,
|
||||
struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
|
||||
void ED_screen_user_menu_remove(struct bUserMenuItem *umi);
|
||||
struct bUserMenuItem *ED_screen_user_menu_find(
|
||||
struct bContext *C,
|
||||
struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
|
||||
void ED_screen_user_menu_register(void);
|
||||
|
||||
/* Cache display helpers */
|
||||
|
||||
|
@ -333,4 +345,3 @@ void ED_area_type_hud_ensure(struct bContext *C, struct ScrArea *sa);
|
|||
#define ED_KEYMAP_HEADER 64
|
||||
|
||||
#endif /* __ED_SCREEN_H__ */
|
||||
|
||||
|
|
|
@ -6649,6 +6649,30 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
|
|||
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
|
||||
}
|
||||
|
||||
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *arg2)
|
||||
{
|
||||
uiBut *but = arg1;
|
||||
bUserMenuItem *umi = arg2;
|
||||
if (umi) {
|
||||
ED_screen_user_menu_remove(umi);
|
||||
}
|
||||
char drawstr[sizeof(but->drawstr)];
|
||||
STRNCPY(drawstr, but->drawstr);
|
||||
if (but->flag & UI_BUT_HAS_SEP_CHAR) {
|
||||
char *sep = strrchr(drawstr, UI_SEP_CHAR);
|
||||
if (sep) {
|
||||
*sep = '\0';
|
||||
}
|
||||
}
|
||||
ED_screen_user_menu_add(C, drawstr, but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
|
||||
}
|
||||
|
||||
static void popup_user_menu_remove_func(bContext *UNUSED(C), void *UNUSED(arg1), void *arg2)
|
||||
{
|
||||
bUserMenuItem *umi = arg2;
|
||||
ED_screen_user_menu_remove(umi);
|
||||
}
|
||||
|
||||
/**
|
||||
* menu to chow when right clicking on the panel header
|
||||
*/
|
||||
|
@ -7021,6 +7045,27 @@ static bool ui_but_menu(bContext *C, uiBut *but)
|
|||
UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
{
|
||||
bUserMenuItem *umi = ED_screen_user_menu_find(
|
||||
C, but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
|
||||
|
||||
but2 = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Favourites Menu"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
|
||||
"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, umi);
|
||||
if (umi) {
|
||||
but2 = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_CANCEL,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Favourites Menu"),
|
||||
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
UI_but_func_set(but2, popup_user_menu_remove_func, NULL, umi);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the operator pointer for python access */
|
||||
uiLayoutSetContextFromBut(layout, but);
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ set(SRC
|
|||
screen_draw.c
|
||||
screen_edit.c
|
||||
screen_ops.c
|
||||
screen_user_menu.c
|
||||
screendump.c
|
||||
workspace_edit.c
|
||||
workspace_layout_edit.c
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/screen/screen_user_menu.c
|
||||
* \ingroup spview3d
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
||||
void ED_screen_user_menu_add(
|
||||
bContext *C, const char *ui_name,
|
||||
wmOperatorType *ot, IDProperty *prop, short opcontext)
|
||||
{
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
bUserMenuItem *umi = MEM_callocN(sizeof(bUserMenuItem), __func__);
|
||||
umi->space_type = sl ? sl->spacetype : SPACE_EMPTY;
|
||||
umi->opcontext = opcontext;
|
||||
if (!STREQ(ui_name, ot->name)) {
|
||||
BLI_strncpy(umi->ui_name, ui_name, OP_MAX_TYPENAME);
|
||||
}
|
||||
BLI_strncpy(umi->opname, ot->idname, OP_MAX_TYPENAME);
|
||||
BLI_strncpy(umi->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
|
||||
umi->prop = prop ? IDP_CopyProperty(prop) : NULL;
|
||||
BLI_addtail(&U.user_menu_items, umi);
|
||||
}
|
||||
|
||||
void ED_screen_user_menu_remove(bUserMenuItem *umi)
|
||||
{
|
||||
BLI_remlink(&U.user_menu_items, umi);
|
||||
if (umi->prop) {
|
||||
IDP_FreeProperty(umi->prop);
|
||||
MEM_freeN(umi->prop);
|
||||
}
|
||||
MEM_freeN(umi);
|
||||
}
|
||||
|
||||
bUserMenuItem *ED_screen_user_menu_find(
|
||||
bContext *C,
|
||||
wmOperatorType *ot, IDProperty *prop, short opcontext)
|
||||
{
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
for (bUserMenuItem *umi = U.user_menu_items.first; umi; umi = umi->next) {
|
||||
if (STREQ(ot->idname, umi->opname) &&
|
||||
(opcontext == umi->opcontext) &&
|
||||
(IDP_EqualsProperties(prop, umi->prop)))
|
||||
{
|
||||
if ((ELEM(umi->space_type, SPACE_TOPBAR) || (sl->spacetype == umi->space_type)) &&
|
||||
(STREQLEN(context, umi->context, OP_MAX_TYPENAME)))
|
||||
{
|
||||
return umi;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Menu Definition
|
||||
* \{ */
|
||||
|
||||
static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
||||
{
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
for (bUserMenuItem *umi = U.user_menu_items.first; umi; umi = umi->next) {
|
||||
if ((ELEM(umi->space_type, SPACE_TOPBAR) || (sl->spacetype == umi->space_type)) &&
|
||||
(STREQLEN(context, umi->context, OP_MAX_TYPENAME)))
|
||||
{
|
||||
IDProperty *prop = umi->prop ? IDP_CopyProperty(umi->prop) : NULL;
|
||||
uiItemFullO(
|
||||
menu->layout, umi->opname, umi->ui_name[0] ? umi->ui_name : NULL,
|
||||
ICON_NONE, prop, umi->opcontext, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ED_screen_user_menu_register(void)
|
||||
{
|
||||
MenuType *mt = MEM_callocN(sizeof(MenuType), __func__);
|
||||
strcpy(mt->idname, "SCREEN_MT_user_menu");
|
||||
strcpy(mt->label, "Quick Favourites");
|
||||
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
mt->draw = screen_user_menu_draw;
|
||||
WM_menutype_add(mt);
|
||||
}
|
||||
|
||||
/** \} */
|
|
@ -127,6 +127,8 @@ void ED_spacetypes_init(void)
|
|||
ED_operatortypes_view2d();
|
||||
ED_operatortypes_ui();
|
||||
|
||||
ED_screen_user_menu_register();
|
||||
|
||||
/* manipulator types */
|
||||
ED_manipulatortypes_button_2d();
|
||||
ED_manipulatortypes_dial_3d();
|
||||
|
|
|
@ -1541,11 +1541,6 @@ void ED_spacetype_view3d(void)
|
|||
art->draw = view3d_tools_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
#if 0
|
||||
/* unfinished still */
|
||||
view3d_toolshelf_register(art);
|
||||
#endif
|
||||
|
||||
/* regions: header */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
|
||||
art->regionid = RGN_TYPE_HEADER;
|
||||
|
|
|
@ -235,7 +235,6 @@ struct Object *ED_view3d_cameracontrol_object_get(
|
|||
|
||||
/* view3d_toolbar.c */
|
||||
void VIEW3D_OT_toolshelf(struct wmOperatorType *ot);
|
||||
void view3d_toolshelf_register(struct ARegionType *art);
|
||||
|
||||
/* view3d_snap.c */
|
||||
bool ED_view3d_minmax_verts(struct Object *obedit, float min[3], float max[3]);
|
||||
|
|
|
@ -28,153 +28,24 @@
|
|||
* \ingroup spview3d
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_undo.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "view3d_intern.h" /* own include */
|
||||
|
||||
/* ******************* */
|
||||
|
||||
typedef struct CustomTool {
|
||||
struct CustomTool *next, *prev;
|
||||
char opname[OP_MAX_TYPENAME];
|
||||
char context[OP_MAX_TYPENAME];
|
||||
} CustomTool;
|
||||
|
||||
static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
|
||||
{
|
||||
wmOperatorType *ot = arg2;
|
||||
|
||||
if (ot) {
|
||||
CustomTool *ct = MEM_callocN(sizeof(CustomTool), "CustomTool");
|
||||
|
||||
BLI_addtail(arg_listbase, ct);
|
||||
BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
|
||||
BLI_strncpy(ct->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
|
||||
{
|
||||
GHashIterator iter;
|
||||
|
||||
for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
|
||||
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
|
||||
|
||||
if (BLI_strcasestr(ot->name, str)) {
|
||||
if (WM_operator_poll((bContext *)C, ot)) {
|
||||
|
||||
if (false == UI_search_item_add(items, ot->name, ot, 0))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ID Search browse menu, open */
|
||||
static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
|
||||
{
|
||||
static char search[OP_MAX_TYPENAME];
|
||||
wmEvent event;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
|
||||
/* clear initial search string, then all items show */
|
||||
search[0] = 0;
|
||||
|
||||
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
|
||||
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
|
||||
|
||||
/* fake button, it holds space for search items */
|
||||
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
|
||||
|
||||
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
|
||||
UI_but_func_search_set(but, NULL, operator_search_cb, arg_listbase, operator_call_cb, NULL);
|
||||
|
||||
UI_block_bounds_set_normal(block, 6);
|
||||
UI_block_direction_set(block, UI_DIR_DOWN);
|
||||
UI_block_end(C, block);
|
||||
|
||||
wm_event_init_from_window(win, &event);
|
||||
event.type = EVT_BUT_OPEN;
|
||||
event.val = KM_PRESS;
|
||||
event.customdata = but;
|
||||
event.customdatafree = false;
|
||||
wm_event_add(win, &event);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
|
||||
{
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
SpaceType *st = NULL;
|
||||
uiLayout *col;
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
|
||||
if (sl)
|
||||
st = BKE_spacetype_from_id(sl->spacetype);
|
||||
|
||||
if (st && st->toolshelf.first) {
|
||||
CustomTool *ct;
|
||||
|
||||
for (ct = st->toolshelf.first; ct; ct = ct->next) {
|
||||
if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) {
|
||||
col = uiLayoutColumn(pa->layout, true);
|
||||
uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
col = uiLayoutColumn(pa->layout, true);
|
||||
uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &st->toolshelf, "Add Tool", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add Tool in shelf, gets saved in files");
|
||||
}
|
||||
|
||||
|
||||
void view3d_toolshelf_register(ARegionType *art)
|
||||
{
|
||||
PanelType *pt;
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
|
||||
strcpy(pt->idname, "VIEW3D_PT_tool_shelf");
|
||||
strcpy(pt->label, N_("Tool Shelf"));
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw = view3d_panel_tool_shelf;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
|
||||
/* ********** operator to open/close toolshelf region */
|
||||
|
||||
static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
@ -200,4 +71,3 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot)
|
|||
/* flags */
|
||||
ot->flag = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -430,6 +430,17 @@ typedef struct bPathCompare {
|
|||
char flag, pad[7];
|
||||
} bPathCompare;
|
||||
|
||||
typedef struct bUserMenuItem {
|
||||
struct bUserMenuItem *next, *prev;
|
||||
char space_type;
|
||||
char opcontext;
|
||||
char _pad0[6];
|
||||
char ui_name[64];
|
||||
char opname[64];
|
||||
char context[64];
|
||||
struct IDProperty *prop;
|
||||
} bUserMenuItem;
|
||||
|
||||
typedef struct SolidLight {
|
||||
int flag, pad;
|
||||
float col[4], spec[4], vec[4];
|
||||
|
@ -511,6 +522,8 @@ typedef struct UserDef {
|
|||
struct ListBase user_keymaps;
|
||||
struct ListBase addons;
|
||||
struct ListBase autoexec_paths;
|
||||
struct ListBase user_menu_items; /* bUserMenuItem */
|
||||
|
||||
char keyconfigstr[64];
|
||||
|
||||
short undosteps;
|
||||
|
|
|
@ -3992,6 +3992,8 @@ void wm_window_keymap(wmKeyConfig *keyconf)
|
|||
WM_keymap_add_item(keymap, "WM_OT_search_menu", F3KEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "WM_OT_search_menu", ACCENTGRAVEKEY, KM_CLICK, 0, 0);
|
||||
|
||||
WM_keymap_add_menu(keymap, "SCREEN_MT_user_menu", QKEY, KM_PRESS, 0, 0);
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue