diff options
author | Joshua Leung <aligorith@gmail.com> | 2014-10-23 07:13:48 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2014-10-23 07:13:48 +0400 |
commit | aadb8305b4dbbb02681772b8c8aeaeb02fdbaffc (patch) | |
tree | 53c11f73ecf63821c2f1bed09e4206bca7fa31b7 | |
parent | 516f55105295e7ccdbec7a6198634bdd1a5b4f91 (diff) |
Border Select for GPencil strokes
5 files changed, 133 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index b7253e00471..e46f7858362 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -109,6 +109,7 @@ class GreasePencilStrokeEditPanel(): subcol = col.column(align=True) subcol.active = edit_ok subcol.operator("gpencil.select_all", text="Select All") + subcol.operator("gpencil.select_border") subcol.operator("gpencil.select_circle") col.separator() @@ -156,6 +157,7 @@ class GPENCIL_PIE_tool_palette(Menu): # S - Select col = pie.column() col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT') + col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT') col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY') #col.operator("gpencil.select", text="Stroke Under Mouse").entire_strokes = True diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index c4a0d02b654..f2745f6f7f0 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -93,6 +93,7 @@ typedef enum eGPencil_PaintModes { void GPENCIL_OT_select(struct wmOperatorType *ot); void GPENCIL_OT_select_all(struct wmOperatorType *ot); void GPENCIL_OT_select_circle(struct wmOperatorType *ot); +void GPENCIL_OT_select_border(struct wmOperatorType *ot); void GPENCIL_OT_strokes_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index cae1d6431be..bda69fa1b57 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -116,6 +116,9 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) /* circle select */ WM_keymap_add_item(keymap, "GPENCIL_OT_select_circle", CKEY, KM_PRESS, 0, 0); + /* border select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0); + /* normal select */ WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); @@ -169,6 +172,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_select); WM_operatortype_append(GPENCIL_OT_select_all); WM_operatortype_append(GPENCIL_OT_select_circle); + WM_operatortype_append(GPENCIL_OT_select_border); WM_operatortype_append(GPENCIL_OT_strokes_copy); diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 3991ec31d30..a0d6d3a716e 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -388,6 +388,131 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot) } /* ********************************************** */ +/* Box Selection */ + +static int gpencil_border_select_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + View2D *v2d = &ar->v2d; + + const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + const bool select = (gesture_mode == GESTURE_MODAL_SELECT); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + + rcti rect; + + rctf *subrect = NULL; /* for using the camera rect within the 3d view */ + rctf subrect_data = {0.0f}; + + bool changed = false; + + + /* sanity checks */ + if (sa == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active area"); + return OPERATOR_CANCELLED; + } + + /* for 3D View, init depth buffer stuff used for 3D projections... */ + if (sa->spacetype == SPACE_VIEW3D) { + wmWindow *win = CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); + View3D *v3d = (View3D *)CTX_wm_space_data(C); + RegionView3D *rv3d = ar->regiondata; + + /* init 3d depth buffers */ + view3d_operator_needs_opengl(C); + view3d_region_operator_needs_opengl(win, ar); + ED_view3d_autodist_init(scene, ar, v3d, 0); + + /* for camera view set the subrect */ + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &subrect_data, true); /* no shift */ + subrect = &subrect_data; + } + } + + /* deselect all strokes first? */ + if (select && !extend) { + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + + gps->flag &= ~GP_STROKE_SELECT; + } + CTX_DATA_END; + } + + /* get settings from operator */ + WM_operator_properties_border_to_rcti(op, &rect); + + /* select/deselect points */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + int x0, y0; + + /* convert point coords to screenspace */ + gp_point_to_xy(ar, v2d, subrect, gps, pt, &x0, &y0); + + /* test if in selection rect */ + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) { + if (select) { + pt->flag |= GP_SPOINT_SELECT; + } + else { + pt->flag &= ~GP_SPOINT_SELECT; + } + + changed = true; + } + } + + /* Ensure that stroke selection is in sync with its points */ + gpencil_stroke_sync_selection(gps); + } + CTX_DATA_END; + + /* updates */ + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select Grease Pencil strokes within a rectangular region"; + ot->idname = "GPENCIL_OT_select_border"; + + /* callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = gpencil_border_select_exec; + ot->modal = WM_border_select_modal; + ot->cancel = WM_border_select_cancel; + + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* rna */ + WM_operator_properties_gesture_border(ot, true); +} + +/* ********************************************** */ /* Mouse Click to Select */ static int gpencil_select_exec(bContext *C, wmOperator *op) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e1bb8637b34..4cd53b705b0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -4742,6 +4742,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border"); /* XXX TODO: zoom border should perhaps map rightmouse to zoom out instead of in+cancel */ WM_modalkeymap_assign(keymap, "IMAGE_OT_render_border"); + WM_modalkeymap_assign(keymap, "GPENCIL_OT_select_border"); } /* zoom to border modal operators */ |