Tool System: uv lasso/box select options
authorCampbell Barton <ideasman42@gmail.com>
Fri, 23 Nov 2018 06:52:28 +0000 (17:52 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 23 Nov 2018 06:52:52 +0000 (17:52 +1100)
These tools now support (new, add, subtract),
(xor, and) could be supported but are complicated by UV's sticky
selection modes.

release/scripts/presets/keyconfig/keymap_data/blender_default.py
release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
source/blender/editors/uvedit/uvedit_ops.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_operator_props.c

index 87ee67c1408f78e57a8654ab06c2d0e2a7520abe..cb334daf6cab3e0158d28c1922e6f003becfe7de 100644 (file)
@@ -221,6 +221,17 @@ def _template_items_tool_select_actions(operator, *, type, value):
     ]
 
 
+def _template_items_tool_select_actions_simple(operator, *, type, value):
+    kmi_args = {"type": type, "value": value}
+    return [
+        (operator, kmi_args,
+         {"properties": [("mode", 'SET')]}),
+        (operator, {**kmi_args, "shift": True},
+         {"properties": [("mode", 'ADD')]}),
+        (operator, {**kmi_args, "ctrl": True},
+         {"properties": [("mode", 'SUB')]}),
+    ]
+
 # ------------------------------------------------------------------------------
 # Window, Screen, Areas, Regions
 
@@ -685,9 +696,9 @@ def km_uv_editor(params):
          {"properties": [("pinned", True)]}),
         ("uv.circle_select", {"type": 'C', "value": 'PRESS'}, None),
         ("uv.select_lasso", {"type": params.action_tweak, "value": 'ANY', "ctrl": True},
-         {"properties": [("deselect", False)]}),
+         {"properties": [("mode", 'ADD')]}),
         ("uv.select_lasso", {"type": params.action_tweak, "value": 'ANY', "shift": True, "ctrl": True},
-         {"properties": [("deselect", True)]}),
+         {"properties": [("mode", 'SUB')]}),
         ("uv.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True},
          {"properties": [("extend", True), ("deselect", False)]}),
         ("uv.select_linked_pick", {"type": 'L', "value": 'PRESS'},
@@ -4912,12 +4923,7 @@ def km_image_editor_tool_uv_select_box(params):
     return (
         "Image Editor Tool: Uv, Select Box",
         {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
-        {"items": (
-            ("uv.select_box", {"type": params.tool_tweak, "value": 'ANY'}, None),
-            ("uv.select_box", {"type": params.tool_tweak, "value": 'ANY', "ctrl": True},
-             {"properties": [("deselect", True)]}),
-        ),
-        },
+        {"items": _template_items_tool_select_actions_simple("uv.select_box", type=params.tool_tweak, value='ANY')},
     )
 
 
@@ -4939,11 +4945,7 @@ def km_image_editor_tool_uv_select_lasso(params):
     return (
         "Image Editor Tool: Uv, Select Lasso",
         {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
-        {"items": (
-            ("uv.select_lasso", {"type": params.tool_tweak, "value": 'ANY'},
-             {"properties": [("deselect", False)]}),
-        ),
-        },
+        {"items": _template_items_tool_select_actions_simple("uv.select_lasso", type=params.tool_tweak, value='ANY')},
     )
 
 
index fab001cdb5cc7327e01564b21cd84c23e5ad9095..53b6a7d0956bcb478e92f423cbe209b63625d506 100644 (file)
@@ -963,7 +963,7 @@ class _defs_image_uv_select:
     def border():
         def draw_settings(context, layout, tool):
             props = tool.operator_properties("uv.select_box")
-            layout.prop(props, "deselect")
+            layout.prop(props, "mode", expand=True)
         return dict(
             text="Select Box",
             icon="ops.generic.select_box",
@@ -974,11 +974,15 @@ class _defs_image_uv_select:
 
     @ToolDef.from_fn
     def lasso():
+        def draw_settings(context, layout, tool):
+            props = tool.operator_properties("uv.select_lasso")
+            layout.prop(props, "mode", expand=True)
         return dict(
             text="Select Lasso",
             icon="ops.generic.select_lasso",
             widget=None,
             keymap=(),
+            draw_settings=draw_settings,
         )
 
     @ToolDef.from_fn
index 2d9995d3cccb15e46ead83c9eb7d5a116fdb7ae8..30c0bc741c2260c64d4289976dac35e152e29f86 100644 (file)
@@ -3185,7 +3185,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
        BMIter iter, liter;
        MLoopUV *luv;
        rctf rectf;
-       bool pinned, select, extend;
+       bool pinned;
        const bool use_face_center = (
                (ts->uv_flag & UV_SYNC_SELECTION) ?
                (ts->selectmode == SCE_SELECT_FACE) :
@@ -3195,9 +3195,9 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
        WM_operator_properties_border_to_rctf(op, &rectf);
        UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
 
-       /* figure out what to select/deselect */
-       select = !RNA_boolean_get(op->ptr, "deselect");
-       extend = RNA_boolean_get(op->ptr, "extend");
+       const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+       const bool select = (sel_op != SEL_OP_SUB);
+
        pinned = RNA_boolean_get(op->ptr, "pinned");
 
        bool changed_multi = false;
@@ -3214,8 +3214,9 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
 
                const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
-               if (!extend)
+               if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
                        uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+               }
 
                /* do actual selection */
                if (use_face_center && !pinned) {
@@ -3308,7 +3309,8 @@ static void UV_OT_select_box(wmOperatorType *ot)
        /* properties */
        RNA_def_boolean(ot->srna, "pinned", 0, "Pinned", "Border select pinned UVs only");
 
-       WM_operator_properties_gesture_box_select(ot);
+       WM_operator_properties_gesture_box(ot);
+       WM_operator_properties_select_operation_simple(ot);
 }
 
 /** \} */
@@ -3454,8 +3456,9 @@ static void UV_OT_select_circle(wmOperatorType *ot)
 /** \name Lasso Select Operator
  * \{ */
 
-static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short moves,
-                                    const bool select, const bool extend)
+static bool do_lasso_select_mesh_uv(
+        bContext *C, const int mcords[][2], short moves,
+        const eSelectOp sel_op)
 {
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
        SpaceImage *sima = CTX_wm_space_image(C);
@@ -3468,7 +3471,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
                (ts->uv_flag & UV_SYNC_SELECTION) ?
                (ts->selectmode == SCE_SELECT_FACE) :
                (ts->uv_selectmode == UV_SELECT_FACE));
-
+       const bool select = (sel_op != SEL_OP_SUB);
 
        BMIter iter, liter;
 
@@ -3493,7 +3496,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
 
                const int cd_loop_uv_offset  = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
-               if (!extend && select) {
+               if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
                        uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
                }
 
@@ -3567,13 +3570,8 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op)
        const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
 
        if (mcords) {
-               bool select, extend;
-               bool changed;
-
-               select = !RNA_boolean_get(op->ptr, "deselect");
-               extend = RNA_boolean_get(op->ptr, "extend");
-               changed = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select, extend);
-
+               const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+               bool changed = do_lasso_select_mesh_uv(C, mcords, mcords_tot, sel_op);
                MEM_freeN((void *)mcords);
 
                return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
@@ -3598,7 +3596,8 @@ static void UV_OT_select_lasso(wmOperatorType *ot)
        ot->flag = OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_gesture_lasso_select(ot);
+       WM_operator_properties_gesture_lasso(ot);
+       WM_operator_properties_select_operation_simple(ot);
 }
 
 /** \} */
index 8e12ac96ea3ec9781542456f7bd8f8275e6b69ac..adf082982b786e880e78367be3c5d2af223fa889 100644 (file)
@@ -374,6 +374,7 @@ void        WM_operator_properties_select_action_simple(struct wmOperatorType *o
 void        WM_operator_properties_select_random(struct wmOperatorType *ot);
 int         WM_operator_properties_select_random_seed_increment_get(wmOperator *op);
 void        WM_operator_properties_select_operation(struct wmOperatorType *ot);
+void        WM_operator_properties_select_operation_simple(struct wmOperatorType *ot);
 struct CheckerIntervalParams {
        int nth;  /* bypass when set to zero */
        int skip;
index f8fa652ed6324d5167b26ac343fca6a03f3a545c..11aef46096a490a5ff75cd3af8aedcc0bb606ddd 100644 (file)
@@ -279,6 +279,19 @@ void WM_operator_properties_select_operation(wmOperatorType *ot)
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 }
 
+/* Some tools don't support XOR/END */
+void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
+{
+       static const EnumPropertyItem select_mode_items[] = {
+               {SEL_OP_SET, "SET", 0, "New", ""},
+               {SEL_OP_ADD, "ADD", 0, "Add", ""},
+               {SEL_OP_SUB, "SUB", 0, "Subtract", ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+       PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
+       RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
 void WM_operator_properties_gesture_box_zoom(wmOperatorType *ot)
 {
        WM_operator_properties_border(ot);