[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33648] trunk/blender/source/blender/ editors: Menu UI feature common in other widget sets:
Campbell Barton
ideasman42 at gmail.com
Tue Dec 14 03:38:39 CET 2010
Revision: 33648
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33648
Author: campbellbarton
Date: 2010-12-14 03:38:29 +0100 (Tue, 14 Dec 2010)
Log Message:
-----------
Menu UI feature common in other widget sets:
Automatically assign menu keys based on name, alternative to pressing number 0-9 on menus items.
keys are assigned by first giving each menu item the first character of any word, if that fails any key in the name is used.
- active key is shown underlined.
- only ascii keys are assigned currently.
- can run operators, open menu items.
- currently this only works in cases where number buttons were used (UI_BLOCK_NUMSELECT), but could be enabled for file menu, splash etc by removing this check.
Modified Paths:
--------------
trunk/blender/source/blender/editors/include/UI_interface.h
trunk/blender/source/blender/editors/interface/interface.c
trunk/blender/source/blender/editors/interface/interface_handlers.c
trunk/blender/source/blender/editors/interface/interface_intern.h
trunk/blender/source/blender/editors/interface/interface_style.c
trunk/blender/source/blender/editors/interface/interface_widgets.c
Modified: trunk/blender/source/blender/editors/include/UI_interface.h
===================================================================
--- trunk/blender/source/blender/editors/include/UI_interface.h 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/include/UI_interface.h 2010-12-14 02:38:29 UTC (rev 33648)
@@ -749,6 +749,8 @@
/* Styled text draw */
void uiStyleFontSet(struct uiFontStyle *fs);
+void uiStyleFontDrawExt(struct uiFontStyle *fs, struct rcti *rect, const char *str,
+ float *r_xofs, float *r_yofs);
void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str);
void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str);
Modified: trunk/blender/source/blender/editors/interface/interface.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface.c 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/interface/interface.c 2010-12-14 02:38:29 UTC (rev 33648)
@@ -29,6 +29,7 @@
#include <limits.h>
#include <math.h>
#include <string.h>
+#include <ctype.h>
#include "MEM_guardedalloc.h"
@@ -585,6 +586,77 @@
return 1;
}
+/* assigns automatic keybindings to menu items for fast access
+ * (underline key in menu) */
+static void ui_menu_block_set_keyaccels(uiBlock *block)
+{
+ uiBut *but;
+
+ unsigned int meny_key_mask= 0;
+ unsigned char menu_key;
+ const char *str_pt;
+ int pass;
+ int tot_missing= 0;
+
+ /* only do it before bounding */
+ if(block->minx != block->maxx)
+ return;
+
+ for(pass=0; pass<2; pass++) {
+ /* 2 Passes, on for first letter only, second for any letter if first fails
+ * fun first pass on all buttons so first word chars always get first priority */
+
+ for(but=block->buttons.first; but; but=but->next) {
+ if(!ELEM4(but->type, BUT, MENU, BLOCK, PULLDOWN) || (but->flag & UI_HIDDEN)) {
+ /* pass */
+ }
+ else if(but->menu_key=='\0') {
+ if(but->str) {
+ for(str_pt= but->str; *str_pt; ) {
+ menu_key= tolower(*str_pt);
+ if((menu_key >= 'a' && menu_key <= 'z') && !(meny_key_mask & 1<<(menu_key-'a'))) {
+ meny_key_mask |= 1<<(menu_key-'a');
+ break;
+ }
+
+ if(pass==0) {
+ /* Skip to next delimeter on first pass (be picky) */
+ while(isalpha(*str_pt))
+ str_pt++;
+
+ if(*str_pt)
+ str_pt++;
+ }
+ else {
+ /* just step over every char second pass and find first usable key */
+ str_pt++;
+ }
+ }
+
+ if(*str_pt) {
+ but->menu_key= menu_key;
+ }
+ else {
+ /* run second pass */
+ tot_missing++;
+ }
+
+ /* if all keys have been used just exit, unlikely */
+ if(meny_key_mask == (1<<26)-1) {
+ return;
+ }
+ }
+ }
+ }
+
+ /* check if second pass is needed */
+ if(!tot_missing) {
+ break;
+ }
+ }
+}
+
+
void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
{
uiBut *but;
@@ -658,6 +730,7 @@
/* handle pending stuff */
if(block->layouts.first) uiBlockLayoutResolve(block, NULL, NULL);
ui_block_do_align(block);
+ if((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block);
/* after keymaps! */
Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c 2010-12-14 02:38:29 UTC (rev 33648)
@@ -5635,8 +5635,65 @@
retval= WM_UI_HANDLER_BREAK;
}
+ break;
+ /* Handle keystrokes on menu items */
+ case AKEY:
+ case BKEY:
+ case CKEY:
+ case DKEY:
+ case EKEY:
+ case FKEY:
+ case GKEY:
+ case HKEY:
+ case IKEY:
+ case JKEY:
+ case KKEY:
+ case LKEY:
+ case MKEY:
+ case NKEY:
+ case OKEY:
+ case PKEY:
+ case QKEY:
+ case RKEY:
+ case SKEY:
+ case TKEY:
+ case UKEY:
+ case VKEY:
+ case WKEY:
+ case XKEY:
+ case YKEY:
+ case ZKEY:
+ {
+ if(event->val == KM_PRESS) {
+ count= 0;
+ for(but= block->buttons.first; but; but= but->next) {
+
+ if(but->menu_key==event->type) {
+ if(but->type == BUT) {
+ /* mainly for operator buttons */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY);
+ }
+ else if(ELEM(but->type, BLOCK, PULLDOWN)) {
+ /* open submenus (like right arrow key) */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
+ }
+ else if (but->type == MENU) {
+ /* activate menu items */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
+ }
+ else {
+ printf("Error, but->menu_key type: %d\n", but->type);
+ }
+
+ break;
+ }
+ }
+
+ retval= WM_UI_HANDLER_BREAK;
+ }
break;
+ }
}
}
Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h 2010-12-14 02:38:29 UTC (rev 33648)
@@ -237,9 +237,10 @@
struct IDProperty *opproperties;
struct PointerRNA *opptr;
short opcontext;
-
+ unsigned char menu_key; /* 'a'-'z', always lower case */
+
/* Draggable data, type is WM_DRAG_... */
- short dragtype;
+ char dragtype;
void *dragpoin;
struct ImBuf *imb;
float imb_scale;
Modified: trunk/blender/source/blender/editors/interface/interface_style.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_style.c 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/interface/interface_style.c 2010-12-14 02:38:29 UTC (rev 33648)
@@ -136,7 +136,9 @@
/* *************** draw ************************ */
-void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, const char *str)
+
+void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
+ float *r_xofs, float *r_yofs)
{
float height;
int xofs=0, yofs;
@@ -171,8 +173,18 @@
BLF_disable(fs->uifont_id, BLF_SHADOW);
if (fs->kerning == 1)
BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+
+ *r_xofs= xofs;
+ *r_yofs= yofs;
}
+void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, const char *str)
+{
+ float xofs, yofs;
+ uiStyleFontDrawExt(fs, rect, str,
+ &xofs, &yofs);
+}
+
/* drawn same as above, but at 90 degree angle */
void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str)
{
Modified: trunk/blender/source/blender/editors/interface/interface_widgets.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_widgets.c 2010-12-14 01:19:51 UTC (rev 33647)
+++ trunk/blender/source/blender/editors/interface/interface_widgets.c 2010-12-14 02:38:29 UTC (rev 33648)
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_rect.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -961,6 +962,9 @@
// int transopts;
char *cpoin = NULL;
+ /* for underline drawing */
+ float font_xofs, font_yofs;
+
uiStyleFontSet(fstyle);
if(but->editstr || (but->flag & UI_TEXT_LEFT))
@@ -1038,8 +1042,41 @@
}
glColor3ubv((unsigned char*)wcol->text);
- uiStyleFontDraw(fstyle, rect, but->drawstr+but->ofs);
+ uiStyleFontDrawExt(fstyle, rect, but->drawstr+but->ofs, &font_xofs, &font_yofs);
+
+ if(but->menu_key != '\0') {
+ char fixedbuf[128];
+ char *str;
+
+ BLI_strncpy(fixedbuf, but->drawstr + but->ofs, sizeof(fixedbuf));
+
+ str= strchr(fixedbuf, but->menu_key-32); /* upper case */
+ if(str==NULL)
+ str= strchr(fixedbuf, but->menu_key);
+
+ if(str) {
+ int ul_index= -1;
+ float ul_advance;
+
+ ul_index= (int)(str - fixedbuf);
+
+ if (fstyle->kerning == 1) {
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ fixedbuf[ul_index]= '\0';
+ ul_advance= BLF_width(fstyle->uifont_id, fixedbuf);
+
+ BLF_position(fstyle->uifont_id, rect->xmin+font_xofs + ul_advance, rect->ymin+font_yofs, 0.0f);
+ BLF_draw(fstyle->uifont_id, "_", 2);
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+ }
+ }
+
/* part text right aligned */
if(cpoin) {
fstyle->align= UI_STYLE_TEXT_RIGHT;
More information about the Bf-blender-cvs
mailing list