Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorIan Thompson <quornian@googlemail.com>2008-07-15 11:04:31 +0400
committerIan Thompson <quornian@googlemail.com>2008-07-15 11:04:31 +0400
commitdbb61988fdaa6085912dee6ab8f5569e63ef88fb (patch)
tree2b1334417dbe2536851bed215777f89e416b6007 /source
parent14c1ed08108df6178a55f6d7f818f19a926ae1df (diff)
Any script can now register a unique key combination as part of its bpy header. For a supported space type, the user may press this shortcut to invoke the script.
Space types that are to support shortcuts like this should call BPY_menu_do_shortcut(...) from the event queue read method (See winqreadtextspace in drawtext.c for example)
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BIF_keyval.h3
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/BPY_interface.c34
-rw-r--r--source/blender/python/BPY_menus.c35
-rw-r--r--source/blender/python/BPY_menus.h1
-rw-r--r--source/blender/src/drawtext.c24
-rw-r--r--source/blender/src/keyval.c195
7 files changed, 284 insertions, 10 deletions
diff --git a/source/blender/include/BIF_keyval.h b/source/blender/include/BIF_keyval.h
index 70d248ded91..9693684e425 100644
--- a/source/blender/include/BIF_keyval.h
+++ b/source/blender/include/BIF_keyval.h
@@ -31,6 +31,9 @@
#define BIF_KEYVAL_H
char *key_event_to_string(unsigned short event);
+int decode_key_string(char *str, unsigned short *key, unsigned short *qual);
#endif
+
+
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index f6a27b80733..3a826d49542 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -91,6 +91,8 @@ extern "C" {
int BPY_txt_do_python_Text( struct Text *text );
int BPY_menu_do_python( short menutype, int event );
+ int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers );
+ int BPY_menu_invoke( struct BPyMenu *pym, short menutype );
void BPY_run_python_script( char *filename );
int BPY_run_script(struct Script *script);
void BPY_free_compiled_text( struct Text *text );
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c
index 360c8fd7f04..e9600e9369f 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -972,8 +972,38 @@ int BPY_run_script(Script *script)
*****************************************************************************/
int BPY_menu_do_python( short menutype, int event )
{
- char *argstr = NULL;
BPyMenu *pym;
+ pym = BPyMenu_GetEntry( menutype, ( short ) event );
+ return BPY_menu_invoke( pym, menutype );
+}
+
+/****************************************************************************
+* Description: This function executes the script by its shortcut.
+* Notes: It is called by the ui code in src/???.c when a user presses an
+* unassigned key combination. Scripts are searched in the BPyMenuTable,
+* using the given menutype and event values to know which one to invoke.
+*****************************************************************************/
+int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short qual )
+{
+ BPyMenu *pym;
+ pym = BPyMenu_GetEntry( menutype, 0 );
+
+ while ( pym ) {
+ if ( pym->key && pym->key == key && pym->qual == qual ) {
+ return BPY_menu_invoke( pym, menutype );
+ }
+ pym = pym->next;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+* Description: This function executes the script described by a menu item.
+*****************************************************************************/
+int BPY_menu_invoke( BPyMenu *pym, short menutype )
+{
+ char *argstr = NULL;
BPySubMenu *pysm;
char scriptname[21];
Script *script = NULL;
@@ -981,8 +1011,6 @@ int BPY_menu_do_python( short menutype, int event )
PyGILState_STATE gilstate;
char filestr[FILE_MAX];
- pym = BPyMenu_GetEntry( menutype, ( short ) event );
-
if( !pym )
return 0;
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c
index 08691973a92..69b50e5c47a 100644
--- a/source/blender/python/BPY_menus.c
+++ b/source/blender/python/BPY_menus.c
@@ -42,6 +42,7 @@
#endif
#include "BKE_global.h"
#include "BKE_utildefines.h"
+#include "BIF_keyval.h"
#include "BLI_blenlib.h"
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h" /* for U.pythondir */
@@ -333,6 +334,23 @@ static void bpymenu_set_tooltip( BPyMenu * pymenu, char *tip )
return;
}
+static void bpymenu_set_shortcut( BPyMenu * pymenu, char *combi )
+{
+ unsigned short key, qual;
+
+ if( !pymenu )
+ return;
+
+ if (!decode_key_string(combi, &key, &qual)) {
+ return; /* TODO: Print some error */
+ }
+
+ pymenu->key = key;
+ pymenu->qual = qual;
+
+ return;
+}
+
/* bpymenu_AddEntry:
* try to find an existing pymenu entry with the given type and name;
* if found, update it with new info, otherwise create a new one and fill it.
@@ -693,6 +711,7 @@ void BPyMenu_PrintAllEntries( void )
* # Blender: <code>short int</code> (minimal Blender version)
* # Group: 'group name' (defines menu)
* # Submenu: 'submenu name' related_1word_arg
+ * # Shortcut: Modifier+Key (optional shortcut combination for supported groups)
* # Tooltip: 'tooltip for the menu'
* # \"\"\"
*
@@ -801,13 +820,19 @@ static int bpymenu_ParseFile(FILE *file, char *fname, int is_userdir)
if ((matches == 3) && (strstr(head, "Submenu:") != NULL)) {
bpymenu_AddSubEntry(scriptMenu, middle, tail);
} else {
- /* Tooltip: 'tooltip for the menu */
+ /* Shortcut: 'key+combination' */
matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail);
- if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) ||
- (strstr(head, "Tip:") != NULL))) {
- bpymenu_set_tooltip(scriptMenu, middle);
+ if ((matches == 3) && (strstr(head, "Shortcut:") != NULL)) {
+ bpymenu_set_shortcut(scriptMenu, middle);
+ } else {
+ /* Tooltip: 'tooltip for the menu */
+ matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail);
+ if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) ||
+ (strstr(head, "Tip:") != NULL))) {
+ bpymenu_set_tooltip(scriptMenu, middle);
+ }
+ parser_state = 0;
}
- parser_state = 0;
}
break;
diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h
index e8bca09d50e..576d7b8dcd6 100644
--- a/source/blender/python/BPY_menus.h
+++ b/source/blender/python/BPY_menus.h
@@ -59,6 +59,7 @@ typedef struct BPyMenu {
char *name;
char *filename;
char *tooltip;
+ unsigned short key, qual; /* Registered shortcut key */
short version; /* Blender version */
int dir; /* 0: default, 1: U.pythondir */
struct BPySubMenu *submenus;
diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c
index c76ac47ffb7..b8cf99383a0 100644
--- a/source/blender/src/drawtext.c
+++ b/source/blender/src/drawtext.c
@@ -81,6 +81,7 @@
#include "BSE_filesel.h"
#include "BPY_extern.h"
+#include "BPY_menus.h"
#include "mydevice.h"
#include "blendef.h"
@@ -1833,10 +1834,17 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (st->showsyntax) get_format_string(st);
pop_space_text(st);
do_draw= 1;
- do_suggest= 1;
+ if (suggesting && ispunct(ascii)) {
+ confirm_suggestion(text);
+ if (st->showsyntax) get_format_string(st);
+ do_suggest= 0;
+ } else {
+ do_suggest= 1;
+ }
}
} else if (val) {
- do_suggest= -1;
+ do_suggest= -1; /* Note that the default label sets this to 0,
+ so -1 only applies to the explicit cases below */
switch (event) {
case AKEY:
if (G.qual & LR_ALTKEY) {
@@ -2102,6 +2110,12 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case ESCKEY:
do_suggest= -1;
break;
+ case SPACEKEY:
+ if (suggesting) {
+ confirm_suggestion(text);
+ if (st->showsyntax) get_format_string(st);
+ }
+ break;
case TABKEY:
if (text && text->id.lib) {
error_libdata();
@@ -2300,6 +2314,12 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
+ if (event && val) {
+ if (BPY_menu_do_shortcut(PYMENU_TEXTPLUGIN, event, G.qual)) {
+ do_draw= 1;
+ }
+ }
+
if (last_check_time < PIL_check_seconds_timer() - 1.0) {
switch (txt_file_modified(text)) {
case 1:
diff --git a/source/blender/src/keyval.c b/source/blender/src/keyval.c
index dab4b4ae839..f59cce0da8f 100644
--- a/source/blender/src/keyval.c
+++ b/source/blender/src/keyval.c
@@ -27,6 +27,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include "stdio.h"
+#include "ctype.h"
+#include "string.h"
+
+#include "BKE_global.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BIF_keyval.h"
@@ -349,3 +354,193 @@ char *key_event_to_string(unsigned short event)
return "";
}
+
+/*
+ * Decodes key combination strings [qual1+[qual2+[...]]]keyname
+ * The '+'s may be replaced by '-' or ' ' characters to support different
+ * formats. No additional whitespace is allowed. The keyname may be an internal
+ * name, like "RETKEY", or a more common name, like "Return". Decoding is case-
+ * insensitive.
+ *
+ * Example strings: "Ctrl+L", "ALT-ESC", "Shift A"
+ *
+ * Returns 1 if successful.
+ */
+int decode_key_string(char *str, unsigned short *key, unsigned short *qual)
+{
+ int i, prev, len, invalid=0;
+
+ len= strlen(str);
+ *key= *qual= 0;
+
+ /* Convert to upper case */
+ for (i=0; i<len; i++) {
+ str[i]= toupper(str[i]);
+ }
+
+ /* Handle modifiers */
+ for (prev=i=0; i<len; i++) {
+ if (str[i]==' ' || str[i]=='+' || str[i]=='-') {
+ if (!strncmp(str+prev, "CTRL", i-prev)) *qual |= LR_CTRLKEY;
+ else if (!strncmp(str+prev, "ALT", i-prev)) *qual |= LR_ALTKEY;
+ else if (!strncmp(str+prev, "SHIFT", i-prev)) *qual |= LR_SHIFTKEY;
+ else if (!strncmp(str+prev, "COMMAND", i-prev)) *qual |= LR_COMMANDKEY;
+ prev=i+1;
+ }
+ }
+
+ /* Compare last part against key names */
+ if (len-prev==1 || len-prev==4 && !strncmp(str+prev, "KEY", 3)) {
+
+ if (str[prev]>='A' && str[prev]<='Z') {
+ *key= str[prev]-'A'+AKEY;
+ } else if (str[prev]>='0' && str[prev]<='9') {
+ *key= str[prev]-'0'+ZEROKEY;
+ } else {
+ invalid= 1;
+ }
+
+ } else if (!strncmp(str+prev, "ZEROKEY", len-prev) || !strncmp(str+prev, "ZERO", len-prev)) {
+ *key= ZEROKEY;
+ } else if (!strncmp(str+prev, "ONEKEY", len-prev) || !strncmp(str+prev, "ONE", len-prev)) {
+ *key= ONEKEY;
+ } else if (!strncmp(str+prev, "TWOKEY", len-prev) || !strncmp(str+prev, "TWO", len-prev)) {
+ *key= TWOKEY;
+ } else if (!strncmp(str+prev, "THREEKEY", len-prev) || !strncmp(str+prev, "THREE", len-prev)) {
+ *key= THREEKEY;
+ } else if (!strncmp(str+prev, "FOURKEY", len-prev) || !strncmp(str+prev, "FOUR", len-prev)) {
+ *key= FOURKEY;
+ } else if (!strncmp(str+prev, "FIVEKEY", len-prev) || !strncmp(str+prev, "FIVE", len-prev)) {
+ *key= FIVEKEY;
+ } else if (!strncmp(str+prev, "SIZEKEY", len-prev) || !strncmp(str+prev, "SIX", len-prev)) {
+ *key= SIXKEY;
+ } else if (!strncmp(str+prev, "SEVENKEY", len-prev) || !strncmp(str+prev, "SEVEN", len-prev)) {
+ *key= SEVENKEY;
+ } else if (!strncmp(str+prev, "EIGHTKEY", len-prev) || !strncmp(str+prev, "EIGHT", len-prev)) {
+ *key= EIGHTKEY;
+ } else if (!strncmp(str+prev, "NINEKEY", len-prev) || !strncmp(str+prev, "NINE", len-prev)) {
+ *key= NINEKEY;
+
+ } else if (!strncmp(str+prev, "ESCKEY", len-prev) || !strncmp(str+prev, "ESC", len-prev)) {
+ *key= ESCKEY;
+ } else if (!strncmp(str+prev, "TABKEY", len-prev) || !strncmp(str+prev, "TAB", len-prev)) {
+ *key= TABKEY;
+ } else if (!strncmp(str+prev, "RETKEY", len-prev) || !strncmp(str+prev, "RETURN", len-prev) || !strncmp(str+prev, "ENTER", len-prev)) {
+ *key= RETKEY;
+ } else if (!strncmp(str+prev, "SPACEKEY", len-prev) || !strncmp(str+prev, "SPACE", len-prev)) {
+ *key= SPACEKEY;
+ } else if (!strncmp(str+prev, "LINEFEEDKEY", len-prev) || !strncmp(str+prev, "LINEFEED", len-prev)) {
+ *key= LINEFEEDKEY;
+ } else if (!strncmp(str+prev, "BACKSPACEKEY", len-prev) || !strncmp(str+prev, "BACKSPACE", len-prev)) {
+ *key= BACKSPACEKEY;
+ } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) {
+ *key= DELKEY;
+
+ } else if (!strncmp(str+prev, "SEMICOLONKEY", len-prev) || !strncmp(str+prev, "SEMICOLON", len-prev)) {
+ *key= SEMICOLONKEY;
+ } else if (!strncmp(str+prev, "PERIODKEY", len-prev) || !strncmp(str+prev, "PERIOD", len-prev)) {
+ *key= PERIODKEY;
+ } else if (!strncmp(str+prev, "COMMAKEY", len-prev) || !strncmp(str+prev, "COMMA", len-prev)) {
+ *key= COMMAKEY;
+ } else if (!strncmp(str+prev, "QUOTEKEY", len-prev) || !strncmp(str+prev, "QUOTE", len-prev)) {
+ *key= QUOTEKEY;
+ } else if (!strncmp(str+prev, "ACCENTGRAVEKEY", len-prev) || !strncmp(str+prev, "ACCENTGRAVE", len-prev)) {
+ *key= ACCENTGRAVEKEY;
+ } else if (!strncmp(str+prev, "MINUSKEY", len-prev) || !strncmp(str+prev, "MINUS", len-prev)) {
+ *key= MINUSKEY;
+ } else if (!strncmp(str+prev, "SLASHKEY", len-prev) || !strncmp(str+prev, "SLASH", len-prev)) {
+ *key= SLASHKEY;
+ } else if (!strncmp(str+prev, "BACKSLASHKEY", len-prev) || !strncmp(str+prev, "BACKSLASH", len-prev)) {
+ *key= BACKSLASHKEY;
+ } else if (!strncmp(str+prev, "EQUALKEY", len-prev) || !strncmp(str+prev, "EQUAL", len-prev)) {
+ *key= EQUALKEY;
+ } else if (!strncmp(str+prev, "LEFTBRACKETKEY", len-prev) || !strncmp(str+prev, "LEFTBRACKET", len-prev)) {
+ *key= LEFTBRACKETKEY;
+ } else if (!strncmp(str+prev, "RIGHTBRACKETKEY", len-prev) || !strncmp(str+prev, "RIGHTBRACKET", len-prev)) {
+ *key= RIGHTBRACKETKEY;
+ } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) {
+ *key= DELKEY;
+
+ } else if (!strncmp(str+prev, "LEFTARROWKEY", len-prev) || !strncmp(str+prev, "LEFTARROW", len-prev)) {
+ *key= LEFTARROWKEY;
+ } else if (!strncmp(str+prev, "DOWNARROWKEY", len-prev) || !strncmp(str+prev, "DOWNARROW", len-prev)) {
+ *key= DOWNARROWKEY;
+ } else if (!strncmp(str+prev, "RIGHTARROWKEY", len-prev) || !strncmp(str+prev, "RIGHTARROW", len-prev)) {
+ *key= RIGHTARROWKEY;
+ } else if (!strncmp(str+prev, "UPARROWKEY", len-prev) || !strncmp(str+prev, "UPARROW", len-prev)) {
+ *key= UPARROWKEY;
+
+ } else if (!strncmp(str+prev, "PAD", 3)) {
+
+ if (len-prev<=4) {
+
+ if (str[prev]>='0' && str[prev]<='9') {
+ *key= str[prev]-'0'+ZEROKEY;
+ } else {
+ invalid= 1;
+ }
+
+ } else if (!strncmp(str+prev+3, "PERIODKEY", len-prev-3) || !strncmp(str+prev+3, "PERIOD", len-prev-3)) {
+ *key= PADPERIOD;
+ } else if (!strncmp(str+prev+3, "SLASHKEY", len-prev-3) || !strncmp(str+prev+3, "SLASH", len-prev-3)) {
+ *key= PADSLASHKEY;
+ } else if (!strncmp(str+prev+3, "ASTERKEY", len-prev-3) || !strncmp(str+prev+3, "ASTERISK", len-prev-3)) {
+ *key= PADASTERKEY;
+ } else if (!strncmp(str+prev+3, "MINUSKEY", len-prev-3) || !strncmp(str+prev+3, "MINUS", len-prev-3)) {
+ *key= PADMINUS;
+ } else if (!strncmp(str+prev+3, "ENTERKEY", len-prev-3) || !strncmp(str+prev+3, "ENTER", len-prev-3)) {
+ *key= PADENTER;
+ } else if (!strncmp(str+prev+3, "PLUSKEY", len-prev-3) || !strncmp(str+prev+3, "PLUS", len-prev-3)) {
+ *key= PADPLUSKEY;
+ } else {
+ invalid= 1;
+ }
+
+ } else if (!strncmp(str+prev, "F1KEY", len-prev) || !strncmp(str+prev, "F1", len-prev)) {
+ *key= F1KEY;
+ } else if (!strncmp(str+prev, "F2KEY", len-prev) || !strncmp(str+prev, "F2", len-prev)) {
+ *key= F2KEY;
+ } else if (!strncmp(str+prev, "F3KEY", len-prev) || !strncmp(str+prev, "F3", len-prev)) {
+ *key= F3KEY;
+ } else if (!strncmp(str+prev, "F4KEY", len-prev) || !strncmp(str+prev, "F4", len-prev)) {
+ *key= F4KEY;
+ } else if (!strncmp(str+prev, "F5KEY", len-prev) || !strncmp(str+prev, "F5", len-prev)) {
+ *key= F5KEY;
+ } else if (!strncmp(str+prev, "F6KEY", len-prev) || !strncmp(str+prev, "F6", len-prev)) {
+ *key= F6KEY;
+ } else if (!strncmp(str+prev, "F7KEY", len-prev) || !strncmp(str+prev, "F7", len-prev)) {
+ *key= F7KEY;
+ } else if (!strncmp(str+prev, "F8KEY", len-prev) || !strncmp(str+prev, "F8", len-prev)) {
+ *key= F8KEY;
+ } else if (!strncmp(str+prev, "F9KEY", len-prev) || !strncmp(str+prev, "F9", len-prev)) {
+ *key= F9KEY;
+ } else if (!strncmp(str+prev, "F10KEY", len-prev) || !strncmp(str+prev, "F10", len-prev)) {
+ *key= F10KEY;
+ } else if (!strncmp(str+prev, "F11KEY", len-prev) || !strncmp(str+prev, "F11", len-prev)) {
+ *key= F11KEY;
+ } else if (!strncmp(str+prev, "F12KEY", len-prev) || !strncmp(str+prev, "F12", len-prev)) {
+ *key= F12KEY;
+
+ } else if (!strncmp(str+prev, "PAUSEKEY", len-prev) || !strncmp(str+prev, "PAUSE", len-prev)) {
+ *key= PAUSEKEY;
+ } else if (!strncmp(str+prev, "INSERTKEY", len-prev) || !strncmp(str+prev, "INSERT", len-prev)) {
+ *key= INSERTKEY;
+ } else if (!strncmp(str+prev, "HOMEKEY", len-prev) || !strncmp(str+prev, "HOME", len-prev)) {
+ *key= HOMEKEY;
+ } else if (!strncmp(str+prev, "PAGEUPKEY", len-prev) || !strncmp(str+prev, "PAGEUP", len-prev)) {
+ *key= PAGEUPKEY;
+ } else if (!strncmp(str+prev, "PAGEDOWNKEY", len-prev) || !strncmp(str+prev, "PAGEDOWN", len-prev)) {
+ *key= PAGEDOWNKEY;
+ } else if (!strncmp(str+prev, "ENDKEY", len-prev) || !strncmp(str+prev, "END", len-prev)) {
+ *key= ENDKEY;
+
+ } else {
+ invalid= 1;
+ }
+
+ if (!invalid && *key) {
+ return 1;
+ }
+
+ return 0;
+}