UI: Properties editor popover and outliner sync

This adds a popover to the properties editor. Currently the only setting
is for controlling outliner to properties syncing.

Because we cannot define a perfect heuristic to determine when
properties editors should change tabs based on outliner icon selection,
we need an option to enable or disable this behavior per properties
editor.

There are 3 options for controlling the syncing. Auto uses the heuristic
to only allow tab switching when a properties editor and outliner share
a border. On and off enable and disable syncing respectively.

Differential Revision: https://developer.blender.org/D9758
This commit is contained in:
Nathan Craddock 2020-12-21 14:27:09 -07:00
parent 2d6e6d035b
commit ffacce5be4
7 changed files with 102 additions and 20 deletions

View File

@ -46,6 +46,8 @@ class PROPERTIES_HT_header(Header):
layout.separator_spacer()
layout.popover(panel="PROPERTIES_PT_options", text="")
class PROPERTIES_PT_navigation_bar(Panel):
bl_space_type = 'PROPERTIES'
@ -69,9 +71,25 @@ class PROPERTIES_PT_navigation_bar(Panel):
layout.prop_tabs_enum(view, "context", icon_only=True)
class PROPERTIES_PT_options(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'HEADER'
bl_label = 'Options'
def draw(self, context):
layout = self.layout
space = context.space_data
col = layout.column()
col.label(text="Sync with Outliner")
col.row().prop(space, "outliner_sync", expand=True)
classes = (
PROPERTIES_HT_header,
PROPERTIES_PT_navigation_bar,
PROPERTIES_PT_options,
)
if __name__ == "__main__": # only for live edit.

View File

@ -1458,5 +1458,17 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
FOREACH_NODETREE_END;
/* Default properties editors to auto outliner sync. */
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
if (space->spacetype == SPACE_PROPERTIES) {
SpaceProperties *space_properties = (SpaceProperties *)space;
space_properties->outliner_sync = PROPERTIES_SYNC_AUTO;
}
}
}
}
}
}

View File

@ -26,6 +26,7 @@
extern "C" {
#endif
struct ScrArea;
struct SpaceProperties;
struct bContext;
@ -36,7 +37,13 @@ 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);
bool ED_buttons_should_sync_with_outliner(const struct bContext *C,
const struct SpaceProperties *sbuts,
struct ScrArea *area);
void ED_buttons_set_context(const struct bContext *C,
struct SpaceProperties *sbuts,
PointerRNA *ptr,
const int context);
#ifdef __cplusplus
}

View File

@ -752,26 +752,25 @@ static bool is_pointer_in_path(ButsContextPath *path, PointerRNA *ptr)
return false;
}
void ED_buttons_set_context(const bContext *C, PointerRNA *ptr, const int context)
bool ED_buttons_should_sync_with_outliner(const bContext *C,
const SpaceProperties *sbuts,
ScrArea *area)
{
ScrArea *active_area = CTX_wm_area(C);
bScreen *screen = CTX_wm_screen(C);
const bool auto_sync = ED_area_has_shared_border(active_area, area) &&
sbuts->outliner_sync == PROPERTIES_SYNC_AUTO;
return auto_sync || sbuts->outliner_sync == PROPERTIES_SYNC_ON;
}
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;
}
void ED_buttons_set_context(const bContext *C,
SpaceProperties *sbuts,
PointerRNA *ptr,
const int context)
{
ButsContextPath path;
if (buttons_context_path(C, sbuts, &path, context, 0) && is_pointer_in_path(&path, ptr)) {
sbuts->mainbuser = context;
sbuts->mainb = sbuts->mainbuser;
}
}

View File

@ -1105,6 +1105,24 @@ bPoseChannel *outliner_find_parent_bone(TreeElement *te, TreeElement **r_bone_te
return NULL;
}
static void outliner_sync_to_properties_editors(const bContext *C,
PointerRNA *ptr,
const int context)
{
bScreen *screen = CTX_wm_screen(C);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype != SPACE_PROPERTIES) {
continue;
}
SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
if (ED_buttons_should_sync_with_outliner(C, sbuts, area)) {
ED_buttons_set_context(C, sbuts, ptr, context);
}
}
}
static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreElem *tselem)
{
PointerRNA ptr = {0};
@ -1285,7 +1303,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE
}
if (ptr.data) {
ED_buttons_set_context(C, &ptr, context);
outliner_sync_to_properties_editors(C, &ptr, context);
}
}

View File

@ -152,9 +152,12 @@ typedef struct SpaceProperties {
short mainb, mainbo, mainbuser;
/** Preview is signal to refresh. */
short preview;
char _pad[5];
char _pad[4];
char flag;
/* eSpaceButtons_OutlinerSync */
char outliner_sync;
/** Runtime. */
void *path;
/** Runtime. */
@ -232,6 +235,13 @@ typedef enum eSpaceButtons_Flag {
SB_SHADING_CONTEXT = (1 << 4),
} eSpaceButtons_Flag;
/* SpaceProperties.outliner_sync */
typedef enum eSpaceButtons_OutlinerSync {
PROPERTIES_SYNC_AUTO = 0,
PROPERTIES_SYNC_OFF = 1,
PROPERTIES_SYNC_ON = 2,
} eSpaceButtons_OutlinerSync;
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -4776,6 +4776,17 @@ static void rna_def_space_properties(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static const EnumPropertyItem tab_sync_items[] = {
{PROPERTIES_SYNC_ON, "ON", 0, "On", "Always sync from outliner editors to this editor"},
{PROPERTIES_SYNC_OFF, "OFF", 0, "Off", "Never sync from outliner editors to this editor"},
{PROPERTIES_SYNC_AUTO,
"AUTO",
0,
"Auto",
"Sync when this editor shares an edge with an outliner editor"},
{0, NULL, 0, NULL, NULL},
};
srna = RNA_def_struct(brna, "SpaceProperties", "Space");
RNA_def_struct_sdna(srna, "SpaceProperties");
RNA_def_struct_ui_text(srna, "Properties Space", "Properties space data");
@ -4826,6 +4837,13 @@ static void rna_def_space_properties(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(
prop, NC_SPACE | ND_SPACE_PROPERTIES, "rna_SpaceProperties_search_filter_update");
/* Outliner sync. */
prop = RNA_def_property(srna, "outliner_sync", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "outliner_sync");
RNA_def_property_enum_items(prop, tab_sync_items);
RNA_def_property_ui_text(prop, "Outliner Sync", "Sync tabs from outliner datablock selection");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
static void rna_def_space_image_overlay(BlenderRNA *brna)