Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_outliner / space_outliner.c
index cb6d673..71ae7ee 100644 (file)
@@ -39,6 +39,7 @@
 #include "BLI_mempool.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_screen.h"
 #include "BKE_scene.h"
 #include "BKE_outliner_treehash.h"
@@ -47,6 +48,7 @@
 #include "ED_screen.h"
 
 #include "WM_api.h"
+#include "WM_message.h"
 #include "WM_types.h"
 
 #include "BIF_gl.h"
@@ -66,7 +68,7 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
 {
        ListBase *lb;
        wmKeyMap *keymap;
-       
+
        /* make sure we keep the hide flags */
        ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
        ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP);  /* prevent any noise of past */
@@ -79,7 +81,7 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
        ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
 
        UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-       
+
        /* own keymap */
        keymap = WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
        /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
@@ -102,10 +104,14 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
                if (GS(id->name) == ID_OB) {
                        /* Ensure item under cursor is valid drop target */
                        TreeElement *te = outliner_dropzone_find(soops, fmval, true);
+                       TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
 
-                       if (te && te->idcode == ID_OB && TREESTORE(te)->type == 0) {
+                       if (!te) {
+                               /* pass */
+                       }
+                       else if (te->idcode == ID_OB && tselem->type == 0) {
                                Scene *scene;
-                               ID *te_id = TREESTORE(te)->id;
+                               ID *te_id = tselem->id;
 
                                /* check if dropping self or parent */
                                if (te_id == id || (Object *)te_id == ((Object *)id)->parent)
@@ -118,9 +124,19 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
                                 * element for object it means that all displayed objects belong to
                                 * active scene and parenting them is allowed (sergey)
                                 */
-                               if (!scene || BKE_scene_base_find(scene, (Object *)id)) {
+                               if (!scene) {
                                        return 1;
                                }
+                               else {
+                                       for (ViewLayer *view_layer = scene->view_layers.first;
+                                            view_layer;
+                                            view_layer = view_layer->next)
+                                       {
+                                               if (BKE_view_layer_base_find(view_layer, (Object *)id)) {
+                                                       return 1;
+                                               }
+                                       }
+                               }
                        }
                }
        }
@@ -143,7 +159,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
 
        UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
 
-       if (!ELEM(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS)) {
+       if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) {
                return false;
        }
 
@@ -156,7 +172,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
 
                                        switch (te->idcode) {
                                                case ID_SCE:
-                                                       return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS));
+                                                       return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER));
                                                case ID_OB:
                                                        return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE));
                                                /* Other codes to ignore? */
@@ -230,7 +246,7 @@ static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop)
        RNA_string_set(drop->ptr, "material", id->name + 2);
 }
 
-static int outliner_group_link_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+static int outliner_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
 {
        ARegion *ar = CTX_wm_region(C);
        SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -239,19 +255,19 @@ static int outliner_group_link_poll(bContext *C, wmDrag *drag, const wmEvent *ev
 
        if (drag->type == WM_DRAG_ID) {
                ID *id = drag->poin;
-               if (GS(id->name) == ID_OB) {
+               if (ELEM(GS(id->name), ID_OB, ID_GR)) {
                        /* Ensure item under cursor is valid drop target */
                        TreeElement *te = outliner_dropzone_find(soops, fmval, true);
-                       return (te && te->idcode == ID_GR && TREESTORE(te)->type == 0);
+                       return (te && outliner_is_collection_tree_element(te));
                }
        }
        return 0;
 }
 
-static void outliner_group_link_copy(wmDrag *drag, wmDropBox *drop)
+static void outliner_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
        ID *id = drag->poin;
-       RNA_string_set(drop->ptr, "object", id->name + 2);
+       RNA_string_set(drop->ptr, "child", id->name + 2);
 }
 
 /* region dropbox definition */
@@ -263,23 +279,23 @@ static void outliner_dropboxes(void)
        WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy);
        WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy);
        WM_dropbox_add(lb, "OUTLINER_OT_material_drop", outliner_material_drop_poll, outliner_material_drop_copy);
-       WM_dropbox_add(lb, "OUTLINER_OT_group_link", outliner_group_link_poll, outliner_group_link_copy);
+       WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", outliner_collection_drop_poll, outliner_collection_drop_copy);
 }
 
 static void outliner_main_region_draw(const bContext *C, ARegion *ar)
 {
        View2D *v2d = &ar->v2d;
        View2DScrollers *scrollers;
-       
+
        /* clear */
        UI_ThemeClearColor(TH_BACK);
        glClear(GL_COLOR_BUFFER_BIT);
-       
+
        draw_outliner(C);
-       
+
        /* reset view matrix */
        UI_view2d_view_restore(C);
-       
+
        /* scrollers */
        scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
        UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -289,10 +305,12 @@ static void outliner_main_region_draw(const bContext *C, ARegion *ar)
 
 static void outliner_main_region_free(ARegion *UNUSED(ar))
 {
-       
+
 }
 
-static void outliner_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void outliner_main_region_listener(
+        bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+        wmNotifier *wmn, const Scene *UNUSED(scene))
 {
        /* context changes */
        switch (wmn->category) {
@@ -308,7 +326,9 @@ static void outliner_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s
                                case ND_RENDER_OPTIONS:
                                case ND_SEQUENCER:
                                case ND_LAYER:
+                               case ND_LAYER_CONTENT:
                                case ND_WORLD:
+                               case ND_SCENEBROWSE:
                                        ED_region_tag_redraw(ar);
                                        break;
                        }
@@ -392,8 +412,31 @@ static void outliner_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s
                        if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
                                ED_region_tag_redraw(ar);
                        break;
+               case NC_SCREEN:
+                       if (ELEM(wmn->data, ND_LAYER)) {
+                               ED_region_tag_redraw(ar);
+                       }
+                       break;
+       }
+
+}
+
+static void outliner_main_region_message_subscribe(
+        const struct bContext *UNUSED(C),
+        struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
+        struct bScreen *UNUSED(screen), struct ScrArea *sa, struct ARegion *ar,
+        struct wmMsgBus *mbus)
+{
+       SpaceOops *soops = sa->spacedata.first;
+       wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+               .owner = ar,
+               .user_data = ar,
+               .notify = ED_region_do_msg_notify_tag_redraw,
+       };
+
+       if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
+               WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
        }
-       
 }
 
 
@@ -414,7 +457,9 @@ static void outliner_header_region_free(ARegion *UNUSED(ar))
 {
 }
 
-static void outliner_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void outliner_header_region_listener(
+        bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+        wmNotifier *wmn, const Scene *UNUSED(scene))
 {
        /* context changes */
        switch (wmn->category) {
@@ -431,27 +476,28 @@ static void outliner_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED
 
 /* ******************** default callbacks for outliner space ***************** */
 
-static SpaceLink *outliner_new(const bContext *UNUSED(C))
+static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
 {
        ARegion *ar;
        SpaceOops *soutliner;
 
        soutliner = MEM_callocN(sizeof(SpaceOops), "initoutliner");
        soutliner->spacetype = SPACE_OUTLINER;
-       
+       soutliner->filter_id_type = ID_GR;
+
        /* header */
        ar = MEM_callocN(sizeof(ARegion), "header for outliner");
-       
+
        BLI_addtail(&soutliner->regionbase, ar);
        ar->regiontype = RGN_TYPE_HEADER;
-       ar->alignment = RGN_ALIGN_BOTTOM;
-       
+       ar->alignment = RGN_ALIGN_TOP;
+
        /* main region */
        ar = MEM_callocN(sizeof(ARegion), "main region for outliner");
-       
+
        BLI_addtail(&soutliner->regionbase, ar);
        ar->regiontype = RGN_TYPE_WINDOW;
-       
+
        return (SpaceLink *)soutliner;
 }
 
@@ -459,7 +505,7 @@ static SpaceLink *outliner_new(const bContext *UNUSED(C))
 static void outliner_free(SpaceLink *sl)
 {
        SpaceOops *soutliner = (SpaceOops *)sl;
-       
+
        outliner_free_tree(&soutliner->tree);
        if (soutliner->treestore) {
                BLI_mempool_destroy(soutliner->treestore);
@@ -472,7 +518,7 @@ static void outliner_free(SpaceLink *sl)
 /* spacetype; init callback */
 static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
 {
-       
+
 }
 
 static SpaceLink *outliner_duplicate(SpaceLink *sl)
@@ -483,7 +529,7 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
        BLI_listbase_clear(&soutlinern->tree);
        soutlinern->treestore = NULL;
        soutlinern->treehash = NULL;
-       
+
        return (SpaceLink *)soutlinern;
 }
 
@@ -525,10 +571,10 @@ void ED_spacetype_outliner(void)
 {
        SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype time");
        ARegionType *art;
-       
+
        st->spaceid = SPACE_OUTLINER;
        strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
-       
+
        st->new = outliner_new;
        st->free = outliner_free;
        st->init = outliner_init;
@@ -542,25 +588,26 @@ void ED_spacetype_outliner(void)
        art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");
        art->regionid = RGN_TYPE_WINDOW;
        art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-       
+
        art->init = outliner_main_region_init;
        art->draw = outliner_main_region_draw;
        art->free = outliner_main_region_free;
        art->listener = outliner_main_region_listener;
+       art->message_subscribe = outliner_main_region_message_subscribe;
        BLI_addhead(&st->regiontypes, art);
-       
+
        /* regions: header */
        art = MEM_callocN(sizeof(ARegionType), "spacetype outliner header region");
        art->regionid = RGN_TYPE_HEADER;
        art->prefsizey = HEADERY;
        art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-       
+
        art->init = outliner_header_region_init;
        art->draw = outliner_header_region_draw;
        art->free = outliner_header_region_free;
        art->listener = outliner_header_region_listener;
        BLI_addhead(&st->regiontypes, art);
-       
+
        BKE_spacetype_register(st);
 }