UI: top-bar reorganization

This hides the top-bar by default for everything
besides paint/sculpt workspaces.

- Use the top-bar mainly for active tool settings &
  popovers panel options.
  (transform / snap settings are an exception for this convention).
- Only show the top-bar (by default)
  in paint work-spaces (sculpt / texture-paint / grease-pencil).
- Add an active-tool panel to the sidebar.
- Split 3D view tabs into (Item / Tool / View).

D4721 with minor changes.

Further work is needed for the top-bar and image-editor.
This commit is contained in:
Campbell Barton 2019-04-29 22:50:14 +10:00
parent 1c4fa32db6
commit 17a4decfea
8 changed files with 218 additions and 143 deletions

View File

@ -566,8 +566,13 @@ class ToolSelectPanelHelper:
context, layout,
*,
show_tool_name=False,
tool_key=None,
):
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(context)
if tool_key is None:
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(context)
else:
space_type, mode = tool_key
if space_type is None:
return None
item, tool, icon_value = ToolSelectPanelHelper._tool_get_active(context, space_type, mode, with_icon=True)

View File

@ -611,6 +611,7 @@ class TOPBAR_PT_active_tool(Panel):
def draw(self, context):
layout = self.layout
tool_mode = context.mode
# Panel display of topbar tool settings.
# currently displays in tool settings, keep here since the same functionality is used for the topbar.
@ -619,7 +620,12 @@ class TOPBAR_PT_active_tool(Panel):
layout.use_property_decorate = False
from .space_toolsystem_common import ToolSelectPanelHelper
ToolSelectPanelHelper.draw_active_tool_header(context, layout, show_tool_name=True)
ToolSelectPanelHelper.draw_active_tool_header(
context,
layout,
show_tool_name=True,
tool_key=('VIEW_3D', tool_mode),
)
# Grease Pencil Object - Primitive curve

View File

@ -33,7 +33,6 @@ from .properties_grease_pencil_common import (
)
from bpy.app.translations import contexts as i18n_contexts
class VIEW3D_HT_tool_header(Header):
bl_space_type = 'VIEW_3D'
bl_region_type = "TOOL_HEADER"
@ -43,145 +42,11 @@ class VIEW3D_HT_tool_header(Header):
layout.row(align=True).template_header()
# mode_string = context.mode
obj = context.active_object
tool_settings = context.tool_settings
object_mode = 'OBJECT' if obj is None else obj.mode
has_pose_mode = (
(object_mode == 'POSE') or
(object_mode == 'WEIGHT_PAINT' and context.pose_object is not None)
)
self.draw_tool_settings(context)
layout.separator_spacer()
# Mode & Transform Settings
scene = context.scene
# Orientation
if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL'} or has_pose_mode:
orient_slot = scene.transform_orientation_slots[0]
row = layout.row(align=True)
sub = row.row()
sub.ui_units_x = 4
sub.prop_with_popover(
orient_slot,
"type",
text="",
panel="VIEW3D_PT_transform_orientations",
)
# Pivot
if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL', 'SCULPT_GPENCIL'} or has_pose_mode:
layout.prop_with_popover(
tool_settings,
"transform_pivot_point",
text="",
icon_only=True,
panel="VIEW3D_PT_pivot_point",
)
# Snap
show_snap = False
if obj is None:
show_snap = True
else:
if (object_mode not in {
'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT',
'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'
}) or has_pose_mode:
show_snap = True
else:
from .properties_paint_common import UnifiedPaintPanel
paint_settings = UnifiedPaintPanel.paint_settings(context)
if paint_settings:
brush = paint_settings.brush
if brush and brush.stroke_method == 'CURVE':
show_snap = True
if show_snap:
snap_items = bpy.types.ToolSettings.bl_rna.properties["snap_elements"].enum_items
snap_elements = tool_settings.snap_elements
if len(snap_elements) == 1:
text = ""
for elem in snap_elements:
icon = snap_items[elem].icon
break
else:
text = "Mix"
icon = 'NONE'
del snap_items, snap_elements
row = layout.row(align=True)
row.prop(tool_settings, "use_snap", text="")
sub = row.row(align=True)
sub.popover(
panel="VIEW3D_PT_snapping",
icon=icon,
text=text,
)
# Proportional editing
gpd = context.gpencil_data
if object_mode in {'EDIT', 'PARTICLE_EDIT'}:
row = layout.row(align=True)
row.prop(tool_settings, "proportional_edit", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.proportional_edit != 'DISABLED'
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
elif object_mode == 'OBJECT':
row = layout.row(align=True)
row.prop(tool_settings, "use_proportional_edit_objects", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.use_proportional_edit_objects
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
elif gpd is not None and obj.type == 'GPENCIL':
if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode:
row = layout.row(align=True)
row.prop(tool_settings, "proportional_edit", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.proportional_edit != 'DISABLED'
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
# grease pencil
if object_mode == 'PAINT_GPENCIL':
layout.prop_with_popover(
tool_settings,
"gpencil_stroke_placement_view3d",
text="",
panel="VIEW3D_PT_gpencil_origin",
)
if object_mode in {'PAINT_GPENCIL', 'SCULPT_GPENCIL'}:
layout.prop_with_popover(
tool_settings.gpencil_sculpt,
"lock_axis",
text="",
panel="VIEW3D_PT_gpencil_lock",
)
if object_mode == 'PAINT_GPENCIL':
# FIXME: this is bad practice!
# Tool options are to be displayed in the topbar.
if context.workspace.tools.from_space_view3d_mode(object_mode).idname == "builtin_brush.Draw":
settings = tool_settings.gpencil_sculpt.guide
row = layout.row(align=True)
row.prop(settings, "use_guide", text="", icon='GRID')
sub = row.row(align=True)
sub.active = settings.use_guide
sub.popover(
panel="VIEW3D_PT_gpencil_guide",
text="Guides",
)
VIEW3D_HT_header.draw_xform_template(layout, context)
layout.separator_spacer()
@ -189,12 +54,15 @@ class VIEW3D_HT_tool_header(Header):
def draw_tool_settings(self, context):
layout = self.layout
tool_mode = context.mode
# Active Tool
# -----------
from .space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.draw_active_tool_header(context, layout)
tool_mode = context.mode if tool is None else tool.mode
tool = ToolSelectPanelHelper.draw_active_tool_header(
context, layout,
tool_key=('VIEW_3D', tool_mode),
)
# Object Mode Options
# -------------------
@ -516,6 +384,143 @@ class _draw_tool_settings_context_mode:
class VIEW3D_HT_header(Header):
bl_space_type = 'VIEW_3D'
@staticmethod
def draw_xform_template(layout, context):
obj = context.active_object
object_mode = 'OBJECT' if obj is None else obj.mode
has_pose_mode = (
(object_mode == 'POSE') or
(object_mode == 'WEIGHT_PAINT' and context.pose_object is not None)
)
tool_settings = context.tool_settings
# Mode & Transform Settings
scene = context.scene
# Orientation
if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL'} or has_pose_mode:
orient_slot = scene.transform_orientation_slots[0]
row = layout.row(align=True)
sub = row.row()
sub.ui_units_x = 4
sub.prop_with_popover(
orient_slot,
"type",
text="",
panel="VIEW3D_PT_transform_orientations",
)
# Pivot
if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL', 'SCULPT_GPENCIL'} or has_pose_mode:
layout.prop_with_popover(
tool_settings,
"transform_pivot_point",
text="",
icon_only=True,
panel="VIEW3D_PT_pivot_point",
)
# Snap
show_snap = False
if obj is None:
show_snap = True
else:
if (object_mode not in {
'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT',
'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'
}) or has_pose_mode:
show_snap = True
else:
from .properties_paint_common import UnifiedPaintPanel
paint_settings = UnifiedPaintPanel.paint_settings(context)
if paint_settings:
brush = paint_settings.brush
if brush and brush.stroke_method == 'CURVE':
show_snap = True
if show_snap:
snap_items = bpy.types.ToolSettings.bl_rna.properties["snap_elements"].enum_items
snap_elements = tool_settings.snap_elements
if len(snap_elements) == 1:
text = ""
for elem in snap_elements:
icon = snap_items[elem].icon
break
else:
text = "Mix"
icon = 'NONE'
del snap_items, snap_elements
row = layout.row(align=True)
row.prop(tool_settings, "use_snap", text="")
sub = row.row(align=True)
sub.popover(
panel="VIEW3D_PT_snapping",
icon=icon,
text=text,
)
# Proportional editing
gpd = context.gpencil_data
if object_mode in {'EDIT', 'PARTICLE_EDIT'}:
row = layout.row(align=True)
row.prop(tool_settings, "proportional_edit", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.proportional_edit != 'DISABLED'
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
elif object_mode == 'OBJECT':
row = layout.row(align=True)
row.prop(tool_settings, "use_proportional_edit_objects", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.use_proportional_edit_objects
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
elif gpd is not None and obj.type == 'GPENCIL':
if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode:
row = layout.row(align=True)
row.prop(tool_settings, "proportional_edit", icon_only=True)
sub = row.row(align=True)
sub.active = tool_settings.proportional_edit != 'DISABLED'
sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
# grease pencil
if object_mode == 'PAINT_GPENCIL':
layout.prop_with_popover(
tool_settings,
"gpencil_stroke_placement_view3d",
text="",
panel="VIEW3D_PT_gpencil_origin",
)
if object_mode in {'PAINT_GPENCIL', 'SCULPT_GPENCIL'}:
layout.prop_with_popover(
tool_settings.gpencil_sculpt,
"lock_axis",
text="",
panel="VIEW3D_PT_gpencil_lock",
)
if object_mode == 'PAINT_GPENCIL':
# FIXME: this is bad practice!
# Tool options are to be displayed in the topbar.
if context.workspace.tools.from_space_view3d_mode(object_mode).idname == "builtin_brush.Draw":
settings = tool_settings.gpencil_sculpt.guide
row = layout.row(align=True)
row.prop(settings, "use_guide", text="", icon='GRID')
sub = row.row(align=True)
sub.active = settings.use_guide
sub.popover(
panel="VIEW3D_PT_gpencil_guide",
text="Guides",
)
def draw(self, context):
layout = self.layout
@ -524,8 +529,9 @@ class VIEW3D_HT_header(Header):
shading = view.shading
# mode_string = context.mode
obj = context.active_object
show_region_tool_header = view.show_region_tool_header
if not view.show_region_tool_header:
if not show_region_tool_header:
layout.row(align=True).template_header()
row = layout.row(align=True)
@ -606,6 +612,11 @@ class VIEW3D_HT_header(Header):
layout.separator_spacer()
if not show_region_tool_header:
VIEW3D_HT_header.draw_xform_template(layout, context)
layout.separator_spacer()
# Viewport Settings
layout.popover(
panel="VIEW3D_PT_object_type_visibility",
@ -4633,6 +4644,26 @@ class VIEW3D_MT_proportional_editing_falloff_pie(Menu):
# ********** Panel **********
class VIEW3D_PT_active_tool(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Active Tool"
bl_category = "Tool"
# bl_context = ".active_tool" # dot on purpose (access from tool settings)
def draw(self, context):
layout = self.layout
# Panel display of topbar tool settings.
# currently displays in tool settings, keep here since the same functionality is used for the topbar.
layout.use_property_split = True
layout.use_property_decorate = False
from .space_toolsystem_common import ToolSelectPanelHelper
ToolSelectPanelHelper.draw_active_tool_header(context, layout, show_tool_name=True)
class VIEW3D_PT_view3d_properties(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@ -6413,6 +6444,7 @@ classes = (
VIEW3D_MT_snap_pie,
VIEW3D_MT_orientations_pie,
VIEW3D_MT_proportional_editing_falloff_pie,
VIEW3D_PT_active_tool,
VIEW3D_PT_view3d_properties,
VIEW3D_PT_view3d_lock,
VIEW3D_PT_view3d_cursor,

View File

@ -3245,6 +3245,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER);
BLI_insertlinkbefore(regionbase, ar_header, ar);
/* Hide by default, enable for painting workspaces (startup only). */
ar->flag |= RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
}
if (ar != NULL) {
SET_FLAG_FROM_TEST(ar->flag, ar->flag & RGN_FLAG_HIDDEN_BY_USER, RGN_FLAG_HIDDEN);

View File

@ -293,6 +293,34 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
}
/* Show toopbar for sculpt/paint modes. */
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
bool show_tool_header = false;
if (app_template == NULL) {
if (STR_ELEM(screen->id.name + 2, "Sculpting", "Texture Paint")) {
show_tool_header = true;
}
}
else if (STREQ(app_template, "2D_Animation")) {
if (STR_ELEM(screen->id.name + 2, "Sculpting", "Texture Paint")) {
show_tool_header = true;
}
}
if (show_tool_header) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
for (ARegion *ar = regionbase->first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_TOOL_HEADER) {
ar->flag &= ~(RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER);
}
}
}
}
}
}
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine));

View File

@ -140,6 +140,7 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
BLI_addtail(&simage->regionbase, ar);
ar->regiontype = RGN_TYPE_TOOL_HEADER;
ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
ar->flag = RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for image");

View File

@ -303,6 +303,7 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
BLI_addtail(&v3d->regionbase, ar);
ar->regiontype = RGN_TYPE_TOOL_HEADER;
ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
ar->flag = RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for view3d");

View File

@ -1605,7 +1605,7 @@ void view3d_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
strcpy(pt->idname, "VIEW3D_PT_transform");
strcpy(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
strcpy(pt->category, "View");
strcpy(pt->category, "Item");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = view3d_panel_transform;
pt->poll = view3d_panel_transform_poll;
@ -1614,7 +1614,7 @@ void view3d_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
strcpy(pt->idname, "VIEW3D_PT_vgroup");
strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
strcpy(pt->category, "View");
strcpy(pt->category, "Item");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = view3d_panel_vgroup;
pt->poll = view3d_panel_vgroup_poll;