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:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_unit.h2
-rw-r--r--source/blender/blenkernel/intern/unit.c43
-rw-r--r--source/blender/editors/animation/anim_markers.c10
-rw-r--r--source/blender/editors/include/ED_numinput.h55
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c123
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c255
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c249
-rw-r--r--source/blender/editors/transform/transform.c974
-rw-r--r--source/blender/editors/util/CMakeLists.txt5
-rw-r--r--source/blender/editors/util/SConscript4
-rw-r--r--source/blender/editors/util/numinput.c489
11 files changed, 1270 insertions, 939 deletions
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 6b5ce5e1d21..133f3d0dfbc 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 17aad7a5a2c..632ac6234b2 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 4af3c051c6d..e65ca3d20be 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 f46332c9a82..e44dab7bff0 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 ddb58cd6c7b..9a6131f76e9 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];
ScrArea *sa = CTX_wm_area(C);
if (sa) {
+ BevelData *opdata = op->customdata;
char offset_str[NUM_STR_REP_LEN];
- BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
- BLI_snprintf(msg, HEADER_LENGTH, str,
- offset_str,
- RNA_int_get(op->ptr, "segments")
- );
+
+ if (hasNumInput(&opdata->num_input)) {
+ outputNumInput(&opdata->num_input, offset_str);
+ }
+ else {
+ BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
+ }
+
+ BLI_snprintf(msg, HEADER_LENGTH, str, offset_str, RNA_int_get(op->ptr, "segments"));
ED_area_headerprint(sa, msg);
}
@@ -94,6 +100,7 @@ static void edbm_bevel_update_header(wmOperator *op, bContext *C)
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BevelData *opdata;
@@ -108,7 +115,10 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->shift_factor = -1.0f;
initNumInput(&opdata->num_input);
- opdata->num_input.flag = NUM_NO_NEGATIVE;
+ opdata->num_input.idx_max = 0;
+ opdata->num_input.val_flag[0] |= NUM_NO_NEGATIVE;
+ opdata->num_input.unit_sys = scene->unit.system;
+ opdata->num_input.unit_type[0] = B_UNIT_NONE; /* Not sure this is a factor or a unit? */
/* avoid the cost of allocating a bm copy */
if (is_modal) {
@@ -306,10 +316,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
BevelData *opdata = op->customdata;
int segments = RNA_int_get(op->ptr, "segments");
- if (event->val == KM_PRESS) {
- /* Try to handle numeric inputs... */
-
- if (handleNumInput(&opdata->num_input, event)) {
+ if (event->val == KM_PRESS && hasNumInput(&opdata->num_input)) {
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (handleNumInput(C, &opdata->num_input, event)) {
float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
@@ -318,51 +327,73 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
}
+ else {
+ bool handled = false;
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ edbm_bevel_cancel(C, op);
+ return OPERATOR_CANCELLED;
+
+ case MOUSEMOVE:
+ if (!hasNumInput(&opdata->num_input)) {
+ const float factor = edbm_bevel_mval_factor(op, event);
+ RNA_float_set(op->ptr, "offset", factor);
+
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(op, C);
+ handled = true;
+ }
+ break;
+
+ case LEFTMOUSE:
+ case PADENTER:
+ case RETKEY:
+ edbm_bevel_calc(op);
+ edbm_bevel_exit(C, op);
+ return OPERATOR_FINISHED;
- switch (event->type) {
- case ESCKEY:
- case RIGHTMOUSE:
- edbm_bevel_cancel(C, op);
- return OPERATOR_CANCELLED;
+ /* Note this will prevent padplus and padminus to ever activate modal numinput.
+ * This is not really an issue though, as we only expect positive values here...
+ * Else we could force them to only modify segments number when shift is pressed, or so.
+ */
- case MOUSEMOVE:
- if (!hasNumInput(&opdata->num_input)) {
- const float factor = edbm_bevel_mval_factor(op, event);
- RNA_float_set(op->ptr, "offset", factor);
+ case WHEELUPMOUSE: /* change number of segments */
+ case PADPLUSKEY:
+ if (event->val == KM_RELEASE)
+ break;
+ segments++;
+ RNA_int_set(op->ptr, "segments", segments);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
- }
- break;
-
- case LEFTMOUSE:
- case PADENTER:
- case RETKEY:
- edbm_bevel_calc(op);
- edbm_bevel_exit(C, op);
- return OPERATOR_FINISHED;
-
- case WHEELUPMOUSE: /* change number of segments */
- case PADPLUSKEY:
- if (event->val == KM_RELEASE)
+ handled = true;
break;
- segments++;
- RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(op);
- edbm_bevel_update_header(op, C);
- break;
+ case WHEELDOWNMOUSE: /* change number of segments */
+ case PADMINUS:
+ if (event->val == KM_RELEASE)
+ break;
- case WHEELDOWNMOUSE: /* change number of segments */
- case PADMINUS:
- if (event->val == KM_RELEASE)
+ segments = max_ii(segments - 1, 1);
+ RNA_int_set(op->ptr, "segments", segments);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(op, C);
+ handled = true;
break;
+ }
- segments = max_ii(segments - 1, 1);
- RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(op);
- edbm_bevel_update_header(op, C);
- break;
+ if (!handled && event->val == KM_PRESS) {
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (handleNumInput(C, &opdata->num_input, event)) {
+ float value = RNA_float_get(op->ptr, "offset");
+ applyNumInput(&opdata->num_input, &value);
+ RNA_float_set(op->ptr, "offset", value);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
}
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 137554459ce..5f23a5deb97 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.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"
@@ -110,6 +111,7 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C)
static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
{
InsetData *opdata;
+ Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -129,6 +131,9 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
initNumInput(&opdata->num_input);
opdata->num_input.idx_max = 1; /* Two elements. */
+ opdata->num_input.unit_sys = scene->unit.system;
+ opdata->num_input.unit_type[0] = B_UNIT_LENGTH;
+ opdata->num_input.unit_type[1] = B_UNIT_LENGTH;
if (is_modal) {
View3D *v3d = CTX_wm_view3d(C);
@@ -291,10 +296,9 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
InsetData *opdata = op->customdata;
- if (event->val == KM_PRESS) {
- /* Try to handle numeric inputs... */
-
- if (handleNumInput(&opdata->num_input, event)) {
+ if (event->val == KM_PRESS && hasNumInput(&opdata->num_input)) {
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (handleNumInput(C, &opdata->num_input, event)) {
float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
@@ -312,134 +316,163 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
+ else {
+ bool handled = false;
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
- switch (event->type) {
- case ESCKEY:
- case RIGHTMOUSE:
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
-
- case MOUSEMOVE:
- if (!hasNumInput(&opdata->num_input)) {
- float mdiff[2];
- float amount;
-
- mdiff[0] = opdata->mcenter[0] - event->mval[0];
- mdiff[1] = opdata->mcenter[1] - event->mval[1];
-
- if (opdata->modify_depth)
- amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
- else
- amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
-
- /* Fake shift-transform... */
- if (opdata->shift)
- amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount;
-
- if (opdata->modify_depth)
- RNA_float_set(op->ptr, "depth", amount);
- else {
- amount = max_ff(amount, 0.0f);
- RNA_float_set(op->ptr, "thickness", amount);
+ case MOUSEMOVE:
+ if (!hasNumInput(&opdata->num_input)) {
+ float mdiff[2];
+ float amount;
+
+ mdiff[0] = opdata->mcenter[0] - event->mval[0];
+ mdiff[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (opdata->modify_depth)
+ amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
+ else
+ amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
+
+ /* Fake shift-transform... */
+ if (opdata->shift)
+ amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount;
+
+ if (opdata->modify_depth)
+ RNA_float_set(op->ptr, "depth", amount);
+ else {
+ amount = max_ff(amount, 0.0f);
+ RNA_float_set(op->ptr, "thickness", amount);
+ }
+
+ if (edbm_inset_calc(op))
+ edbm_inset_update_header(op, C);
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
+ }
+ break;
+
+ case LEFTMOUSE:
+ case PADENTER:
+ case RETKEY:
+ edbm_inset_calc(op);
+ edbm_inset_exit(C, op);
+ return OPERATOR_FINISHED;
+
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ if (event->val == KM_PRESS) {
+ if (opdata->modify_depth)
+ opdata->shift_amount = RNA_float_get(op->ptr, "depth");
+ else
+ opdata->shift_amount = RNA_float_get(op->ptr, "thickness");
+ opdata->shift = true;
+ handled = true;
}
-
- if (edbm_inset_calc(op))
- edbm_inset_update_header(op, C);
else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
+ opdata->shift_amount = 0.0f;
+ opdata->shift = false;
+ handled = true;
}
- }
- break;
-
- case LEFTMOUSE:
- case PADENTER:
- case RETKEY:
- edbm_inset_calc(op);
- edbm_inset_exit(C, op);
- return OPERATOR_FINISHED;
-
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- if (event->val == KM_PRESS) {
- if (opdata->modify_depth)
- opdata->shift_amount = RNA_float_get(op->ptr, "depth");
- else
- opdata->shift_amount = RNA_float_get(op->ptr, "thickness");
- opdata->shift = true;
- }
- else {
- opdata->shift_amount = 0.0f;
- opdata->shift = false;
- }
- break;
-
- case LEFTCTRLKEY:
- case RIGHTCTRLKEY:
- {
- float mlen[2];
+ break;
- mlen[0] = opdata->mcenter[0] - event->mval[0];
- mlen[1] = opdata->mcenter[1] - event->mval[1];
-
- if (event->val == KM_PRESS) {
- opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
- if (opdata->shift)
- opdata->shift_amount = opdata->old_thickness;
- opdata->modify_depth = true;
- }
- else {
- opdata->old_depth = RNA_float_get(op->ptr, "depth");
- if (opdata->shift)
- opdata->shift_amount = opdata->old_depth;
- opdata->modify_depth = false;
- }
- opdata->initial_length = len_v2(mlen);
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ {
+ float mlen[2];
- edbm_inset_update_header(op, C);
- break;
- }
+ mlen[0] = opdata->mcenter[0] - event->mval[0];
+ mlen[1] = opdata->mcenter[1] - event->mval[1];
- case OKEY:
- if (event->val == KM_PRESS) {
- const bool use_outset = RNA_boolean_get(op->ptr, "use_outset");
- RNA_boolean_set(op->ptr, "use_outset", !use_outset);
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
+ if (event->val == KM_PRESS) {
+ opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
+ if (opdata->shift)
+ opdata->shift_amount = opdata->old_thickness;
+ opdata->modify_depth = true;
}
else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
+ opdata->old_depth = RNA_float_get(op->ptr, "depth");
+ if (opdata->shift)
+ opdata->shift_amount = opdata->old_depth;
+ opdata->modify_depth = false;
}
+ opdata->initial_length = len_v2(mlen);
+
+ edbm_inset_update_header(op, C);
+ handled = true;
+ break;
}
- break;
- case BKEY:
- if (event->val == KM_PRESS) {
- const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
- RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
+
+ case OKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_outset = RNA_boolean_get(op->ptr, "use_outset");
+ RNA_boolean_set(op->ptr, "use_outset", !use_outset);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
}
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
+ break;
+ case BKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
+ RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
}
- }
- break;
- case IKEY:
- if (event->val == KM_PRESS) {
- const bool use_individual = RNA_boolean_get(op->ptr, "use_individual");
- RNA_boolean_set(op->ptr, "use_individual", !use_individual);
+ break;
+ case IKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_individual = RNA_boolean_get(op->ptr, "use_individual");
+ RNA_boolean_set(op->ptr, "use_individual", !use_individual);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
+ }
+ break;
+ }
+
+ if (!handled && event->val == KM_PRESS) {
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (handleNumInput(C, &opdata->num_input, event)) {
+ float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
+ RNA_float_get(op->ptr, "depth")};
+ applyNumInput(&opdata->num_input, amounts);
+ amounts[0] = max_ff(amounts[0], 0.0f);
+ RNA_float_set(op->ptr, "thickness", amounts[0]);
+ RNA_float_set(op->ptr, "depth", amounts[1]);
+
if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
}
else {
edbm_inset_cancel(C, op);
return OPERATOR_CANCELLED;
}
}
- break;
-
+ }
}
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 9223f6d9450..fd24981bde0 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -43,6 +43,7 @@
#include "BKE_report.h"
#include "BKE_editmesh.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_unit.h"
#include "BIF_gl.h"
@@ -392,6 +393,7 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
static int ringsel_init(bContext *C, wmOperator *op, bool do_cut)
{
RingSelOpData *lcd;
+ Scene *scene = CTX_data_scene(C);
/* alloc new customdata */
lcd = op->customdata = MEM_callocN(sizeof(RingSelOpData), "ringsel Modal Op Data");
@@ -405,8 +407,12 @@ static int ringsel_init(bContext *C, wmOperator *op, bool do_cut)
lcd->do_cut = do_cut;
initNumInput(&lcd->num);
- lcd->num.idx_max = 0;
- lcd->num.flag |= NUM_NO_NEGATIVE | NUM_NO_FRACTION;
+ lcd->num.idx_max = 1;
+ lcd->num.val_flag[0] |= NUM_NO_NEGATIVE | NUM_NO_FRACTION;
+ /* No specific flags for smoothness. */
+ lcd->num.unit_sys = scene->unit.system;
+ lcd->num.unit_type[0] = B_UNIT_NONE;
+ lcd->num.unit_type[1] = B_UNIT_NONE;
/* XXX, temp, workaround for [# ] */
EDBM_mesh_ensure_valid_dm_hack(CTX_data_scene(C), lcd->em);
@@ -529,126 +535,163 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
view3d_operator_needs_opengl(C);
- switch (event->type) {
- case RETKEY:
- case PADENTER:
- case LEFTMOUSE: /* confirm */ // XXX hardcoded
- if (event->val == KM_PRESS) {
- /* finish */
+ /* using the keyboard to input the number of cuts */
+ if (event->val == KM_PRESS && hasNumInput(&lcd->num)) {
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (handleNumInput(C, &lcd->num, event)) {
+ float values[2] = {(float)cuts, smoothness};
+ applyNumInput(&lcd->num, values);
+
+ /* allow zero so you can backspace and type in a value
+ * otherwise 1 as minimum would make more sense */
+ cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
+ smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
+
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = true;
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+
+ ED_region_tag_redraw(lcd->ar);
+ }
+ }
+ else {
+ bool handled = false;
+ switch (event->type) {
+ case RETKEY:
+ case PADENTER:
+ case LEFTMOUSE: /* confirm */ // XXX hardcoded
+ if (event->val == KM_PRESS) {
+ /* finish */
+ ED_region_tag_redraw(lcd->ar);
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+
+ if (lcd->eed) {
+ /* set for redo */
+ BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
+ RNA_int_set(op->ptr, "edge_index", BM_elem_index_get(lcd->eed));
+
+ /* execute */
+ ringsel_finish(C, op);
+ ringsel_exit(C, op);
+ }
+ else {
+ ringcut_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+ }
+
+ ED_region_tag_redraw(lcd->ar);
+ handled = true;
+ break;
+ case RIGHTMOUSE: /* abort */ // XXX hardcoded
ED_region_tag_redraw(lcd->ar);
+ ringsel_exit(C, op);
ED_area_headerprint(CTX_wm_area(C), NULL);
- if (lcd->eed) {
- /* set for redo */
- BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
- RNA_int_set(op->ptr, "edge_index", BM_elem_index_get(lcd->eed));
-
- /* execute */
- ringsel_finish(C, op);
- ringsel_exit(C, op);
- }
- else {
+ return OPERATOR_FINISHED;
+ case ESCKEY:
+ if (event->val == KM_RELEASE) {
+ /* cancel */
+ ED_region_tag_redraw(lcd->ar);
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+
ringcut_cancel(C, op);
return OPERATOR_CANCELLED;
}
-
- return OPERATOR_FINISHED;
- }
-
- ED_region_tag_redraw(lcd->ar);
- break;
- case RIGHTMOUSE: /* abort */ // XXX hardcoded
- ED_region_tag_redraw(lcd->ar);
- ringsel_exit(C, op);
- ED_area_headerprint(CTX_wm_area(C), NULL);
-
- return OPERATOR_FINISHED;
- case ESCKEY:
- if (event->val == KM_RELEASE) {
- /* cancel */
+
ED_region_tag_redraw(lcd->ar);
- ED_area_headerprint(CTX_wm_area(C), NULL);
+ handled = true;
+ break;
+ case PADPLUSKEY:
+ case PAGEUPKEY:
+ case WHEELUPMOUSE: /* change number of cuts */
+ if (event->val == KM_RELEASE)
+ break;
+ if (event->alt == 0) {
+ cuts++;
+ cuts = CLAMPIS(cuts, 0, SUBD_CUTS_MAX);
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = true;
+ }
+ else {
+ smoothness = min_ff(smoothness + 0.05f, SUBD_SMOOTH_MAX);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = true;
+ }
- ringcut_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
-
- ED_region_tag_redraw(lcd->ar);
- break;
- case PADPLUSKEY:
- case PAGEUPKEY:
- case WHEELUPMOUSE: /* change number of cuts */
- if (event->val == KM_RELEASE)
+ ED_region_tag_redraw(lcd->ar);
+ handled = true;
break;
- if (event->alt == 0) {
- cuts++;
- cuts = CLAMPIS(cuts, 0, SUBD_CUTS_MAX);
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = true;
- }
- else {
- smoothness = min_ff(smoothness + 0.05f, SUBD_SMOOTH_MAX);
- RNA_float_set(op->ptr, "smoothness", smoothness);
- show_cuts = true;
- }
-
- ED_region_tag_redraw(lcd->ar);
- break;
- case PADMINUS:
- case PAGEDOWNKEY:
- case WHEELDOWNMOUSE: /* change number of cuts */
- if (event->val == KM_RELEASE)
+ case PADMINUS:
+ case PAGEDOWNKEY:
+ case WHEELDOWNMOUSE: /* change number of cuts */
+ if (event->val == KM_RELEASE)
+ break;
+
+ if (event->alt == 0) {
+ cuts = max_ii(cuts - 1, 1);
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = true;
+ }
+ else {
+ smoothness = max_ff(smoothness - 0.05f, -SUBD_SMOOTH_MAX);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = true;
+ }
+
+ ED_region_tag_redraw(lcd->ar);
+ handled = true;
+ break;
+ case MOUSEMOVE: /* mouse moved somewhere to select another loop */
+ {
+ lcd->vc.mval[0] = event->mval[0];
+ lcd->vc.mval[1] = event->mval[1];
+ loopcut_mouse_move(lcd, cuts);
+
+ ED_region_tag_redraw(lcd->ar);
+ handled = true;
break;
+ }
+ }
- if (event->alt == 0) {
- cuts = max_ii(cuts - 1, 1);
+ if (!handled && event->val == KM_PRESS) {
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (handleNumInput(C, &lcd->num, event)) {
+ float values[2] = {(float)cuts, smoothness};
+ applyNumInput(&lcd->num, values);
+
+ /* allow zero so you can backspace and type in a value
+ * otherwise 1 as minimum would make more sense */
+ cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
+ smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
+
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
- }
- else {
- smoothness = max_ff(smoothness - 0.05f, -SUBD_SMOOTH_MAX);
RNA_float_set(op->ptr, "smoothness", smoothness);
- show_cuts = true;
+
+ ED_region_tag_redraw(lcd->ar);
}
-
- ED_region_tag_redraw(lcd->ar);
- break;
- case MOUSEMOVE: /* mouse moved somewhere to select another loop */
- {
- lcd->vc.mval[0] = event->mval[0];
- lcd->vc.mval[1] = event->mval[1];
- loopcut_mouse_move(lcd, cuts);
-
- ED_region_tag_redraw(lcd->ar);
- break;
- }
- }
-
- /* using the keyboard to input the number of cuts */
- if (event->val == KM_PRESS) {
- /* init as zero so backspace clears */
-
- if (handleNumInput(&lcd->num, event)) {
- float value = RNA_int_get(op->ptr, "number_cuts");
- applyNumInput(&lcd->num, &value);
-
- /* allow zero so you can backspace and type in a value
- * otherwise 1 as minimum would make more sense */
- cuts = CLAMPIS(value, 0, SUBD_CUTS_MAX);
-
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = true;
-
- ED_region_tag_redraw(lcd->ar);
}
}
-
+
if (show_cuts) {
- char buf[64];
- BLI_snprintf(buf, sizeof(buf), IFACE_("Number of Cuts: %d, Smooth: %.2f (Alt)"), cuts, smoothness);
+ char buf[64 + NUM_STR_REP_LEN * 2];
+ char str_rep[NUM_STR_REP_LEN * 2];
+ if (hasNumInput(&lcd->num)) {
+ outputNumInput(&lcd->num, str_rep);
+ }
+ else {
+ BLI_snprintf(str_rep, NUM_STR_REP_LEN, "%d", cuts);
+ BLI_snprintf(str_rep + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%.2f", smoothness);
+ }
+ BLI_snprintf(buf, sizeof(buf), IFACE_("Number of Cuts: %s, Smooth: %s (Alt)"),
+ str_rep, str_rep + NUM_STR_REP_LEN);
ED_area_headerprint(CTX_wm_area(C), buf);
}
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f0756a6f86e..35aa3a3f1d7 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -944,8 +944,8 @@ int transformEvent(TransInfo *t, const wmEvent *event)
{
float mati[3][3] = MAT3_UNITY;
char cmode = constraintModeToChar(t);
- int handled = 1;
-
+ bool handled = false;
+
t->redraw |= handleMouseInput(t, &t->mouse, event);
if (event->type == MOUSEMOVE) {
@@ -957,7 +957,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
// t->redraw |= TREDRAW_SOFT; /* Use this for soft redraw. Might cause flicker in object mode */
t->redraw |= TREDRAW_HARD;
-
if (t->state == TRANS_STARTING) {
t->state = TRANS_RUNNING;
}
@@ -966,445 +965,503 @@ int transformEvent(TransInfo *t, const wmEvent *event)
// Snapping mouse move events
t->redraw |= handleSnapping(t, event);
+ handled = true;
}
-
/* 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 (ELEM5(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- resetTransModal(t);
- resetTransRestrictions(t);
- restoreTransObjects(t);
- initTranslation(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- WM_event_add_mousemove(t->context);
- }
- else if (t->mode == TFM_SEQ_SLIDE) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- }
- else {
- if (t->obedit && t->obedit->type == OB_MESH) {
- if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
+ else if (event->type == EVT_MODAL_MAP) {
+ /* Handle modal numinput events first, if already activated. */
+ if (hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else {
+ switch (event->val) {
+ case TFM_MODAL_CANCEL:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ case TFM_MODAL_CONFIRM:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
+ case TFM_MODAL_TRANSLATE:
+ /* only switch when... */
+ if (ELEM5(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initTranslation(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ WM_event_add_mousemove(t->context);
+ handled = true;
+ }
+ else if (t->mode == TFM_SEQ_SLIDE) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else {
+ if (t->obedit && t->obedit->type == OB_MESH) {
+ if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+
+ /* first try edge slide */
+ initEdgeSlide(t);
+ /* if that fails, do vertex slide */
+ if (t->state == TRANS_CANCEL) {
+ t->state = TRANS_STARTING;
+ initVertSlide(t);
+ }
+ /* vert slide can fail on unconnected vertices (rare but possible) */
+ if (t->state == TRANS_CANCEL) {
+ t->state = TRANS_STARTING;
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initTranslation(t);
+ }
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ WM_event_add_mousemove(t->context);
+ }
+ }
+ else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
+ if (t->mode == TFM_TRANSLATION) {
+ restoreTransObjects(t);
+
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ }
+ break;
+ case TFM_MODAL_ROTATE:
+ /* only switch when... */
+ if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
+ if (ELEM6(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
resetTransModal(t);
resetTransRestrictions(t);
- restoreTransObjects(t);
-
- /* first try edge slide */
- initEdgeSlide(t);
- /* if that fails, do vertex slide */
- if (t->state == TRANS_CANCEL) {
- t->state = TRANS_STARTING;
- initVertSlide(t);
+
+ if (t->mode == TFM_ROTATION) {
+ restoreTransObjects(t);
+ initTrackball(t);
}
- /* vert slide can fail on unconnected vertices (rare but possible) */
- if (t->state == TRANS_CANCEL) {
- t->state = TRANS_STARTING;
- resetTransRestrictions(t);
+ else {
restoreTransObjects(t);
- initTranslation(t);
+ initRotation(t);
}
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
- WM_event_add_mousemove(t->context);
+ handled = true;
}
}
- else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- if (t->mode == TFM_TRANSLATION) {
+ break;
+ case TFM_MODAL_RESIZE:
+ /* only switch when... */
+ if (ELEM5(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initResize(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (t->mode == TFM_SHRINKFATTEN) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if (t->options & CTX_MOVIECLIP) {
restoreTransObjects(t);
t->flag ^= T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
+ handled = true;
}
}
- }
- break;
- case TFM_MODAL_ROTATE:
- /* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
- if (ELEM6(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- resetTransModal(t);
- resetTransRestrictions(t);
-
- if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
- initTrackball(t);
+ break;
+
+ case TFM_MODAL_SNAP_INV_ON:
+ t->modifiers |= MOD_SNAP_INVERT;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_SNAP_INV_OFF:
+ t->modifiers &= ~MOD_SNAP_INVERT;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_SNAP_TOGGLE:
+ t->modifiers ^= MOD_SNAP;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
+ case TFM_MODAL_AXIS_X:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ if (cmode == 'X') {
+ stopConstraint(t);
}
else {
- restoreTransObjects(t);
- initRotation(t);
+ if (t->flag & T_2D_EDIT) {
+ setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), IFACE_("along X"));
+ }
+ else {
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0), IFACE_("along %s X"));
+ }
}
- initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- }
- break;
- case TFM_MODAL_RESIZE:
- /* only switch when... */
- if (ELEM5(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- resetTransModal(t);
- resetTransRestrictions(t);
- restoreTransObjects(t);
- initResize(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- }
- else if (t->mode == TFM_SHRINKFATTEN) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- }
- else if (t->mode == TFM_RESIZE) {
- if (t->options & CTX_MOVIECLIP) {
- restoreTransObjects(t);
-
- t->flag ^= T_ALT_TRANSFORM;
+ break;
+ case TFM_MODAL_AXIS_Y:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ if (cmode == 'Y') {
+ stopConstraint(t);
+ }
+ else {
+ if (t->flag & T_2D_EDIT) {
+ setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), IFACE_("along Y"));
+ }
+ else {
+ setUserConstraint(t, t->current_orientation, (CON_AXIS1), IFACE_("along %s Y"));
+ }
+ }
t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- }
- break;
-
- case TFM_MODAL_SNAP_INV_ON:
- t->modifiers |= MOD_SNAP_INVERT;
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_SNAP_INV_OFF:
- t->modifiers &= ~MOD_SNAP_INVERT;
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_SNAP_TOGGLE:
- t->modifiers ^= MOD_SNAP;
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_AXIS_X:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (cmode == 'X') {
- stopConstraint(t);
+ break;
+ case TFM_MODAL_AXIS_Z:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ if (cmode == 'Z') {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, t->current_orientation, (CON_AXIS2), IFACE_("along %s Z"));
+ }
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- else {
- if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), IFACE_("along X"));
+ break;
+ case TFM_MODAL_PLANE_X:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ if (cmode == 'X') {
+ stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0), IFACE_("along %s X"));
+ setUserConstraint(t, t->current_orientation, (CON_AXIS1 | CON_AXIS2), IFACE_("locking %s X"));
}
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_AXIS_Y:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (cmode == 'Y') {
- stopConstraint(t);
+ break;
+ case TFM_MODAL_PLANE_Y:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ if (cmode == 'Y') {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS2), IFACE_("locking %s Y"));
+ }
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- else {
- if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), IFACE_("along Y"));
+ break;
+ case TFM_MODAL_PLANE_Z:
+ if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
+ if (cmode == 'Z') {
+ stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS1), IFACE_("along %s Y"));
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS1), IFACE_("locking %s Z"));
}
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_AXIS_Z:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- if (cmode == 'Z') {
+ break;
+ case TFM_MODAL_CONS_OFF:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
stopConstraint(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS2), IFACE_("along %s Z"));
- }
+ break;
+ case TFM_MODAL_ADD_SNAP:
+ addSnapPoint(t);
t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_PLANE_X:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- if (cmode == 'X') {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS1 | CON_AXIS2), IFACE_("locking %s X"));
- }
+ handled = true;
+ break;
+ case TFM_MODAL_REMOVE_SNAP:
+ removeSnapPoint(t);
t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_PLANE_Y:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- if (cmode == 'Y') {
- stopConstraint(t);
+ handled = true;
+ break;
+ case TFM_MODAL_PROPSIZE:
+ /* MOUSEPAN usage... */
+ if (t->flag & T_PROP_EDIT) {
+ float fac = 1.0f + 0.005f *(event->y - event->prevy);
+ t->prop_size *= fac;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS2), IFACE_("locking %s Y"));
+ break;
+ case TFM_MODAL_PROPSIZE_UP:
+ if (t->flag & T_PROP_EDIT) {
+ t->prop_size *= 1.1f;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
+ break;
+ case TFM_MODAL_PROPSIZE_DOWN:
+ if (t->flag & T_PROP_EDIT) {
+ t->prop_size *= 0.90909090f;
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case TFM_MODAL_EDGESLIDE_UP:
+ case TFM_MODAL_EDGESLIDE_DOWN:
t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_PLANE_Z:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- if (cmode == 'Z') {
- stopConstraint(t);
+ handled = true;
+ break;
+ case TFM_MODAL_AUTOIK_LEN_INC:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, 1);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS1), IFACE_("locking %s Z"));
+ break;
+ case TFM_MODAL_AUTOIK_LEN_DEC:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, -1);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_CONS_OFF:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- stopConstraint(t);
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case TFM_MODAL_ADD_SNAP:
- addSnapPoint(t);
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_REMOVE_SNAP:
- removeSnapPoint(t);
- t->redraw |= TREDRAW_HARD;
- break;
-
- case TFM_MODAL_PROPSIZE:
- /* MOUSEPAN usage... */
- if (t->flag & T_PROP_EDIT) {
- float fac = 1.0f + 0.005f *(event->y - event->prevy);
- t->prop_size *= fac;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
- t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
- calculatePropRatio(t);
- }
- t->redraw |= TREDRAW_HARD;
- break;
-
- case TFM_MODAL_PROPSIZE_UP:
- if (t->flag & T_PROP_EDIT) {
- t->prop_size *= 1.1f;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
- t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
- calculatePropRatio(t);
- }
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_PROPSIZE_DOWN:
- if (t->flag & T_PROP_EDIT) {
- t->prop_size *= 0.90909090f;
- calculatePropRatio(t);
- }
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_EDGESLIDE_UP:
- case TFM_MODAL_EDGESLIDE_DOWN:
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_AUTOIK_LEN_INC:
- if (t->flag & T_AUTOIK)
- transform_autoik_update(t, 1);
- t->redraw |= TREDRAW_HARD;
- break;
- case TFM_MODAL_AUTOIK_LEN_DEC:
- if (t->flag & T_AUTOIK)
- transform_autoik_update(t, -1);
- t->redraw |= TREDRAW_HARD;
- break;
- default:
- handled = 0;
- break;
- }
+ break;
+ default:
+ break;
+ }
- /* Modal numinput events */
- if (handleNumInput(&(t->num), event)) {
- t->redraw |= TREDRAW_HARD;
+ /* Modal numinput events */
+ if (!handled && handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
}
}
/* else do non-mapped events */
else if (event->val == KM_PRESS) {
- switch (event->type) {
- case RIGHTMOUSE:
- t->state = TRANS_CANCEL;
- break;
- /* enforce redraw of transform when modifiers are used */
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- t->modifiers |= MOD_CONSTRAINT_PLANE;
- t->redraw |= TREDRAW_HARD;
- break;
+ /* Handle modal numinput events first, if already activated. */
+ if (hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else {
+ switch (event->type) {
+ case RIGHTMOUSE:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ /* enforce redraw of transform when modifiers are used */
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ t->modifiers |= MOD_CONSTRAINT_PLANE;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ break;
- case SPACEKEY:
- t->state = TRANS_CONFIRM;
- break;
+ case SPACEKEY:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
- case MIDDLEMOUSE:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- /* exception for switching to dolly, or trackball, in camera view */
- if (t->flag & T_CAMERA) {
- if (t->mode == TFM_TRANSLATION)
- setLocalConstraint(t, (CON_AXIS2), IFACE_("along local Z"));
- else if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
- initTrackball(t);
- }
- }
- else {
- t->modifiers |= MOD_CONSTRAINT_SELECT;
- if (t->con.mode & CON_APPLY) {
- stopConstraint(t);
+ case MIDDLEMOUSE:
+ if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ /* exception for switching to dolly, or trackball, in camera view */
+ if (t->flag & T_CAMERA) {
+ if (t->mode == TFM_TRANSLATION)
+ setLocalConstraint(t, (CON_AXIS2), IFACE_("along local Z"));
+ else if (t->mode == TFM_ROTATION) {
+ restoreTransObjects(t);
+ initTrackball(t);
+ }
}
else {
- if (event->shift) {
- initSelectConstraint(t, t->spacemtx);
+ t->modifiers |= MOD_CONSTRAINT_SELECT;
+ if (t->con.mode & CON_APPLY) {
+ stopConstraint(t);
}
else {
- /* bit hackish... but it prevents mmb select to print the orientation from menu */
- strcpy(t->spacename, "global");
- initSelectConstraint(t, mati);
+ if (event->shift) {
+ initSelectConstraint(t, t->spacemtx);
+ }
+ else {
+ /* bit hackish... but it prevents mmb select to print the orientation from menu */
+ strcpy(t->spacename, "global");
+ initSelectConstraint(t, mati);
+ }
+ postSelectConstraint(t);
}
- postSelectConstraint(t);
}
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case ESCKEY:
- t->state = TRANS_CANCEL;
- break;
- case PADENTER:
- case RETKEY:
- t->state = TRANS_CONFIRM;
- break;
- case GKEY:
- /* only switch when... */
- if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
- resetTransModal(t);
- resetTransRestrictions(t);
- restoreTransObjects(t);
- initTranslation(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case SKEY:
- /* only switch when... */
- if (ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
- resetTransModal(t);
- resetTransRestrictions(t);
- restoreTransObjects(t);
- initResize(t);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case RKEY:
- /* only switch when... */
- if (!(t->options & CTX_TEXTURE)) {
- if (ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
+ break;
+ case ESCKEY:
+ t->state = TRANS_CANCEL;
+ handled = true;
+ break;
+ case PADENTER:
+ case RETKEY:
+ t->state = TRANS_CONFIRM;
+ handled = true;
+ break;
+ case GKEY:
+ /* only switch when... */
+ if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
resetTransModal(t);
resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initTranslation(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case SKEY:
+ /* only switch when... */
+ if (ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initResize(t);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case RKEY:
+ /* only switch when... */
+ if (!(t->options & CTX_TEXTURE)) {
+ if (ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
+ resetTransModal(t);
+ resetTransRestrictions(t);
- if (t->mode == TFM_ROTATION) {
- restoreTransObjects(t);
- initTrackball(t);
- }
- else {
- restoreTransObjects(t);
- initRotation(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 |= TREDRAW_HARD;
+ handled = true;
}
- initSnapping(t, NULL); // need to reinit after mode change
+ }
+ break;
+ case CKEY:
+ if (event->alt) {
+ t->flag ^= T_PROP_CONNECTED;
+ sort_trans_data_dist(t);
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ else {
+ stopConstraint(t);
t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case XKEY:
+ case YKEY:
+ case ZKEY:
+ transform_event_xyz_constraint(t, event->type, cmode);
+ handled = true;
+ break;
+ case OKEY:
+ if (t->flag & T_PROP_EDIT && event->shift) {
+ t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
+ calculatePropRatio(t);
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PADPLUSKEY:
+ if (event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size *= 1.1f;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PAGEUPKEY:
+ case WHEELDOWNMOUSE:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, 1);
+ }
+ else {
+ view_editmove(event->type);
}
- }
- break;
- case CKEY:
- if (event->alt) {
- t->flag ^= T_PROP_CONNECTED;
- sort_trans_data_dist(t);
- calculatePropRatio(t);
t->redraw = TREDRAW_HARD;
- }
- else {
- stopConstraint(t);
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case XKEY:
- case YKEY:
- case ZKEY:
- transform_event_xyz_constraint(t, event->type, cmode);
- break;
- case OKEY:
- if (t->flag & T_PROP_EDIT && event->shift) {
- t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
- calculatePropRatio(t);
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case PADPLUSKEY:
- if (event->alt && t->flag & T_PROP_EDIT) {
- t->prop_size *= 1.1f;
- if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
- t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
- calculatePropRatio(t);
- }
- t->redraw = TREDRAW_HARD;
- break;
- case PAGEUPKEY:
- case WHEELDOWNMOUSE:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, 1);
- }
- else {
- view_editmove(event->type);
- }
- t->redraw = TREDRAW_HARD;
- break;
- case PADMINUS:
- if (event->alt && t->flag & T_PROP_EDIT) {
- t->prop_size *= 0.90909090f;
- calculatePropRatio(t);
- }
- t->redraw = TREDRAW_HARD;
- break;
- case PAGEDOWNKEY:
- case WHEELUPMOUSE:
- if (t->flag & T_AUTOIK) {
- transform_autoik_update(t, -1);
- }
- else {
- view_editmove(event->type);
- }
- t->redraw = TREDRAW_HARD;
- break;
- case LEFTALTKEY:
- case RIGHTALTKEY:
- if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
- t->flag |= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- }
-
- break;
- default:
- handled = 0;
- break;
- }
+ handled = true;
+ break;
+ case PADMINUS:
+ if (event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size *= 0.90909090f;
+ calculatePropRatio(t);
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ case PAGEDOWNKEY:
+ case WHEELUPMOUSE:
+ if (t->flag & T_AUTOIK) {
+ transform_autoik_update(t, -1);
+ }
+ else {
+ view_editmove(event->type);
+ }
+ t->redraw = TREDRAW_HARD;
+ handled = true;
+ break;
+ case LEFTALTKEY:
+ case RIGHTALTKEY:
+ if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
+ t->flag |= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ break;
+ default:
+ break;
+ }
- /* Numerical input events */
- if (handleNumInput(&(t->num), event)) {
- t->redraw |= TREDRAW_HARD;
+ /* Numerical input events */
+ if (!handled && handleNumInput(t->context, &(t->num), event)) {
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
}
/* Snapping key events */
t->redraw |= handleSnapping(t, event);
-
}
else if (event->val == KM_RELEASE) {
switch (event->type) {
@@ -1412,6 +1469,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
case RIGHTSHIFTKEY:
t->modifiers &= ~MOD_CONSTRAINT_PLANE;
t->redraw |= TREDRAW_HARD;
+ handled = true;
break;
case MIDDLEMOUSE:
@@ -1419,6 +1477,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->modifiers &= ~MOD_CONSTRAINT_SELECT;
postSelectConstraint(t);
t->redraw |= TREDRAW_HARD;
+ handled = true;
}
break;
case LEFTALTKEY:
@@ -1426,11 +1485,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
t->flag &= ~T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
+ handled = true;
}
-
break;
default:
- handled = 0;
break;
}
@@ -1442,8 +1500,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
}
- else
- handled = 0;
// Per transform event, if present
if (t->handleEvent)
@@ -2706,8 +2762,12 @@ static void initBend(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
-
- t->num.increment = 1.0f;
+
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
+ t->num.unit_type[1] = B_UNIT_LENGTH;
t->flag |= T_NO_CONSTRAINT;
@@ -2795,7 +2855,6 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
&c[0], &c[NUM_STR_REP_LEN],
WM_bool_as_string(is_clamp));
- values.angle = DEG2RADF(values.angle);
values.scale = values.scale / data->warp_init_dist;
}
else {
@@ -2896,8 +2955,10 @@ static void initShear(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
- t->num.increment = 0.1f;
+
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE; /* Don't think we have any unit here? */
t->flag |= T_NO_CONSTRAINT;
}
@@ -3028,11 +3089,15 @@ static void initResize(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
- t->num.flag |= NUM_NULL_ONE;
+ t->num.val_flag[0] |= NUM_NULL_ONE;
+ t->num.val_flag[1] |= NUM_NULL_ONE;
+ t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if (!t->obedit) {
t->flag |= T_NO_ZERO;
- t->num.flag |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[1] |= NUM_NO_ZERO;
+ t->num.val_flag[2] |= NUM_NO_ZERO;
}
t->idx_max = 2;
@@ -3041,7 +3106,11 @@ static void initResize(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
+ t->num.unit_type[2] = B_UNIT_NONE;
}
static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
@@ -3313,11 +3382,15 @@ static void initSkinResize(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
- t->num.flag |= NUM_NULL_ONE;
+ t->num.val_flag[0] |= NUM_NULL_ONE;
+ t->num.val_flag[1] |= NUM_NULL_ONE;
+ t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if (!t->obedit) {
t->flag |= T_NO_ZERO;
- t->num.flag |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
+ t->num.val_flag[1] |= NUM_NO_ZERO;
+ t->num.val_flag[2] |= NUM_NO_ZERO;
}
t->idx_max = 2;
@@ -3326,7 +3399,11 @@ static void initSkinResize(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
+ t->num.unit_type[2] = B_UNIT_NONE;
}
static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
@@ -3415,9 +3492,11 @@ static void initToSphere(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
- t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
+ t->num.val_flag[0] |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
// Calculate average radius
@@ -3517,7 +3596,10 @@ static void initRotation(TransInfo *t)
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
- t->num.increment = 1.0f;
+ copy_v3_fl(t->num.val_inc, t->snap[2]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
@@ -3808,8 +3890,8 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
- /* Clamp between -180 and 180 */
- final = angle_wrap_rad(DEG2RADF(final));
+ /* Clamp between -PI and PI */
+ final = angle_wrap_rad(final);
}
else {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %.2f%s %s"),
@@ -3850,7 +3932,11 @@ static void initTrackball(TransInfo *t)
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
- t->num.increment = 1.0f;
+ copy_v3_fl(t->num.val_inc, t->snap[2]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
+ t->num.unit_type[1] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT;
}
@@ -3911,9 +3997,6 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"),
&c[0], &c[NUM_STR_REP_LEN], t->proptext);
-
- phi[0] = DEG2RADF(phi[0]);
- phi[1] = DEG2RADF(phi[1]);
}
else {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %.2f %.2f %s"),
@@ -3987,7 +4070,12 @@ static void initTranslation(TransInfo *t)
t->snap[1] = t->snap[2] = 1.0f;
}
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_LENGTH;
+ t->num.unit_type[1] = B_UNIT_LENGTH;
+ t->num.unit_type[2] = B_UNIT_LENGTH;
+
}
static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
@@ -4215,7 +4303,9 @@ static void initShrinkFatten(TransInfo *t)
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_LENGTH;
t->flag |= T_NO_CONSTRAINT;
}
@@ -4309,7 +4399,10 @@ static void initTilt(TransInfo *t)
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[2]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -4336,8 +4429,6 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
- final = DEG2RADF(final);
-
/* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */
t->values[0] = final;
}
@@ -4383,10 +4474,12 @@ static void initCurveShrinkFatten(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
- t->num.flag |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
t->flag |= T_NO_CONSTRAINT;
}
@@ -4456,10 +4549,12 @@ static void initMaskShrinkFatten(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_ZERO;
- t->num.flag |= NUM_NO_ZERO;
+ t->num.val_flag[0] |= NUM_NO_ZERO;
t->flag |= T_NO_CONSTRAINT;
}
@@ -4550,7 +4645,9 @@ static void initPushPull(TransInfo *t)
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_LENGTH;
}
@@ -4639,7 +4736,9 @@ static void initBevelWeight(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -4716,7 +4815,9 @@ static void initCrease(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -4792,13 +4893,19 @@ static void initBoneSize(TransInfo *t)
t->idx_max = 2;
t->num.idx_max = 2;
- t->num.flag |= NUM_NULL_ONE;
+ t->num.val_flag[0] |= NUM_NULL_ONE;
+ t->num.val_flag[1] |= NUM_NULL_ONE;
+ t->num.val_flag[2] |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
+ t->num.unit_type[2] = B_UNIT_NONE;
}
static void headerBoneSize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
@@ -4919,7 +5026,9 @@ static void initBoneEnvelope(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -5864,7 +5973,9 @@ static void initEdgeSlide(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -6370,7 +6481,9 @@ static void initVertSlide(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -6626,7 +6739,10 @@ static void initBoneRoll(TransInfo *t)
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
- t->num.increment = 1.0f;
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
+ t->num.unit_type[0] = B_UNIT_ROTATION;
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
@@ -6651,8 +6767,6 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]);
-
- final = DEG2RADF(final);
}
else {
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %.2f"), RAD2DEGF(final));
@@ -6693,7 +6807,9 @@ static void initBakeTime(TransInfo *t)
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE; /* Don't think this uses units? */
}
static void applyBakeTime(TransInfo *t, const int mval[2])
@@ -6920,7 +7036,11 @@ static void initSeqSlide(TransInfo *t)
t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
t->snap[2] = 10.0f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ /* Would be nice to have a time handling in units as well (supporting frames in addition to "natural" time...). */
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
}
static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN])
@@ -7187,7 +7307,10 @@ static void initTimeTranslate(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ /* No time unit supporting frames currently... */
+ t->num.unit_type[0] = B_UNIT_NONE;
}
static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
@@ -7346,7 +7469,10 @@ static void initTimeSlide(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ /* No time unit supporting frames currently... */
+ t->num.unit_type[0] = B_UNIT_NONE;
}
static void headerTimeSlide(TransInfo *t, float sval, char str[MAX_INFO_LEN])
@@ -7481,7 +7607,7 @@ static void initTimeScale(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
- t->num.flag |= NUM_NULL_ONE;
+ t->num.val_flag[0] |= NUM_NULL_ONE;
/* num-input has max of (n-1) */
t->idx_max = 0;
@@ -7492,7 +7618,9 @@ static void initTimeScale(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
- t->num.increment = t->snap[1];
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
}
static void headerTimeScale(TransInfo *t, char str[MAX_INFO_LEN])
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 6c0bf92a484..89d1bc7acdf 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -98,4 +98,9 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_PYTHON)
+ add_definitions(-DWITH_PYTHON)
+ set(INC ${INC} ../../python)
+endif()
+
blender_add_lib(bf_editor_util "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript
index 223ee5731f1..0876fe48c91 100644
--- a/source/blender/editors/util/SConscript
+++ b/source/blender/editors/util/SConscript
@@ -46,4 +46,8 @@ incs = [
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
+if env['WITH_BF_PYTHON']:
+ defs.append('WITH_PYTHON')
+ incs.append('../../python')
+
env.BlenderLib ( 'bf_editors_util', sources, incs, defines=defs, libtype=['core','player'], priority=[330,210] )
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 0feaf936172..891051185ac 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -24,93 +24,97 @@
* \ingroup edutil
*/
-
-#include <math.h> /* fabs */
-#include <stdio.h> /* for size_t */
+#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_string_cursor_utf8.h"
+
+#include "BKE_context.h"
+#include "BKE_unit.h"
+
+#include "DNA_scene_types.h"
+#include "WM_api.h"
#include "WM_types.h"
+#ifdef WITH_PYTHON
+#include "BPY_extern.h"
+#endif
+
#include "ED_numinput.h"
+
+/* NumInput.val_flag[] */
+enum {
+ /* (1 << 8) and below are reserved for public flags! */
+ NUM_EDITED = (1 << 9), /* User has edited this value somehow. */
+ NUM_INVALID = (1 << 10), /* Current expression for this value is invalid. */
+};
+
/* ************************** Functions *************************** */
/* ************************** NUMINPUT **************************** */
void initNumInput(NumInput *n)
{
- n->flag =
- n->idx =
- n->idx_max =
- n->inv[0] =
- n->inv[1] =
- n->inv[2] =
- n->ctrl[0] =
- n->ctrl[1] =
- n->ctrl[2] = 0;
-
- n->val[0] =
- n->val[1] =
- n->val[2] = 0.0f;
+ n->unit_sys = USER_UNIT_NONE;
+ n->unit_type[0] = n->unit_type[1] = n->unit_type[2] = B_UNIT_NONE;
+ n->idx = 0;
+ n->idx_max = 0;
+ n->flag = 0;
+ n->val_flag[0] = n->val_flag[1] = n->val_flag[2] = 0;
+ zero_v3(n->val_org);
+ zero_v3(n->val);
+ n->str[0] = '\0';
+ n->str_cur = 0;
+ copy_v3_fl(n->val_inc, 1.0f);
}
+/* str must be NUM_STR_REP_LEN * (idx_max + 1) length. */
void outputNumInput(NumInput *n, char *str)
{
- char cur;
- char inv[] = "1/";
short i, j;
const int ln = NUM_STR_REP_LEN;
+ const int prec = 4; /* draw-only, and avoids too much issues with radian->degrees conversion. */
for (j = 0; j <= n->idx_max; j++) {
/* if AFFECTALL and no number typed and cursor not on number, use first number */
- if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
- i = 0;
- else
- i = j;
-
- if (n->idx != i)
- cur = ' ';
- else
- cur = '|';
-
- if (n->inv[i])
- inv[0] = '1';
- else
- inv[0] = 0;
-
- if (n->val[i] > 1e10f || n->val[i] < -1e10f)
- BLI_snprintf(&str[j * ln], ln, "%s%.4e%c", inv, n->val[i], cur);
- else
- switch (n->ctrl[i]) {
- case 0:
- BLI_snprintf(&str[j * ln], ln, "%sNONE%c", inv, cur);
- break;
- case 1:
- case -1:
- BLI_snprintf(&str[j * ln], ln, "%s%.0f%c", inv, n->val[i], cur);
- break;
- case 10:
- case -10:
- BLI_snprintf(&str[j * ln], ln, "%s%.f.%c", inv, n->val[i], cur);
- break;
- case 100:
- case -100:
- BLI_snprintf(&str[j * ln], ln, "%s%.1f%c", inv, n->val[i], cur);
- break;
- case 1000:
- case -1000:
- BLI_snprintf(&str[j * ln], ln, "%s%.2f%c", inv, n->val[i], cur);
- break;
- case 10000:
- case -10000:
- BLI_snprintf(&str[j * ln], ln, "%s%.3f%c", inv, n->val[i], cur);
- break;
- default:
- BLI_snprintf(&str[j * ln], ln, "%s%.4e%c", inv, n->val[i], cur);
- break;
+ i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
+
+ if (n->val_flag[i] & NUM_EDITED) {
+ if (i == n->idx && n->str[0]) {
+ char before_cursor[NUM_STR_REP_LEN];
+ char val[16];
+ if (n->val_flag[i] & NUM_INVALID) {
+ BLI_strncpy(val, "Invalid", sizeof(val));
+ }
+ else {
+ bUnit_AsString(val, sizeof(val), (double)n->val[i], prec,
+ n->unit_sys, n->unit_type[i], true, false);
+ }
+ BLI_strncpy(before_cursor, n->str, n->str_cur + 1); /* +1 because of trailing '\0' */
+ BLI_snprintf(&str[j * ln], ln, "[%s|%s] = %s", before_cursor, &n->str[n->str_cur], val);
}
+ else {
+ const char *cur = (i == n->idx) ? "|" : "";
+ if (n->unit_use_radians && n->unit_type[i] == B_UNIT_ROTATION) {
+ /* Radian exception... */
+ BLI_snprintf(&str[j * ln], ln, "%s%.6gr%s", cur, n->val[i], cur);
+ }
+ else {
+ char tstr[NUM_STR_REP_LEN];
+ bUnit_AsString(tstr, ln, (double)n->val[i], prec, n->unit_sys, n->unit_type[i], true, false);
+ BLI_snprintf(&str[j * ln], ln, "%s%s%s", cur, tstr, cur);
+ }
+ }
+ }
+ else {
+ const char *cur = (i == n->idx) ? "|" : "";
+ BLI_snprintf(&str[j * ln], ln, "%sNONE%s", cur, cur);
+ }
}
}
@@ -119,8 +123,9 @@ bool hasNumInput(const NumInput *n)
short i;
for (i = 0; i <= n->idx_max; i++) {
- if (n->ctrl[i])
+ if (n->val_flag[i] & NUM_EDITED) {
return true;
+ }
}
return false;
@@ -132,177 +137,247 @@ bool hasNumInput(const NumInput *n)
void applyNumInput(NumInput *n, float *vec)
{
short i, j;
+ float val;
if (hasNumInput(n)) {
for (j = 0; j <= n->idx_max; j++) {
/* if AFFECTALL and no number typed and cursor not on number, use first number */
- if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
- i = 0;
- else
- i = j;
+ i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
+ val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i];
- if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
- vec[j] = 1.0f;
+ if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) {
+ val = 0.0f;
}
- else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
- vec[j] = 0.0001f;
+ if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
+ val = 0.0001f;
}
- else {
- if (n->inv[i]) {
- vec[j] = 1.0f / n->val[i];
- }
- else {
- vec[j] = n->val[i];
+ if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) {
+ val = floorf(val + 0.5f);
+ if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
+ val = 1.0f;
}
}
+ vec[j] = val;
}
}
}
-bool handleNumInput(NumInput *n, const wmEvent *event)
+
+static void value_to_editstr(NumInput *n, int idx)
{
- float Val = 0;
- short idx = n->idx, idx_max = n->idx_max;
+ const int prec = 6; /* editing, higher precision needed. */
+ bUnit_AsString(n->str, NUM_STR_REP_LEN, (double)n->val[idx], prec,
+ n->unit_sys, n->unit_type[idx], true, false);
+ n->str_cur = strlen(n->str);
+}
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case NUM_MODAL_INCREMENT_UP:
- if (!n->ctrl[idx])
- n->ctrl[idx] = 1;
+static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf_len)
+{
+ int cur = n->str_cur;
+ int len = strlen(&n->str[cur]) + 1; /* +1 for the trailing '\0'. */
+ int n_cur = cur + buf_len;
- n->val[idx] += n->increment;
- break;
- case NUM_MODAL_INCREMENT_DOWN:
- if (!n->ctrl[idx])
- n->ctrl[idx] = 1;
+ if (n_cur + len >= NUM_STR_REP_LEN) {
+ return false;
+ }
+
+ memmove(&n->str[n_cur], &n->str[cur], len);
+ memcpy(&n->str[cur], buf, sizeof(char) * buf_len);
+
+ n->str_cur = n_cur;
+ return true;
+}
+
+bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
+{
+ const char *utf8_buf = NULL;
+ char ascii[2] = {'\0', '\0'};
+ bool updated = false;
+ short idx = n->idx, idx_max = n->idx_max;
+ short dir = STRCUR_DIR_NEXT, mode = STRCUR_JUMP_NONE;
+ int cur;
+ double val;
- n->val[idx] -= n->increment;
+ switch (event->type) {
+ case EVT_MODAL_MAP:
+ if (ELEM(event->val, NUM_MODAL_INCREMENT_UP, NUM_MODAL_INCREMENT_DOWN)) {
+ n->val[idx] += (event->val == NUM_MODAL_INCREMENT_UP) ? n->val_inc[idx] : -n->val_inc[idx];
+ value_to_editstr(n, idx);
+ n->val_flag[idx] |= NUM_EDITED;
+ updated = true;
+ }
+ else {
+ /* might be a char too... */
+ utf8_buf = event->utf8_buf;
+ ascii[0] = event->ascii;
+ }
+ break;
+ case BACKSPACEKEY:
+ /* Part specific to backspace... */
+ if (!(n->val_flag[idx] & NUM_EDITED)) {
+ copy_v3_v3(n->val, n->val_org);
+ n->val_flag[0] &= ~NUM_EDITED;
+ n->val_flag[1] &= ~NUM_EDITED;
+ n->val_flag[2] &= ~NUM_EDITED;
+ updated = true;
break;
- default:
- return 0;
- }
- }
- else {
- switch (event->type) {
- case BACKSPACEKEY:
- if (n->ctrl[idx] == 0) {
- n->val[0] =
- n->val[1] =
- n->val[2] = 0.0f;
- n->ctrl[0] =
- n->ctrl[1] =
- n->ctrl[2] = 0;
- n->inv[0] =
- n->inv[1] =
- n->inv[2] = 0;
- }
- else {
- n->val[idx] = 0.0f;
- n->ctrl[idx] = 0;
- n->inv[idx] = 0;
- }
+ }
+ else if (event->shift || !n->str[0]) {
+ n->val[idx] = n->val_org[idx];
+ n->val_flag[idx] &= ~NUM_EDITED;
+ n->str[0] = '\0';
+ n->str_cur = 0;
+ updated = true;
break;
- case PERIODKEY: case PADPERIOD:
- if (n->flag & NUM_NO_FRACTION)
- return 0;
-
- switch (n->ctrl[idx]) {
- case 0:
- case 1:
- n->ctrl[idx] = 10;
- break;
- case -1:
- n->ctrl[idx] = -10;
- break;
+ }
+ /* Else, common behavior with DELKEY, only difference is remove char(s) before/after the cursor. */
+ dir = STRCUR_DIR_PREV;
+ /* fall-through */
+ case DELKEY:
+ if ((n->val_flag[idx] & NUM_EDITED) && n->str[0]) {
+ int t_cur = cur = n->str_cur;
+ if (event->ctrl) {
+ mode = STRCUR_JUMP_DELIM;
}
- break;
- case PADMINUS:
- if (event->alt)
- break;
- /* fall-through */
- case MINUSKEY:
- if (n->flag & NUM_NO_NEGATIVE)
- return 0;
-
- if (n->ctrl[idx]) {
- n->ctrl[idx] *= -1;
- n->val[idx] *= -1;
+ BLI_str_cursor_step_utf8(n->str, strlen(n->str), &t_cur, dir, mode, true);
+ if (t_cur != cur) {
+ if (t_cur < cur) {
+ SWAP(int, t_cur, cur);
+ n->str_cur = cur;
+ }
+ memmove(&n->str[cur], &n->str[t_cur], strlen(&n->str[t_cur]) + 1); /* +1 for trailing '\0'. */
+ updated = true;
}
- else
- n->ctrl[idx] = -1;
- break;
- case PADSLASHKEY: case SLASHKEY:
- if (n->flag & NUM_NO_FRACTION)
- return 0;
+ }
+ else {
+ return false;
+ }
+ break;
+ case LEFTARROWKEY:
+ dir = STRCUR_DIR_PREV;
+ /* fall-through */
+ case RIGHTARROWKEY:
+ cur = n->str_cur;
+ if (event->ctrl) {
+ mode = STRCUR_JUMP_DELIM;
+ }
+ BLI_str_cursor_step_utf8(n->str, strlen(n->str), &cur, dir, mode, true);
+ if (cur != n->str_cur) {
+ n->str_cur = cur;
+ return true;
+ }
+ return false;
+ case HOMEKEY:
+ if (n->str[0]) {
+ n->str_cur = 0;
+ return true;
+ }
+ return false;
+ case ENDKEY:
+ if (n->str[0]) {
+ n->str_cur = strlen(n->str);
+ return true;
+ }
+ return false;
+ case TABKEY:
+ n->val_org[idx] = n->val[idx];
- n->inv[idx] = !n->inv[idx];
- break;
- case TABKEY:
- if (idx_max == 0)
- return 0;
-
- idx++;
- if (idx > idx_max)
- idx = 0;
- n->idx = idx;
+ idx += event->ctrl ? -1 : 1;
+ idx %= idx_max + 1;
+ n->idx = idx;
+ n->val[idx] = n->val_org[idx];
+ if (n->val_flag[idx] & NUM_EDITED) {
+ value_to_editstr(n, idx);
+ }
+ else {
+ n->str[0] = '\0';
+ n->str_cur = 0;
+ }
+ return true;
+ case CKEY:
+ if (event->ctrl) {
+ /* Copy current str to the copypaste buffer. */
+ WM_clipboard_text_set(n->str, 0);
+ updated = true;
break;
- case PAD9: case NINEKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD8: case EIGHTKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD7: case SEVENKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD6: case SIXKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD5: case FIVEKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD4: case FOURKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD3: case THREEKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD2: case TWOKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD1: case ONEKEY:
- Val += 1.0f;
- /* fall-through */
- case PAD0: case ZEROKEY:
- if (!n->ctrl[idx])
- n->ctrl[idx] = 1;
-
- if (fabsf(n->val[idx]) > 9999999.0f) {
- /* pass */
- }
- else if (n->ctrl[idx] == 1) {
- n->val[idx] *= 10;
- n->val[idx] += Val;
- }
- else if (n->ctrl[idx] == -1) {
- n->val[idx] *= 10;
- n->val[idx] -= Val;
- }
- else {
- /* float resolution breaks when over six digits after comma */
- if (ABS(n->ctrl[idx]) < 10000000) {
- n->val[idx] += Val / (float)n->ctrl[idx];
- n->ctrl[idx] *= 10;
+ }
+ /* fall-through */
+ case VKEY:
+ if (event->ctrl) {
+ /* extract the first line from the clipboard */
+ char *pbuf = WM_clipboard_text_get(0);
+
+ if (pbuf) {
+ bool success;
+ /* Only copy string until first of this char. */
+ char *cr = strchr(pbuf, '\r');
+ char *cn = strchr(pbuf, '\n');
+ if (cn && cn < cr) cr = cn;
+ if (cr) *cr = '\0';
+
+ success = editstr_insert_at_cursor(n, pbuf, strlen(pbuf));
+
+ MEM_freeN(pbuf);
+ if (!success) {
+ return false;
}
+
+ n->val_flag[idx] |= NUM_EDITED;
}
+ updated = true;
break;
- default:
- return 0;
+ }
+ /* fall-through */
+ default:
+ utf8_buf = event->utf8_buf;
+ ascii[0] = event->ascii;
+ break;
+ }
+
+ if (utf8_buf && !utf8_buf[0] && ascii[0]) {
+ /* Fallback to ascii. */
+ utf8_buf = ascii;
+ }
+
+ if (utf8_buf && utf8_buf[0]) {
+ if (!editstr_insert_at_cursor(n, utf8_buf, BLI_str_utf8_size(utf8_buf))) {
+ return false;
+ }
+
+ n->val_flag[idx] |= NUM_EDITED;
+ }
+ else if (!updated) {
+ return false;
+ }
+
+ /* At this point, our value has changed, try to interpret it with python (if str is not empty!). */
+ if (n->str[0]) {
+#ifdef WITH_PYTHON
+ char str_unit_convert[NUM_STR_REP_LEN * 6]; /* Should be more than enough! */
+ const char *default_unit = NULL;
+
+ /* Make radian default unit when needed. */
+ if (n->unit_use_radians && n->unit_type[idx] == B_UNIT_ROTATION)
+ default_unit = "r";
+
+ BLI_strncpy(str_unit_convert, n->str, sizeof(str_unit_convert));
+
+ bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), default_unit, 1.0,
+ n->unit_sys, n->unit_type[idx]);
+
+ /* Note: with angles, we always get values as radians here... */
+ if (BPY_button_exec(C, str_unit_convert, &val, false) != -1) {
+ n->val[idx] = (float)val;
+ n->val_flag[idx] &= ~NUM_INVALID;
+ }
+ else {
+ n->val_flag[idx] |= NUM_INVALID;
}
+#else /* Very unlikely, but does not harm... */
+ n->val[idx] = (float)atof(n->str);
+#endif /* WITH_PYTHON */
}
-
- // printf("%f\n", n->val[idx]);
/* REDRAW SINCE NUMBERS HAVE CHANGED */
- return 1;
+ return true;
}