diff options
-rw-r--r-- | source/blender/editors/space_outliner/outliner.c | 150 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_ops.c | 13 |
3 files changed, 116 insertions, 50 deletions
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 4776b42b631..b6d1f31dd5c 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1528,7 +1528,7 @@ void outliner_toggle_selected(ARegion *ar, SpaceOops *soops) soops->storeflag |= SO_TREESTORE_REDRAW; } - +/* helper function for Show/Hide one level operator */ static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curlevel, int level, int open) { TreeElement *te; @@ -1548,6 +1548,44 @@ static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curleve } } +static int outliner_one_level_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + int add= RNA_boolean_get(op->ptr, "open"); + int level; + + level= outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1); + if(add==1) { + if(level) outliner_openclose_level(soops, &soops->tree, 1, level, 1); + } + else { + if(level==0) level= outliner_count_levels(soops, &soops->tree, 0); + if(level) outliner_openclose_level(soops, &soops->tree, 1, level-1, 0); + } + + // XXX need proper notifiers here instead + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_show_one_level(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show/Hide One Level"; + ot->idname= "OUTLINER_OT_show_one_level"; + + /* callbacks */ + ot->exec= outliner_one_level_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep."); +} + /* return 1 when levels were opened */ static int outliner_open_back(SpaceOops *soops, TreeElement *te) { @@ -1590,22 +1628,7 @@ static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *te } #endif -void outliner_one_level(SpaceOops *soops, int add) -{ - int level; - - level= outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1); - if(add==1) { - if(level) outliner_openclose_level(soops, &soops->tree, 1, level, 1); - } - else { - if(level==0) level= outliner_count_levels(soops, &soops->tree, 0); - if(level) outliner_openclose_level(soops, &soops->tree, 1, level-1, 0); - } - - BIF_undo_push("Outliner show/hide one level"); -} - +// XXX just use View2D ops for this? void outliner_page_up_down(Scene *scene, ARegion *ar, SpaceOops *soops, int up) { int dy= ar->v2d.mask.ymax-ar->v2d.mask.ymin; @@ -2235,6 +2258,7 @@ static int outliner_activate_click(bContext *C, wmOperator *op, wmEvent *event) BIF_undo_push("Outliner selection event"); } + // XXX need proper notifiers here instead ED_region_tag_redraw(ar); return OPERATOR_FINISHED; @@ -2302,53 +2326,57 @@ static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) return NULL; } -void outliner_show_active(Scene *scene, ARegion *ar, SpaceOops *so) +static int outliner_show_active_exec(bContext *C, wmOperator *op) { + SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + View2D *v2d= &ar->v2d; + TreeElement *te; int xdelta, ytop; - if(OBACT == NULL) return; + // TODO: make this get this info from context instead... + if (OBACT == NULL) + return OPERATOR_CANCELLED; te= outliner_find_id(so, &so->tree, (ID *)OBACT); - if(te) { + if (te) { /* make te->ys center of view */ - ytop= (int)(te->ys + (ar->v2d.mask.ymax-ar->v2d.mask.ymin)/2); - if(ytop>0) ytop= 0; - ar->v2d.cur.ymax= (float)ytop; - ar->v2d.cur.ymin= (float)(ytop-(ar->v2d.mask.ymax-ar->v2d.mask.ymin)); + ytop= (int)(te->ys + (v2d->mask.ymax - v2d->mask.ymin)/2); + if (ytop>0) ytop= 0; + + v2d->cur.ymax= (float)ytop; + v2d->cur.ymin= (float)(ytop-(v2d->mask.ymax - v2d->mask.ymin)); /* make te->xs ==> te->xend center of view */ - xdelta = (int)(te->xs - ar->v2d.cur.xmin); - ar->v2d.cur.xmin += xdelta; - ar->v2d.cur.xmax += xdelta; + xdelta = (int)(te->xs - v2d->cur.xmin); + v2d->cur.xmin += xdelta; + v2d->cur.xmax += xdelta; so->storeflag |= SO_TREESTORE_REDRAW; } + + // XXX need proper notifiers here instead + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; } -void outliner_show_selected(Scene *scene, ARegion *ar, SpaceOops *so) +void OUTLINER_OT_show_active(wmOperatorType *ot) { - TreeElement *te; - int xdelta, ytop; + /* identifiers */ + ot->name= "Show Active"; + ot->idname= "OUTLINER_OT_show_active"; + ot->description= "Adjust the view so that the active Object is shown centered."; - te= outliner_find_id(so, &so->tree, (ID *)OBACT); - if(te) { - /* make te->ys center of view */ - ytop= (int)(te->ys + (ar->v2d.mask.ymax-ar->v2d.mask.ymin)/2); - if(ytop>0) ytop= 0; - ar->v2d.cur.ymax= (float)ytop; - ar->v2d.cur.ymin= (float)(ytop-(ar->v2d.mask.ymax-ar->v2d.mask.ymin)); - - /* make te->xs ==> te->xend center of view */ - xdelta = (int)(te->xs - ar->v2d.cur.xmin); - ar->v2d.cur.xmin += xdelta; - ar->v2d.cur.xmax += xdelta; - - so->storeflag |= SO_TREESTORE_REDRAW; - } + /* callbacks */ + ot->exec= outliner_show_active_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } - /* find next element that has this name */ static TreeElement *outliner_find_named(SpaceOops *soops, ListBase *lb, char *name, int flags, TreeElement *prev, int *prevFound) { @@ -2488,6 +2516,7 @@ void outliner_find_panel(Scene *scene, ARegion *ar, SpaceOops *soops, int again, } } +/* helper function for tree_element_shwo_hierarchy() - recursively checks whether subtrees have any objects*/ static int subtree_has_objects(SpaceOops *soops, ListBase *lb) { TreeElement *te; @@ -2501,6 +2530,7 @@ static int subtree_has_objects(SpaceOops *soops, ListBase *lb) return 0; } +/* recursive helper function for Show Hierarchy operator */ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase *lb) { TreeElement *te; @@ -2521,19 +2551,39 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase } } else tselem->flag |= TSE_CLOSED; - + if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree); } - } /* show entire object level hierarchy */ -void outliner_show_hierarchy(Scene *scene, SpaceOops *soops) +static int outliner_show_hierarchy_exec(bContext *C, wmOperator *op) { + SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + /* recursively open/close levels */ tree_element_show_hierarchy(scene, soops, &soops->tree); - BIF_undo_push("Outliner show hierarchy"); + // XXX need proper notifiers here instead + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_show_hierarchy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show Hierarchy"; + ot->idname= "OUTLINER_OT_show_hierarchy"; + ot->description= "Open all object entries and close all others."; + + /* callbacks */ + ot->exec= outliner_show_hierarchy_exec; + ot->poll= ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views... + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } void outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting) diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 204298f2b70..263de4efc5b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -120,6 +120,9 @@ void outliner_select(struct SpaceOops *soops, struct ListBase *lb, int *index, s void draw_outliner(const struct bContext *C); void OUTLINER_OT_activate_click(struct wmOperatorType *ot); +void OUTLINER_OT_show_one_level(struct wmOperatorType *ot); +void OUTLINER_OT_show_active(struct wmOperatorType *ot); +void OUTLINER_OT_show_hierarchy(struct wmOperatorType *ot); void OUTLINER_OT_keyingset_add_selected(struct wmOperatorType *ot); void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 0efbdb06cd2..d07a3ea299e 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -45,6 +45,10 @@ void outliner_operatortypes(void) { WM_operatortype_append(OUTLINER_OT_activate_click); + WM_operatortype_append(OUTLINER_OT_show_one_level); + WM_operatortype_append(OUTLINER_OT_show_active); + WM_operatortype_append(OUTLINER_OT_show_hierarchy); + WM_operatortype_append(OUTLINER_OT_keyingset_add_selected); WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected); @@ -58,6 +62,15 @@ void outliner_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "OUTLINER_OT_activate_click", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "OUTLINER_OT_show_hierarchy", HOMEKEY, KM_PRESS, 0, 0); + + WM_keymap_verify_item(keymap, "OUTLINER_OT_show_active", PERIODKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "OUTLINER_OT_show_active", PADPERIOD, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADPLUSKEY, KM_PRESS, 0, 0); /* open */ + RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADMINUS, KM_PRESS, 0, 0)->ptr, "open", 0); /* close */ + + /* keying sets - only for databrowse */ WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_add_selected", KKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_remove_selected", KKEY, KM_PRESS, KM_ALT, 0); |