Active Tool Settings UI in Header vs Properties / N-panel

I’m in the process of adding the rest of bevel’s options to the active tool so that it can be a useful alternative to the modal tool. I’ve run into the situation where it makes sense to define a separate interface for the header and non-header versions of the UI (the issue pictured below).

I would like to draw the list of boolean options with a menu or popover in the header, but to do that I need to detect the region it’s drawing in. Something like this seems like the intuitive solution, but they’re both Horizontal, and I haven’t found another way to do this.

    @ToolDef.from_fn
    def bevel():
        def draw_settings(_context, layout, tool):
            props = tool.operator_properties("mesh.bevel")
            
            # I'd like to detect region (header or N-panel / properties 
            if layout.direction == 'VERTICAL': # NOT HEADER
                ...
            else: # HEADER
                ...

Any ideas?

4 Likes

If you want to draw something in the sidebar, but not the top bar or the properties editor, use something like this in draw_settings

reg = bpy.context.region.type

if reg == 'UI'
    layout.popover(panel="PANELNAME_PT_panel_name")

You can build it out into an if... elif... else... sequence to define elements for all three display areas, or use if not... if you’re just excluding things from TOOL_HEADER

That’s exactly what I’m looking for. I should have thought to look through context in the API docs. Still new to the bpy side of things…

Thanks.

I was procrastinating this morning and I, uh, lost track of time.

The panel:

class TOOLPOP_PT_bevel_popover(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'HEADER'
    bl_label = "Advanced"

    def draw(self, context):

        tool = context.workspace.tools.from_space_view3d_mode(context.mode)

        props = tool.operator_properties("mesh.bevel")

        layout = self.layout
        layout.ui_units_x = 16
        flow = layout.grid_flow(columns=2, even_columns=True, align=True)
        flow.scale_x = 0.75
        flow.scale_y = 0.85

        flow.prop(props, "vertex_only")
        flow.prop(props, "mark_seam")
        flow.prop(props, "mark_sharp")
        flow.prop(props, "harden_normals")
        flow.prop(props, "face_strength_mode")
        flow.prop(props, "miter_outer")
        flow.prop(props, "miter_inner")
        flow.prop(props, "material")

        row = layout.row(align=True)
        row.prop(props, "spread")

The tool definition:

    @ToolDef.from_fn
    def bevel():
        def draw_settings(_context, layout, tool):

            props = tool.operator_properties("mesh.bevel")

            reg = bpy.context.region.type

            if not reg == 'TOOL_HEADER':
                layout.prop(props, "offset_type")
                layout.prop(props, "segments")
                layout.prop(props, "profile", slider=True)
                layout.prop(props, "vertex_only")
                layout.prop(props, "mark_seam")
                layout.prop(props, "mark_sharp")
                layout.prop(props, "harden_normals")
                layout.prop(props, "face_strength_mode")
                layout.prop(props, "miter_outer")
                layout.prop(props, "miter_inner")
                layout.prop(props, "spread")
                layout.prop(props, "material")
            else:
                layout.prop(props, "offset_type")
                layout.prop(props, "segments")
                layout.prop(props, "profile", slider=True)
                layout.popover(panel="TOOLPOP_PT_bevel_popover")

        return dict(
            idname="builtin.bevel",
            label="Bevel",
            icon="ops.mesh.bevel",
            widget=None,
            keymap=(),
            draw_settings=draw_settings,
        )
1 Like

I arrived at something similar:

Code here: https://developer.blender.org/D5832

My summer of code branch includes a change to the redo panel and modifier bevel UI as well.

I wonder if there are other active tools with a limited selection of the options? Would be an easy thing to fix up.

1 Like

I’d lean heavier on the breakpoints for the profile widget layout and go multi-column for the popover. You’ll see some friction from new users due to Accot’s law, otherwise.

I agree a two column layout would be nice, but I’m not sure there’s a great way to do it with the given options. The “Spread” option provides a nice visual stop in your layout, but one of the less important settings, it only matters when the inner miter is changed. Also “Face Strength Mode” is a long label, but I’m not sure it’s right to abbreviate it, which means it sort of has to be on its own line.

And with all 6 boolean options it starts to look imbalanced, which was also the problem the modifier had with its two column layout.

For the Bevel UI in the redo and modifier panels, blank space is one consideration, but space efficiency is another-- there are so many options that the modifier started to get tall enough that it just gets more annoying to scroll and move around if there is more blank space.

Don’t underestimate nested grid_flow elements.

image

2 Likes