Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_buttons / buttons_context.c
index f5e0ccb..9caf381 100644 (file)
@@ -39,6 +39,7 @@
 #include "BLT_translation.h"
 
 #include "DNA_armature_types.h"
+#include "DNA_group_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_node_types.h"
@@ -49,6 +50,7 @@
 
 #include "BKE_context.h"
 #include "BKE_action.h"
+#include "BKE_layer.h"
 #include "BKE_material.h"
 #include "BKE_modifier.h"
 #include "BKE_paint.h"
@@ -56,6 +58,7 @@
 #include "BKE_screen.h"
 #include "BKE_texture.h"
 #include "BKE_linestyle.h"
+#include "BKE_workspace.h"
 
 #include "RNA_access.h"
 
@@ -111,6 +114,20 @@ static int buttons_context_path_scene(ButsContextPath *path)
        return RNA_struct_is_a(ptr->type, &RNA_Scene);
 }
 
+static int buttons_context_path_view_layer(ButsContextPath *path, WorkSpace *workspace)
+{
+       if (buttons_context_path_scene(path)) {
+               Scene *scene = path->ptr[path->len - 1].data;
+               ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
+
+               RNA_pointer_create(&scene->id, &RNA_ViewLayer, view_layer, &path->ptr[path->len]);
+               path->len++;
+               return 1;
+       }
+
+       return 0;
+}
+
 /* note: this function can return 1 without adding a world to the path
  * so the buttons stay visible, but be sure to check the ID type if a ID_WO */
 static int buttons_context_path_world(ButsContextPath *path)
@@ -142,9 +159,8 @@ static int buttons_context_path_world(ButsContextPath *path)
        return 0;
 }
 
-static int buttons_context_path_linestyle(ButsContextPath *path)
+static int buttons_context_path_linestyle(ButsContextPath *path, WorkSpace *workspace)
 {
-       Scene *scene;
        FreestyleLineStyle *linestyle;
        PointerRNA *ptr = &path->ptr[path->len - 1];
 
@@ -152,10 +168,10 @@ static int buttons_context_path_linestyle(ButsContextPath *path)
        if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
                return 1;
        }
-       /* if we have a scene, use the lineset's linestyle */
-       else if (buttons_context_path_scene(path)) {
-               scene = path->ptr[path->len - 1].data;
-               linestyle = BKE_linestyle_active_from_scene(scene);
+       /* if we have a view layer, use the lineset's linestyle */
+       else if (buttons_context_path_view_layer(path, workspace)) {
+               ViewLayer *view_layer = path->ptr[path->len - 1].data;
+               linestyle = BKE_linestyle_active_from_view_layer(view_layer);
                if (linestyle) {
                        RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]);
                        path->len++;
@@ -167,27 +183,31 @@ static int buttons_context_path_linestyle(ButsContextPath *path)
        return 0;
 }
 
+static int buttons_context_path_workspace(ButsContextPath *path)
+{
+       PointerRNA *ptr = &path->ptr[path->len - 1];
+
+       /* This one just verifies. */
+       return RNA_struct_is_a(ptr->type, &RNA_WorkSpace);
+}
+
 static int buttons_context_path_object(ButsContextPath *path)
 {
-       Scene *scene;
-       Object *ob;
        PointerRNA *ptr = &path->ptr[path->len - 1];
 
        /* if we already have a (pinned) object, we're done */
        if (RNA_struct_is_a(ptr->type, &RNA_Object)) {
                return 1;
        }
-       /* if we have a scene, use the scene's active object */
-       else if (buttons_context_path_scene(path)) {
-               scene = path->ptr[path->len - 1].data;
-               ob = (scene->basact) ? scene->basact->object : NULL;
 
-               if (ob) {
-                       RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
-                       path->len++;
+       ViewLayer *view_layer = ptr->data;
+       Object *ob = (view_layer->basact) ? view_layer->basact->object : NULL;
 
-                       return 1;
-               }
+       if (ob) {
+               RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
+               path->len++;
+
+               return 1;
        }
 
        /* no path to a object possible */
@@ -208,6 +228,7 @@ static int buttons_context_path_data(ButsContextPath *path, int type)
        else if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) return 1;
        else if (RNA_struct_is_a(ptr->type, &RNA_Lamp) && (type == -1 || type == OB_LAMP)) return 1;
        else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1;
+       else if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) return 1;
        /* try to get an object in the path, no pinning supported here */
        else if (buttons_context_path_object(path)) {
                ob = path->ptr[path->len - 1].data;
@@ -238,7 +259,7 @@ static int buttons_context_path_modifier(ButsContextPath *path)
        return 0;
 }
 
-static int buttons_context_path_material(ButsContextPath *path, bool for_texture, bool new_shading)
+static int buttons_context_path_material(ButsContextPath *path)
 {
        Object *ob;
        PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -256,18 +277,6 @@ static int buttons_context_path_material(ButsContextPath *path, bool for_texture
                        ma = give_current_material(ob, ob->actcol);
                        RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
                        path->len++;
-
-                       if (for_texture && give_current_material_texture_node(ma))
-                               return 1;
-
-                       if (!new_shading) {
-                               /* Only try to get mat from node in case of old shading system (see T40331). */
-                               ma = give_node_material(ma);
-                               if (ma) {
-                                       RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
-                                       path->len++;
-                               }
-                       }
                        return 1;
                }
        }
@@ -367,7 +376,7 @@ static int buttons_context_path_particle(ButsContextPath *path)
        return 0;
 }
 
-static int buttons_context_path_brush(ButsContextPath *path)
+static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
 {
        Scene *scene;
        Brush *br = NULL;
@@ -381,8 +390,10 @@ static int buttons_context_path_brush(ButsContextPath *path)
        else if (buttons_context_path_scene(path)) {
                scene = path->ptr[path->len - 1].data;
 
-               if (scene)
-                       br = BKE_paint_brush(BKE_paint_get_active(scene));
+               if (scene) {
+                       ViewLayer *view_layer = CTX_data_view_layer(C);
+                       br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer));
+               }
 
                if (br) {
                        RNA_id_pointer_create((ID *)br, &path->ptr[path->len]);
@@ -396,141 +407,46 @@ static int buttons_context_path_brush(ButsContextPath *path)
        return 0;
 }
 
-static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct)
+static int buttons_context_path_texture(const bContext *C, ButsContextPath *path, ButsContextTexture *ct)
 {
-       if (ct) {
-               /* new shading system */
-               PointerRNA *ptr = &path->ptr[path->len - 1];
-               ID *id;
-
-               /* if we already have a (pinned) texture, we're done */
-               if (RNA_struct_is_a(ptr->type, &RNA_Texture))
-                       return 1;
-
-               if (!ct->user)
-                       return 0;
-
-               id = ct->user->id;
-
-               if (id) {
-                       if (GS(id->name) == ID_BR)
-                               buttons_context_path_brush(path);
-                       else if (GS(id->name) == ID_MA)
-                               buttons_context_path_material(path, false, true);
-                       else if (GS(id->name) == ID_WO)
-                               buttons_context_path_world(path);
-                       else if (GS(id->name) == ID_LA)
-                               buttons_context_path_data(path, OB_LAMP);
-                       else if (GS(id->name) == ID_PA)
-                               buttons_context_path_particle(path);
-                       else if (GS(id->name) == ID_OB)
-                               buttons_context_path_object(path);
-                       else if (GS(id->name) == ID_LS)
-                               buttons_context_path_linestyle(path);
-               }
+       PointerRNA *ptr = &path->ptr[path->len - 1];
+       ID *id;
 
-               if (ct->texture) {
-                       RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]);
-                       path->len++;
-               }
+       if (!ct)
+               return 0;
 
+       /* if we already have a (pinned) texture, we're done */
+       if (RNA_struct_is_a(ptr->type, &RNA_Texture))
                return 1;
-       }
-       else {
-               /* old shading system */
-               Material *ma;
-               Lamp *la;
-               World *wo;
-               ParticleSystem *psys;
-               FreestyleLineStyle *ls;
-               Tex *tex;
-               PointerRNA *ptr = &path->ptr[path->len - 1];
-
-               /* if we already have a (pinned) texture, we're done */
-               if (RNA_struct_is_a(ptr->type, &RNA_Texture)) {
-                       return 1;
-               }
-               /* try world */
-               else if ((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
-                       wo = path->ptr[path->len - 1].data;
-
-                       if (wo && GS(wo->id.name) == ID_WO) {
-                               tex = give_current_world_texture(wo);
-
-                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                               path->len++;
-                               return 1;
-                       }
-               }
-               /* try particles */
-               else if ((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
-                       if (path->ptr[path->len - 1].type == &RNA_ParticleSettings) {
-                               ParticleSettings *part = path->ptr[path->len - 1].data;
 
-                               tex = give_current_particle_texture(part);
-                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                               path->len++;
-                               return 1;
-                       }
-                       else {
-                               psys = path->ptr[path->len - 1].data;
-
-                               if (psys && psys->part && GS(psys->part->id.name) == ID_PA) {
-                                       tex = give_current_particle_texture(psys->part);
-
-                                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                                       path->len++;
-                                       return 1;
-                               }
-                       }
-               }
-               /* try material */
-               else if ((path->tex_ctx == SB_TEXC_MATERIAL) && buttons_context_path_material(path, true, false)) {
-                       ma = path->ptr[path->len - 1].data;
-
-                       if (ma) {
-                               tex = give_current_material_texture(ma);
-
-                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                               path->len++;
-                               return 1;
-                       }
-               }
-               /* try lamp */
-               else if ((path->tex_ctx == SB_TEXC_LAMP) && buttons_context_path_data(path, OB_LAMP)) {
-                       la = path->ptr[path->len - 1].data;
-
-                       if (la) {
-                               tex = give_current_lamp_texture(la);
+       if (!ct->user)
+               return 0;
 
-                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                               path->len++;
-                               return 1;
-                       }
-               }
-               /* try linestyle */
-               else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) {
-                       ls = path->ptr[path->len - 1].data;
+       id = ct->user->id;
 
-                       if (ls) {
-                               tex = give_current_linestyle_texture(ls);
+       if (id) {
+               if (GS(id->name) == ID_BR)
+                       buttons_context_path_brush(C, path);
+               else if (GS(id->name) == ID_PA)
+                       buttons_context_path_particle(path);
+               else if (GS(id->name) == ID_OB)
+                       buttons_context_path_object(path);
+               else if (GS(id->name) == ID_LS)
+                       buttons_context_path_linestyle(path, CTX_wm_workspace(C));
+       }
 
-                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                               path->len++;
-                               return 1;
-                       }
-               }
+       if (ct->texture) {
+               RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]);
+               path->len++;
        }
 
-       /* no path to a texture possible */
-       return 0;
+       return 1;
 }
 
 #ifdef WITH_FREESTYLE
-static bool buttons_context_linestyle_pinnable(const bContext *C)
+static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *view_layer)
 {
        Scene *scene = CTX_data_scene(C);
-       SceneRenderLayer *actsrl;
        FreestyleConfig *config;
        SpaceButs *sbuts;
 
@@ -539,8 +455,7 @@ static bool buttons_context_linestyle_pinnable(const bContext *C)
                return false;
        }
        /* if Freestyle is not in the Parameter Editor mode */
-       actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay);
-       config = &actsrl->freestyleConfig;
+       config = &view_layer->freestyle_config;
        if (config->mode != FREESTYLE_CONTROL_EDITOR_MODE) {
                return false;
        }
@@ -556,26 +471,37 @@ static bool buttons_context_linestyle_pinnable(const bContext *C)
 static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
 {
        SpaceButs *sbuts = CTX_wm_space_buts(C);
+       Scene *scene = CTX_data_scene(C);
+       WorkSpace *workspace = CTX_wm_workspace(C);
+       ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
        ID *id;
        int found;
 
        memset(path, 0, sizeof(*path));
        path->flag = flag;
-       path->tex_ctx = sbuts->texture_context;
 
-       /* if some ID datablock is pinned, set the root pointer */
+       /* If some ID datablock is pinned, set the root pointer. */
        if (sbuts->pinid) {
                id = sbuts->pinid;
 
                RNA_id_pointer_create(id, &path->ptr[0]);
                path->len++;
        }
+       /* No pinned root, use scene as initial root. */
+       else {
+               if (mainb == BCONTEXT_WORKSPACE) {
+                       RNA_id_pointer_create(&workspace->id, &path->ptr[0]);
+                       path->len++;
+               }
+               else {
+                       RNA_id_pointer_create(&scene->id, &path->ptr[0]);
+                       path->len++;
 
-       /* no pinned root, use scene as root */
-       if (path->len == 0) {
-               id = (ID *)CTX_data_scene(C);
-               RNA_id_pointer_create(id, &path->ptr[0]);
-               path->len++;
+                       if (!ELEM(mainb, BCONTEXT_SCENE, BCONTEXT_RENDER, BCONTEXT_VIEW_LAYER, BCONTEXT_WORLD)) {
+                               RNA_pointer_create(NULL, &RNA_ViewLayer, view_layer, &path->ptr[path->len]);
+                               path->len++;
+                       }
+               }
        }
 
        /* now for each buttons context type, we try to construct a path,
@@ -585,20 +511,23 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
                case BCONTEXT_RENDER:
                        found = buttons_context_path_scene(path);
                        break;
-               case BCONTEXT_RENDER_LAYER:
+               case BCONTEXT_VIEW_LAYER:
 #ifdef WITH_FREESTYLE
-                       if (buttons_context_linestyle_pinnable(C)) {
-                               found = buttons_context_path_linestyle(path);
+                       if (buttons_context_linestyle_pinnable(C, view_layer)) {
+                               found = buttons_context_path_linestyle(path, workspace);
                                if (found) {
                                        break;
                                }
                        }
 #endif
-                       found = buttons_context_path_scene(path);
+                       found = buttons_context_path_view_layer(path, workspace);
                        break;
                case BCONTEXT_WORLD:
                        found = buttons_context_path_world(path);
                        break;
+               case BCONTEXT_WORKSPACE:
+                       found = buttons_context_path_workspace(path);
+                       break;
                case BCONTEXT_OBJECT:
                case BCONTEXT_PHYSICS:
                case BCONTEXT_CONSTRAINT:
@@ -614,10 +543,10 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
                        found = buttons_context_path_particle(path);
                        break;
                case BCONTEXT_MATERIAL:
-                       found = buttons_context_path_material(path, false, (sbuts->texuser != NULL));
+                       found = buttons_context_path_material(path);
                        break;
                case BCONTEXT_TEXTURE:
-                       found = buttons_context_path_texture(path, sbuts->texuser);
+                       found = buttons_context_path_texture(C, path, sbuts->texuser);
                        break;
                case BCONTEXT_BONE:
                        found = buttons_context_path_bone(path);
@@ -672,7 +601,7 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
 
        path = sbuts->path;
 
-       /* We need to set Scene path now! Else, buttons_texture_context_compute() might not get a valid scene. */
+       /* Set scene path. */
        buttons_context_path(C, path, BCONTEXT_SCENE, pflag);
 
        buttons_texture_context_compute(C, sbuts);
@@ -740,11 +669,11 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
 
 const char *buttons_context_dir[] = {
        "texture_slot", "scene", "world", "object", "mesh", "armature", "lattice", "curve",
-       "meta_ball", "lamp", "speaker", "camera", "material", "material_slot",
+       "meta_ball", "lamp", "speaker", "lightprobe", "camera", "material", "material_slot",
        "texture", "texture_user", "texture_user_property", "bone", "edit_bone",
        "pose_bone", "particle_system", "particle_system_editable", "particle_settings",
        "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint",
-       "line_style", NULL
+       "line_style", "collection", NULL
 };
 
 int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -809,6 +738,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                set_pointer_type(path, result, &RNA_Speaker);
                return 1;
        }
+       else if (CTX_data_equals(member, "lightprobe")) {
+               set_pointer_type(path, result, &RNA_LightProbe);
+               return 1;
+       }
        else if (CTX_data_equals(member, "material")) {
                set_pointer_type(path, result, &RNA_Material);
                return 1;
@@ -817,13 +750,8 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                ButsContextTexture *ct = sbuts->texuser;
 
                if (ct) {
-                       /* new shading system */
                        CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture);
                }
-               else {
-                       /* old shading system */
-                       set_pointer_type(path, result, &RNA_Texture);
-               }
 
                return 1;
        }
@@ -847,7 +775,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                ButsContextTexture *ct = sbuts->texuser;
 
                if (!ct)
-                       return -1;  /* old shading system (found but not available) */
+                       return -1;
 
                if (ct->user && ct->user->ptr.data) {
                        ButsTextureUser *user = ct->user;
@@ -860,7 +788,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                ButsContextTexture *ct = sbuts->texuser;
 
                if (!ct)
-                       return -1;  /* old shading system (found but not available) */
+                       return -1;
 
                if (ct->user && ct->user->ptr.data) {
                        ButsTextureUser *user = ct->user;
@@ -878,21 +806,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                                CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node);
                        }
 
-                       return 1;
-               }
-               else {
-                       /* old shading system */
-                       PointerRNA *ptr;
-
-                       if ((ptr = get_pointer_type(path, &RNA_Material))) {
-                               Material *ma = ptr->data;
-
-                               if (ma) {
-                                       bNode *node = give_current_material_texture_node(ma);
-                                       CTX_data_pointer_set(result, &ma->nodetree->id, &RNA_Node, node);
-                               }
-                       }
-
                        return 1;
                }
        }
@@ -910,38 +823,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                else if (ct) {
                        return 0;  /* new shading system */
                }
-               else if ((ptr = get_pointer_type(path, &RNA_Material))) {
-                       Material *ma = ptr->data;
-
-                       /* if we have a node material, get slot from material in material node */
-                       if (ma && ma->use_nodes && ma->nodetree) {
-                               /* if there's an active texture node in the node tree,
-                                * then that texture is in context directly, without a texture slot */
-                               if (give_current_material_texture_node(ma))
-                                       return 0;
-
-                               ma = give_node_material(ma);
-                               if (ma)
-                                       CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]);
-                               else
-                                       return 0;
-                       }
-                       else if (ma) {
-                               CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]);
-                       }
-               }
-               else if ((ptr = get_pointer_type(path, &RNA_Lamp))) {
-                       Lamp *la = ptr->data;
-
-                       if (la)
-                               CTX_data_pointer_set(result, &la->id, &RNA_LampTextureSlot, la->mtex[(int)la->texact]);
-               }
-               else if ((ptr = get_pointer_type(path, &RNA_World))) {
-                       World *wo = ptr->data;
-
-                       if (wo)
-                               CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]);
-               }
                else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) {
                        FreestyleLineStyle *ls = ptr->data;
 
@@ -1121,10 +1002,15 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
                        name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL);
 
                        if (name) {
-                               if (!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_RENDER_LAYER) && ptr->type == &RNA_Scene)
+                               if ((!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_VIEW_LAYER) && ptr->type == &RNA_Scene)) {
                                        uiItemLDrag(row, ptr, "", icon);  /* save some space */
-                               else
+                               }
+                               else if ((!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_VIEW_LAYER) && ptr->type == &RNA_ViewLayer)) {
+                                       uiItemLDrag(row, ptr, "", icon);  /* save some space */
+                               }
+                               else {
                                        uiItemLDrag(row, ptr, name, icon);
+                               }
 
                                if (name != namebuf)
                                        MEM_freeN(name);