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:
authorTon Roosendaal <ton@blender.org>2009-07-26 16:52:39 +0400
committerTon Roosendaal <ton@blender.org>2009-07-26 16:52:39 +0400
commit9ac754eca5466d62abed6d207d1efdbbb7d77b18 (patch)
tree3b0d63d120c6b24de6f5c161774cc9a3d874ab08 /source/blender/editors
parent7084447c73bd5b2b5fb9aa12a4e3b2e983723c2f (diff)
2.5
First step towards keymap editor! Before getting too excited: - doesn't save yet - no rna properties can be defined - no insert/remove keymap options yet - no option yet to set 'key press/release' But what does work; - Keymap list is in outliner, new category (Keymaps are listed in order as being created now) - enable/disable a keymap entry: click on dot icon - it displays python api names for ops - browse new operator for keymap (menu button) - set keymap to use other keys, mouse or tweak events - four modifier key options I first intent to test it all well, there are still quite some modal map conflicts (like border select) and there's problems assigning items to tweaks Another issue is that a visual editor for keymaps might be quite hard to use... the amount of data and options is just not so fun for a buttons menu. There are ways to improve this though. Maybe do this via a script?
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_markers.c2
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c7
-rw-r--r--source/blender/editors/interface/view2d_ops.c6
-rw-r--r--source/blender/editors/space_outliner/outliner.c309
-rw-r--r--source/blender/editors/space_outliner/outliner_header.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
7 files changed, 322 insertions, 10 deletions
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 7de3acdacef..d33eece52c9 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -85,6 +85,7 @@ static ListBase *context_get_markers(const bContext *C)
}
/* Get the marker that is closest to this point */
+/* XXX for select, the min_dist should be small */
TimeMarker *ED_markers_find_nearest_marker (ListBase *markers, float x)
{
TimeMarker *marker, *nearest=NULL;
@@ -828,6 +829,7 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
/* XXX marker context */
for(marker= markers->first; marker; marker= marker->next) {
if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
+ /* XXX weak... */
switch (event_type) {
case LEFTMOUSE:
if ((marker->flag & SELECT) == 0)
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 18634e21a36..ca3be250a92 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -740,7 +740,7 @@ static void ui_is_but_sel(uiBut *but)
push= 2;
break;
case KEYEVT:
- if (value==-1) push= 1;
+ push= 2;
break;
case TOGBUT:
case TOG:
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 1736cd1ef52..0987f0d2f2a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1805,7 +1805,10 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+ short event= (short)ui_get_but_val(but);
+ /* hardcoded prevention from editing or assigning ESC */
+ if(event!=ESCKEY)
+ button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
return WM_UI_HANDLER_BREAK;
}
}
@@ -1814,7 +1817,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
return WM_UI_HANDLER_CONTINUE;
if(event->val==KM_PRESS) {
- if(WM_key_event_string(event->type)[0])
+ if(event->type!=ESCKEY && WM_key_event_string(event->type)[0])
ui_set_but_val(but, event->type);
else
data->cancel= 1;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 44b7f1d13da..ee2a50d12a9 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -151,6 +151,12 @@ static void view_pan_apply(bContext *C, wmOperator *op)
/* request updates to be done... */
ED_area_tag_redraw(vpd->sa);
UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
+
+ /* exceptions */
+ if(vpd->sa->spacetype==SPACE_OUTLINER) {
+ SpaceOops *soops= vpd->sa->spacedata.first;
+ soops->storeflag |= SO_TREESTORE_REDRAW;
+ }
}
/* cleanup temp customdata */
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 0df0cb46473..b1919391c8d 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -1123,6 +1123,45 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
}
}
+ else if(type == TSE_KEYMAP) {
+ wmKeyMap *km= (wmKeyMap *)idv;
+ wmKeymapItem *kmi;
+ char opname[OP_MAX_TYPENAME];
+
+ te->directdata= idv;
+ te->name= km->nameid;
+
+ if(!(tselem->flag & TSE_CLOSED)) {
+
+ for (kmi= km->keymap.first; kmi; kmi= kmi->next) {
+ const char *key= WM_key_event_string(kmi->type);
+
+ if(key[0]) {
+ wmOperatorType *ot= NULL;
+
+ if(kmi->propvalue);
+ else ot= WM_operatortype_find(kmi->idname, 0);
+
+ if(ot || kmi->propvalue) {
+ TreeElement *ten= outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
+
+ ten->directdata= kmi;
+
+ if(kmi->propvalue) {
+ ten->name= "Modal map, not yet";
+ }
+ else {
+ WM_operator_py_idname(opname, ot->idname);
+ ten->name= BLI_strdup(opname);
+ ten->flag |= TE_FREE_NAME;
+ }
+ }
+ }
+ }
+ }
+ else
+ te->flag |= TE_LAZY_CLOSED;
+ }
return te;
}
@@ -1376,6 +1415,14 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
tselem->flag &= ~TSE_CLOSED;
}
}
+ else if(soops->outlinevis==SO_KEYMAP) {
+ wmWindowManager *wm= mainvar->wm.first;
+ wmKeyMap *km;
+
+ for(km= wm->keymaps.first; km; km= km->next) {
+ ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0);
+ }
+ }
else {
ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
if(ten) ten->directdata= BASACT;
@@ -2193,6 +2240,21 @@ static int tree_element_active_sequence_dup(bContext *C, Scene *scene, TreeEleme
return(0);
}
+static int tree_element_active_keymap_item(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set)
+{
+ wmKeymapItem *kmi= te->directdata;
+
+ if(set==0) {
+ if(kmi->inactive) return 0;
+ return 1;
+ }
+ else {
+ kmi->inactive= !kmi->inactive;
+ }
+ return 0;
+}
+
+
/* generic call for non-id data to make/check active in UI */
/* Context can be NULL when set==0 */
static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set)
@@ -2213,10 +2275,8 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
break;
case TSE_LINKED_PSYS:
return tree_element_active_psys(C, scene, te, tselem, set);
- break;
case TSE_POSE_BASE:
return tree_element_active_pose(C, scene, te, tselem, set);
- break;
case TSE_POSE_CHANNEL:
return tree_element_active_posechannel(C, scene, te, tselem, set);
case TSE_CONSTRAINT:
@@ -2227,10 +2287,11 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
return tree_element_active_posegroup(C, scene, te, tselem, set);
case TSE_SEQUENCE:
return tree_element_active_sequence(C, te, tselem, set);
- break;
case TSE_SEQUENCE_DUP:
return tree_element_active_sequence_dup(C, scene, te, tselem, set);
- break;
+ case TSE_KEYMAP_ITEM:
+ return tree_element_active_keymap_item(C, te, tselem, set);
+
}
return 0;
}
@@ -4953,6 +5014,241 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
}
}
+static void operator_call_cb(struct bContext *C, void *arg_kmi, void *arg2)
+{
+ wmOperatorType *ot= arg2;
+ wmKeymapItem *kmi= arg_kmi;
+
+ if(ot)
+ BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg_kmi, char *str, uiSearchItems *items)
+{
+ wmOperatorType *ot = WM_operatortype_first();
+
+ for(; ot; ot= ot->next) {
+
+ if(BLI_strcasestr(ot->idname, str)) {
+ char name[OP_MAX_TYPENAME];
+
+ /* display name for menu */
+ WM_operator_py_idname(name, ot->idname);
+
+ if(0==uiSearchItemAdd(items, name, ot, 0))
+ break;
+ }
+ }
+}
+
+/* operator Search browse menu, open */
+static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
+{
+ static char search[OP_MAX_TYPENAME];
+ wmEvent event;
+ wmWindow *win= CTX_wm_window(C);
+ wmKeymapItem *kmi= arg_kmi;
+ wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0);
+ uiBlock *block;
+ uiBut *but;
+
+ /* clear initial search string, then all items show */
+ search[0]= 0;
+
+ block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+ uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
+
+ uiBoundsBlock(block, 6);
+ uiBlockSetDirection(block, UI_DOWN);
+ uiEndBlock(C, block);
+
+ event= *(win->eventstate); /* XXX huh huh? make api call */
+ event.type= EVT_BUT_OPEN;
+ event.val= KM_PRESS;
+ event.customdata= but;
+ event.customdatafree= FALSE;
+ wm_event_add(win, &event);
+
+ return block;
+}
+
+#define OL_KM_KEYBOARD 0
+#define OL_KM_MOUSE 1
+#define OL_KM_TWEAK 2
+#define OL_KM_SPECIALS 3
+
+static short keymap_menu_type(short type)
+{
+ if(ISKEYBOARD(type)) return OL_KM_KEYBOARD;
+ if(WM_key_event_is_tweak(type)) return OL_KM_TWEAK;
+ if(type >= LEFTMOUSE && type <= WHEELOUTMOUSE) return OL_KM_MOUSE;
+// return OL_KM_SPECIALS;
+ return 0;
+}
+
+static char *keymap_type_menu(void)
+{
+ static char string[500];
+ static char formatstr[] = "|%s %%x%d";
+ char *str= string;
+
+ str += sprintf(str, "Event Type %%t");
+
+ str += sprintf(str, formatstr, "Keyboard", OL_KM_KEYBOARD);
+ str += sprintf(str, formatstr, "Mouse", OL_KM_MOUSE);
+ str += sprintf(str, formatstr, "Tweak", OL_KM_TWEAK);
+// str += sprintf(str, formatstr, "Specials", OL_KM_SPECIALS);
+
+ return string;
+}
+
+static char *keymap_mouse_menu(void)
+{
+ static char string[500];
+ static char formatstr[] = "|%s %%x%d";
+ char *str= string;
+
+ str += sprintf(str, "Mouse Event %%t");
+
+ str += sprintf(str, formatstr, "Left Mouse", LEFTMOUSE);
+ str += sprintf(str, formatstr, "Middle Mouse", MIDDLEMOUSE);
+ str += sprintf(str, formatstr, "Right Mouse", RIGHTMOUSE);
+ str += sprintf(str, formatstr, "Action Mouse", ACTIONMOUSE);
+ str += sprintf(str, formatstr, "Select Mouse", SELECTMOUSE);
+ str += sprintf(str, formatstr, "Mouse Move", MOUSEMOVE);
+ str += sprintf(str, formatstr, "Wheel Up", WHEELUPMOUSE);
+ str += sprintf(str, formatstr, "Wheel Down", WHEELDOWNMOUSE);
+ str += sprintf(str, formatstr, "Wheel In", WHEELINMOUSE);
+ str += sprintf(str, formatstr, "Wheel Out", WHEELOUTMOUSE);
+
+ return string;
+}
+
+static char *keymap_tweak_menu(void)
+{
+ static char string[500];
+ static char formatstr[] = "|%s %%x%d";
+ char *str= string;
+
+ str += sprintf(str, "Tweak Event %%t");
+
+ str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L);
+ str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M);
+ str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R);
+ str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A);
+ str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S);
+
+ return string;
+}
+
+static void keymap_type_cb(bContext *C, void *kmi_v, void *unused_v)
+{
+ wmKeymapItem *kmi= kmi_v;
+ short maptype= keymap_menu_type(kmi->type);
+
+ if(maptype!=kmi->maptype) {
+ switch(kmi->maptype) {
+ case OL_KM_KEYBOARD:
+ kmi->type= AKEY;
+ kmi->val= KM_PRESS;
+ break;
+ case OL_KM_MOUSE:
+ kmi->type= LEFTMOUSE;
+ kmi->val= KM_PRESS;
+ break;
+ case OL_KM_TWEAK:
+ kmi->type= EVT_TWEAK_L;
+ kmi->val= KM_ANY;
+ break;
+ case OL_KM_SPECIALS:
+ kmi->type= AKEY;
+ kmi->val= KM_PRESS;
+ }
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
+}
+
+static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ uiBlockSetEmboss(block, UI_EMBOSST);
+
+ for(te= lb->first; te; te= te->next) {
+ tselem= TREESTORE(te);
+ if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ uiBut *but;
+ char *str;
+ int xstart= 240;
+ int butw1= 20; /* operator */
+ int butw2= 90; /* event type, menus */
+ int butw3= 43; /* modifiers */
+
+ if(tselem->type == TSE_KEYMAP_ITEM) {
+ wmKeymapItem *kmi= te->directdata;
+
+ /* modal map? */
+ if(kmi->propvalue);
+ else {
+ uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator");
+ }
+ xstart+= butw1+10;
+
+ /* map type button */
+ kmi->maptype= keymap_menu_type(kmi->type);
+
+ str= keymap_type_menu();
+ but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+ uiButSetFunc(but, keymap_type_cb, kmi, NULL);
+ xstart+= butw2+5;
+
+ /* edit actual event */
+ switch(kmi->maptype) {
+ case OL_KM_KEYBOARD:
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code");
+ xstart+= butw2+5;
+ break;
+ case OL_KM_MOUSE:
+ str= keymap_mouse_menu();
+ uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Mouse button");
+ xstart+= butw2+5;
+ break;
+ case OL_KM_TWEAK:
+ str= keymap_tweak_menu();
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture");
+ xstart+= butw2+5;
+ break;
+ }
+
+ /* modifiers */
+ uiBlockBeginAlign(block);
+ uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
+ uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ uiDefButS(block, OPTION, 0, "Cmd", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ xstart+= 5;
+ uiBlockEndAlign(block);
+
+ /* rna property */
+ if(kmi->ptr && kmi->ptr->data)
+ uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
+
+
+ }
+ }
+
+ if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
+ }
+}
+
+
static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
{
uiBut *bt;
@@ -5007,7 +5303,7 @@ void draw_outliner(const bContext *C)
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
- if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
+ if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) {
/* RNA has two columns:
* - column 1 is (max_width + OL_RNA_COL_SPACEX) or
* (OL_RNA_COL_X), whichever is wider...
@@ -5053,6 +5349,9 @@ void draw_outliner(const bContext *C)
outliner_draw_rnacols(ar, soops, sizex_rna);
outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree);
}
+ else if(soops->outlinevis == SO_KEYMAP) {
+ outliner_draw_keymapbuts(block, ar, soops, &soops->tree);
+ }
else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
/* draw restriction columns */
outliner_draw_restrictcols(ar, soops);
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index fe2f054899c..0743a447298 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -233,9 +233,9 @@ void outliner_header_buttons(const bContext *C, ARegion *ar)
/* data selector*/
if(G.main->library.first)
- uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12||Key Maps %x13", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
else
- uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12||Key Maps %x13", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
xco += 120;
/* KeyingSet editing buttons */
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index d5986f3ebbd..65b0708d64b 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -95,6 +95,8 @@ typedef struct TreeElement {
#define TSE_RNA_PROPERTY 31
#define TSE_RNA_ARRAY_ELEM 32
#define TSE_NLA_TRACK 33
+#define TSE_KEYMAP 34
+#define TSE_KEYMAP_ITEM 35
/* outliner search flags */
#define OL_FIND 0