add an operator for mesh mode switching,
authorCampbell Barton <ideasman42@gmail.com>
Tue, 13 Nov 2012 05:44:49 +0000 (05:44 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 13 Nov 2012 05:44:49 +0000 (05:44 +0000)
this lets python menu for mode setting do mixed selection and extending the selection - just like the buttons in the header.

release/scripts/startup/bl_ui/space_view3d.py
source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/space_view3d/view3d_header.c

index b29f51d90a2eb18c0433e083d8eb24e3a6b310ca..dad3f4a72ef7e208ce18eb8758de668a04fca387 100644 (file)
@@ -1736,18 +1736,9 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
         layout = self.layout
 
         layout.operator_context = 'INVOKE_REGION_WIN'
-
-        props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
-        props.value = "(True, False, False)"
-        props.data_path = "tool_settings.mesh_select_mode"
-
-        props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
-        props.value = "(False, True, False)"
-        props.data_path = "tool_settings.mesh_select_mode"
-
-        props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
-        props.value = "(False, False, True)"
-        props.data_path = "tool_settings.mesh_select_mode"
+        layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
+        layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
+        layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
 
 
 class VIEW3D_MT_edit_mesh_extrude(Menu):
index 5ffcfbd94f0ca6208ec5ac98b1a1d8b5467c77d9..865da8f0e6e3085f2b7d5b94c3fee6b45576c440 100644 (file)
@@ -153,6 +153,11 @@ int  EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
 void EDBM_selectmode_set(struct BMEditMesh *em);
 void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new);
 
+/* user access this */
+int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
+                           const int action, const int use_extend, const int use_expand);
+
+
 void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
 
 void EDBM_select_toggle_all(struct BMEditMesh *em);
index 2acbbb6e006088d5d0d07d24f9635ad35aa5a0ca..5be03c50240fec559311cf3e6dc55db348b7d4b8 100644 (file)
@@ -56,6 +56,7 @@
 
 #include "ED_mesh.h"
 #include "ED_screen.h"
+#include "ED_util.h"
 #include "ED_uvedit.h"
 #include "ED_object.h"
 #include "ED_view3d.h"
@@ -68,6 +69,7 @@
 
 #include "mesh_intern.h"
 
+#include "UI_resources.h"
 
 /* ****************************** MIRROR **************** */
 
@@ -915,6 +917,74 @@ void MESH_OT_select_similar(wmOperatorType *ot)
        RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
 }
 
+
+/* ****************  Mode Select *************** */
+
+static int edbm_select_mode_exec(bContext *C, wmOperator *op)
+{
+       const int type       = RNA_enum_get(op->ptr,    "type");
+       const int action     = RNA_enum_get(op->ptr,    "action");
+       const int use_extend = RNA_boolean_get(op->ptr, "use_extend");
+       const int use_expand = RNA_boolean_get(op->ptr, "use_expand");
+
+       if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) {
+               return OPERATOR_FINISHED;
+       }
+       else {
+               return OPERATOR_CANCELLED;
+       }
+}
+
+static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       // RNA_enum_set(op->ptr, "type");  /* type must be set already */
+       RNA_boolean_set(op->ptr, "use_extend", event->shift);
+       RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
+       return edbm_select_mode_exec(C, op);
+}
+
+void MESH_OT_select_mode(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+
+       static EnumPropertyItem elem_items[] = {
+               {SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
+               {SCE_SELECT_EDGE,   "EDGE", ICON_EDGESEL, "Edges", ""},
+               {SCE_SELECT_FACE,   "FACE", ICON_FACESEL, "Faces", ""},
+               {0, NULL, 0, NULL, NULL},
+       };
+
+       static EnumPropertyItem actions_items[] = {
+               {0, "DISABLE", 0, "Disable", "Disable selected markers"},
+               {1, "ENABLE", 0, "Enable", "Enable selected markers"},
+               {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
+               {0, NULL, 0, NULL, NULL}
+       };
+
+       /* identifiers */
+       ot->name = "Select Mode";
+       ot->idname = "MESH_OT_select_mode";
+       ot->description = "Change selection mode";
+
+       /* api callbacks */
+       ot->invoke = edbm_select_mode_invoke;
+       ot->exec = edbm_select_mode_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", "");
+       RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+       prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", "");
+       RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+       ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", "");
+       RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+       RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
+}
+
 /* ***************************************************** */
 
 /* ****************  LOOP SELECTS *************** */
@@ -1926,6 +1996,101 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
        }
 }
 
+/* user facing function, does notification and undo push */
+int EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
+                           const int action, const int use_extend, const int use_expand)
+{
+       ToolSettings *ts = CTX_data_tool_settings(C);
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = NULL;
+       int ret = FALSE;
+
+       if (obedit && obedit->type == OB_MESH) {
+               em = BMEdit_FromObject(obedit);
+       }
+
+       if (em == NULL) {
+               return ret;
+       }
+
+       switch (action) {
+               case -1:
+                       /* already set */
+                       break;
+               case 0:  /* disable */
+                       /* check we have something to do */
+                       if ((em->selectmode & selectmode_new) == 0) {
+                               return FALSE;
+                       }
+                       em->selectmode &= ~selectmode_new;
+                       break;
+               case 1:  /* enable */
+                       /* check we have something to do */
+                       if ((em->selectmode & selectmode_new) != 0) {
+                               return FALSE;
+                       }
+                       em->selectmode |= selectmode_new;
+                       break;
+               case 2:  /* toggle */
+                       /* can't disable this flag if its the only one set */
+                       if (em->selectmode == selectmode_new) {
+                               return FALSE;
+                       }
+                       em->selectmode ^= selectmode_new;
+                       break;
+               default:
+                       BLI_assert(0);
+       }
+
+       switch (selectmode_new) {
+               case SCE_SELECT_VERTEX:
+                       if (use_extend == 0 || em->selectmode == 0)
+                               em->selectmode = SCE_SELECT_VERTEX;
+                       ts->selectmode = em->selectmode;
+                       EDBM_selectmode_set(em);
+                       ret = TRUE;
+                       break;
+               case SCE_SELECT_EDGE:
+                       if (use_extend == 0 || em->selectmode == 0) {
+                               if (use_expand) {
+                                       const short selmode_max = highest_order_bit_s(ts->selectmode);
+                                       if (selmode_max == SCE_SELECT_VERTEX) {
+                                               EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
+                                       }
+                               }
+                               em->selectmode = SCE_SELECT_EDGE;
+                       }
+                       ts->selectmode = em->selectmode;
+                       EDBM_selectmode_set(em);
+                       ret = TRUE;
+                       break;
+               case SCE_SELECT_FACE:
+                       if (use_extend == 0 || em->selectmode == 0) {
+                               if (use_expand) {
+                                       const short selmode_max = highest_order_bit_s(ts->selectmode);
+                                       if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
+                                               EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
+                                       }
+                               }
+
+                               em->selectmode = SCE_SELECT_FACE;
+                       }
+                       ts->selectmode = em->selectmode;
+                       EDBM_selectmode_set(em);
+                       ret = TRUE;
+                       break;
+               default:
+                       BLI_assert(0);
+                       break;
+       }
+
+       if (ret == TRUE) {
+               WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+               WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+       }
+
+       return ret;
+}
 
 void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
 {
index 82b785e5785b96434ccb1b0e5197c66ef787869b..8e63bd74ecea685c6ea90d55291dad2b02aa6e2a 100644 (file)
@@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
 void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
 void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
 void MESH_OT_select_similar(struct wmOperatorType *ot);
+void MESH_OT_select_mode(struct wmOperatorType *ot);
 void MESH_OT_select_random(struct wmOperatorType *ot);
 void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
 void MESH_OT_mark_seam(struct wmOperatorType *ot);
index d319fdcca262ddc242357ef5c2b718c904ad507b..91fb6e0c4874e36837f8e98fe86fe1844c572bb8 100644 (file)
@@ -129,6 +129,7 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_edge_face_add);
        WM_operatortype_append(MESH_OT_select_shortest_path);
        WM_operatortype_append(MESH_OT_select_similar);
+       WM_operatortype_append(MESH_OT_select_mode);
        WM_operatortype_append(MESH_OT_loop_multi_select);
        WM_operatortype_append(MESH_OT_mark_seam);
        WM_operatortype_append(MESH_OT_mark_sharp);
index 7acb371041ce85be1e908e23c7f7db1ee875ffd5..79bf003a5636c3a5d391c4d048dc6f1e7db9f394 100644 (file)
@@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
        return (string);
 }
 
-
 static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
 {
        wmWindow *win = CTX_wm_window(C);
-       ToolSettings *ts = CTX_data_tool_settings(C);
        ScrArea *sa = CTX_wm_area(C);
        View3D *v3d = sa->spacedata.first;
-       Object *obedit = CTX_data_edit_object(C);
-       BMEditMesh *em = NULL;
        const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
        PointerRNA props_ptr;
-       
-       if (obedit && obedit->type == OB_MESH) {
-               em = BMEdit_FromObject(obedit);
-       }
+
        /* watch it: if sa->win does not exist, check that when calling direct drawing routines */
 
        switch (event) {
@@ -336,47 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
                        break;
 
                case B_SEL_VERT:
-                       if (em) {
-                               if (shift == 0 || em->selectmode == 0)
-                                       em->selectmode = SCE_SELECT_VERTEX;
-                               ts->selectmode = em->selectmode;
-                               EDBM_selectmode_set(em);
-                               WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+                       if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
                                ED_undo_push(C, "Selectmode Set: Vertex");
                        }
                        break;
                case B_SEL_EDGE:
-                       if (em) {
-                               if (shift == 0 || em->selectmode == 0) {
-                                       if (ctrl) {
-                                               const short selmode_max = highest_order_bit_s(ts->selectmode);
-                                               if (selmode_max == SCE_SELECT_VERTEX) {
-                                                       EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
-                                               }
-                                       }
-                                       em->selectmode = SCE_SELECT_EDGE;
-                               }
-                               ts->selectmode = em->selectmode;
-                               EDBM_selectmode_set(em);
-                               WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+                       if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
                                ED_undo_push(C, "Selectmode Set: Edge");
                        }
                        break;
                case B_SEL_FACE:
-                       if (em) {
-                               if (shift == 0 || em->selectmode == 0) {
-                                       if (ctrl) {
-                                               const short selmode_max = highest_order_bit_s(ts->selectmode);
-                                               if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
-                                                       EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
-                                               }
-                                       }
-
-                                       em->selectmode = SCE_SELECT_FACE;
-                               }
-                               ts->selectmode = em->selectmode;
-                               EDBM_selectmode_set(em);
-                               WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+                       if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
                                ED_undo_push(C, "Selectmode Set: Face");
                        }
                        break;