diff options
Diffstat (limited to 'source/blender/editors/space_buttons')
5 files changed, 186 insertions, 43 deletions
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 397d79e1dbe..ec866780122 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../../blenkernel ../../blenlib ../../blentranslation + ../../depsgraph ../../gpu ../../makesdna ../../makesrna diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index da3364d872d..ebb14d3caeb 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -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,9 +58,12 @@ #include "BKE_screen.h" #include "BKE_texture.h" #include "BKE_linestyle.h" +#include "BKE_workspace.h" #include "RNA_access.h" +#include "DEG_depsgraph.h" + #include "ED_buttons.h" #include "ED_armature.h" #include "ED_screen.h" @@ -167,27 +172,64 @@ 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_collection(ButsContextPath *path, eSpaceButtons_Collection_Context collection_context) +{ + PointerRNA *ptr = &path->ptr[path->len - 1]; + + /* if we already have a (pinned) Collection, we're done */ + if (RNA_struct_is_a(ptr->type, &RNA_LayerCollection)) { + return 1; + } + + ViewLayer *view_layer = ptr->data; + + if (collection_context == SB_COLLECTION_CTX_GROUP) { + Object *ob = OBACT(view_layer); + if (ob && ob->dup_group) { + view_layer = ob->dup_group->view_layer; + + /* Replace the view layer by the group in the context path. */ + RNA_pointer_create(NULL, &RNA_Group, ob->dup_group, &path->ptr[path->len - 1]); + } + } + + LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer); + + if (layer_collection) { + RNA_pointer_create(NULL, &RNA_LayerCollection, layer_collection, &path->ptr[path->len]); + path->len++; + return 1; + } + + /* no path to a collection possible */ + return 0; +} + 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 +250,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; @@ -367,7 +410,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 +424,11 @@ 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) { + const WorkSpace *workspace = CTX_wm_workspace(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer, workspace->object_mode)); + } if (br) { RNA_id_pointer_create((ID *)br, &path->ptr[path->len]); @@ -396,7 +442,7 @@ 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 */ @@ -414,7 +460,7 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur if (id) { if (GS(id->name) == ID_BR) - buttons_context_path_brush(path); + buttons_context_path_brush(C, path); else if (GS(id->name) == ID_MA) buttons_context_path_material(path, false, true); else if (GS(id->name) == ID_WO) @@ -530,7 +576,7 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur static bool buttons_context_linestyle_pinnable(const bContext *C) { Scene *scene = CTX_data_scene(C); - SceneRenderLayer *actsrl; + ViewLayer *active_view_layer; FreestyleConfig *config; SpaceButs *sbuts; @@ -539,8 +585,8 @@ 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; + active_view_layer = BLI_findlink(&scene->view_layers, scene->active_view_layer); + config = &active_view_layer->freestyle_config; if (config->mode != FREESTYLE_CONTROL_EDITOR_MODE) { return false; } @@ -556,6 +602,8 @@ 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); ID *id; int found; @@ -563,18 +611,32 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma path->flag = flag; path->tex_ctx = sbuts->texture_context; - /* if some ID datablock is pinned, set the root pointer */ + const bool use_scene_settings = BKE_workspace_use_scene_settings_get(workspace); + + /* 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 or workspace as initial root. */ + else { + if ((mainb != BCONTEXT_WORKSPACE) && (use_scene_settings || + ELEM(mainb, BCONTEXT_SCENE, BCONTEXT_RENDER, BCONTEXT_VIEW_LAYER, BCONTEXT_WORLD))) + { + RNA_id_pointer_create(&scene->id, &path->ptr[0]); + path->len++; + } + else { + RNA_id_pointer_create(&workspace->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]); + if (!ELEM(mainb, BCONTEXT_WORKSPACE, BCONTEXT_SCENE, BCONTEXT_RENDER, BCONTEXT_VIEW_LAYER, BCONTEXT_WORLD)) { + ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); + RNA_pointer_create(NULL, &RNA_ViewLayer, view_layer, &path->ptr[path->len]); path->len++; } @@ -585,7 +647,7 @@ 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); @@ -599,6 +661,12 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma case BCONTEXT_WORLD: found = buttons_context_path_world(path); break; + case BCONTEXT_WORKSPACE: + found = buttons_context_path_workspace(path); + break; + case BCONTEXT_COLLECTION: + found = buttons_context_path_collection(path, sbuts->collection_context); + break; case BCONTEXT_OBJECT: case BCONTEXT_PHYSICS: case BCONTEXT_CONSTRAINT: @@ -617,7 +685,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found = buttons_context_path_material(path, false, (sbuts->texuser != NULL)); 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); @@ -740,11 +808,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", "workspace", NULL }; int buttons_context(const bContext *C, const char *member, bContextDataResult *result) @@ -773,6 +841,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_World); return 1; } + else if (CTX_data_equals(member, "workspace")) { + /* Do not return one here if scene not found in path, in this case we want to get default context scene! */ + return set_pointer_type(path, result, &RNA_WorkSpace); + } else if (CTX_data_equals(member, "object")) { set_pointer_type(path, result, &RNA_Object); return 1; @@ -809,6 +881,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; @@ -1064,6 +1140,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_FreestyleLineStyle); return 1; } + else if (CTX_data_equals(member, "collection")) { + set_pointer_type(path, result, &RNA_LayerCollection); + return 1; + } else { return 0; /* not found */ } @@ -1121,10 +1201,14 @@ 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) || + (!ELEM(sbuts->mainb, BCONTEXT_WORKSPACE) && ptr->type == &RNA_WorkSpace)) + { uiItemLDrag(row, ptr, "", icon); /* save some space */ - else + } + else { uiItemLDrag(row, ptr, name, icon); + } if (name != namebuf) MEM_freeN(name); diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 7fc35a6b1e7..e6d19caad47 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -65,6 +65,7 @@ typedef struct ButsContextPath { int len; int flag; int tex_ctx; + int collection_ctx; } ButsContextPath; typedef struct ButsTextureUser { diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 3c48f3c1111..c6dda7f9f0d 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -54,6 +54,7 @@ #include "DNA_linestyle_types.h" #include "BKE_context.h" +#include "BKE_layer.h" #include "BKE_linestyle.h" #include "BKE_material.h" #include "BKE_modifier.h" @@ -108,14 +109,14 @@ bool ED_texture_context_check_linestyle(const bContext *C) { #ifdef WITH_FREESTYLE Scene *scene = CTX_data_scene(C); - SceneRenderLayer *actsrl; + ViewLayer *active_view_layer; FreestyleConfig *config; FreestyleLineSet *lineset; FreestyleLineStyle *linestyle; if (scene && (scene->r.mode & R_EDGE_FRS)) { - actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay); - config = &actsrl->freestyleConfig; + active_view_layer = BLI_findlink(&scene->view_layers, scene->active_view_layer); + config = &active_view_layer->freestyle_config; if (config->mode == FREESTYLE_CONTROL_EDITOR_MODE) { lineset = BKE_freestyle_lineset_get_active(config); if (lineset) { @@ -195,7 +196,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts) else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) { sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES; } - else if ((sbuts->mainb == BCONTEXT_RENDER_LAYER) && valid_linestyle) { + else if ((sbuts->mainb == BCONTEXT_VIEW_LAYER) && valid_linestyle) { sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LINESTYLE; } else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) { @@ -324,6 +325,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * Material *ma = NULL; Lamp *la = NULL; World *wrld = NULL; + WorkSpace *workspace = NULL; FreestyleLineStyle *linestyle = NULL; Brush *brush = NULL; ID *pinid = sbuts->pinid; @@ -345,16 +347,26 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * brush = (Brush *)pinid; else if (GS(pinid->name) == ID_LS) linestyle = (FreestyleLineStyle *)pinid; + else if (GS(pinid->name) == ID_WS) + workspace = (WorkSpace *)workspace; } - if (!scene) + if (!scene) { scene = CTX_data_scene(C); + } - if (!pinid || GS(pinid->name) == ID_SCE) { - ob = (scene->basact) ? scene->basact->object : NULL; - wrld = scene->world; + const ID_Type id_type = pinid != NULL ? GS(pinid->name) : -1; + if (!pinid || ELEM(id_type, ID_SCE, ID_WS)) { brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); - linestyle = BKE_linestyle_active_from_scene(scene); + + if (workspace == NULL) { + wrld = scene->world; + linestyle = BKE_linestyle_active_from_scene(scene); + workspace = CTX_wm_workspace(C); + } + + ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); + ob = OBACT(view_layer); } if (ob && ob->type == OB_LAMP && !la) diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index e4c23ad74f8..179780bf517 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -44,6 +44,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" #include "RNA_access.h" @@ -147,10 +148,14 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, "scene", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_RENDER) ED_region_panels(C, ar, "render", sbuts->mainb, vertical); - else if (sbuts->mainb == BCONTEXT_RENDER_LAYER) - ED_region_panels(C, ar, "render_layer", sbuts->mainb, vertical); + else if (sbuts->mainb == BCONTEXT_VIEW_LAYER) + ED_region_panels(C, ar, "view_layer", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_WORLD) ED_region_panels(C, ar, "world", sbuts->mainb, vertical); + else if (sbuts->mainb == BCONTEXT_WORKSPACE) + ED_region_panels(C, ar, "workspace", sbuts->mainb, vertical); + else if (sbuts->mainb == BCONTEXT_COLLECTION) + ED_region_panels(C, ar, "collection", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_OBJECT) ED_region_panels(C, ar, "object", sbuts->mainb, vertical); else if (sbuts->mainb == BCONTEXT_DATA) @@ -176,6 +181,20 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar) sbuts->mainbo = sbuts->mainb; } +static void buttons_main_region_listener( + bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn, + const Scene *UNUSED(scene)) +{ + /* context changes */ + switch (wmn->category) { + case NC_SCREEN: + if (ELEM(wmn->data, ND_LAYER)) { + ED_region_tag_redraw(ar); + } + break; + } +} + static void buttons_operatortypes(void) { WM_operatortype_append(BUTTONS_OT_toolbox); @@ -206,6 +225,28 @@ static void buttons_header_region_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } +static void buttons_header_region_message_subscribe( + const bContext *UNUSED(C), + WorkSpace *UNUSED(workspace), Scene *UNUSED(scene), + bScreen *UNUSED(screen), ScrArea *sa, ARegion *ar, + struct wmMsgBus *mbus) +{ + SpaceButs *sbuts = sa->spacedata.first; + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + + /* Don't check for SpaceButs.mainb here, we may toggle between view-layers + * where one has no active object, so that available contexts changes. */ + WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw); + + if (!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_WORLD)) { + WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw); + } +} + /* draw a certain button set only if properties area is currently * showing that button set, to reduce unnecessary drawing. */ static void buttons_area_redraw(ScrArea *sa, short buttons) @@ -218,7 +259,9 @@ static void buttons_area_redraw(ScrArea *sa, short buttons) } /* reused! */ -static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) +static void buttons_area_listener( + bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { SpaceButs *sbuts = sa->spacedata.first; @@ -228,7 +271,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier * switch (wmn->data) { case ND_RENDER_OPTIONS: buttons_area_redraw(sa, BCONTEXT_RENDER); - buttons_area_redraw(sa, BCONTEXT_RENDER_LAYER); + buttons_area_redraw(sa, BCONTEXT_VIEW_LAYER); break; case ND_WORLD: buttons_area_redraw(sa, BCONTEXT_WORLD); @@ -468,6 +511,7 @@ void ED_spacetype_buttons(void) art->regionid = RGN_TYPE_WINDOW; art->init = buttons_main_region_init; art->draw = buttons_main_region_draw; + art->listener = buttons_main_region_listener; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; BLI_addhead(&st->regiontypes, art); @@ -481,6 +525,7 @@ void ED_spacetype_buttons(void) art->init = buttons_header_region_init; art->draw = buttons_header_region_draw; + art->message_subscribe = buttons_header_region_message_subscribe; BLI_addhead(&st->regiontypes, art); BKE_spacetype_register(st); |