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:
authorHoward Trickey <howard.trickey@gmail.com>2019-02-11 00:08:25 +0300
committerHoward Trickey <howard.trickey@gmail.com>2019-02-11 00:08:25 +0300
commit9ca6fc41ae7cc9d8e5ce89b10d1237c035ce5d63 (patch)
treee9ad91819dd5636ec9c09458dba5a76cd0372b31 /source/blender/editors/mesh/editmesh_bevel.c
parent09f45057124f70fac797859eb704989f094ca38e (diff)
Bevel: Make modal keymap instead of hardcoded.
Also added keys for toggling harden normals, and cycling through miter types. Still to do: add some shortcuts for affecting the spread value for arc miters.
Diffstat (limited to 'source/blender/editors/mesh/editmesh_bevel.c')
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c372
1 files changed, 243 insertions, 129 deletions
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index eb787a69d4e..29dde0e5200 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -50,6 +50,9 @@
#include "ED_transform.h"
#include "ED_view3d.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "mesh_intern.h" /* own include */
@@ -97,38 +100,97 @@ typedef struct {
float segments; /* Segments as float so smooth mouse pan works in small increments */
} BevelData;
+enum {
+ BEV_MODAL_CANCEL = 1,
+ BEV_MODAL_CONFIRM,
+ BEV_MODAL_VALUE_OFFSET,
+ BEV_MODAL_VALUE_PROFILE,
+ BEV_MODAL_VALUE_SEGMENTS,
+ BEV_MODAL_SEGMENTS_UP,
+ BEV_MODAL_SEGMENTS_DOWN,
+ BEV_MODAL_OFFSET_MODE_CHANGE,
+ BEV_MODAL_CLAMP_OVERLAP_TOGGLE,
+ BEV_MODAL_VERTEX_ONLY_TOGGLE,
+ BEV_MODAL_HARDEN_NORMALS_TOGGLE,
+ BEV_MODAL_MARK_SEAM_TOGGLE,
+ BEV_MODAL_MARK_SHARP_TOGGLE,
+ BEV_MODAL_OUTER_MITER_CHANGE,
+ BEV_MODAL_INNER_MITER_CHANGE,
+};
+
static void edbm_bevel_update_header(bContext *C, wmOperator *op)
{
- const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Mode: %s (M), Clamp Overlap: %s (C), "
- "Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d, Profile: %.3f");
-
- char msg[UI_MAX_DRAW_STR];
- ScrArea *sa = CTX_wm_area(C);
+ char header[UI_MAX_DRAW_STR];
+ char buf[UI_MAX_DRAW_STR];
+ char *p = buf;
+ int available_len = sizeof(buf);
Scene *sce = CTX_data_scene(C);
+ BevelData *opdata = op->customdata;
+ char offset_str[NUM_STR_REP_LEN];
+ const char *mode_str, *omiter_str, *imiter_str;
+ PropertyRNA *prop;
- if (sa) {
- BevelData *opdata = op->customdata;
- char offset_str[NUM_STR_REP_LEN];
- const char *type_str;
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset_type");
-
- if (hasNumInput(&opdata->num_input[OFFSET_VALUE])) {
- outputNumInput(&opdata->num_input[OFFSET_VALUE], offset_str, &sce->unit);
- }
- else {
- BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
- }
-
- RNA_property_enum_name_gettexted(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &type_str);
-
- BLI_snprintf(msg, sizeof(msg), str, type_str,
- WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
- WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")),
- WM_bool_as_string(opdata->value_mode == PROFILE_VALUE),
- offset_str, RNA_int_get(op->ptr, "segments"), RNA_float_get(op->ptr, "profile"));
+#define WM_MODALKEY(_id) \
+ WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
- ED_area_status_text(sa, msg);
+ if (hasNumInput(&opdata->num_input[OFFSET_VALUE])) {
+ outputNumInput(&opdata->num_input[OFFSET_VALUE], offset_str, &sce->unit);
+ }
+ else {
+ BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
}
+
+ prop = RNA_struct_find_property(op->ptr, "offset_type");
+ RNA_property_enum_name_gettexted(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &mode_str);
+ prop = RNA_struct_find_property(op->ptr, "miter_outer");
+ RNA_property_enum_name_gettexted(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &omiter_str);
+ prop = RNA_struct_find_property(op->ptr, "miter_inner");
+ RNA_property_enum_name_gettexted(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &imiter_str);
+
+ BLI_snprintf(header, sizeof(header),
+ IFACE_("%s: confirm, "
+ "%s: cancel, "
+ "%s: mode (%s), "
+ "%s: offset (%s), "
+ "%s: segments (%d), "
+ "%s: profile (%.3f), "
+ "%s: clamp overlap (%s), "
+ "%s: vertex only (%s), "
+ "%s: outer miter (%s), "
+ "%s: inner imter (%s), "
+ "%s: harden normals (%s), "
+ "%s: mark seam (%s), "
+ "%s: mark sharp (%s)"
+ ),
+ WM_MODALKEY(BEV_MODAL_CONFIRM),
+ WM_MODALKEY(BEV_MODAL_CANCEL),
+ WM_MODALKEY(BEV_MODAL_OFFSET_MODE_CHANGE),
+ mode_str,
+ WM_MODALKEY(BEV_MODAL_VALUE_OFFSET),
+ offset_str,
+ WM_MODALKEY(BEV_MODAL_VALUE_SEGMENTS),
+ RNA_int_get(op->ptr, "segments"),
+ WM_MODALKEY(BEV_MODAL_VALUE_PROFILE),
+ RNA_float_get(op->ptr, "profile"),
+ WM_MODALKEY(BEV_MODAL_CLAMP_OVERLAP_TOGGLE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
+ WM_MODALKEY(BEV_MODAL_VERTEX_ONLY_TOGGLE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")),
+ WM_MODALKEY(BEV_MODAL_OUTER_MITER_CHANGE),
+ omiter_str,
+ WM_MODALKEY(BEV_MODAL_INNER_MITER_CHANGE),
+ imiter_str,
+ WM_MODALKEY(BEV_MODAL_HARDEN_NORMALS_TOGGLE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "harden_normals")),
+ WM_MODALKEY(BEV_MODAL_MARK_SEAM_TOGGLE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_seam")),
+ WM_MODALKEY(BEV_MODAL_MARK_SHARP_TOGGLE),
+ WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_sharp"))
+ );
+
+#undef WM_MODALKEY
+
+ ED_workspace_status_text(C, header);
}
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
@@ -463,40 +525,96 @@ static void edbm_bevel_numinput_set_value(wmOperator *op)
}
}
+wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
+{
+ static const EnumPropertyItem modal_items[] = {
+ {BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"},
+ {BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"},
+ {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Value is offset",
+ "Value changes offset"},
+ {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Value is profile",
+ "Value changes profile"},
+ {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Value is segments",
+ "Value changes segments"},
+ {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase segments",
+ "Increase segments"},
+ {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease segments",
+ "Decrease segments"},
+ {BEV_MODAL_OFFSET_MODE_CHANGE, "OFFSET_MODE_CHANGE", 0, "Change offset mode",
+ "Cycle through offset modes"},
+ {BEV_MODAL_CLAMP_OVERLAP_TOGGLE, "CLAMP_OVERLAP_TOGGLE", 0, "Toggle clamp overlap",
+ "Toggle clamp overlap flag"},
+ {BEV_MODAL_VERTEX_ONLY_TOGGLE, "VERTEX_ONLY_TOGGLE", 0, "Toggle vertex only",
+ "Toggle vertex only flag"},
+ {BEV_MODAL_HARDEN_NORMALS_TOGGLE, "HARDEN_NORMALS_TOGGLE", 0, "Toggle harden normals",
+ "Toggle harden normals flag"},
+ {BEV_MODAL_MARK_SEAM_TOGGLE, "MARK_SEAM_TOGGLE", 0, "Toggle mark seam",
+ "Toggle mark seam flag"},
+ {BEV_MODAL_MARK_SHARP_TOGGLE, "MARK_SHARP_TOGGLE", 0, "Toggle mark sharp",
+ "Toggle mark sharp flag"},
+ {BEV_MODAL_OUTER_MITER_CHANGE, "OUTER_MITER_CHANGE", 0, "Change outer miter",
+ "Cycle through outer miter kinds"},
+ {BEV_MODAL_INNER_MITER_CHANGE, "INNER_MITER_CHANGE", 0, "Change inner miter",
+ "Cycle through inner miter kinds"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Bevel Modal Map");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items)
+ return NULL;
+
+ keymap = WM_modalkeymap_add(keyconf, "Bevel Modal Map", modal_items);
+
+ WM_modalkeymap_assign(keymap, "MESH_OT_bevel");
+
+ return keymap;
+}
+
static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
+ bool handled = false;
/* Modal numinput active, try to handle numeric inputs first... */
- if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+ if (event->type != EVT_MODAL_MAP && event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
edbm_bevel_numinput_set_value(op);
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
}
- else {
- bool handled = false;
- switch (event->type) {
- case ESCKEY:
- case RIGHTMOUSE:
+ else if (event->type == MOUSEMOVE) {
+ if (!has_numinput) {
+ edbm_bevel_mouse_set_value(op, event);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
+ }
+ }
+ else if (event->type == MOUSEPAN) {
+ float delta = 0.02f * (event->y - event->prevy);
+ if (opdata->segments >= 1 && opdata->segments + delta < 1)
+ opdata->segments = 1;
+ else
+ opdata->segments += delta;
+ RNA_int_set(op->ptr, "segments", (int)opdata->segments);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
+ }
+ else if (event->type == EVT_MODAL_MAP){
+ switch (event->val) {
+ case BEV_MODAL_CANCEL:
edbm_bevel_cancel(C, op);
return OPERATOR_CANCELLED;
- case MOUSEMOVE:
- if (!has_numinput) {
- edbm_bevel_mouse_set_value(op, event);
- edbm_bevel_calc(op);
- edbm_bevel_update_header(C, op);
- handled = true;
- }
- break;
-
- case LEFTMOUSE:
- case PADENTER:
- case RETKEY:
+ case BEV_MODAL_CONFIRM:
+#if 0
if ((event->val == KM_PRESS) ||
((event->val == KM_RELEASE) && RNA_boolean_get(op->ptr, "release_confirm")))
+#endif
{
edbm_bevel_calc(op);
edbm_bevel_exit(C, op);
@@ -504,29 +622,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
break;
- case MOUSEPAN: {
- float delta = 0.02f * (event->y - event->prevy);
- if (opdata->segments >= 1 && opdata->segments + delta < 1)
- opdata->segments = 1;
- else
- opdata->segments += delta;
- RNA_int_set(op->ptr, "segments", (int)opdata->segments);
- edbm_bevel_calc(op);
- edbm_bevel_update_header(C, op);
- handled = true;
- break;
- }
-
- /* 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 WHEELUPMOUSE: /* change number of segments */
- case PADPLUSKEY:
- if (event->val == KM_RELEASE)
- break;
-
+ case BEV_MODAL_SEGMENTS_UP:
opdata->segments = opdata->segments + 1;
RNA_int_set(op->ptr, "segments", (int)opdata->segments);
edbm_bevel_calc(op);
@@ -534,11 +630,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
handled = true;
break;
- case WHEELDOWNMOUSE: /* change number of segments */
- case PADMINUS:
- if (event->val == KM_RELEASE)
- break;
-
+ case BEV_MODAL_SEGMENTS_DOWN:
opdata->segments = max_ff(opdata->segments - 1, 1);
RNA_int_set(op->ptr, "segments", (int)opdata->segments);
edbm_bevel_calc(op);
@@ -546,13 +638,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
handled = true;
break;
- case MKEY:
- if (event->val == KM_RELEASE)
- break;
-
+ case BEV_MODAL_OFFSET_MODE_CHANGE:
{
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset_type");
- int type = RNA_property_enum_get(op->ptr, prop);
+ int type = RNA_enum_get(op->ptr, "offset_type");
type++;
if (type > BEVEL_AMT_PERCENT) {
type = BEVEL_AMT_OFFSET;
@@ -561,7 +649,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
opdata->value_mode = OFFSET_VALUE_PERCENT;
else if (opdata->value_mode == OFFSET_VALUE_PERCENT && type != BEVEL_AMT_PERCENT)
opdata->value_mode = OFFSET_VALUE;
- RNA_property_enum_set(op->ptr, prop, type);
+ RNA_enum_set(op->ptr, "offset_type", type);
if (opdata->initial_length[opdata->value_mode] == -1.0f)
edbm_bevel_calc_initial_length(op, event, true);
}
@@ -575,84 +663,110 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_bevel_update_header(C, op);
handled = true;
break;
- case CKEY:
- if (event->val == KM_RELEASE)
- break;
+ case BEV_MODAL_CLAMP_OVERLAP_TOGGLE:
{
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "clamp_overlap");
- RNA_property_boolean_set(op->ptr, prop, !RNA_property_boolean_get(op->ptr, prop));
- }
- edbm_bevel_calc(op);
- edbm_bevel_update_header(C, op);
- handled = true;
- break;
- case PKEY:
- if (event->val == KM_RELEASE)
+ bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
+ RNA_boolean_set(op->ptr, "clamp_overlap", !clamp_overlap);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
break;
- if (opdata->value_mode == PROFILE_VALUE) {
- opdata->value_mode = OFFSET_VALUE;
- }
- else {
- opdata->value_mode = PROFILE_VALUE;
}
+
+ case BEV_MODAL_VALUE_OFFSET:
+ opdata->value_mode = OFFSET_VALUE;
edbm_bevel_calc_initial_length(op, event, true);
break;
- case SKEY:
- if (event->val == KM_RELEASE)
- break;
- if (opdata->value_mode == SEGMENTS_VALUE) {
- opdata->value_mode = OFFSET_VALUE;
- }
- else {
- opdata->value_mode = SEGMENTS_VALUE;
- }
+
+ case BEV_MODAL_VALUE_PROFILE:
+ opdata->value_mode = PROFILE_VALUE;
edbm_bevel_calc_initial_length(op, event, true);
break;
- case VKEY:
- if (event->val == KM_RELEASE)
- break;
- {
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "vertex_only");
- RNA_property_boolean_set(op->ptr, prop, !RNA_property_boolean_get(op->ptr, prop));
- }
- edbm_bevel_calc(op);
- edbm_bevel_update_header(C, op);
- handled = true;
+ case BEV_MODAL_VALUE_SEGMENTS:
+ opdata->value_mode = SEGMENTS_VALUE;
+ edbm_bevel_calc_initial_length(op, event, true);
break;
- case UKEY:
- if (event->val == KM_RELEASE)
+
+ case BEV_MODAL_VERTEX_ONLY_TOGGLE:
+ {
+ bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
+ RNA_boolean_set(op->ptr, "vertex_only", !vertex_only);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
break;
- else {
+ }
+
+ case BEV_MODAL_MARK_SEAM_TOGGLE:
+ {
bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
RNA_boolean_set(op->ptr, "mark_seam", !mark_seam);
edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
handled = true;
break;
}
- case KKEY:
- if (event->val == KM_RELEASE)
- break;
- else {
+
+ case BEV_MODAL_MARK_SHARP_TOGGLE:
+ {
bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
RNA_boolean_set(op->ptr, "mark_sharp", !mark_sharp);
edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
handled = true;
break;
}
- }
+ case BEV_MODAL_INNER_MITER_CHANGE:
+ {
+ int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
+ miter_inner++;
+ if (miter_inner == BEVEL_MITER_PATCH)
+ miter_inner++; /* no patch option for inner miter */
+ if (miter_inner > BEVEL_MITER_ARC)
+ miter_inner = BEVEL_MITER_SHARP;
+ RNA_enum_set(op->ptr, "miter_inner", miter_inner);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
+ break;
+ }
- /* Modal numinput inactive, try to handle numeric inputs last... */
- if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
- edbm_bevel_numinput_set_value(op);
- edbm_bevel_calc(op);
- edbm_bevel_update_header(C, op);
- return OPERATOR_RUNNING_MODAL;
+ case BEV_MODAL_OUTER_MITER_CHANGE:
+ {
+ int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
+ miter_outer++;
+ if (miter_outer > BEVEL_MITER_ARC)
+ miter_outer = BEVEL_MITER_SHARP;
+ RNA_enum_set(op->ptr, "miter_outer", miter_outer);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
+ break;
+ }
+
+ case BEV_MODAL_HARDEN_NORMALS_TOGGLE:
+ {
+ bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
+ RNA_boolean_set(op->ptr, "harden_normals", !harden_normals);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ handled = true;
+ break;
+ }
}
}
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+ edbm_bevel_numinput_set_value(op);
+ edbm_bevel_calc(op);
+ edbm_bevel_update_header(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+
return OPERATOR_RUNNING_MODAL;
}