Blender V4.3
wm_toolsystem.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <cstring>
12
13#include "CLG_log.h"
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_listbase.h"
18#include "BLI_string.h"
19#include "BLI_utildefines.h"
20
21#include "DNA_ID.h"
22#include "DNA_brush_types.h"
23#include "DNA_object_types.h"
24#include "DNA_scene_types.h"
25#include "DNA_space_types.h"
27#include "DNA_workspace_types.h"
28
29#include "BKE_asset_edit.hh"
30#include "BKE_brush.hh"
31#include "BKE_context.hh"
32#include "BKE_idprop.hh"
33#include "BKE_layer.hh"
34#include "BKE_lib_id.hh"
35#include "BKE_main.hh"
36#include "BKE_paint.hh"
37#include "BKE_workspace.hh"
38
39#include "RNA_access.hh"
40#include "RNA_enum_types.hh"
41
42#include "WM_api.hh"
43#include "WM_message.hh"
44#include "WM_toolsystem.hh" /* Own include. */
45#include "WM_types.hh"
46
47static void toolsystem_reinit_with_toolref(bContext *C, WorkSpace * /*workspace*/, bToolRef *tref);
49 WorkSpace *workspace,
50 const bToolKey *tkey,
51 const char *default_tool);
53 WorkSpace *workspace,
54 bToolRef *tref);
55static void toolsystem_ref_set_by_brush_type(bContext *C, const char *brush_type);
56
57/* -------------------------------------------------------------------- */
60
62{
63 WorkSpace *workspace = CTX_wm_workspace(C);
64 if (workspace == nullptr) {
65 return nullptr;
66 }
67 const Scene *scene = CTX_data_scene(C);
68 ViewLayer *view_layer = CTX_data_view_layer(C);
69 ScrArea *area = CTX_wm_area(C);
70 if ((area == nullptr) || ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
71 return nullptr;
72 }
73 bToolKey tkey{};
74 tkey.space_type = area->spacetype;
75 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
76 bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
77 /* We could return 'area->runtime.tool' in this case. */
78 if (area->runtime.is_tool_set) {
79 BLI_assert(tref == area->runtime.tool);
80 }
81 return tref;
82}
83
85{
87 return tref ? tref->runtime : nullptr;
88}
89
91{
93 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
94 if ((tref->space_type == tkey->space_type) && (tref->mode == tkey->mode)) {
95 return tref;
96 }
97 }
98 return nullptr;
99}
100
102{
103 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
104 return tref ? tref->runtime : nullptr;
105}
106
107bool WM_toolsystem_ref_ensure(WorkSpace *workspace, const bToolKey *tkey, bToolRef **r_tref)
108{
109 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
110 if (tref) {
111 *r_tref = tref;
112 return false;
113 }
114 tref = static_cast<bToolRef *>(MEM_callocN(sizeof(*tref), __func__));
115 BLI_addhead(&workspace->tools, tref);
116 tref->space_type = tkey->space_type;
117 tref->mode = tkey->mode;
118 *r_tref = tref;
119 return true;
120}
121
126 ViewLayer *view_layer,
127 ScrArea *area)
128{
129 bToolKey tkey{};
130
131 if (area && ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK)) {
132 tkey.space_type = area->spacetype;
133 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
134 return tkey;
135 }
136
137 /* Otherwise: Fallback to getting the active tool for 3D views. */
139 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, nullptr, SPACE_VIEW3D);
140 return tkey;
141}
142
151{
152 /* Current space & mode has its own active tool, use that. */
153 const ScrArea *area = CTX_wm_area(C);
154 if (area && ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK)) {
156 }
157
158 /* Otherwise: Fallback to getting the active tool for 3D views. */
159 WorkSpace *workspace = CTX_wm_workspace(C);
160 if (workspace == nullptr) {
161 return nullptr;
162 }
163 const Scene *scene = CTX_data_scene(C);
164 ViewLayer *view_layer = CTX_data_view_layer(C);
165 bToolKey tkey{};
167 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, nullptr, SPACE_VIEW3D);
168 return WM_toolsystem_ref_find(workspace, &tkey);
169}
170
172
173static void toolsystem_unlink_ref(bContext *C, WorkSpace * /*workspace*/, bToolRef *tref)
174{
175 bToolRef_Runtime *tref_rt = tref->runtime;
176
177 if (tref_rt->gizmo_group[0]) {
178 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false);
179 if (gzgt != nullptr) {
180 Main *bmain = CTX_data_main(C);
181 WM_gizmo_group_remove_by_tool(C, bmain, gzgt, tref);
182 }
183 }
184}
185void WM_toolsystem_unlink(bContext *C, WorkSpace *workspace, const bToolKey *tkey)
186{
187 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
188 if (tref && tref->runtime) {
189 toolsystem_unlink_ref(C, workspace, tref);
190 }
191}
192
193/* -------------------------------------------------------------------- */
196
197static const char *brush_type_identifier_get(const int brush_type, const PaintMode paint_mode)
198{
199 const EnumPropertyItem *type_enum = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
200 const int item_idx = RNA_enum_from_value(type_enum, brush_type);
201 if (item_idx == -1) {
202 return "";
203 }
204 return type_enum[item_idx].identifier;
205}
206
207static bool brush_type_matches_active_tool(bContext *C, const int brush_type)
208{
210
211 if (!(active_tool->runtime->flag & TOOLREF_FLAG_USE_BRUSHES)) {
212 return false;
213 }
214
216 return active_tool->runtime->brush_type == brush_type;
217}
218
220 const char *brush_type_name)
221{
222 return static_cast<NamedBrushAssetReference *>(
224 brush_type_name,
226}
227
232{
235
236 if (paint->brush != nullptr) {
237 if (std::optional<AssetWeakReference> brush_asset_reference =
239 {
240 paint->tool_brush_bindings.main_brush_asset_reference = MEM_new<AssetWeakReference>(
241 __func__, *brush_asset_reference);
242 }
243 }
244}
245
247 const PaintMode paint_mode,
248 const int brush_type)
249{
250 if (paint->brush == nullptr) {
251 return;
252 }
253 const char *brush_type_name = brush_type_identifier_get(brush_type, paint_mode);
254 if (!brush_type_name || !brush_type_name[0]) {
255 return;
256 }
257
258 /* Update existing reference. */
260 paint, brush_type_name))
261 {
262 MEM_delete(existing_brush_ref->brush_asset_reference);
263 existing_brush_ref->brush_asset_reference = MEM_new<AssetWeakReference>(
264 __func__, *paint->brush_asset_reference);
265 }
266 /* Add new reference. */
267 else {
268 NamedBrushAssetReference *new_brush_ref = MEM_cnew<NamedBrushAssetReference>(__func__);
269
270 new_brush_ref->name = BLI_strdup(brush_type_name);
271 new_brush_ref->brush_asset_reference = MEM_new<AssetWeakReference>(
272 __func__, *paint->brush_asset_reference);
274 }
275}
276
278{
281
282 if (!BKE_paint_brush_poll(paint, brush)) {
283 /* Avoid switching tool when brush isn't valid for this mode anyway. */
284 return false;
285 }
286
287 /* If necessary, find a compatible tool to switch to. */
288 {
289 std::optional<int> brush_type = BKE_paint_get_brush_type_from_paintmode(brush, paint_mode);
290 if (!brush_type) {
292 WM_toolsystem_ref_set_by_id(C, "builtin.brush");
293 }
294 else if (!brush_type_matches_active_tool(C, *brush_type)) {
295 const char *brush_type_name = brush_type_identifier_get(*brush_type, paint_mode);
296 /* Calls into .py to query available tools. */
297 toolsystem_ref_set_by_brush_type(C, brush_type_name);
298 }
299 }
300
301 /* Do after switching tool, since switching tool will attempt to restore the last used brush of
302 * that tool (in #toolsystem_brush_activate_from_toolref_for_object_paint()). */
303 if (!BKE_paint_brush_set(paint, brush)) {
304 return false;
305 }
306
307 if (active_tool->runtime->brush_type == -1) {
308 /* Only update the main brush binding to reference the newly active brush. */
310 }
311 else {
312 toolsystem_brush_type_binding_update(paint, paint_mode, active_tool->runtime->brush_type);
313 }
314
315 return true;
316}
317
319 const WorkSpace *workspace,
320 const bToolRef *tref)
321{
322 const Main *bmain = CTX_data_main(C);
323 const bToolRef_Runtime *tref_rt = tref->runtime;
324
325 if (!tref_rt->data_block[0]) {
326 return;
327 }
328
330 const int i = RNA_enum_from_identifier(items, tref_rt->data_block);
331 if (i == -1) {
332 return;
333 }
334
335 const wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
336 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
337 if (workspace == WM_window_get_active_workspace(win)) {
338 Scene *scene = WM_window_get_active_scene(win);
339 ToolSettings *ts = scene->toolsettings;
340 ts->particle.brushtype = items[i].value;
341 }
342 }
343}
344
346 const WorkSpace *workspace,
347 const bToolRef *tref)
348{
349 Main *bmain = CTX_data_main(C);
350 bToolRef_Runtime *tref_rt = tref->runtime;
351
352 const PaintMode paint_mode = BKE_paintmode_get_from_tool(tref);
353 BLI_assert(paint_mode != PaintMode::Invalid);
354
355 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
356 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
357 if (workspace != WM_window_get_active_workspace(win)) {
358 continue;
359 }
360 Scene *scene = WM_window_get_active_scene(win);
361 BKE_paint_ensure_from_paintmode(scene, paint_mode);
362 Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
363
364 /* Attempt to re-activate a brush remembered for this brush type, as stored in a brush
365 * binding. */
366 if (tref_rt->brush_type != -1) {
367 std::optional<AssetWeakReference> brush_asset_reference =
368 [&]() -> std::optional<AssetWeakReference> {
369 const char *brush_type_name = brush_type_identifier_get(tref_rt->brush_type, paint_mode);
371 paint, brush_type_name);
372
373 if (brush_ref && brush_ref->brush_asset_reference) {
374 return *brush_ref->brush_asset_reference;
375 }
376 /* No remembered brush found for this type, use a default for the type. */
378 tref_rt->brush_type);
379 }();
380
381 if (brush_asset_reference) {
382 BKE_paint_brush_set(bmain, paint, &*brush_asset_reference);
383 }
384 }
385 /* Re-activate the main brush, regardless of the brush type. */
386 else {
390 }
391 else {
392 std::optional<AssetWeakReference> main_brush_asset_reference =
393 [&]() -> std::optional<AssetWeakReference> {
396 }
398 std::nullopt);
399 }();
400
401 if (main_brush_asset_reference) {
402 BKE_paint_brush_set(bmain, paint, &*main_brush_asset_reference);
404 }
405 }
406 }
407 }
408}
409
414 const WorkSpace *workspace,
415 const bToolRef *tref)
416{
418
419 if (tref->space_type == SPACE_VIEW3D) {
420 if (tref->mode == CTX_MODE_PARTICLE) {
422 }
423 else {
425 }
426 }
427 else if (tref->space_type == SPACE_IMAGE) {
428 if (tref->mode == SI_MODE_PAINT) {
430 }
431 }
432}
433
435
436static void toolsystem_ref_link(const bContext *C, WorkSpace *workspace, bToolRef *tref)
437{
438 bToolRef_Runtime *tref_rt = tref->runtime;
439 if (tref_rt->gizmo_group[0]) {
440 const char *idname = tref_rt->gizmo_group;
441 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
442 if (gzgt != nullptr) {
443 if ((gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_INIT) == 0) {
445 /* Even if the group-type was has been linked, it's possible the space types
446 * were not previously using it. (happens with multiple windows). */
449 }
450 }
451 }
452 else {
453 CLOG_WARN(WM_LOG_TOOLS, "'%s' widget not found", idname);
454 }
455 }
456
457 if (tref_rt->flag & TOOLREF_FLAG_USE_BRUSHES) {
459 }
460}
461
462static void toolsystem_refresh_ref(const bContext *C, WorkSpace *workspace, bToolRef *tref)
463{
464 if (tref->runtime == nullptr) {
465 return;
466 }
467 /* Currently same operation. */
468 toolsystem_ref_link(C, workspace, tref);
469}
470void WM_toolsystem_refresh(const bContext *C, WorkSpace *workspace, const bToolKey *tkey)
471{
472 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
473 if (tref) {
474 toolsystem_refresh_ref(C, workspace, tref);
475 }
476}
477
478static void toolsystem_reinit_ref(bContext *C, WorkSpace *workspace, bToolRef *tref)
479{
480 toolsystem_reinit_with_toolref(C, workspace, tref);
481}
482void WM_toolsystem_reinit(bContext *C, WorkSpace *workspace, const bToolKey *tkey)
483{
484 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
485 if (tref) {
486 toolsystem_reinit_ref(C, workspace, tref);
487 }
488}
489
491{
492 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
493 tref->tag = 0;
494 }
495
496 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
497 if (tref->runtime) {
498 if (tref->tag == 0) {
499 toolsystem_unlink_ref(C, workspace, tref);
500 tref->tag = 1;
501 }
502 }
503 }
504}
505
507{
508 BLI_assert(0);
509 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
510 toolsystem_refresh_ref(C, workspace, tref);
511 }
512}
514{
516 const Scene *scene = WM_window_get_active_scene(win);
518 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
519 if (((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
520 continue;
521 }
522
524 bToolKey tkey{};
525 tkey.space_type = area->spacetype;
526 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
527 bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
528 if (tref) {
529 if (tref->tag == 0) {
530 toolsystem_reinit_ref(C, workspace, tref);
531 tref->tag = 1;
532 }
533 }
534 }
535}
536
538 WorkSpace *workspace,
539 bToolRef *tref,
540 const bToolRef_Runtime *tref_rt,
541 const char *idname)
542{
543 Main *bmain = CTX_data_main(C);
544
545 if (tref->runtime) {
546 toolsystem_unlink_ref(C, workspace, tref);
547 }
548
549 STRNCPY(tref->idname, idname);
550
551 if (tref->runtime == nullptr) {
552 tref->runtime = static_cast<bToolRef_Runtime *>(MEM_callocN(sizeof(*tref->runtime), __func__));
553 }
554
555 if (tref_rt != tref->runtime) {
556 *tref->runtime = *tref_rt;
557 }
558
559 /* Ideally Python could check this gizmo group flag and not
560 * pass in the argument to begin with. */
561 bool use_fallback_keymap = false;
562
563 if (tref->idname_fallback[0] || tref->runtime->keymap_fallback[0]) {
564 if (tref_rt->flag & TOOLREF_FLAG_FALLBACK_KEYMAP) {
565 use_fallback_keymap = true;
566 }
567 else if (tref_rt->gizmo_group[0]) {
568 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false);
569 if (gzgt) {
571 use_fallback_keymap = true;
572 }
573 }
574 }
575 }
576 if (use_fallback_keymap == false) {
577 tref->idname_fallback[0] = '\0';
578 tref->runtime->keymap_fallback[0] = '\0';
579 }
580
581 toolsystem_ref_link(C, workspace, tref);
582
583 toolsystem_refresh_screen_from_active_tool(bmain, workspace, tref);
584
585 /* Set the cursor if possible, if not - it's fine as entering the region will refresh it. */
586 {
587 wmWindow *win = CTX_wm_window(C);
588 if (win != nullptr) {
589 win->addmousemove = true;
590 win->tag_cursor_refresh = true;
591 }
592 }
593
594 {
596 WM_msg_publish_rna_prop(mbus, &workspace->id, workspace, WorkSpace, tools);
597 }
598}
599
601{
602 bToolRef_Runtime *tref_rt = tref->runtime;
603 if ((tref_rt == nullptr) || (tref_rt->data_block[0] == '\0')) {
604 return;
605 }
606 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
607 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
608 if (workspace != WM_window_get_active_workspace(win)) {
609 continue;
610 }
611
612 Scene *scene = WM_window_get_active_scene(win);
613 ToolSettings *ts = scene->toolsettings;
615 BKE_view_layer_synced_ensure(scene, view_layer);
616 const Object *ob = BKE_view_layer_active_object_get(view_layer);
617 if (ob == nullptr) {
618 /* Pass. */
619 }
620 if ((tref->space_type == SPACE_VIEW3D) && (tref->mode == CTX_MODE_PARTICLE)) {
621 if (ob->mode & OB_MODE_PARTICLE_EDIT) {
623 const int i = RNA_enum_from_value(items, ts->particle.brushtype);
624 const EnumPropertyItem *item = &items[i];
625 if (!STREQ(tref_rt->data_block, item->identifier)) {
626 STRNCPY(tref_rt->data_block, item->identifier);
627 SNPRINTF(tref->idname, "builtin_brush.%s", item->name);
628 }
629 }
630 }
631 }
632}
633
635{
636 Main *bmain = CTX_data_main(C);
637
638 BLI_assert(CTX_wm_window(C) == nullptr);
639
640 LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
641 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
642 MEM_SAFE_FREE(tref->runtime);
643 }
644 }
645
646 /* Rely on screen initialization for gizmos. */
647}
648
649static bool toolsystem_key_ensure_check(const bToolKey *tkey)
650{
651 switch (tkey->space_type) {
652 case SPACE_VIEW3D:
653 return true;
654 case SPACE_IMAGE:
655 if (ELEM(tkey->mode, SI_MODE_PAINT, SI_MODE_UV)) {
656 return true;
657 }
658 break;
659 case SPACE_NODE:
660 return true;
661 case SPACE_SEQ:
662 return true;
663 }
664 return false;
665}
666
668 ViewLayer *view_layer,
669 ScrArea *area,
670 int space_type)
671{
672 int mode = -1;
673 switch (space_type) {
674 case SPACE_VIEW3D: {
675 /* 'area' may be nullptr in this case. */
676 BKE_view_layer_synced_ensure(scene, view_layer);
677 Object *obact = BKE_view_layer_active_object_get(view_layer);
678 if (obact != nullptr) {
679 Object *obedit = OBEDIT_FROM_OBACT(obact);
680 mode = CTX_data_mode_enum_ex(obedit, obact, eObjectMode(obact->mode));
681 }
682 else {
683 mode = CTX_MODE_OBJECT;
684 }
685 break;
686 }
687 case SPACE_IMAGE: {
688 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
689 mode = sima->mode;
690 break;
691 }
692 case SPACE_NODE: {
693 mode = 0;
694 break;
695 }
696 case SPACE_SEQ: {
697 SpaceSeq *sseq = static_cast<SpaceSeq *>(area->spacedata.first);
698 mode = sseq->view;
699 break;
700 }
701 }
702 return mode;
703}
704
706 ViewLayer *view_layer,
707 ScrArea *area,
708 bToolKey *tkey)
709{
710 int space_type = SPACE_EMPTY;
711 int mode = -1;
712
713 if (area != nullptr) {
714 space_type = area->spacetype;
715 mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, space_type);
716 }
717
718 if (mode != -1) {
719 tkey->space_type = space_type;
720 tkey->mode = mode;
721 return true;
722 }
723 return false;
724}
725
727{
728 Main *bmain = CTX_data_main(C);
729
730 struct {
731 wmWindow *win;
732 ScrArea *area;
733 ARegion *region;
734 bool is_set;
735 } context_prev = {nullptr};
736
737 for (wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first); wm;
738 wm = static_cast<wmWindowManager *>(wm->id.next))
739 {
740 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
743 const Scene *scene = WM_window_get_active_scene(win);
745 /* Could skip loop for modes that don't depend on space type. */
746 int space_type_mask_handled = 0;
747 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
748 /* Don't change the space type of the active tool, only update its mode. */
749 const int space_type_mask = (1 << area->spacetype);
750 if ((space_type_mask & WM_TOOLSYSTEM_SPACE_MASK) &&
751 ((space_type_mask_handled & space_type_mask) == 0))
752 {
753 space_type_mask_handled |= space_type_mask;
754 bToolKey tkey{};
755 tkey.space_type = area->spacetype;
756 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
757 bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
758 if (tref != area->runtime.tool) {
759 if (context_prev.is_set == false) {
760 context_prev.win = CTX_wm_window(C);
761 context_prev.area = CTX_wm_area(C);
762 context_prev.region = CTX_wm_region(C);
763 context_prev.is_set = true;
764 }
765
766 CTX_wm_window_set(C, win);
767 CTX_wm_area_set(C, area);
768
769 toolsystem_reinit_ensure_toolref(C, workspace, &tkey, nullptr);
770 }
771 }
772 }
773 }
774 }
775
776 if (context_prev.is_set) {
777 CTX_wm_window_set(C, context_prev.win);
778 CTX_wm_area_set(C, context_prev.area);
779 CTX_wm_region_set(C, context_prev.region);
780 }
781
783
784 LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
785 if (workspace->id.tag & ID_TAG_DOIT) {
786 workspace->id.tag &= ~ID_TAG_DOIT;
787 /* Refresh to ensure data is initialized.
788 * This is needed because undo can load a state which no longer has the underlying DNA data
789 * needed for the tool (un-initialized paint-slots for eg), see: #64339. */
790 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
791 toolsystem_refresh_ref(C, workspace, tref);
792 }
793 }
794 }
795}
796
798 const Scene *scene,
799 ViewLayer *view_layer,
800 ScrArea *area)
801{
802 const bool is_tool_set_prev = area->runtime.is_tool_set;
803 const bToolRef *tref_prev = area->runtime.tool;
804
805 area->runtime.tool = nullptr;
806 area->runtime.is_tool_set = true;
807 const int mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
808 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
809 if (tref->space_type == area->spacetype) {
810 if (tref->mode == mode) {
811 area->runtime.tool = tref;
812 break;
813 }
814 }
815 }
816 return !(is_tool_set_prev && (tref_prev == area->runtime.tool));
817}
818
820{
822 bool space_type_has_tools[SPACE_TYPE_NUM] = {false};
823 LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
824 space_type_has_tools[tref->space_type] = true;
825 }
827 const Scene *scene = WM_window_get_active_scene(win);
829 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
830 area->runtime.tool = nullptr;
831 area->runtime.is_tool_set = true;
832 if (space_type_has_tools[area->spacetype]) {
833 WM_toolsystem_refresh_screen_area(workspace, scene, view_layer, area);
834 }
835 }
836}
837
839{
840 /* Update all ScrArea's tools. */
841 for (wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first); wm;
842 wm = static_cast<wmWindowManager *>(wm->id.next))
843 {
844 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
846 }
847 }
848}
849
851 WorkSpace *workspace,
852 bToolRef *tref)
853{
854 /* Update all ScrArea's tools. */
855 for (wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first); wm;
856 wm = static_cast<wmWindowManager *>(wm->id.next))
857 {
858 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
859 if (workspace == WM_window_get_active_workspace(win)) {
861 const Scene *scene = WM_window_get_active_scene(win);
863 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
864 if (area->spacetype == tref->space_type) {
865 int mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
866 if (mode == tref->mode) {
867 area->runtime.tool = tref;
868 area->runtime.is_tool_set = true;
869 }
870 }
871 }
872 }
873 }
874 }
875}
876
878 bContext *C, WorkSpace *workspace, const bToolKey *tkey, const char *name, bool cycle)
879{
880 wmOperatorType *ot = WM_operatortype_find("WM_OT_tool_set_by_id", false);
881 /* On startup, Python operators are not yet loaded. */
882 if (ot == nullptr) {
883 return nullptr;
884 }
885
886/* Some contexts use the current space type (image editor for e.g.),
887 * ensure this is set correctly or there is no area. */
888#ifndef NDEBUG
889 /* Exclude this check for some space types where the space type isn't used. */
891 ScrArea *area = CTX_wm_area(C);
892 BLI_assert(area == nullptr || area->spacetype == tkey->space_type);
893 }
894#endif
895
896 PointerRNA op_props;
898 RNA_string_set(&op_props, "name", name);
899
901
902 RNA_enum_set(&op_props, "space_type", tkey->space_type);
903 RNA_boolean_set(&op_props, "cycle", cycle);
904
905 WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props, nullptr);
907
908 bToolRef *tref = WM_toolsystem_ref_find(workspace, tkey);
909
910 if (tref) {
911 Main *bmain = CTX_data_main(C);
912 toolsystem_refresh_screen_from_active_tool(bmain, workspace, tref);
913 }
914
915 return (tref && STREQ(tref->idname, name)) ? tref : nullptr;
916}
917
919{
920 const Scene *scene = CTX_data_scene(C);
921 ViewLayer *view_layer = CTX_data_view_layer(C);
922 ScrArea *area = CTX_wm_area(C);
923 bToolKey tkey;
924 if (WM_toolsystem_key_from_context(scene, view_layer, area, &tkey)) {
925 WorkSpace *workspace = CTX_wm_workspace(C);
926 return WM_toolsystem_ref_set_by_id_ex(C, workspace, &tkey, name, false);
927 }
928 return nullptr;
929}
930
931static void toolsystem_ref_set_by_brush_type(bContext *C, const char *brush_type)
932{
933 const Scene *scene = CTX_data_scene(C);
934 ViewLayer *view_layer = CTX_data_view_layer(C);
935 ScrArea *area = CTX_wm_area(C);
936 const bToolKey tkey = toolsystem_key_from_context_or_view3d(scene, view_layer, area);
937 WorkSpace *workspace = CTX_wm_workspace(C);
938
939 wmOperatorType *ot = WM_operatortype_find("WM_OT_tool_set_by_brush_type", false);
940 /* On startup, Python operators are not yet loaded. */
941 if (ot == nullptr) {
942 return;
943 }
944
945/* Some contexts use the current space type (image editor for e.g.),
946 * ensure this is set correctly or there is no area. */
947#ifndef NDEBUG
948 /* Exclude this check for some space types where the space type isn't used. */
950 ScrArea *area = CTX_wm_area(C);
951 BLI_assert(area == nullptr || area->spacetype == tkey.space_type);
952 }
953#endif
954
955 PointerRNA op_props;
957 RNA_string_set(&op_props, "brush_type", brush_type);
958
960
961 RNA_enum_set(&op_props, "space_type", tkey.space_type);
962
963 WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props, nullptr);
965
966 bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
967
968 if (tref) {
969 Main *bmain = CTX_data_main(C);
970 toolsystem_refresh_screen_from_active_tool(bmain, workspace, tref);
971 }
972}
973
975{
976 bToolKey tkey{};
977 tkey.space_type = tref->space_type;
978 tkey.mode = tref->mode;
979 WM_toolsystem_ref_set_by_id_ex(C, workspace, &tkey, tref->idname, false);
980}
981
982static const char *toolsystem_default_tool(const bToolKey *tkey)
983{
984 switch (tkey->space_type) {
985 case SPACE_VIEW3D:
986 switch (tkey->mode) {
987 case CTX_MODE_SCULPT:
1000 return "builtin.brush";
1001 case CTX_MODE_PARTICLE:
1002 return "builtin_brush.Comb";
1003 case CTX_MODE_EDIT_TEXT:
1004 return "builtin.select_text";
1005 }
1006 break;
1007 case SPACE_IMAGE:
1008 switch (tkey->mode) {
1009 case SI_MODE_PAINT:
1010 return "builtin.brush";
1011 }
1012 break;
1013 case SPACE_NODE: {
1014 return "builtin.select_box";
1015 }
1016 case SPACE_SEQ: {
1017 return "builtin.select_box";
1018 }
1019 }
1020
1021 return "builtin.select_box";
1022}
1023
1028 WorkSpace *workspace,
1029 const bToolKey *tkey,
1030 const char *default_tool)
1031{
1032 bToolRef *tref;
1033 if (WM_toolsystem_ref_ensure(workspace, tkey, &tref)) {
1034 if (default_tool == nullptr) {
1035 default_tool = toolsystem_default_tool(tkey);
1036 }
1037 STRNCPY(tref->idname, default_tool);
1038 }
1039 toolsystem_reinit_with_toolref(C, workspace, tref);
1040 return tref;
1041}
1042
1044{
1045 const Scene *scene = CTX_data_scene(C);
1046 ViewLayer *view_layer = CTX_data_view_layer(C);
1047 int space_type = SPACE_VIEW3D;
1048 bToolKey tkey{};
1049 tkey.space_type = space_type;
1050 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, nullptr, space_type);
1051 toolsystem_reinit_ensure_toolref(C, workspace, &tkey, nullptr);
1052}
1053
1055{
1056 WorkSpace *workspace = CTX_wm_workspace(C);
1057 if (workspace) {
1059 }
1060
1061 /* Multi window support. */
1062 Main *bmain = CTX_data_main(C);
1063 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
1064 if (!BLI_listbase_is_single(&wm->windows)) {
1065 wmWindow *win_prev = CTX_wm_window(C);
1066 ScrArea *area_prev = CTX_wm_area(C);
1067 ARegion *region_prev = CTX_wm_region(C);
1068
1069 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
1070 if (win != win_prev) {
1071 WorkSpace *workspace_iter = WM_window_get_active_workspace(win);
1072 if (workspace_iter != workspace) {
1073
1074 CTX_wm_window_set(C, win);
1075
1077
1078 CTX_wm_window_set(C, win_prev);
1079 CTX_wm_area_set(C, area_prev);
1080 CTX_wm_region_set(C, region_prev);
1081 }
1082 }
1083 }
1084 }
1085}
1086
1088 bContext *C, WorkSpace *workspace, const Scene *scene, ViewLayer *view_layer, ScrArea *area)
1089{
1090 bToolKey tkey{};
1091 tkey.space_type = area->spacetype;
1092 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
1093 if (toolsystem_key_ensure_check(&tkey)) {
1094 toolsystem_reinit_ensure_toolref(C, workspace, &tkey, nullptr);
1095 }
1096}
1097
1099{
1101 return tref_rt && (tref_rt->flag & TOOLREF_FLAG_USE_BRUSHES);
1102}
1103
1105{
1107 return tref_rt && (tref_rt->cursor != WM_CURSOR_DEFAULT);
1108}
1109
1111 wmMsgSubscribeKey * /*msg_key*/,
1112 wmMsgSubscribeValue *msg_val)
1113{
1114 ScrArea *area = static_cast<ScrArea *>(msg_val->user_data);
1115 Main *bmain = CTX_data_main(C);
1116 wmWindow *win = static_cast<wmWindow *>(((wmWindowManager *)bmain->wm.first)->windows.first);
1117 if (win->next != nullptr) {
1118 do {
1119 bScreen *screen = WM_window_get_active_screen(win);
1120 if (BLI_findindex(&screen->areabase, area) != -1) {
1121 break;
1122 }
1123 } while ((win = win->next));
1124 }
1125
1126 WorkSpace *workspace = WM_window_get_active_workspace(win);
1127 const Scene *scene = WM_window_get_active_scene(win);
1128 ViewLayer *view_layer = WM_window_get_active_view_layer(win);
1129
1130 bToolKey tkey{};
1131 tkey.space_type = area->spacetype;
1132 tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
1133 WM_toolsystem_refresh(C, workspace, &tkey);
1134 WM_toolsystem_refresh_screen_area(workspace, scene, view_layer, area);
1135}
1136
1137static IDProperty *idprops_ensure_named_group(IDProperty *group, const char *idname)
1138{
1139 IDProperty *prop = IDP_GetPropertyFromGroup(group, idname);
1140 if ((prop == nullptr) || (prop->type != IDP_GROUP)) {
1141 prop = blender::bke::idprop::create_group(__func__).release();
1142 STRNCPY(prop->name, idname);
1143 IDP_ReplaceInGroup_ex(group, prop, nullptr);
1144 }
1145 return prop;
1146}
1147
1149{
1150 IDProperty *group = tref->properties;
1151 if (group == nullptr) {
1152 return nullptr;
1153 }
1154 return IDP_GetPropertyFromGroup(group, tref->idname);
1155}
1156
1158{
1159 if (tref->properties == nullptr) {
1160 tref->properties = blender::bke::idprop::create_group(__func__).release();
1161 }
1162 return idprops_ensure_named_group(tref->properties, tref->idname);
1163}
1164
1166 const char *idname,
1167 StructRNA *type,
1168 PointerRNA *r_ptr)
1169{
1171 IDProperty *prop = group ? IDP_GetPropertyFromGroup(group, idname) : nullptr;
1172 *r_ptr = RNA_pointer_create(nullptr, type, prop);
1173 return (prop != nullptr);
1174}
1175
1177 const char *idname,
1178 StructRNA *type,
1179 PointerRNA *r_ptr)
1180{
1182 IDProperty *prop = idprops_ensure_named_group(group, idname);
1183 *r_ptr = RNA_pointer_create(nullptr, type, prop);
1184}
1185
1187 PointerRNA *dst_ptr,
1188 PointerRNA *src_ptr,
1190{
1191 *dst_ptr = *src_ptr;
1192 if (dst_ptr->data) {
1193 dst_ptr->data = IDP_CopyProperty(static_cast<const IDProperty *>(dst_ptr->data));
1194 }
1195 else {
1196 dst_ptr->data = blender::bke::idprop::create_group("wmOpItemProp").release();
1197 }
1199 if (group != nullptr) {
1200 IDProperty *prop = IDP_GetPropertyFromGroup(group, ot->idname);
1201 if (prop) {
1202 /* Important key-map items properties don't get overwritten by the tools.
1203 * - When a key-map item doesn't set a property, the tool-systems is used.
1204 * - When it does, it overrides the tool-system.
1205 *
1206 * This way the default action can be to follow the top-bar tool-settings &
1207 * modifier keys can be used to perform different actions that aren't clobbered here.
1208 */
1209 IDP_MergeGroup(static_cast<IDProperty *>(dst_ptr->data), prop, false);
1210 }
1211 }
1212}
WorkSpace * CTX_wm_workspace(const bContext *C)
@ CTX_MODE_VERTEX_GPENCIL_LEGACY
@ CTX_MODE_WEIGHT_GPENCIL_LEGACY
@ CTX_MODE_SCULPT_GPENCIL_LEGACY
@ CTX_MODE_PAINT_GREASE_PENCIL
@ CTX_MODE_PAINT_GPENCIL_LEGACY
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_SCULPT_GREASE_PENCIL
@ CTX_MODE_PARTICLE
@ CTX_MODE_SCULPT
@ CTX_MODE_OBJECT
@ CTX_MODE_SCULPT_CURVES
@ CTX_MODE_EDIT_TEXT
@ CTX_MODE_WEIGHT_GREASE_PENCIL
@ CTX_MODE_VERTEX_GREASE_PENCIL
@ CTX_MODE_PAINT_VERTEX
@ CTX_MODE_PAINT_WEIGHT
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, eObjectMode object_mode)
void CTX_wm_window_set(bContext *C, wmWindow *win)
Main * CTX_data_main(const bContext *C)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
ARegion * CTX_wm_region(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:763
void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
Definition idprop.cc:654
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:861
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, bool do_overwrite) ATTR_NONNULL()
Definition idprop.cc:717
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
PaintMode
Definition BKE_paint.hh:99
bool BKE_paint_brush_set(Paint *paint, Brush *brush)
Definition paint.cc:714
Paint * BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
Definition paint.cc:371
const EnumPropertyItem * BKE_paint_get_tool_enum_from_paintmode(PaintMode mode)
Definition paint.cc:408
std::optional< AssetWeakReference > BKE_paint_brush_type_default_reference(eObjectMode ob_mode, std::optional< int > brush_type)
Definition paint.cc:1030
std::optional< int > BKE_paint_get_brush_type_from_paintmode(const Brush *brush, const PaintMode mode)
Definition paint.cc:1308
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:506
bool BKE_paint_brush_poll(const Paint *paint, const Brush *brush)
Definition paint.cc:659
PaintMode BKE_paintmode_get_from_tool(const bToolRef *tref)
Definition paint.cc:565
bool BKE_paint_ensure_from_paintmode(Scene *sce, PaintMode mode)
Definition paint.cc:320
void BKE_workspace_id_tag_all_visible(Main *bmain, int tag) ATTR_NONNULL()
Definition workspace.cc:546
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:90
#define LISTBASE_FOREACH(type, var, list)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring_ptr(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
#define ELEM(...)
#define STREQ(a, b)
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
ID and Library types, which are fundamental for SDNA.
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ IDP_GROUP
eObjectMode
@ OB_MODE_PARTICLE_EDIT
Object is a sort of wrapper for general info.
#define OBEDIT_FROM_OBACT(ob)
@ SPACE_NODE
@ SPACE_SEQ
@ SPACE_EMPTY
@ SPACE_IMAGE
@ SPACE_VIEW3D
#define SPACE_TYPE_NUM
@ SI_MODE_PAINT
@ SI_MODE_UV
@ TOOLREF_FLAG_FALLBACK_KEYMAP
@ TOOLREF_FLAG_USE_BRUSHES
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition RandGen.cpp:29
@ WM_GIZMOGROUPTYPE_TOOL_INIT
@ WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP
#define WM_TOOLSYSTEM_SPACE_MASK
#define WM_TOOLSYSTEM_SPACE_MASK_MODE_FROM_SPACE
CLG_LogRef * WM_LOG_TOOLS
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:225
#define offsetof(t, d)
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRefNull prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
std::optional< AssetWeakReference > asset_edit_weak_reference_from_id(const ID &id)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_enum_from_identifier(const EnumPropertyItem *item, const char *identifier)
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[]
const char * identifier
Definition RNA_types.hh:506
const char * name
Definition RNA_types.hh:510
char name[64]
Definition DNA_ID.h:163
char type
Definition DNA_ID.h:154
void * first
ListBase wm
Definition BKE_main.hh:239
ListBase workspaces
Definition BKE_main.hh:246
struct AssetWeakReference * brush_asset_reference
unsigned short ob_mode
struct Paint_Runtime runtime
struct AssetWeakReference * brush_asset_reference
struct Brush * brush
ToolSystemBrushBindings tool_brush_bindings
void * data
Definition RNA_types.hh:42
struct ToolSettings * toolsettings
struct bToolRef * tool
ListBase spacedata
ScrArea_Runtime runtime
struct ParticleEditSettings particle
struct AssetWeakReference * main_brush_asset_reference
ListBase areabase
IDProperty * properties
bToolRef_Runtime * runtime
char idname_fallback[64]
wmGizmoMapType_Params gzmap_params
eWM_GizmoFlagGroupTypeFlag flag
struct wmWindow * next
@ WM_CURSOR_DEFAULT
Definition wm_cursors.hh:15
int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
wmOperatorType * ot
Definition wm_files.cc:4125
bool WM_gizmo_group_type_ensure_ptr(wmGizmoGroupType *gzgt)
void WM_gizmo_group_remove_by_tool(bContext *C, Main *bmain, const wmGizmoGroupType *gzgt, const bToolRef *tref)
wmGizmoGroupType * WM_gizmogrouptype_find(const char *idname, bool quiet)
void WM_gizmoconfig_update_tag_group_type_init(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
wmGizmoMapType * WM_gizmomaptype_ensure(const wmGizmoMapType_Params *gzmap_params)
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_free(PointerRNA *ptr)
static void toolsystem_brush_activate_from_toolref_for_object_paint(const bContext *C, const WorkSpace *workspace, const bToolRef *tref)
void WM_toolsystem_reinit(bContext *C, WorkSpace *workspace, const bToolKey *tkey)
void WM_toolsystem_update_from_context(bContext *C, WorkSpace *workspace, const Scene *scene, ViewLayer *view_layer, ScrArea *area)
bToolRef * WM_toolsystem_ref_find(WorkSpace *workspace, const bToolKey *tkey)
bool WM_toolsystem_key_from_context(const Scene *scene, ViewLayer *view_layer, ScrArea *area, bToolKey *tkey)
void WM_toolsystem_init(const bContext *C)
bool WM_toolsystem_ref_properties_get_ex(bToolRef *tref, const char *idname, StructRNA *type, PointerRNA *r_ptr)
static void wm_toolsystem_update_from_context_view3d_impl(bContext *C, WorkSpace *workspace)
bToolRef_Runtime * WM_toolsystem_runtime_find(WorkSpace *workspace, const bToolKey *tkey)
void WM_toolsystem_refresh_all(const bContext *C, WorkSpace *workspace)
static const bToolRef * toolsystem_active_tool_from_context_or_view3d(const bContext *C)
static void toolsystem_refresh_screen_from_active_tool(Main *bmain, WorkSpace *workspace, bToolRef *tref)
IDProperty * WM_toolsystem_ref_properties_ensure_idprops(bToolRef *tref)
static void toolsystem_ref_set_by_brush_type(bContext *C, const char *brush_type)
static void toolsystem_brush_activate_from_toolref_for_object_particle(const bContext *C, const WorkSpace *workspace, const bToolRef *tref)
void WM_toolsystem_unlink(bContext *C, WorkSpace *workspace, const bToolKey *tkey)
void WM_toolsystem_reinit_all(bContext *C, wmWindow *win)
int WM_toolsystem_mode_from_spacetype(const Scene *scene, ViewLayer *view_layer, ScrArea *area, int space_type)
bool WM_toolsystem_active_tool_is_brush(const bContext *C)
void WM_toolsystem_refresh_screen_all(Main *bmain)
static bool toolsystem_key_ensure_check(const bToolKey *tkey)
static void toolsystem_refresh_ref(const bContext *C, WorkSpace *workspace, bToolRef *tref)
static void toolsystem_unlink_ref(bContext *C, WorkSpace *, bToolRef *tref)
void WM_toolsystem_refresh(const bContext *C, WorkSpace *workspace, const bToolKey *tkey)
void WM_toolsystem_ref_properties_init_for_keymap(bToolRef *tref, PointerRNA *dst_ptr, PointerRNA *src_ptr, wmOperatorType *ot)
static void toolsystem_brush_type_binding_update(Paint *paint, const PaintMode paint_mode, const int brush_type)
static const char * brush_type_identifier_get(const int brush_type, const PaintMode paint_mode)
static void toolsystem_ref_link(const bContext *C, WorkSpace *workspace, bToolRef *tref)
bToolRef * WM_toolsystem_ref_set_by_id(bContext *C, const char *name)
static void toolsystem_main_brush_binding_update_from_active(Paint *paint)
static NamedBrushAssetReference * toolsystem_brush_type_binding_lookup(const Paint *paint, const char *brush_type_name)
IDProperty * WM_toolsystem_ref_properties_get_idprops(bToolRef *tref)
bToolRef * WM_toolsystem_ref_set_by_id_ex(bContext *C, WorkSpace *workspace, const bToolKey *tkey, const char *name, bool cycle)
static void toolsystem_reinit_with_toolref(bContext *C, WorkSpace *, bToolRef *tref)
void WM_toolsystem_do_msg_notify_tag_refresh(bContext *C, wmMsgSubscribeKey *, wmMsgSubscribeValue *msg_val)
bool WM_toolsystem_activate_brush_and_tool(bContext *C, Paint *paint, Brush *brush)
bToolRef_Runtime * WM_toolsystem_runtime_from_context(const bContext *C)
bool WM_toolsystem_refresh_screen_area(WorkSpace *workspace, const Scene *scene, ViewLayer *view_layer, ScrArea *area)
bool WM_toolsystem_active_tool_has_custom_cursor(const bContext *C)
void WM_toolsystem_ref_set_from_runtime(bContext *C, WorkSpace *workspace, bToolRef *tref, const bToolRef_Runtime *tref_rt, const char *idname)
void WM_toolsystem_refresh_screen_window(wmWindow *win)
static void toolsystem_reinit_ref(bContext *C, WorkSpace *workspace, bToolRef *tref)
void WM_toolsystem_update_from_context_view3d(bContext *C)
void WM_toolsystem_refresh_active(bContext *C)
void WM_toolsystem_unlink_all(bContext *C, WorkSpace *workspace)
static bToolRef * toolsystem_reinit_ensure_toolref(bContext *C, WorkSpace *workspace, const bToolKey *tkey, const char *default_tool)
static bToolKey toolsystem_key_from_context_or_view3d(const Scene *scene, ViewLayer *view_layer, ScrArea *area)
static const char * toolsystem_default_tool(const bToolKey *tkey)
bool WM_toolsystem_ref_ensure(WorkSpace *workspace, const bToolKey *tkey, bToolRef **r_tref)
void WM_toolsystem_ref_properties_ensure_ex(bToolRef *tref, const char *idname, StructRNA *type, PointerRNA *r_ptr)
void WM_toolsystem_ref_sync_from_context(Main *bmain, WorkSpace *workspace, bToolRef *tref)
static void toolsystem_brush_activate_from_toolref(const bContext *C, const WorkSpace *workspace, const bToolRef *tref)
bToolRef * WM_toolsystem_ref_from_context(const bContext *C)
static IDProperty * idprops_ensure_named_group(IDProperty *group, const char *idname)
static bool brush_type_matches_active_tool(bContext *C, const int brush_type)
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)