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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-01-29 02:29:27 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-01-29 02:29:27 +0300
commitb18defbffbf9171f26ab6ccabe5cb5609ad842a9 (patch)
tree2cb59d5c8a55174fc2a119dba0b5b626d8ea0c85 /source/blender
parent59147ad98391c0e15621c0c743b094bbf14bfe07 (diff)
2.5:
* Automatic shortcut keys in menus now compare operator properties as well. Implemented IDP_EqualsProperties for this. * I imagine all these compares may be a bit slow, for this case it's not so bad though because it only happens for one menu when it is opened.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/intern/idprop.c54
-rw-r--r--source/blender/editors/interface/interface.c27
-rw-r--r--source/blender/editors/interface/interface_intern.h4
-rw-r--r--source/blender/editors/interface/interface_regions.c3
-rw-r--r--source/blender/editors/space_image/image_header.c1
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c53
8 files changed, 115 insertions, 31 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 4f57e1d6d14..1980ba78c86 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -142,6 +142,8 @@ void IDP_FreeIterBeforeEnd(void *vself);
struct IDProperty *IDP_GetProperties(struct ID *id, int create_if_needed);
struct IDProperty *IDP_CopyProperty(struct IDProperty *prop);
+int IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2);
+
/*
Allocate a new ID.
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index c2474e847ae..3be47778674 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -527,6 +527,60 @@ IDProperty *IDP_GetProperties(ID *id, int create_if_needed)
}
}
+int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
+{
+ if(prop1 == NULL && prop2 == NULL)
+ return 1;
+ else if(prop1 == NULL || prop2 == NULL)
+ return 0;
+ else if(prop1->type != prop2->type)
+ return 0;
+
+ if(prop1->type == IDP_INT)
+ return (IDP_Int(prop1) == IDP_Int(prop2));
+ else if(prop1->type == IDP_FLOAT)
+ return (IDP_Float(prop1) == IDP_Float(prop2));
+ else if(prop1->type == IDP_DOUBLE)
+ return (IDP_Double(prop1) == IDP_Double(prop2));
+ else if(prop1->type == IDP_STRING)
+ return BSTR_EQ(IDP_String(prop1), IDP_String(prop2));
+ else if(prop1->type == IDP_ARRAY) {
+ if(prop1->len == prop2->len && prop1->subtype == prop2->subtype)
+ return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[prop1->subtype]*prop1->len);
+ else
+ return 0;
+ }
+ else if(prop1->type == IDP_GROUP) {
+ IDProperty *link1, *link2;
+
+ if(BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group))
+ return 0;
+
+ for(link1=prop1->data.group.first; link1; link1=link1->next) {
+ link2= IDP_GetPropertyFromGroup(prop2, link1->name);
+
+ if(!IDP_EqualsProperties(link1, link2))
+ return 0;
+ }
+
+ return 1;
+ }
+ else if(prop1->type == IDP_IDPARRAY) {
+ IDProperty *array1= IDP_IDPArray(prop1);
+ IDProperty *array2= IDP_IDPArray(prop2);
+ int i;
+
+ if(prop1->len != prop2->len)
+ return 0;
+
+ for(i=0; i<prop1->len; i++)
+ if(!IDP_EqualsProperties(&array1[i], &array2[i]))
+ return 0;
+ }
+
+ return 1;
+}
+
IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name)
{
IDProperty *prop=NULL;
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index d2c1e6859cb..5b8dda2f3b4 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -207,11 +207,17 @@ void ui_window_to_region(const ARegion *ar, int *x, int *y)
/* ******************* block calc ************************* */
-/* only for pulldowns */
void uiTextBoundsBlock(uiBlock *block, int addval)
{
+ block->textbounds= addval;
+ block->dotextbounds= 1;
+}
+
+/* only for pulldowns */
+static void ui_text_bounds_block(uiBlock *block)
+{
uiBut *bt;
- int i = 0, j, x1addval= 0, nextcol;
+ int i = 0, j, x1addval= 0, nextcol, addval= block->textbounds;
bt= block->buttons.first;
while(bt) {
@@ -482,13 +488,15 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
{
uiBut *but;
+ IDProperty *prop;
char buf[512], *butstr;
+ int bounds= 0;;
- /* XXX bounds? */
for(but=block->buttons.first; but; but=but->next) {
- /* only hotkey for menus without properties */
- if(but->opname && but->opptr==NULL) {
- if(WM_key_event_operator_string(C, but->opname, but->opcontext, buf, sizeof(buf))) {
+ if(but->opname) {
+ prop= (but->opptr)? but->opptr->data: NULL;
+
+ if(WM_key_event_operator_string(C, but->opname, but->opcontext, prop, buf, sizeof(buf))) {
butstr= MEM_mallocN(strlen(but->str)+strlen(buf)+2, "menu_block_set_keymaps");
strcpy(butstr, but->str);
strcat(butstr, "|");
@@ -499,6 +507,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
MEM_freeN(butstr);
ui_check_but(but);
+ bounds= 1;
}
}
}
@@ -526,9 +535,12 @@ void uiEndBlock(const bContext *C, uiBlock *block)
/* handle pending stuff */
if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block);
+ if(block->dotextbounds) ui_text_bounds_block(block); /* after keymaps! */
if(block->autofill) ui_autofill(block);
if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0);
if(block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block);
+
+ block->endblock= 1;
}
/* ************** BLOCK DRAWING FUNCTION ************* */
@@ -537,6 +549,9 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
{
uiBut *but;
+ if(!block->endblock)
+ uiEndBlock(C, block);
+
/* we set this only once */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f4e37867fc3..43b7e280170 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -214,7 +214,9 @@ struct uiBlock {
int lock;
char *lockstr;
- float xofs, yofs; // offset to parent button
+ float xofs, yofs; // offset to parent button
+ int textbounds, dotextbounds; // for doing delayed
+ int endblock; // uiEndBlock done?
rctf safety; // pulldowns, to detect outside, can differ per case how it is created
ListBase saferct; // uiSafetyRct list
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index d29cf6103fe..90385ab2897 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -651,6 +651,9 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *
block= block_func(C, handle, arg);
block->handle= handle;
+ if(!block->endblock)
+ uiEndBlock(C, block);
+
/* if this is being created from a button */
if(but) {
if(ELEM(but->type, BLOCK, PULLDOWN))
diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c
index f9601e175ce..e015d5aeedf 100644
--- a/source/blender/editors/space_image/image_header.c
+++ b/source/blender/editors/space_image/image_header.c
@@ -112,6 +112,7 @@ static uiBlock *image_view_viewnavmenu(bContext *C, uiMenuBlockHandle *handle, v
/* position menu */
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
+ uiEndBlock(C, block);
return block;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 8eb12543b86..cb6d26a1506 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -81,7 +81,7 @@ ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid,
int spaceid, int regionid);
char *WM_key_event_string(short type);
-char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, char *str, int len);
+char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
/* handlers */
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 864146a8576..46a5c45a30d 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -37,6 +37,7 @@
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
@@ -507,13 +508,35 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len)
return str;
}
-char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, char *str, int len)
+static char *wm_keymap_item_find(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, char *str, int len)
{
wmEventHandler *handler;
wmKeymapItem *kmi;
- ListBase *handlers= NULL;
- /* find right handler list based on specified context */
+ /* find keymap item in handlers */
+ for(handler=handlers->first; handler; handler=handler->next)
+ if(handler->keymap)
+ for(kmi=handler->keymap->first; kmi; kmi=kmi->next)
+ if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0])
+ if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data))
+ return wm_keymap_item_to_string(kmi, str, len);
+
+ return NULL;
+}
+
+char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, char *str, int len)
+{
+ char *found= NULL;
+
+ /* look into multiple handler lists to find the item */
+ if(CTX_wm_window(C))
+ if((found= wm_keymap_item_find(&CTX_wm_window(C)->handlers, opname, opcontext, properties, str, len)))
+ return found;
+
+ if(CTX_wm_area(C))
+ if((found= wm_keymap_item_find(&CTX_wm_area(C)->handlers, opname, opcontext, properties, str, len)))
+ return found;
+
if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) {
if(CTX_wm_area(C)) {
ARegion *ar= CTX_wm_area(C)->regionbase.first;
@@ -522,32 +545,16 @@ char *WM_key_event_operator_string(const bContext *C, const char *opname, int op
break;
if(ar)
- handlers= &ar->handlers;
+ if((found= wm_keymap_item_find(&ar->handlers, opname, opcontext, properties, str, len)))
+ return found;
}
}
- else if(ELEM(opcontext, WM_OP_EXEC_AREA, WM_OP_INVOKE_AREA)) {
- if(CTX_wm_area(C))
- handlers= &CTX_wm_area(C)->handlers;
- }
- else if(ELEM(opcontext, WM_OP_EXEC_SCREEN, WM_OP_INVOKE_SCREEN)) {
- if(CTX_wm_window(C))
- handlers= &CTX_wm_window(C)->handlers;
- }
else {
if(CTX_wm_region(C))
- handlers= &CTX_wm_region(C)->handlers;
+ if((found= wm_keymap_item_find(&CTX_wm_region(C)->handlers, opname, opcontext, properties, str, len)))
+ return found;
}
- if(!handlers)
- return NULL;
-
- /* find keymap item in handlers */
- for(handler=handlers->first; handler; handler=handler->next)
- if(handler->keymap)
- for(kmi=handler->keymap->first; kmi; kmi=kmi->next)
- if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0])
- return wm_keymap_item_to_string(kmi, str, len);
-
return NULL;
}