[Bf-blender-cvs] [87cc890] master: Support units in modal numinput

Bastien Montagne noreply at git.blender.org
Sat Dec 21 18:02:06 CET 2013


Commit: 87cc890aef53c4660448b1125dc0c40a187ae1f2
Author: Bastien Montagne
Date:   Sat Dec 21 17:11:43 2013 +0100
http://developer.blender.org/rB87cc890aef53c4660448b1125dc0c40a187ae1f2

Support units in modal numinput

Summary:
This completly changes the way modal numinput is handled. Now, edited expression is a string, which then gets unit- and py-evaluated to get a float value.

We gain many power and flexibility, but lose a few "shortcuts" like '-' to negate, or '/' to inverse (if they are really needed, we still can add them with modifiers, like e.g. ctrl-/ or so).

Features:
- units (cm, ", deg, etc.).
- basic operations from python/BKE_unit (+, *, **, etc.), and math constants and functions (pi, sin, etc.).
- you can navigate in edited value (left/right key, ctrl to move by block) and insert/delete chars, e.g. to fix a typo without having to rewrite everything.
- you can go to next/previous value with (ctrl-)TAB key.
- As before, hitting backspace after having deleted all leading chars will first reset the edited value to init state, and on second press, the whole "modal numinput" editing will be cancelled, going back to usual transform with mouse.

Notes:
- Did not touch to how values are shown in header when modal numinput is not enabled (would do that in another commit), so this is still quite inconsistent.
- Added back radian support in BKE_unit.
- Added arcminute/arcsecond to BKE_unit.
(those unit changes affect all angle UI controls, btw, so you can now enter radians or longitude/latitude values when in degrees units).

Related to T37600.

Reviewers: brecht, campbellbarton, carter2422

Reviewed By: brecht, campbellbarton, carter2422
Thanks everybody!

Differential Revision: http://developer.blender.org/D61

===================================================================

M	source/blender/blenkernel/BKE_unit.h
M	source/blender/blenkernel/intern/unit.c
M	source/blender/editors/animation/anim_markers.c
M	source/blender/editors/include/ED_numinput.h
M	source/blender/editors/mesh/editmesh_bevel.c
M	source/blender/editors/mesh/editmesh_inset.c
M	source/blender/editors/mesh/editmesh_loopcut.c
M	source/blender/editors/transform/transform.c
M	source/blender/editors/util/CMakeLists.txt
M	source/blender/editors/util/SConscript
M	source/blender/editors/util/numinput.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 6b5ce5e..133f3d0 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -34,7 +34,7 @@ extern "C" {
 /* in all cases the value is assumed to be scaled by the user preference */
 
 /* humanly readable representation of a value in units (used for button drawing) */
-void    bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, int split, int pad);
+size_t  bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, int split, int pad);
 
 /* replace units with values, used before python button evaluation */
 int     bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type);
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 17aad7a..632ac62 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -260,9 +260,12 @@ static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0,
 
 
 static struct bUnitDef buNaturalRotDef[] = {
-	{"degree", "degrees",			"°", NULL, "Degrees",		M_PI / 180.0, 0.0,	B_UNIT_DEF_NONE},
-//	{"radian", "radians",			"r", NULL, "Radians",		1.0, 0.0,			B_UNIT_DEF_NONE},
-//	{"turn", "turns",				"t", NULL, "Turns",			1.0/(M_PI*2.0), 0.0,B_UNIT_DEF_NONE},
+	{"degree",    "degrees",     "°",  "d",   "Degrees",     M_PI / 180.0,             0.0,  B_UNIT_DEF_NONE},
+	/* arcminutes/arcseconds are used in Astronomy/Navigation areas... */
+	{"arcminute", "arcminutes",  "'",  NULL,  "Arcminutes",  (M_PI / 180.0) / 60.0,    0.0,  B_UNIT_DEF_SUPPRESS},
+	{"arcsecond", "arcseconds",  "\"", NULL,  "Arcseconds",  (M_PI / 180.0) / 3600.0,  0.0,  B_UNIT_DEF_SUPPRESS},
+	{"radian",    "radians",     "r",  NULL,  "Radians",     1.0,                      0.0,  B_UNIT_DEF_NONE},
+//	{"turn",      "turns",       "t",  NULL,  "Turns",       1.0 / (M_PI * 2.0),       0.0,  B_UNIT_DEF_NONE},
 	{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef) / sizeof(bUnitDef)};
@@ -340,12 +343,12 @@ static void unit_dual_convert(double value, bUnitCollection *usys, bUnitDef **un
 	*unit_b = unit_best_fit(*value_b, usys, *unit_a, 1);
 }
 
-static int unit_as_string(char *str, int len_max, double value, int prec, bUnitCollection *usys,
-                          /* non exposed options */
-                          bUnitDef *unit, char pad)
+static size_t unit_as_string(char *str, int len_max, double value, int prec, bUnitCollection *usys,
+                             /* non exposed options */
+                             bUnitDef *unit, char pad)
 {
 	double value_conv;
-	int len, i;
+	size_t len, i;
 
 	if (unit) {
 		/* use unit without finding the best one */
@@ -413,8 +416,10 @@ static int unit_as_string(char *str, int len_max, double value, int prec, bUnitC
 	return i;
 }
 
-/* Used for drawing number buttons, try keep fast */
-void bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, int split, int pad)
+/* Used for drawing number buttons, try keep fast.
+ * Return the length of the generated string.
+ */
+size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, int split, int pad)
 {
 	bUnitCollection *usys = unit_get_system(system, type);
 
@@ -430,20 +435,21 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system,
 
 		/* check the 2 is a smaller unit */
 		if (unit_b > unit_a) {
-			int i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0');
+			size_t i;
+			i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0');
 
 			/* is there enough space for at least 1 char of the next unit? */
 			if (i + 2 < len_max) {
 				str[i++] = ' ';
 
 				/* use low precision since this is a smaller unit */
-				unit_as_string(str + i, len_max - i, value_b, prec ? 1 : 0, usys, unit_b, '\0');
+				i += unit_as_string(str + i, len_max - i, value_b, prec ? 1 : 0, usys, unit_b, '\0');
 			}
-			return;
+			return i;
 		}
 	}
 
-	unit_as_string(str, len_max, value, prec, usys, NULL, pad ? ' ' : '\0');
+	return unit_as_string(str, len_max, value, prec, usys, NULL, pad ? ' ' : '\0');
 }
 
 BLI_INLINE int isalpha_or_utf8(const int ch)
@@ -606,15 +612,8 @@ int bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double sca
 		return 0;
 	}
 
-	{ /* make lowercase */
-		int i;
-		char *ch = str;
-
-		for (i = 0; (i < len_max) && (*ch != '\0'); i++, ch++) {
-			if ((*ch >= 'A') && (*ch <= 'Z'))
-				*ch += ('a' - 'A');
-		}
-	}
+	/* make lowercase */
+	BLI_ascii_strtolower(str, len_max);
 
 	for (unit = usys->units; unit->name; unit++) {
 		/* in case there are multiple instances */
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 4af3c05..e65ca3d 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -45,6 +45,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
+#include "BKE_unit.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -603,6 +604,7 @@ typedef struct MarkerMove {
 /* return 0 if not OK */
 static int ed_marker_move_init(bContext *C, wmOperator *op)
 {
+	Scene *scene = CTX_data_scene(C);
 	ListBase *markers = ED_context_get_markers(C);
 	MarkerMove *mm;
 	TimeMarker *marker;
@@ -623,8 +625,10 @@ static int ed_marker_move_init(bContext *C, wmOperator *op)
 
 	initNumInput(&mm->num);
 	mm->num.idx_max = 0; /* one axis */
-	mm->num.flag |= NUM_NO_FRACTION;
-	mm->num.increment = 1.0f;
+	mm->num.val_flag[0] |= NUM_NO_FRACTION;
+	mm->num.unit_sys = scene->unit.system;
+	/* No time unit supporting frames currently... */
+	mm->num.unit_type[0] = B_UNIT_NONE;
 	
 	for (a = 0, marker = markers->first; marker; marker = marker->next) {
 		if (marker->flag & SELECT) {
@@ -832,7 +836,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even
 	}
 
 	if (event->val == KM_PRESS) {
-		if (handleNumInput(&mm->num, event)) {
+		if (handleNumInput(C, &mm->num, event)) {
 			char str_tx[NUM_STR_REP_LEN];
 			float value = RNA_int_get(op->ptr, "frames");
 			applyNumInput(&mm->num, &value);
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index f46332c..e44dab7 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -27,40 +27,49 @@
 #ifndef __ED_NUMINPUT_H__
 #define __ED_NUMINPUT_H__
 
-/*
- *  The ctrl value has different meaning:
- *      0           : No value has been typed
- *
- *      otherwise, |value| - 1 is where the cursor is located after the period
- *      Positive    : number is positive
- *      Negative    : number is negative
- */
+#define NUM_STR_REP_LEN 64
+#define NUM_MAX_ELEMENTS 3
 
 typedef struct NumInput {
-	short  idx;
-	short  idx_max;
-	short  flag;        /* Different flags to indicate different behaviors                                */
-	char   inv[3];      /* If the value is inverted or not                                                */
-	float  val[3];      /* Direct value of the input                                                      */
-	int    ctrl[3];     /* Control to indicate what to do with the numbers that are typed                 */
-	float  increment;
+	short  idx_max;                      /* idx_max < NUM_MAX_ELEMENTS */
+	int    unit_sys;
+	int    unit_type[NUM_MAX_ELEMENTS];  /* Each value can have a different type */
+	bool   unit_use_radians;
+
+	short  flag;                         /* Flags affecting all values' behavior */
+	short  val_flag[NUM_MAX_ELEMENTS];   /* Per-value flags */
+	float  val[NUM_MAX_ELEMENTS];        /* Direct value of the input */
+	float  val_org[NUM_MAX_ELEMENTS];    /* Original value of the input, for reset */
+	float  val_inc[NUM_MAX_ELEMENTS];    /* Increment steps */
+
+	short  idx;                          /* Active element/value */
+	char   str[NUM_STR_REP_LEN];         /* String as typed by user for edited value (we assume ASCII world!) */
+	/* Current position of cursor in edited value str (first byte of "current" letter, so 0 for an empty str) */
+	int    str_cur;
 } NumInput;
 
-/* NUMINPUT FLAGS */
-#define NUM_NULL_ONE        2
-#define NUM_NO_NEGATIVE     4
-#define NUM_NO_ZERO         8
-#define NUM_NO_FRACTION     16
-#define NUM_AFFECT_ALL      32
+/* NumInput.flag */
+enum {
+	NUM_AFFECT_ALL      = (1 << 0),
+};
+
+/* NumInput.val_flag[] */
+enum {
+	/* Public! */
+	NUM_NULL_ONE        = (1 << 0),
+	NUM_NO_NEGATIVE     = (1 << 1),
+	NUM_NO_ZERO         = (1 << 2),
+	NUM_NO_FRACTION     = (1 << 3),
+	/* (1 << 9) and above are reserved for internal flags! */
+};
 
 /*********************** NumInput ********************************/
 
 void initNumInput(NumInput *n);
-#define NUM_STR_REP_LEN 20 /* str must be NUM_STR_LEN * (idx_max + 1) length. */
 void outputNumInput(NumInput *n, char *str);
 bool hasNumInput(const NumInput *n);
 void applyNumInput(NumInput *n, float *vec);
-bool handleNumInput(NumInput *n, const struct wmEvent *event);
+bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event);
 
 #define NUM_MODAL_INCREMENT_UP   18
 #define NUM_MODAL_INCREMENT_DOWN 19
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index ddb58cd..9a6131f 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -36,6 +36,7 @@
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_editmesh.h"
+#include "BKE_unit.h"
 
 #include "RNA_define.h"
 #include "RNA_access.h"
@@ -74,18 +75,23 @@ typedef struct {
 
 static void edbm_bevel_update_header(wmOperator *op, bContext *C)
 {
-	const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RMB), Offset: %s, Segments: %d");
+	const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Offset: %s, Segments: %d");
 
 	char msg[HEADER_LENGTH];
 	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list