diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2019-02-11 00:08:25 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2019-02-11 00:08:25 +0300 |
commit | 9ca6fc41ae7cc9d8e5ce89b10d1237c035ce5d63 (patch) | |
tree | e9ad91819dd5636ec9c09458dba5a76cd0372b31 /source | |
parent | 09f45057124f70fac797859eb704989f094ca38e (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')
-rw-r--r-- | source/blender/editors/mesh/editmesh_bevel.c | 372 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 1 |
3 files changed, 245 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; } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index c430b023675..af939e2dc8d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -88,6 +88,7 @@ void MESH_OT_primitive_cube_add_gizmo(struct wmOperatorType *ot); /* *** editmesh_bevel.c *** */ void MESH_OT_bevel(struct wmOperatorType *ot); +struct wmKeyMap *bevel_modal_keymap(struct wmKeyConfig *keyconf); /* *** editmesh_bisect.c *** */ void MESH_OT_bisect(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 76de198ee00..53f45350851 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -320,4 +320,5 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) knifetool_modal_keymap(keyconf); point_normals_modal_keymap(keyconf); + bevel_modal_keymap(keyconf); } |