From 65fdb3fa307abbec417abcf85d6624cdc402d235 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 16 Sep 2024 13:04:08 +0200 Subject: [PATCH] Grease Pencil: Properly support brushes with draw mode primitive tools Part of blender/blender!125449. Since brush assets were merged, the brush asset selector and some other brush UIs wouldn't show up for the primitive tools. This is addressed now. The primitive tools use the same brush as the brush tool, although only the draw brushes will work properly. !125449 addresses this so the primitive tools remember their own draw brush, separate from the brush tool. Turns out that these primitive tools were never tagged as using brushes by setting the `data_block` member (or setting the `'USE_BRUSHES'` option since b64bf66257). The UI was just hardcoded to display things like the brush selector for primitive tools. So as far as the tool system knew, these tools did not use brushes. Tagging the tools properly exposed some issues that are addressed here (see PR for details). Pull Request: https://projects.blender.org/blender/blender/pulls/127204 --- .../startup/bl_ui/space_toolsystem_toolbar.py | 18 ++++++++ scripts/startup/bl_ui/space_view3d.py | 11 +++++ .../editors/gpencil_legacy/gpencil_utils.cc | 2 +- .../grease_pencil/intern/grease_pencil_ops.cc | 20 ++++++++- .../editors/sculpt_paint/paint_intern.hh | 3 ++ .../editors/sculpt_paint/paint_stroke.cc | 42 +++++++++++++++---- source/blender/editors/sculpt_paint/sculpt.cc | 2 +- source/blender/windowmanager/WM_toolsystem.hh | 1 + .../windowmanager/intern/wm_toolsystem.cc | 6 +++ 9 files changed, 93 insertions(+), 12 deletions(-) diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 72a9c517630..e37d0f842ee 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -2019,6 +2019,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn @@ -2035,6 +2038,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn @@ -2051,6 +2057,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn @@ -2067,6 +2076,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn @@ -2083,6 +2095,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn @@ -2099,6 +2114,9 @@ class _defs_grease_pencil_paint: widget=None, keymap=(), draw_settings=draw_settings, + # Only allow draw brushes, no eraser, fill or tint. + data_block='DRAW', + options={'USE_BRUSHES'}, ) @ToolDef.from_fn diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index dd0f6be658e..b29468d7046 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -719,6 +719,17 @@ class _draw_tool_settings_context_mode: if (tool is None) or (not tool.use_brushes): return False + # These draw their own properties. + if tool.idname in { + "builtin.arc", + "builtin.curve", + "builtin.line", + "builtin.box", + "builtin.circle", + "builtin.polyline", + }: + return False + tool_settings = context.tool_settings paint = tool_settings.gpencil_paint diff --git a/source/blender/editors/gpencil_legacy/gpencil_utils.cc b/source/blender/editors/gpencil_legacy/gpencil_utils.cc index 3989fb43f03..63803ba4077 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_utils.cc +++ b/source/blender/editors/gpencil_legacy/gpencil_utils.cc @@ -1722,7 +1722,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) bool ED_gpencil_brush_cursor_poll(bContext *C) { - if (WM_toolsystem_active_tool_is_brush(C)) { + if (WM_toolsystem_active_tool_is_brush(C) && !WM_toolsystem_active_tool_has_custom_cursor(C)) { return true; } return false; diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc index 083f31b1d5f..6057d71395e 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc @@ -168,7 +168,7 @@ static void keymap_grease_pencil_vertex_paint_mode(wmKeyConfig *keyconf) keymap->poll = grease_pencil_vertex_painting_poll; } -/* Enabled for all tools except the fill tool. */ +/* Enabled for all tools except the fill tool and primitive tools. */ static bool keymap_grease_pencil_brush_stroke_poll(bContext *C) { if (!grease_pencil_painting_poll(C)) { @@ -177,6 +177,24 @@ static bool keymap_grease_pencil_brush_stroke_poll(bContext *C) if (!WM_toolsystem_active_tool_is_brush(C)) { return false; } + + /* Don't use the normal brush stroke keymap while the primitive tools are active. Otherwise + * simple mouse presses start freehand drawing instead of invoking the primitive operators. Could + * be a flag on the tool itself, for now making it a hardcoded exception. */ + if (const bToolRef *tref = WM_toolsystem_ref_from_context(C)) { + const Set primitive_tools = { + "builtin.line", + "builtin.polyline", + "builtin.arc", + "builtin.curve", + "builtin.box", + "builtin.circle", + }; + if (primitive_tools.contains(tref->idname)) { + return false; + } + } + ToolSettings *ts = CTX_data_tool_settings(C); Brush *brush = BKE_paint_brush(&ts->gp_paint->paint); return brush && brush->gpencil_settings && brush->gpencil_brush_type != GPAINT_BRUSH_TYPE_FILL; diff --git a/source/blender/editors/sculpt_paint/paint_intern.hh b/source/blender/editors/sculpt_paint/paint_intern.hh index c1d09fb1a2c..bac6cf4aefe 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.hh +++ b/source/blender/editors/sculpt_paint/paint_intern.hh @@ -132,7 +132,10 @@ void paint_stroke_jitter_pos(Scene &scene, const float mval[2], float r_mouse_out[2]); +/** Returns true if the active tool uses brushes. */ bool paint_brush_tool_poll(bContext *C); +/** Returns true if the brush cursor should be activated. */ +bool paint_brush_cursor_poll(bContext *C); bool paint_brush_update(bContext *C, const Brush &brush, PaintMode mode, diff --git a/source/blender/editors/sculpt_paint/paint_stroke.cc b/source/blender/editors/sculpt_paint/paint_stroke.cc index 3b6ca043c74..247f835512d 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.cc +++ b/source/blender/editors/sculpt_paint/paint_stroke.cc @@ -1533,8 +1533,11 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS br = BKE_paint_brush(paint); if (paint_supports_smooth_stroke(stroke, *br, mode)) { - stroke->stroke_cursor = WM_paint_cursor_activate( - SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_tool_poll, paint_draw_smooth_cursor, stroke); + stroke->stroke_cursor = WM_paint_cursor_activate(SPACE_TYPE_ANY, + RGN_TYPE_ANY, + paint_brush_cursor_poll, + paint_draw_smooth_cursor, + stroke); } if (br->flag & BRUSH_AIRBRUSH) { @@ -1544,7 +1547,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS if (br->flag & BRUSH_LINE) { stroke->stroke_cursor = WM_paint_cursor_activate( - SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_tool_poll, paint_draw_line_cursor, stroke); + SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_cursor_poll, paint_draw_line_cursor, stroke); } first_dab = true; @@ -1721,7 +1724,7 @@ bool paint_stroke_started(PaintStroke *stroke) return stroke->stroke_started; } -bool paint_brush_tool_poll(bContext *C) +static const bToolRef *brush_tool_get(const bContext *C) { Paint *paint = BKE_paint_get_active_from_context(C); Object *ob = CTX_data_active_object(C); @@ -1732,13 +1735,34 @@ bool paint_brush_tool_poll(bContext *C) (area && ELEM(area->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) && (region && region->regiontype == RGN_TYPE_WINDOW)) { - /* Check the current tool is a brush. */ - bToolRef *tref = area->runtime.tool; - if (tref && tref->runtime && (tref->runtime->flag & TOOLREF_FLAG_USE_BRUSHES)) { - return true; + if (area->runtime.tool && area->runtime.tool->runtime && + (area->runtime.tool->runtime->flag & TOOLREF_FLAG_USE_BRUSHES)) + { + return area->runtime.tool; } } - return false; + return nullptr; +} + +bool paint_brush_tool_poll(bContext *C) +{ + /* Check the current tool is a brush. */ + return brush_tool_get(C) != nullptr; +} + +bool paint_brush_cursor_poll(bContext *C) +{ + const bToolRef *tref = brush_tool_get(C); + if (!tref) { + return false; + } + + /* Don't use brush cursor when the tool sets its own cursor. */ + if (tref->runtime->cursor != WM_CURSOR_DEFAULT) { + return false; + } + + return true; } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 515ef0cc0a5..cb4e88ba216 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -3996,7 +3996,7 @@ static bool is_brush_related_tool(bContext *C) bool SCULPT_brush_cursor_poll(bContext *C) { using namespace blender::ed::sculpt_paint; - return SCULPT_mode_poll(C) && (paint_brush_tool_poll(C) || is_brush_related_tool(C)); + return SCULPT_mode_poll(C) && (paint_brush_cursor_poll(C) || is_brush_related_tool(C)); } static const char *sculpt_brush_type_name(const Sculpt &sd) diff --git a/source/blender/windowmanager/WM_toolsystem.hh b/source/blender/windowmanager/WM_toolsystem.hh index 3e9c7bd5562..ef9031942f2 100644 --- a/source/blender/windowmanager/WM_toolsystem.hh +++ b/source/blender/windowmanager/WM_toolsystem.hh @@ -95,6 +95,7 @@ void WM_toolsystem_update_from_context( * For paint modes to support non-brush tools. */ bool WM_toolsystem_active_tool_is_brush(const bContext *C); +bool WM_toolsystem_active_tool_has_custom_cursor(const bContext *C); /** Follow #wmMsgNotifyFn spec. */ void WM_toolsystem_do_msg_notify_tag_refresh(bContext *C, diff --git a/source/blender/windowmanager/intern/wm_toolsystem.cc b/source/blender/windowmanager/intern/wm_toolsystem.cc index d8b6653f9bf..d9410dd3aa0 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.cc +++ b/source/blender/windowmanager/intern/wm_toolsystem.cc @@ -784,6 +784,12 @@ bool WM_toolsystem_active_tool_is_brush(const bContext *C) return tref_rt && (tref_rt->flag & TOOLREF_FLAG_USE_BRUSHES); } +bool WM_toolsystem_active_tool_has_custom_cursor(const bContext *C) +{ + bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C); + return tref_rt && (tref_rt->cursor != WM_CURSOR_DEFAULT); +} + void WM_toolsystem_do_msg_notify_tag_refresh(bContext *C, wmMsgSubscribeKey * /*msg_key*/, wmMsgSubscribeValue *msg_val)