Sculpt/Paint: Add asset shelf option to filter brushes by the active tool #128450
@ -3,7 +3,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bpy.types import Menu, Panel
|
||||
|
||||
|
||||
class BrushAssetShelf:
|
||||
@ -18,12 +18,43 @@ class BrushAssetShelf:
|
||||
def poll(cls, context):
|
||||
return hasattr(context, "object") and context.object and context.object.mode == cls.mode
|
||||
|
||||
@classmethod
|
||||
def has_tool_with_brush_type(cls, context, brush_type):
|
||||
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
|
||||
space_type = context.space_data.type
|
||||
|
||||
brush_type_items = bpy.types.Brush.bl_rna.properties[cls.tool_prop].enum_items
|
||||
|
||||
tool_helper_cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
|
||||
for item in ToolSelectPanelHelper._tools_flatten(
|
||||
tool_helper_cls.tools_from_context(context, mode=context.mode),
|
||||
):
|
||||
if item is None:
|
||||
continue
|
||||
if item.idname in {
|
||||
"builtin.arc",
|
||||
"builtin.curve",
|
||||
"builtin.line",
|
||||
"builtin.box",
|
||||
"builtin.circle",
|
||||
"builtin.polyline",
|
||||
}:
|
||||
continue
|
||||
if item.options is None or ('USE_BRUSHES' not in item.options):
|
||||
continue
|
||||
if item.brush_type is not None:
|
||||
if brush_type_items[item.brush_type].value == brush_type:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@classmethod
|
||||
def brush_type_poll(cls, context, asset):
|
||||
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
|
||||
tool = ToolSelectPanelHelper.tool_active_from_context(context)
|
||||
|
||||
if not tool or tool.brush_type == 'ANY':
|
||||
if not tool:
|
||||
return True
|
||||
if not cls.brush_type_prop or not cls.tool_prop:
|
||||
return True
|
||||
@ -33,9 +64,14 @@ class BrushAssetShelf:
|
||||
# certain brush type.
|
||||
if asset_brush_type is None:
|
||||
return False
|
||||
brush_type_items = bpy.types.Brush.bl_rna.properties[cls.tool_prop].enum_items
|
||||
|
||||
return brush_type_items[asset_brush_type].identifier == tool.brush_type
|
||||
# For the general brush that supports any brush type, filter out brushes that show up for
|
||||
# other tools already.
|
||||
if tool.brush_type == 'ANY':
|
||||
return not cls.has_tool_with_brush_type(context, asset_brush_type)
|
||||
|
||||
brush_type_items = bpy.types.Brush.bl_rna.properties[cls.tool_prop].enum_items
|
||||
return brush_type_items[tool.brush_type].value == asset_brush_type
|
||||
|
||||
@classmethod
|
||||
def asset_poll(cls, asset):
|
||||
@ -45,12 +81,13 @@ class BrushAssetShelf:
|
||||
return False
|
||||
|
||||
context = bpy.context
|
||||
prefs = context.preferences
|
||||
|
||||
is_asset_shelf_region = context.region and context.region.type == 'ASSET_SHELF'
|
||||
# Show all brushes in the permanent asset shelf region. Otherwise filter out brushes that
|
||||
# Show all brushes in the popup asset shelves. Otherwise filter out brushes that
|
||||
# are incompatible with the tool.
|
||||
if not is_asset_shelf_region and not cls.brush_type_poll(context, asset):
|
||||
return False
|
||||
if is_asset_shelf_region and prefs.view.use_filter_brushes_by_tool:
|
||||
return cls.brush_type_poll(context, asset)
|
||||
|
||||
return True
|
||||
|
||||
@ -112,6 +149,25 @@ class BrushAssetShelf:
|
||||
)
|
||||
|
||||
|
||||
class VIEW3D_PT_brush_asset_shelf_filter(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filter"
|
||||
bl_parent_id = "ASSETSHELF_PT_display"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if context.asset_shelf is None:
|
||||
return False
|
||||
return context.asset_shelf.bl_idname == BrushAssetShelf.get_shelf_name_from_context(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
prefs = context.preferences
|
||||
|
||||
layout.prop(prefs.view, "use_filter_brushes_by_tool", text="By Active Tool")
|
||||
|
||||
|
||||
class UnifiedPaintPanel:
|
||||
# subclass must set
|
||||
# bl_space_type = 'IMAGE_EDITOR'
|
||||
@ -1828,6 +1884,7 @@ def brush_basic_grease_pencil_vertex_settings(layout, context, brush, *, compact
|
||||
|
||||
|
||||
classes = (
|
||||
VIEW3D_PT_brush_asset_shelf_filter,
|
||||
VIEW3D_MT_tools_projectpaint_clone,
|
||||
)
|
||||
|
||||
|
@ -31,7 +31,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 0
|
||||
#define BLENDER_FILE_SUBVERSION 1
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
@ -946,7 +946,7 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
|
||||
if (!USER_VERSION_ATLEAST(400, 24)) {
|
||||
/* Clear deprecated USER_MENUFIXEDORDER user flag for reuse. */
|
||||
userdef->uiflag &= ~USER_UIFLAG_UNUSED_4;
|
||||
userdef->uiflag &= ~(1 << 23);
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(400, 26)) {
|
||||
@ -1064,6 +1064,10 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
userdef->sequencer_editor_flag |= USER_SEQ_ED_CONNECT_STRIPS_BY_DEFAULT;
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(403, 30)) {
|
||||
userdef->uiflag |= USER_FILTER_BRUSHES_BY_TOOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
|
||||
|
@ -1294,7 +1294,8 @@ typedef enum eUserpref_UI_Flag {
|
||||
USER_ZOOM_TO_MOUSEPOS = (1 << 20),
|
||||
USER_SHOW_FPS = (1 << 21),
|
||||
USER_REGISTER_ALL_USERS = (1 << 22),
|
||||
USER_UIFLAG_UNUSED_4 = (1 << 23), /* Cleared. */
|
||||
/** Actually implemented in .py. */
|
||||
USER_FILTER_BRUSHES_BY_TOOL = (1 << 23),
|
||||
USER_CONTINUOUS_MOUSE = (1 << 24),
|
||||
USER_ZOOM_INVERT = (1 << 25),
|
||||
USER_ZOOM_HORIZ = (1 << 26), /* for CONTINUE and DOLLY zoom */
|
||||
|
@ -5323,6 +5323,14 @@ static void rna_def_userdef_view(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "uiflag", USER_PLAINMENUS);
|
||||
RNA_def_property_ui_text(prop, "Toolbox Column Layout", "Use a column layout for toolbox");
|
||||
|
||||
prop = RNA_def_property(srna, "use_filter_brushes_by_tool", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "uiflag", USER_FILTER_BRUSHES_BY_TOOL);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Filter Brushes by Tool",
|
||||
"Only show brushes applicable for the currently active tool in the "
|
||||
"asset shelf. Stored in the Preferences, which may have to be saved "
|
||||
"manually if Auto-Save Preferences is disabled");
|
||||
|
||||
static const EnumPropertyItem header_align_items[] = {
|
||||
{0, "NONE", 0, "Keep Existing", "Keep existing header alignment"},
|
||||
{USER_HEADER_FROM_PREF, "TOP", 0, "Top", "Top aligned on load"},
|
||||
|
Loading…
Reference in New Issue
Block a user