Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Craddock <nzcraddock@gmail.com>2020-10-28 20:43:10 +0300
committerNathan Craddock <nzcraddock@gmail.com>2020-10-28 20:54:29 +0300
commit0e47e57eb77d0c84ce3b9aa6b9c502a50f0ea6f2 (patch)
treedbaf93b75c2adaac35dde4a5bc78659715b76220
parent5af8fc8192c4e4cdec98f84cf34d436cd85da1ae (diff)
Outliner: Properties editor sync on selection
When outliner datablocks are selected, switch to the corresponding tab for that datablock in properties editors. Only properties editors that share an edge with the outliner will change tabs. Additionally, when modifiers, constraints, and shader effects are selected from the outliner, the panel will be expanded in all properties editors. Part of T77408 Manifest Task: https://developer.blender.org/T63991 Differential Revision: https://developer.blender.org/D8638
-rw-r--r--source/blender/blenkernel/BKE_constraint.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h1
-rw-r--r--source/blender/blenkernel/BKE_modifier.h1
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h1
-rw-r--r--source/blender/blenkernel/intern/constraint.c5
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c5
-rw-r--r--source/blender/blenkernel/intern/modifier.c5
-rw-r--r--source/blender/blenkernel/intern/shader_fx.c5
-rw-r--r--source/blender/editors/include/ED_buttons.h3
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/screen/area.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c44
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c203
13 files changed, 265 insertions, 16 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index ecb891760b7..5ff0e7597e9 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -183,6 +183,8 @@ bool BKE_constraint_remove_ex(ListBase *list,
bool clear_dep);
bool BKE_constraint_remove(ListBase *list, struct bConstraint *con);
+void BKE_constraint_panel_expand(struct bConstraint *con);
+
/* Constraints + Proxies function prototypes */
void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src);
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index e003144047b..78a17e3568d 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -249,6 +249,7 @@ typedef struct GpencilModifierTypeInfo {
void BKE_gpencil_modifier_init(void);
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname);
+void BKE_gpencil_modifier_panel_expand(struct GpencilModifierData *md);
const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType type);
struct GpencilModifierData *BKE_gpencil_modifier_new(int type);
void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 10528a651e5..4909fe012b5 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -396,6 +396,7 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type);
/* For modifier UI panels. */
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname);
+void BKE_modifier_panel_expand(struct ModifierData *md);
/* Modifier utility calls, do call through type pointer and return
* default values if pointer is optional.
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index da14487c1f4..4b9688f9515 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -151,6 +151,7 @@ typedef struct ShaderFxTypeInfo {
void BKE_shaderfx_init(void);
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname);
+void BKE_shaderfx_panel_expand(struct ShaderFxData *fx);
const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type);
struct ShaderFxData *BKE_shaderfx_new(int type);
void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 274546132fb..2301267cd21 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -5406,6 +5406,11 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool
return false;
}
+void BKE_constraint_panel_expand(bConstraint *con)
+{
+ con->ui_expand_flag |= (1 << 0);
+}
+
/* ......... */
/* Creates a new constraint, initializes its data, and returns it */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index d12e445fe99..f4041fae047 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -411,6 +411,11 @@ void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
strcat(r_idname, mti->name);
}
+void BKE_gpencil_modifier_panel_expand(GpencilModifierData *md)
+{
+ md->ui_expand_flag |= (1 << 0);
+}
+
/**
* Generic grease pencil modifier copy data.
* \param md_src: Source modifier data
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index d79a03dce6e..1ac63e653c0 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -130,6 +130,11 @@ void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
strcat(r_idname, mti->name);
}
+void BKE_modifier_panel_expand(ModifierData *md)
+{
+ md->ui_expand_flag |= (1 << 0);
+}
+
/***/
ModifierData *BKE_modifier_new(int type)
diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c
index f2cdf08b415..29cb574c7bc 100644
--- a/source/blender/blenkernel/intern/shader_fx.c
+++ b/source/blender/blenkernel/intern/shader_fx.c
@@ -175,6 +175,11 @@ void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname)
strcat(r_idname, fxi->name);
}
+void BKE_shaderfx_panel_expand(ShaderFxData *fx)
+{
+ fx->ui_expand_flag |= (1 << 0);
+}
+
void BKE_shaderfx_copydata_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst)
{
const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx_src->type);
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 5d153757900..90d3a527b0c 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -26,6 +26,7 @@
extern "C" {
#endif
+struct bContext;
struct SpaceProperties;
int ED_buttons_tabs_list(struct SpaceProperties *sbuts, short *context_tabs_array);
@@ -35,6 +36,8 @@ void ED_buttons_search_string_set(struct SpaceProperties *sbuts, const char *val
int ED_buttons_search_string_length(struct SpaceProperties *sbuts);
const char *ED_buttons_search_string_get(struct SpaceProperties *sbuts);
+void ED_buttons_set_context(const struct bContext *C, PointerRNA *ptr, const int context);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index b8500ba0c37..dc1c43c0337 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -199,6 +199,7 @@ int ED_region_global_size_y(void);
void ED_area_update_region_sizes(struct wmWindowManager *wm,
struct wmWindow *win,
struct ScrArea *area);
+bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b);
ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f5962f36412..cffcb1cb4dc 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1871,6 +1871,11 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE;
}
+bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b)
+{
+ return area_getorientation(a, b) != -1;
+}
+
/* called in screen_refresh, or screens_init, also area size changes */
void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 60ce86740cd..8fc16e66466 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -56,6 +56,7 @@
#include "RNA_access.h"
+#include "ED_buttons.h"
#include "ED_physics.h"
#include "ED_screen.h"
@@ -512,11 +513,11 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie
}
#endif
-static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
+static bool buttons_context_path(
+ const bContext *C, SpaceProperties *sbuts, ButsContextPath *path, int mainb, int flag)
{
/* Note we don't use CTX_data here, instead we get it from the window.
* Otherwise there is a loop reading the context that we are setting. */
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
wmWindow *window = CTX_wm_window(C);
Scene *scene = WM_window_get_active_scene(window);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
@@ -660,14 +661,14 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
int flag = 0;
/* Set scene path. */
- buttons_context_path(C, path, BCONTEXT_SCENE, pflag);
+ buttons_context_path(C, sbuts, path, BCONTEXT_SCENE, pflag);
buttons_texture_context_compute(C, sbuts);
/* for each context, see if we can compute a valid path to it, if
* this is the case, we know we have to display the button */
for (int i = 0; i < BCONTEXT_TOT; i++) {
- if (buttons_context_path(C, path, i, pflag)) {
+ if (buttons_context_path(C, sbuts, path, i, pflag)) {
flag |= (1 << i);
/* setting icon for data context */
@@ -713,7 +714,7 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
}
}
- buttons_context_path(C, path, sbuts->mainb, pflag);
+ buttons_context_path(C, sbuts, path, sbuts->mainb, pflag);
if (!(flag & (1 << sbuts->mainb))) {
if (flag & (1 << BCONTEXT_OBJECT)) {
@@ -734,6 +735,39 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
sbuts->pathflag = flag;
}
+static bool is_pointer_in_path(ButsContextPath *path, PointerRNA *ptr)
+{
+ for (int i = 0; i < path->len; ++i) {
+ if (ptr->owner_id == path->ptr[i].owner_id) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ED_buttons_set_context(const bContext *C, PointerRNA *ptr, const int context)
+{
+ ScrArea *active_area = CTX_wm_area(C);
+ bScreen *screen = CTX_wm_screen(C);
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ /* Only update for properties editors that are visible and share a border. */
+ if (area->spacetype != SPACE_PROPERTIES) {
+ continue;
+ }
+ if (!ED_area_has_shared_border(active_area, area)) {
+ continue;
+ }
+
+ SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
+ ButsContextPath path;
+ if (buttons_context_path(C, sbuts, &path, context, 0) && is_pointer_in_path(&path, ptr)) {
+ sbuts->mainbuser = context;
+ sbuts->mainb = sbuts->mainbuser;
+ }
+ }
+}
+
/************************* Context Callback ************************/
const char *buttons_context_dir[] = {
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 8034996f5c3..c818aa8caa9 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -27,12 +27,16 @@
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_shader_fx_types.h"
#include "DNA_world_types.h"
#include "BLI_listbase.h"
@@ -40,21 +44,27 @@
#include "BKE_armature.h"
#include "BKE_collection.h"
+#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_layer.h"
#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "BKE_particle.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "BKE_shader_fx.h"
#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_armature.h"
+#include "ED_buttons.h"
#include "ED_gpencil.h"
#include "ED_object.h"
#include "ED_outliner.h"
@@ -769,15 +779,26 @@ static eOLDrawState tree_element_active_psys(bContext *C,
}
static int tree_element_active_constraint(bContext *C,
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(sl),
- TreeElement *UNUSED(te),
+ Scene *scene,
+ ViewLayer *view_layer,
+ TreeElement *te,
TreeStoreElem *tselem,
const eOLSetState set)
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
+ /* Activate the parent bone if this is a bone constraint. */
+ te = te->parent;
+ while (te) {
+ tselem = TREESTORE(te);
+ if (tselem->type == TSE_POSE_CHANNEL) {
+ tree_element_active_posechannel(C, scene, view_layer, ob, te, tselem, set, false);
+ return OL_DRAWSEL_NONE;
+ }
+ te = te->parent;
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
}
@@ -1009,6 +1030,7 @@ eOLDrawState tree_element_type_active(bContext *C,
case TSE_POSE_CHANNEL:
return tree_element_active_posechannel(
C, tvc->scene, tvc->view_layer, tvc->ob_pose, te, tselem, set, recursive);
+ case TSE_CONSTRAINT_BASE:
case TSE_CONSTRAINT:
return tree_element_active_constraint(C, tvc->scene, tvc->view_layer, te, tselem, set);
case TSE_R_LAYER:
@@ -1049,6 +1071,169 @@ bPoseChannel *outliner_find_parent_bone(TreeElement *te, TreeElement **r_bone_te
return NULL;
}
+static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreElem *tselem)
+{
+ PointerRNA ptr = {0};
+ int context = 0;
+
+ /* ID Types */
+ if (tselem->type == 0) {
+ RNA_id_pointer_create(tselem->id, &ptr);
+
+ switch (te->idcode) {
+ case ID_SCE:
+ context = BCONTEXT_SCENE;
+ break;
+ case ID_OB:
+ context = BCONTEXT_OBJECT;
+ break;
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_IM:
+ case ID_LT:
+ case ID_LA:
+ case ID_CA:
+ case ID_KE:
+ case ID_SPK:
+ case ID_AR:
+ case ID_GD:
+ case ID_LP:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ context = BCONTEXT_DATA;
+ break;
+ case ID_MA:
+ context = BCONTEXT_MATERIAL;
+ break;
+ case ID_WO:
+ context = BCONTEXT_WORLD;
+ break;
+ }
+ }
+ else {
+ switch (tselem->type) {
+ case TSE_DEFGROUP_BASE:
+ case TSE_DEFGROUP:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ case TSE_CONSTRAINT_BASE:
+ case TSE_CONSTRAINT: {
+ TreeElement *bone_te = NULL;
+ bPoseChannel *pchan = outliner_find_parent_bone(te, &bone_te);
+
+ if (pchan) {
+ RNA_pointer_create(TREESTORE(bone_te)->id, &RNA_PoseBone, pchan, &ptr);
+ context = BCONTEXT_BONE_CONSTRAINT;
+ }
+ else {
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_CONSTRAINT;
+ }
+
+ /* Expand the selected constraint in the properties editor. */
+ if (tselem->type != TSE_CONSTRAINT_BASE) {
+ BKE_constraint_panel_expand(te->directdata);
+ }
+ break;
+ }
+ case TSE_MODIFIER_BASE:
+ case TSE_MODIFIER:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_MODIFIER;
+
+ if (tselem->type != TSE_MODIFIER_BASE) {
+ Object *ob = (Object *)tselem->id;
+
+ if (ob->type == OB_GPENCIL) {
+ BKE_gpencil_modifier_panel_expand(te->directdata);
+ }
+ else {
+ BKE_modifier_panel_expand(te->directdata);
+ }
+ }
+ break;
+ case TSE_GPENCIL_EFFECT_BASE:
+ case TSE_GPENCIL_EFFECT:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_SHADERFX;
+
+ if (tselem->type != TSE_GPENCIL_EFFECT_BASE) {
+ BKE_shaderfx_panel_expand(te->directdata);
+ }
+ break;
+ case TSE_BONE: {
+ bArmature *arm = (bArmature *)tselem->id;
+ Bone *bone = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_EBONE: {
+ bArmature *arm = (bArmature *)tselem->id;
+ EditBone *ebone = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_POSE_CHANNEL: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_PoseBone, pchan, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_POSE_BASE: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+
+ RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ case TSE_R_LAYER_BASE:
+ case TSE_R_LAYER: {
+ ViewLayer *view_layer = te->directdata;
+
+ RNA_pointer_create(tselem->id, &RNA_ViewLayer, view_layer, &ptr);
+ context = BCONTEXT_VIEW_LAYER;
+ break;
+ }
+ case TSE_POSEGRP_BASE:
+ case TSE_POSEGRP: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+
+ RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ case TSE_LINKED_PSYS: {
+ Object *ob = (Object *)tselem->id;
+ ParticleSystem *psys = psys_get_current(ob);
+
+ RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &ptr);
+ context = BCONTEXT_PARTICLE;
+ break;
+ }
+ case TSE_GP_LAYER:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ }
+
+ if (ptr.data) {
+ ED_buttons_set_context(C, &ptr, context);
+ }
+}
+
/* ================================================ */
/**
@@ -1073,14 +1258,8 @@ static void do_outliner_item_activate_tree_element(bContext *C,
TSE_SEQUENCE_DUP,
TSE_EBONE,
TSE_LAYER_COLLECTION)) {
- /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects,
- * we do not want to switch out of edit mode (see T48328 for details). */
- }
- else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- /* Support edit-mode toggle, keeping the active object as is. */
- }
- else if (tselem->type == TSE_POSE_BASE) {
- /* Support pose mode toggle, keeping the active object as is. */
+ /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several
+ * objects, we do not want to switch out of edit mode (see T48328 for details). */
}
else if (do_activate_data) {
tree_element_set_active_object(C,
@@ -1155,6 +1334,8 @@ static void do_outliner_item_activate_tree_element(bContext *C,
extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
recursive);
}
+
+ outliner_set_properties_tab(C, te, tselem);
}
/* Select the item using the set flags */