Index: source/blender/windowmanager/intern/wm_operators.c =================================================================== --- source/blender/windowmanager/intern/wm_operators.c (revision 43501) +++ source/blender/windowmanager/intern/wm_operators.c (working copy) @@ -3807,6 +3807,7 @@ WM_modalkeymap_assign(keymap, "MARKER_OT_select_border"); WM_modalkeymap_assign(keymap, "NLA_OT_select_border"); WM_modalkeymap_assign(keymap, "NODE_OT_select_border"); + WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border"); // WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template WM_modalkeymap_assign(keymap, "SEQUENCER_OT_select_border"); WM_modalkeymap_assign(keymap, "SEQUENCER_OT_view_ghost_border"); Index: source/blender/editors/space_outliner/outliner_select.c =================================================================== --- source/blender/editors/space_outliner/outliner_select.c (revision 43501) +++ source/blender/editors/space_outliner/outliner_select.c (working copy) @@ -55,6 +55,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math_base.h" +#include "BLI_rect.h" #if defined WIN32 && !defined _LIBC # include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ @@ -875,3 +876,92 @@ } /* ****************************************************** */ + +/* **************** Border Select Tool ****************** */ +static void outliner_item_border_select(Scene *scene, SpaceOops *soops, rctf *rectf, TreeElement *te, int gesture_mode) +{ + TreeStoreElem *tselem= TREESTORE(te); + Object *ob; + Base *base; + rctf iconrect; + + iconrect.xmin= te->xs + UI_UNIT_X; + iconrect.xmax= te->xs + 2.0f*UI_UNIT_X; + iconrect.ymin= te->ys; + iconrect.ymax= te->ys + UI_UNIT_Y; + + if(te->idcode == ID_OB) { + if(BLI_isect_rctf(rectf, &iconrect, NULL)) { + ob= (Object *)find_id("OB", te->name); + base= object_in_scene(ob, scene); + if(gesture_mode==GESTURE_MODAL_SELECT) { + if((base->flag & SELECT)==0) + ED_base_object_select(base, BA_SELECT); + } + else + if(base->flag & SELECT) { + base->flag= ob->flag &= ~SELECT; + } + } + } + + /* Look at its children. */ + if(((tselem->flag & TSE_CLOSED)==0) && (te->subtree.first)) { + for(te = te->subtree.first; te; te = te->next) { + outliner_item_border_select(scene, soops, rectf, te, gesture_mode); + } + } + return; +} + +static int outliner_border_select_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + TreeElement *te; + rcti rect; + rctf rectf; + int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); + + rect.xmin= RNA_int_get(op->ptr, "xmin"); + rect.ymin= RNA_int_get(op->ptr, "ymin"); + UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + + rect.xmax= RNA_int_get(op->ptr, "xmax"); + rect.ymax= RNA_int_get(op->ptr, "ymax"); + UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + for(te= soops->tree.first; te; te= te->next) { + outliner_item_border_select(scene, soops, &rectf, te, gesture_mode); + } + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Border Select"; + ot->idname= "OUTLINER_OT_select_border"; + ot->description= "Use box selection to select tree elements"; + + /* api callbacks */ + ot->invoke= WM_border_select_invoke; + ot->exec= outliner_border_select_exec; + ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; + + ot->poll= ED_operator_outliner_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* rna */ + WM_operator_properties_gesture_border(ot, FALSE); +} + +/* ****************************************************** */ Index: source/blender/editors/space_outliner/outliner_ops.c =================================================================== --- source/blender/editors/space_outliner/outliner_ops.c (revision 43501) +++ source/blender/editors/space_outliner/outliner_ops.c (working copy) @@ -49,6 +49,7 @@ void outliner_operatortypes(void) { WM_operatortype_append(OUTLINER_OT_item_activate); + WM_operatortype_append(OUTLINER_OT_select_border); WM_operatortype_append(OUTLINER_OT_item_openclose); WM_operatortype_append(OUTLINER_OT_item_rename); WM_operatortype_append(OUTLINER_OT_operation); @@ -89,6 +90,9 @@ RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); + + WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", EVT_TWEAK_L, KM_ANY, 0, 0)->ptr, "tweak", 1); kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "all", FALSE); Index: source/blender/editors/space_outliner/outliner_intern.h =================================================================== --- source/blender/editors/space_outliner/outliner_intern.h (revision 43501) +++ source/blender/editors/space_outliner/outliner_intern.h (working copy) @@ -167,6 +167,8 @@ int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set); int tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, int set); +void OUTLINER_OT_select_border(struct wmOperatorType *ot); + /* outliner_edit.c ---------------------------------------------- */ void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,