Outliner: Support box select on click+drag
This commit is contained in:
@@ -710,6 +710,11 @@ def km_outliner(params):
|
|||||||
("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True, "ctrl": True},
|
("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True, "ctrl": True},
|
||||||
{"properties": [("extend", True), ("recursive", True)]}),
|
{"properties": [("extend", True), ("recursive", True)]}),
|
||||||
("outliner.select_box", {"type": 'B', "value": 'PRESS'}, None),
|
("outliner.select_box", {"type": 'B', "value": 'PRESS'}, None),
|
||||||
|
("outliner.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("tweak", True)]}),
|
||||||
|
("outliner.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True},
|
||||||
|
{"properties": [("tweak", True), ("mode", "ADD")]}),
|
||||||
|
("outliner.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True},
|
||||||
|
{"properties": [("tweak", True), ("mode", "SUB")]}),
|
||||||
("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'UP')]}),
|
("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'UP')]}),
|
||||||
("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True},
|
("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True},
|
||||||
{"properties": [("direction", 'UP'), ("extend", True)]}),
|
{"properties": [("direction", 'UP'), ("extend", True)]}),
|
||||||
|
|||||||
@@ -895,6 +895,12 @@ static int outliner_item_drag_drop_invoke(bContext *C,
|
|||||||
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
|
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float view_mval[2];
|
||||||
|
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
|
||||||
|
if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
|
||||||
|
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
|
||||||
|
}
|
||||||
|
|
||||||
wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
|
wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
|
||||||
|
|
||||||
if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
|
if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
|
||||||
|
|||||||
@@ -1428,6 +1428,37 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op)
|
|||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find if x coordinate is over an icon or name */
|
||||||
|
static bool outliner_item_is_co_over_name_icons(TreeElement *te, float view_co_x)
|
||||||
|
{
|
||||||
|
/* Special case: count area left of Scene Collection as empty space */
|
||||||
|
bool outside_left = (TREESTORE(te)->type == TSE_VIEW_COLLECTION_BASE) ?
|
||||||
|
(view_co_x > te->xs + UI_UNIT_X) :
|
||||||
|
(view_co_x > te->xs);
|
||||||
|
|
||||||
|
return outside_left && (view_co_x < te->xend);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int outliner_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
|
{
|
||||||
|
SpaceOutliner *soops = CTX_wm_space_outliner(C);
|
||||||
|
ARegion *ar = CTX_wm_region(C);
|
||||||
|
float view_mval[2];
|
||||||
|
const bool tweak = RNA_boolean_get(op->ptr, "tweak");
|
||||||
|
|
||||||
|
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
|
||||||
|
|
||||||
|
/* Find element clicked on */
|
||||||
|
TreeElement *te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
|
||||||
|
|
||||||
|
/* Pass through if click is over name or icons, or not tweak event */
|
||||||
|
if (te && tweak && outliner_item_is_co_over_name_icons(te, view_mval[0])) {
|
||||||
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WM_gesture_box_invoke(C, op, event);
|
||||||
|
}
|
||||||
|
|
||||||
void OUTLINER_OT_select_box(wmOperatorType *ot)
|
void OUTLINER_OT_select_box(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
@@ -1436,7 +1467,7 @@ void OUTLINER_OT_select_box(wmOperatorType *ot)
|
|||||||
ot->description = "Use box selection to select tree elements";
|
ot->description = "Use box selection to select tree elements";
|
||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->invoke = WM_gesture_box_invoke;
|
ot->invoke = outliner_box_select_invoke;
|
||||||
ot->exec = outliner_box_select_exec;
|
ot->exec = outliner_box_select_exec;
|
||||||
ot->modal = WM_gesture_box_modal;
|
ot->modal = WM_gesture_box_modal;
|
||||||
ot->cancel = WM_gesture_box_cancel;
|
ot->cancel = WM_gesture_box_cancel;
|
||||||
@@ -1447,6 +1478,12 @@ void OUTLINER_OT_select_box(wmOperatorType *ot)
|
|||||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
prop = RNA_def_boolean(
|
||||||
|
ot->srna, "tweak", false, "Tweak", "Tweak gesture from empty space for box selection");
|
||||||
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
|
||||||
WM_operator_properties_gesture_box(ot);
|
WM_operator_properties_gesture_box(ot);
|
||||||
WM_operator_properties_select_operation_simple(ot);
|
WM_operator_properties_select_operation_simple(ot);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user