[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21757] branches/blender2.5/blender/source /blender: 2.5

Ton Roosendaal ton at blender.org
Tue Jul 21 13:03:07 CEST 2009


Revision: 21757
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21757
Author:   ton
Date:     2009-07-21 13:03:07 +0200 (Tue, 21 Jul 2009)

Log Message:
-----------
2.5

Modal keymaps.

I've tried to make it as simple as possible, yet still using sufficient facilities to enable self-documenting UIs, saving/reading in files, and proper Python support.

The simplicity is: the 'modal keymap' just checks an event, uses event matching similarly to other keymap matching, and if there's a match it changes the event type, and sets the event value to what the modal keymap has defined. The event values are being defined using EnumPropertyItem structs, so the UI will be able to show all options in self-documenting way.
This system also allows to still handle hardcoded own events.

Tech doc:

1) define keymap
- Create map with unique name, WM_modalkeymap_add()
- Give map property definitions (EnumPropertyItem *)
  This only for UI, so user can get information on available options

2) items
- WM_modalkeymap_add_item(): give it an enum value for events

3) activate
- In keymap definition code, assign the modal keymap to operatortype
  WM_modalkeymap_assign()

4) event manager
- The event handler will check for modal keymap, if so:
  - If the modal map has a match:
    - Sets event->type to EVT_MODAL_MAP
    - Sets event->val to the enum value

5) modal handler
- If event type is EVT_MODAL_MAP:
  - Check event->val, handle it
- Other events can just be handled still

Two examples added in the code:

editors/transform/transform.c: transform_modal_keymap()
editors/screen/screen_ops.c: keymap_modal_set()

Also: to support 'key release' the define KM_RELEASE now is officially
used in event manager, this is not '0', so don't check key events with
the old convention if(event->val) but use if(event->val==KM_PRESS)

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c
    branches/blender2.5/blender/source/blender/editors/transform/transform.c
    branches/blender2.5/blender/source/blender/editors/transform/transform.h
    branches/blender2.5/blender/source/blender/editors/transform/transform_ops.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h
    branches/blender2.5/blender/source/blender/windowmanager/WM_api.h
    branches/blender2.5/blender/source/blender/windowmanager/intern/wm_event_system.c
    branches/blender2.5/blender/source/blender/windowmanager/intern/wm_keymap.c
    branches/blender2.5/blender/source/blender/windowmanager/wm_event_types.h

Modified: branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c	2009-07-21 10:40:13 UTC (rev 21756)
+++ branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c	2009-07-21 11:03:07 UTC (rev 21757)
@@ -76,6 +76,11 @@
 
 #include "screen_intern.h"	/* own module include */
 
+#define KM_MODAL_CANCEL		1
+#define KM_MODAL_APPLY		2
+#define KM_MODAL_STEP10		3
+#define KM_MODAL_STEP10_OFF	4
+
 /* ************** Exported Poll tests ********************** */
 
 int ED_operator_regionactive(bContext *C)
@@ -719,7 +724,7 @@
 */
 
 typedef struct sAreaMoveData {
-	int bigger, smaller, origval;
+	int bigger, smaller, origval, step;
 	char dir;
 } sAreaMoveData;
 
@@ -876,32 +881,40 @@
 /* modal callback for while moving edges */
 static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
-	sAreaMoveData *md;
+	sAreaMoveData *md= op->customdata;
 	int delta, x, y;
 
-	md= op->customdata;
-
-	x= RNA_int_get(op->ptr, "x");
-	y= RNA_int_get(op->ptr, "y");
-
 	/* execute the events */
 	switch(event->type) {
 		case MOUSEMOVE:
+			
+			x= RNA_int_get(op->ptr, "x");
+			y= RNA_int_get(op->ptr, "y");
+			
 			delta= (md->dir == 'v')? event->x - x: event->y - y;
+			if(md->step) delta= delta - (delta % md->step);
 			RNA_int_set(op->ptr, "delta", delta);
 
 			area_move_apply(C, op);
 			break;
 			
-		case LEFTMOUSE:
-			if(event->val==0) {
-				area_move_exit(C, op);
-				return OPERATOR_FINISHED;
+		case EVT_MODAL_MAP:
+			
+			switch (event->val) {
+				case KM_MODAL_APPLY:
+					area_move_exit(C, op);
+					return OPERATOR_FINISHED;
+
+				case KM_MODAL_CANCEL:
+					return area_move_cancel(C, op);
+					
+				case KM_MODAL_STEP10:
+					md->step= 10;
+					break;
+				case KM_MODAL_STEP10_OFF:
+					md->step= 0;
+					break;
 			}
-			break;
-			
-		case ESCKEY:
-			return area_move_cancel(C, op);
 	}
 	
 	return OPERATOR_RUNNING_MODAL;
@@ -2877,6 +2890,31 @@
 	
 }
 
+static void keymap_modal_set(wmWindowManager *wm)
+{
+	static EnumPropertyItem modal_items[] = {
+		{KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+		{KM_MODAL_APPLY, "APPLY", 0, "Apply", ""},
+		{KM_MODAL_STEP10, "STEP10", 0, "Steps on", ""},
+		{KM_MODAL_STEP10_OFF, "STEP10_OFF", 0, "Steps off", ""},
+		{0, NULL, 0, NULL, NULL}};
+	wmKeyMap *keymap;
+	
+	/* Standard Modal keymap ------------------------------------------------ */
+	keymap= WM_modalkeymap_add(wm, "Standard Modal Map", modal_items);
+	
+	WM_modalkeymap_add_item(keymap, ESCKEY,    KM_PRESS, KM_ANY, 0, KM_MODAL_CANCEL);
+	WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KM_MODAL_APPLY);
+	WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
+	WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
+
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_STEP10);
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_STEP10_OFF);
+	
+	WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
+
+}
+
 /* called in spacetypes.c */
 void ED_keymap_screen(wmWindowManager *wm)
 {
@@ -2948,5 +2986,7 @@
 	/* play (forward and backwards) */
 	WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0);
 	RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", 1);
+
+	keymap_modal_set(wm);
 }
 

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform.c	2009-07-21 10:40:13 UTC (rev 21756)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform.c	2009-07-21 11:03:07 UTC (rev 21757)
@@ -496,6 +496,63 @@
 
 /* ************************************************* */
 
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define TFM_MODAL_CANCEL			1
+#define TFM_MODAL_CONFIRM			2
+#define TFM_MODAL_TRANSLATE			3
+#define TFM_MODAL_ROTATE			4
+#define TFM_MODAL_RESIZE			5
+#define TFM_MODAL_SNAP_GEARS		6
+#define TFM_MODAL_SNAP_GEARS_OFF	7
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void transform_modal_keymap(wmWindowManager *wm)
+{
+	static EnumPropertyItem modal_items[] = {
+	{TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+	{TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+	{TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
+	{TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
+	{TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
+	{TFM_MODAL_SNAP_GEARS, "SNAP_GEARS", 0, "Snap On", ""},
+	{TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""},
+	{0, NULL, 0, NULL, NULL}};
+	
+	wmKeyMap *keymap= WM_modalkeymap_get(wm, "Transform Modal Map");
+	
+	/* this function is called for each spacetype, only needs to add map once */
+	if(keymap) return;
+	
+	keymap= WM_modalkeymap_add(wm, "Transform Modal Map", modal_items);
+	
+	/* items for modal map */
+	WM_modalkeymap_add_item(keymap, ESCKEY,    KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL);
+	WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, TFM_MODAL_CONFIRM);
+	WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+	WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+
+	WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, TFM_MODAL_TRANSLATE);
+	WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, TFM_MODAL_ROTATE);
+	WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, TFM_MODAL_RESIZE);
+	
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_GEARS);
+	WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_GEARS_OFF);
+	
+	/* assign map to operators */
+	WM_modalkeymap_assign(keymap, "TFM_OT_transform");
+	WM_modalkeymap_assign(keymap, "TFM_OT_translate");
+	WM_modalkeymap_assign(keymap, "TFM_OT_rotate");
+	WM_modalkeymap_assign(keymap, "TFM_OT_tosphere");
+	WM_modalkeymap_assign(keymap, "TFM_OT_resize");
+	WM_modalkeymap_assign(keymap, "TFM_OT_shear");
+	WM_modalkeymap_assign(keymap, "TFM_OT_warp");
+	WM_modalkeymap_assign(keymap, "TFM_OT_shrink_fatten");
+	WM_modalkeymap_assign(keymap, "TFM_OT_tilt");
+	WM_modalkeymap_assign(keymap, "TFM_OT_trackball");
+	
+}
+
+
 void transformEvent(TransInfo *t, wmEvent *event)
 {
 	float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
@@ -513,7 +570,67 @@
 		applyMouseInput(t, &t->mouse, t->mval, t->values);
 	}
 
-	if (event->val) {
+	/* handle modal keymap first */
+	if (event->type == EVT_MODAL_MAP) {
+		switch (event->val) {
+			case TFM_MODAL_CANCEL:
+				t->state = TRANS_CANCEL;
+				break;
+			case TFM_MODAL_CONFIRM:
+				t->state = TRANS_CONFIRM;
+				break;
+				
+			case TFM_MODAL_TRANSLATE:
+				/* only switch when... */
+				if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
+					resetTransRestrictions(t);
+					restoreTransObjects(t);
+					initTranslation(t);
+					initSnapping(t, NULL); // need to reinit after mode change
+					t->redraw = 1;
+				}
+				break;
+			case TFM_MODAL_ROTATE:
+				/* only switch when... */
+				if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
+					
+					resetTransRestrictions(t);
+					
+					if (t->mode == TFM_ROTATION) {
+						restoreTransObjects(t);
+						initTrackball(t);
+					}
+					else {
+						restoreTransObjects(t);
+						initRotation(t);
+					}
+					initSnapping(t, NULL); // need to reinit after mode change
+					t->redraw = 1;
+				}
+				break;
+			case TFM_MODAL_RESIZE:
+				/* only switch when... */
+				if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
+					resetTransRestrictions(t);
+					restoreTransObjects(t);
+					initResize(t);
+					initSnapping(t, NULL); // need to reinit after mode change
+					t->redraw = 1;
+				}
+				break;
+				
+			case TFM_MODAL_SNAP_GEARS:
+				t->modifiers |= MOD_SNAP_GEARS;
+				t->redraw = 1;
+				break;
+			case TFM_MODAL_SNAP_GEARS_OFF:
+				t->modifiers &= ~MOD_SNAP_GEARS;
+				t->redraw = 1;
+				break;
+		}
+	}
+	/* else do non-mapped events */
+	else if (event->val==KM_PRESS) {
 		switch (event->type){
 		case RIGHTMOUSE:
 			t->state = TRANS_CANCEL;

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform.h	2009-07-21 10:40:13 UTC (rev 21756)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform.h	2009-07-21 11:03:07 UTC (rev 21757)
@@ -47,6 +47,7 @@
 struct BezTriple;
 struct wmOperatorType;
 struct wmOperator;
+struct wmWindowManager;
 struct bContext;
 struct wmEvent;
 struct wmTimer;
@@ -482,9 +483,11 @@
 void initAlign(TransInfo *t);
 int Align(TransInfo *t, short mval[2]);
 
-
 void drawPropCircle(const struct bContext *C, TransInfo *t);
 
+void transform_modal_keymap(struct wmWindowManager *wm);
+
+
 /*********************** transform_conversions.c ********** */
 struct ListBase;
 

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform_ops.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform_ops.c	2009-07-21 10:40:13 UTC (rev 21756)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform_ops.c	2009-07-21 11:03:07 UTC (rev 21757)
@@ -587,6 +587,10 @@
 void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid)
 {
 	wmKeymapItem *km;
+	
+	/* transform.c, only adds modal map once, checks if it's there */
+	transform_modal_keymap(wm);
+	
 	switch(spaceid)
 	{
 		case SPACE_VIEW3D:

Modified: branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h
===================================================================
--- branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h	2009-07-21 10:40:13 UTC (rev 21756)
+++ branches/blender2.5/blender/source/blender/makesdna/DNA_windowmanager_types.h	2009-07-21 11:03:07 UTC (rev 21757)
@@ -41,6 +41,7 @@
 struct wmGesture;
 struct wmOperatorType;
 struct wmOperator;
+struct wmKeyMap;
 
 /* forwards */
 struct bContext;
@@ -54,6 +55,10 @@
 struct ReportList;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list