Blender V4.3
space_buttons.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_bitmap.h"
15#include "BLI_blenlib.h"
16#include "BLI_utildefines.h"
17
18#include "BKE_context.hh"
19#include "BKE_lib_query.hh"
20#include "BKE_lib_remap.hh"
21#include "BKE_modifier.hh"
22#include "BKE_screen.hh"
23#include "BKE_shader_fx.h"
24
25#include "ED_buttons.hh"
26#include "ED_screen.hh"
27#include "ED_space_api.hh"
28#include "ED_view3d.hh" /* To draw toolbar UI. */
29
30#include "WM_api.hh"
31#include "WM_message.hh"
32#include "WM_types.hh"
33
34#include "RNA_access.hh"
35
36#include "UI_interface.hh"
37#include "UI_resources.hh"
38
39#include "BLO_read_write.hh"
40
41#include "buttons_intern.hh" /* own include */
42
43/* -------------------------------------------------------------------- */
47static SpaceLink *buttons_create(const ScrArea * /*area*/, const Scene * /*scene*/)
48{
49 ARegion *region;
50 SpaceProperties *sbuts;
51
52 sbuts = static_cast<SpaceProperties *>(MEM_callocN(sizeof(SpaceProperties), "initbuts"));
54
55 sbuts->mainb = sbuts->mainbuser = BCONTEXT_OBJECT;
56
57 /* header */
58 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "header for buts"));
59
60 BLI_addtail(&sbuts->regionbase, region);
61 region->regiontype = RGN_TYPE_HEADER;
62 region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
63
64 /* navigation bar */
65 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "navigation bar for buts"));
66
67 BLI_addtail(&sbuts->regionbase, region);
68 region->regiontype = RGN_TYPE_NAV_BAR;
69 region->alignment = RGN_ALIGN_LEFT;
70
71#if 0
72 /* context region */
73 region = MEM_callocN(sizeof(ARegion), "context region for buts");
74 BLI_addtail(&sbuts->regionbase, region);
75 region->regiontype = RGN_TYPE_CHANNELS;
76 region->alignment = RGN_ALIGN_TOP;
77#endif
78
79 /* main region */
80 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "main region for buts"));
81
82 BLI_addtail(&sbuts->regionbase, region);
83 region->regiontype = RGN_TYPE_WINDOW;
84
85 return (SpaceLink *)sbuts;
86}
87
88/* Doesn't free the space-link itself. */
89static void buttons_free(SpaceLink *sl)
90{
91 SpaceProperties *sbuts = (SpaceProperties *)sl;
92
93 if (sbuts->path) {
94 MEM_delete(static_cast<ButsContextPath *>(sbuts->path));
95 }
96
97 if (sbuts->texuser) {
98 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
100 MEM_delete(user);
101 }
103 MEM_freeN(ct);
104 }
105
106 if (sbuts->runtime != nullptr) {
108 MEM_freeN(sbuts->runtime);
109 }
110}
111
112/* spacetype; init callback */
113static void buttons_init(wmWindowManager * /*wm*/, ScrArea *area)
114{
115 SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
116
117 if (sbuts->runtime == nullptr) {
118 sbuts->runtime = static_cast<SpaceProperties_Runtime *>(
119 MEM_mallocN(sizeof(SpaceProperties_Runtime), __func__));
120 sbuts->runtime->search_string[0] = '\0';
121 sbuts->runtime->tab_search_results = BLI_BITMAP_NEW(BCONTEXT_TOT * 2, __func__);
122 }
123}
124
126{
127 SpaceProperties *sfile_old = (SpaceProperties *)sl;
128 SpaceProperties *sbutsn = static_cast<SpaceProperties *>(MEM_dupallocN(sl));
129
130 /* clear or remove stuff from old */
131 sbutsn->path = nullptr;
132 sbutsn->texuser = nullptr;
133 if (sfile_old->runtime != nullptr) {
134 sbutsn->runtime = static_cast<SpaceProperties_Runtime *>(MEM_dupallocN(sfile_old->runtime));
135 sbutsn->runtime->search_string[0] = '\0';
137 }
138
139 return (SpaceLink *)sbutsn;
140}
141
142/* add handlers, stuff you only do once or on area/region changes */
144{
145 wmKeyMap *keymap;
146
147 ED_region_panels_init(wm, region);
148
149 keymap = WM_keymap_ensure(wm->defaultconf, "Property Editor", SPACE_PROPERTIES, RGN_TYPE_WINDOW);
150 WM_event_add_keymap_handler(&region->handlers, keymap);
151}
152
155/* -------------------------------------------------------------------- */
159int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
160{
161 int length = 0;
162 if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
163 context_tabs_array[length] = BCONTEXT_TOOL;
164 length++;
165 }
166 if (length != 0) {
167 context_tabs_array[length] = -1;
168 length++;
169 }
170 if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
171 context_tabs_array[length] = BCONTEXT_RENDER;
172 length++;
173 }
174 if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
175 context_tabs_array[length] = BCONTEXT_OUTPUT;
176 length++;
177 }
178 if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
179 context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
180 length++;
181 }
182 if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
183 context_tabs_array[length] = BCONTEXT_SCENE;
184 length++;
185 }
186 if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
187 context_tabs_array[length] = BCONTEXT_WORLD;
188 length++;
189 }
190 if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
191 if (length != 0) {
192 context_tabs_array[length] = -1;
193 length++;
194 }
195 context_tabs_array[length] = BCONTEXT_COLLECTION;
196 length++;
197 }
198 if (length != 0) {
199 context_tabs_array[length] = -1;
200 length++;
201 }
202 if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
203 context_tabs_array[length] = BCONTEXT_OBJECT;
204 length++;
205 }
206 if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
207 context_tabs_array[length] = BCONTEXT_MODIFIER;
208 length++;
209 }
210 if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
211 context_tabs_array[length] = BCONTEXT_SHADERFX;
212 length++;
213 }
214 if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
215 context_tabs_array[length] = BCONTEXT_PARTICLE;
216 length++;
217 }
218 if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
219 context_tabs_array[length] = BCONTEXT_PHYSICS;
220 length++;
221 }
222 if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
223 context_tabs_array[length] = BCONTEXT_CONSTRAINT;
224 length++;
225 }
226 if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
227 context_tabs_array[length] = BCONTEXT_DATA;
228 length++;
229 }
230 if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
231 context_tabs_array[length] = BCONTEXT_BONE;
232 length++;
233 }
234 if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
235 context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT;
236 length++;
237 }
238 if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
239 context_tabs_array[length] = BCONTEXT_MATERIAL;
240 length++;
241 }
242 if (length != 0) {
243 context_tabs_array[length] = -1;
244 length++;
245 }
246 if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
247 context_tabs_array[length] = BCONTEXT_TEXTURE;
248 length++;
249 }
250
251 return length;
252}
253
254static const char *buttons_main_region_context_string(const short mainb)
255{
256 switch (mainb) {
257 case BCONTEXT_SCENE:
258 return "scene";
259 case BCONTEXT_RENDER:
260 return "render";
261 case BCONTEXT_OUTPUT:
262 return "output";
264 return "view_layer";
265 case BCONTEXT_WORLD:
266 return "world";
268 return "collection";
269 case BCONTEXT_OBJECT:
270 return "object";
271 case BCONTEXT_DATA:
272 return "data";
274 return "material";
275 case BCONTEXT_TEXTURE:
276 return "texture";
278 return "particle";
279 case BCONTEXT_PHYSICS:
280 return "physics";
281 case BCONTEXT_BONE:
282 return "bone";
284 return "modifier";
286 return "shaderfx";
288 return "constraint";
290 return "bone_constraint";
291 case BCONTEXT_TOOL:
292 return "tool";
293 }
294
295 /* All the cases should be handled. */
296 BLI_assert(false);
297 return "";
298}
299
301 SpaceProperties *sbuts,
302 ARegion *region)
303{
304 buttons_context_compute(C, sbuts);
305
306 const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), nullptr};
307
309 C, region, &region->type->paneltypes, WM_OP_INVOKE_REGION_WIN, contexts, nullptr);
310}
311
314/* -------------------------------------------------------------------- */
319{
320 return (sbuts->runtime) ? sbuts->runtime->search_string : "";
321}
322
324{
325 return (sbuts->runtime) ?
326 BLI_strnlen(sbuts->runtime->search_string, sizeof(sbuts->runtime->search_string)) :
327 0;
328}
329
330void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
331{
332 if (sbuts->runtime) {
333 STRNCPY(sbuts->runtime->search_string, value);
334 }
335}
336
338{
339 if (!sbuts->runtime) {
340 return false;
341 }
342 return BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, index);
343}
344
347/* -------------------------------------------------------------------- */
351static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts)
352{
353 const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), nullptr};
354
355 if (sbuts->mainb == BCONTEXT_TOOL) {
356 return false;
357 }
358
359 buttons_context_compute(C, sbuts);
360 return ED_region_property_search(C, region, &region->type->paneltypes, contexts, nullptr);
361}
362
364 const short *context_tabs_array,
365 const int tabs_len)
366{
367 /* As long as all-tab search in the tool is disabled in the tool context, don't move from it. */
368 if (sbuts->mainb == BCONTEXT_TOOL) {
369 return;
370 }
371
372 int current_tab_index = 0;
373 for (int i = 0; i < tabs_len; i++) {
374 if (sbuts->mainb == context_tabs_array[i]) {
375 current_tab_index = i;
376 break;
377 }
378 }
379
380 /* Try the tabs after the current tab. */
381 for (int i = current_tab_index; i < tabs_len; i++) {
383 sbuts->mainbuser = context_tabs_array[i];
384 return;
385 }
386 }
387
388 /* Try the tabs before the current tab. */
389 for (int i = 0; i < current_tab_index; i++) {
391 sbuts->mainbuser = context_tabs_array[i];
392 return;
393 }
394 }
395}
396
398 SpaceProperties *sbuts,
399 ARegion *region_original,
400 const short *context_tabs_array,
401 const int tabs_len)
402{
403 /* Use local copies of the area and duplicate the region as a mainly-paranoid protection
404 * against changing any of the space / region data while running the search. */
405 ScrArea *area_original = CTX_wm_area(C);
406 ScrArea area_copy = blender::dna::shallow_copy(*area_original);
407 ARegion *region_copy = BKE_area_region_copy(area_copy.type, region_original);
408 /* Set the region visible field. Otherwise some layout code thinks we're drawing in a popup.
409 * This likely isn't necessary, but it's nice to emulate a "real" region where possible. */
410 region_copy->visible = true;
411 CTX_wm_area_set((bContext *)C, &area_copy);
412 CTX_wm_region_set((bContext *)C, region_copy);
413
414 SpaceProperties sbuts_copy = blender::dna::shallow_copy(*sbuts);
415 sbuts_copy.path = nullptr;
416 sbuts_copy.texuser = nullptr;
417 sbuts_copy.runtime = static_cast<SpaceProperties_Runtime *>(MEM_dupallocN(sbuts->runtime));
418 sbuts_copy.runtime->tab_search_results = nullptr;
419 BLI_listbase_clear(&area_copy.spacedata);
420 BLI_addtail(&area_copy.spacedata, &sbuts_copy);
421
422 /* Loop through the tabs added to the properties editor. */
423 for (int i = 0; i < tabs_len; i++) {
424 /* -1 corresponds to a spacer. */
425 if (context_tabs_array[i] == -1) {
426 continue;
427 }
428
429 /* Handle search for the current tab in the normal layout pass. */
430 if (context_tabs_array[i] == sbuts->mainb) {
431 continue;
432 }
433
434 sbuts_copy.mainb = sbuts_copy.mainbo = sbuts_copy.mainbuser = context_tabs_array[i];
435
436 /* Actually do the search and store the result in the bitmap. */
438 i,
439 property_search_for_context(C, region_copy, &sbuts_copy));
440
441 UI_blocklist_free(C, region_copy);
442 }
443
444 BKE_area_region_free(area_copy.type, region_copy);
445 MEM_freeN(region_copy);
446 buttons_free((SpaceLink *)&sbuts_copy);
447
448 CTX_wm_area_set((bContext *)C, area_original);
449 CTX_wm_region_set((bContext *)C, region_original);
450}
451
457 SpaceProperties *sbuts,
458 ARegion *region)
459{
460 /* Theoretical maximum of every context shown with a spacer between every tab. */
461 short context_tabs_array[BCONTEXT_TOT * 2];
462 int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array);
463
464 property_search_all_tabs(C, sbuts, region, context_tabs_array, tabs_len);
465
466 /* Check whether the current tab has a search match. */
467 bool current_tab_has_search_match = false;
468 LISTBASE_FOREACH (Panel *, panel, &region->panels) {
470 current_tab_has_search_match = true;
471 }
472 }
473
474 /* Find which index in the list the current tab corresponds to. */
475 int current_tab_index = -1;
476 for (int i = 0; i < tabs_len; i++) {
477 if (context_tabs_array[i] == sbuts->mainb) {
478 current_tab_index = i;
479 }
480 }
481 BLI_assert(current_tab_index != -1);
482
483 /* Update the tab search match flag for the current tab. */
485 sbuts->runtime->tab_search_results, current_tab_index, current_tab_has_search_match);
486
487 /* Move to the next tab with a result */
488 if (!current_tab_has_search_match) {
489 if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
490 property_search_move_to_next_tab_with_results(sbuts, context_tabs_array, tabs_len);
491 }
492 }
493}
494
497/* -------------------------------------------------------------------- */
501static void buttons_main_region_layout(const bContext *C, ARegion *region)
502{
503 /* draw entirely, view changes should be handled here */
505
506 if (sbuts->mainb == BCONTEXT_TOOL) {
507 ED_view3d_buttons_region_layout_ex(C, region, "Tool");
508 }
509 else {
511 }
512
513 if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
514 buttons_main_region_property_search(C, sbuts, region);
515 }
516
517 sbuts->mainbo = sbuts->mainb;
518}
519
521{
522 ARegion *region = params->region;
523 const wmNotifier *wmn = params->notifier;
524
525 /* context changes */
526 switch (wmn->category) {
527 case NC_SCREEN:
528 if (ELEM(wmn->data, ND_LAYER)) {
529 ED_region_tag_redraw(region);
530 }
531 break;
532 }
533}
534
544
545static void buttons_keymap(wmKeyConfig *keyconf)
546{
547 WM_keymap_ensure(keyconf, "Property Editor", SPACE_PROPERTIES, RGN_TYPE_WINDOW);
548}
549
552/* -------------------------------------------------------------------- */
556/* add handlers, stuff you only do once or on area/region changes */
558{
559 ED_region_header_init(region);
560}
561
562static void buttons_header_region_draw(const bContext *C, ARegion *region)
563{
565
566 /* Needed for RNA to get the good values! */
567 buttons_context_compute(C, sbuts);
568
569 ED_region_header(C, region);
570}
571
573{
574 wmMsgBus *mbus = params->message_bus;
575 ScrArea *area = params->area;
576 ARegion *region = params->region;
577 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
578
579 wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
580 msg_sub_value_region_tag_redraw.owner = region;
581 msg_sub_value_region_tag_redraw.user_data = region;
582 msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
583
584 /* Don't check for SpaceProperties.mainb here, we may toggle between view-layers
585 * where one has no active object, so that available contexts changes. */
586 WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
587
589 WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
590 }
591
592 if (sbuts->mainb == BCONTEXT_TOOL) {
593 WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
594 }
595}
596
599/* -------------------------------------------------------------------- */
604{
605 region->flag |= RGN_FLAG_NO_USER_RESIZE;
606
607 ED_region_panels_init(wm, region);
608 region->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
609}
610
612{
614 buttons_context_compute(C, sbuts);
615
616 LISTBASE_FOREACH (PanelType *, pt, &region->type->paneltypes) {
617 pt->flag |= PANEL_TYPE_LAYOUT_VERT_BAR;
618 }
619
620 ED_region_panels_layout(C, region);
621 /* #ED_region_panels_layout adds vertical scroll-bars, we don't want them. */
622 region->v2d.scroll &= ~V2D_SCROLL_VERTICAL;
623 ED_region_panels_draw(C, region);
624}
625
628{
629 wmMsgBus *mbus = params->message_bus;
630 ARegion *region = params->region;
631
632 wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
633 msg_sub_value_region_tag_redraw.owner = region;
634 msg_sub_value_region_tag_redraw.user_data = region;
635 msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
636
637 WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
638 /* Redraw when image editor mode changes, texture tab needs to be added when switching to "Paint"
639 * mode. */
641 mbus, SpaceImageEditor, ui_mode, &msg_sub_value_region_tag_redraw);
642}
643
644/* draw a certain button set only if properties area is currently
645 * showing that button set, to reduce unnecessary drawing. */
646static void buttons_area_redraw(ScrArea *area, short buttons)
647{
648 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
649
650 /* if the area's current button set is equal to the one to redraw */
651 if (sbuts->mainb == buttons) {
652 ED_area_tag_redraw(area);
653 }
654}
655
658/* -------------------------------------------------------------------- */
662/* reused! */
664{
665 ScrArea *area = params->area;
666 const wmNotifier *wmn = params->notifier;
667 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
668
669 /* context changes */
670 switch (wmn->category) {
671 case NC_SCENE:
672 switch (wmn->data) {
677 break;
678 case ND_WORLD:
680 sbuts->preview = 1;
681 break;
682 case ND_FRAME:
683 /* any buttons area can have animated properties so redraw all */
684 ED_area_tag_redraw(area);
685 sbuts->preview = 1;
686 break;
687 case ND_OB_ACTIVE:
688 ED_area_tag_redraw(area);
689 sbuts->preview = 1;
690 break;
691 case ND_KEYINGSET:
693 break;
694 case ND_RENDER_RESULT:
695 break;
696 case ND_MODE:
697 case ND_LAYER:
698 default:
699 ED_area_tag_redraw(area);
700 break;
701 }
702 break;
703 case NC_OBJECT:
704 switch (wmn->data) {
705 case ND_TRANSFORM:
707 buttons_area_redraw(area, BCONTEXT_DATA); /* Auto-texture-space flag. */
708 break;
709 case ND_POSE:
710 case ND_BONE_ACTIVE:
711 case ND_BONE_SELECT:
716 break;
717 case ND_MODIFIER:
718 if (wmn->action == NA_RENAME) {
719 ED_area_tag_redraw(area);
720 }
721 else {
723 }
725 break;
726 case ND_CONSTRAINT:
729 break;
730 case ND_SHADERFX:
732 break;
733 case ND_PARTICLE:
734 if (wmn->action == NA_EDITED) {
736 }
737 sbuts->preview = 1;
738 break;
739 case ND_DRAW:
743 /* Needed to refresh context path when changing active particle system index. */
746 break;
747 case ND_DRAW_ANIMVIZ:
749 break;
750 default:
751 /* Not all object RNA props have a ND_ notifier (yet) */
752 ED_area_tag_redraw(area);
753 break;
754 }
755 break;
756 case NC_GEOM:
757 switch (wmn->data) {
758 case ND_SELECT:
759 case ND_DATA:
760 case ND_VERTEX_GROUP:
761 ED_area_tag_redraw(area);
762 break;
763 }
764 break;
765 case NC_MATERIAL:
766 ED_area_tag_redraw(area);
767 switch (wmn->data) {
768 case ND_SHADING:
769 case ND_SHADING_DRAW:
770 case ND_SHADING_LINKS:
772 case ND_NODES:
773 /* currently works by redraws... if preview is set, it (re)starts job */
774 sbuts->preview = 1;
775 break;
776 }
777 break;
778 case NC_WORLD:
780 sbuts->preview = 1;
781 break;
782 case NC_LAMP:
784 sbuts->preview = 1;
785 break;
786 case NC_GROUP:
788 break;
789 case NC_BRUSH:
792 sbuts->preview = 1;
793 break;
794 case NC_TEXTURE:
795 case NC_IMAGE:
796 if (wmn->action != NA_PAINTING) {
797 ED_area_tag_redraw(area);
798 sbuts->preview = 1;
799 }
800 break;
801 case NC_WORKSPACE:
803 break;
804 case NC_SPACE:
805 if (wmn->data == ND_SPACE_PROPERTIES) {
806 ED_area_tag_redraw(area);
807 }
808 else if (wmn->data == ND_SPACE_CHANGED) {
809 ED_area_tag_redraw(area);
810 sbuts->preview = 1;
811 }
812 break;
813 case NC_ID:
814 if (ELEM(wmn->action, NA_RENAME, NA_EDITED)) {
815 ED_area_tag_redraw(area);
816 }
817 break;
818 case NC_ANIMATION:
819 switch (wmn->data) {
820 case ND_NLA_ACTCHANGE:
821 ED_area_tag_redraw(area);
822 break;
823 case ND_KEYFRAME:
824 if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
825 ED_area_tag_redraw(area);
826 }
827 break;
828 }
829 break;
830 case NC_GPENCIL:
831 if (wmn->data == ND_DATA) {
833 ED_area_tag_redraw(area);
834 }
835 }
836 else if (wmn->action == NA_EDITED) {
837 ED_area_tag_redraw(area);
838 }
839 break;
840 case NC_NODE:
841 if (wmn->action == NA_SELECTED) {
842 ED_area_tag_redraw(area);
843 /* new active node, update texture preview */
844 if (sbuts->mainb == BCONTEXT_TEXTURE) {
845 sbuts->preview = 1;
846 }
847 }
848 break;
849 /* Listener for preview render, when doing an global undo. */
850 case NC_WM:
851 if (wmn->data == ND_UNDO) {
852 ED_area_tag_redraw(area);
853 sbuts->preview = 1;
854 }
855 break;
856 case NC_SCREEN:
857 if (wmn->data == ND_LAYOUTSET) {
858 ED_area_tag_redraw(area);
859 sbuts->preview = 1;
860 }
861 break;
862#ifdef WITH_FREESTYLE
863 case NC_LINESTYLE:
864 ED_area_tag_redraw(area);
865 sbuts->preview = 1;
866 break;
867#endif
868 }
869
870 if (wmn->data == ND_KEYS) {
871 ED_area_tag_redraw(area);
872 }
873}
874
875static void buttons_id_remap(ScrArea * /*area*/,
876 SpaceLink *slink,
877 const blender::bke::id::IDRemapper &mappings)
878{
879 SpaceProperties *sbuts = (SpaceProperties *)slink;
880
882 sbuts->flag &= ~SB_PIN_CONTEXT;
883 }
884
885 if (sbuts->path) {
886 ButsContextPath *path = static_cast<ButsContextPath *>(sbuts->path);
887 for (int i = 0; i < path->len; i++) {
888 switch (mappings.apply(&path->ptr[i].owner_id, ID_REMAP_APPLY_DEFAULT)) {
890 path->len = i;
891 if (i != 0) {
892 /* If the first item in the path is cleared, the whole path is cleared, so no need to
893 * clear further items here, see also at the end of this block. */
894 for (int j = i; j < path->len; j++) {
895 path->ptr[j] = {};
896 }
897 }
898 break;
899 }
901 path->ptr[i] = RNA_id_pointer_create(path->ptr[i].owner_id);
902 /* There is no easy way to check/make path downwards valid, just nullify it.
903 * Next redraw will rebuild this anyway. */
904 i++;
905 for (int j = i; j < path->len; j++) {
906 path->ptr[j] = {};
907 }
908 path->len = i;
909 break;
910 }
911
914 /* Nothing to do. */
915 break;
916 }
917 }
918 }
919 if (path->len == 0 && sbuts->path) {
920 MEM_delete(static_cast<ButsContextPath *>(sbuts->path));
921 sbuts->path = nullptr;
922 }
923 }
924
925 if (sbuts->texuser) {
926 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
927 mappings.apply(reinterpret_cast<ID **>(&ct->texture), ID_REMAP_APPLY_DEFAULT);
929 MEM_delete(user);
930 }
932 ct->user = nullptr;
933 }
934}
935
936static void buttons_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
937{
938 SpaceProperties *sbuts = reinterpret_cast<SpaceProperties *>(space_link);
939 const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
940 const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
941
943 if (!is_readonly) {
944 if (sbuts->pinid == nullptr) {
945 sbuts->flag &= ~SB_PIN_CONTEXT;
946 }
947 /* NOTE: Restoring path pointers is complicated, if not impossible, because this contains
948 * data pointers too, not just ID ones. See #40046. */
949 if (sbuts->path) {
950 MEM_delete(static_cast<ButsContextPath *>(sbuts->path));
951 sbuts->path = nullptr;
952 }
953 }
954
955 if (sbuts->texuser) {
956 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
958
959 if (!is_readonly) {
961 MEM_delete(user);
962 }
964 ct->user = nullptr;
965 }
966 }
967}
968
970{
971 SpaceProperties *sbuts = (SpaceProperties *)sl;
972
973 sbuts->path = nullptr;
974 sbuts->texuser = nullptr;
975 sbuts->mainbo = sbuts->mainb;
976 sbuts->mainbuser = sbuts->mainb;
977 sbuts->runtime = nullptr;
978}
979
981 ID * /*parent_id*/,
982 SpaceLink *sl)
983{
984 SpaceProperties *sbuts = reinterpret_cast<SpaceProperties *>(sl);
985
986 if (sbuts->pinid == nullptr) {
987 sbuts->flag &= ~SB_PIN_CONTEXT;
988 }
989}
990
992{
994}
995
998/* -------------------------------------------------------------------- */
1003{
1004 std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
1005 ARegionType *art;
1006
1007 st->spaceid = SPACE_PROPERTIES;
1008 STRNCPY(st->name, "Buttons");
1009
1010 st->create = buttons_create;
1011 st->free = buttons_free;
1012 st->init = buttons_init;
1013 st->duplicate = buttons_duplicate;
1014 st->operatortypes = buttons_operatortypes;
1015 st->keymap = buttons_keymap;
1016 st->listener = buttons_area_listener;
1017 st->context = buttons_context;
1018 st->id_remap = buttons_id_remap;
1019 st->foreach_id = buttons_foreach_id;
1020 st->blend_read_data = buttons_space_blend_read_data;
1021 st->blend_read_after_liblink = buttons_space_blend_read_after_liblink;
1022 st->blend_write = buttons_space_blend_write;
1023
1024 /* regions: main window */
1025 art = static_cast<ARegionType *>(MEM_callocN(sizeof(ARegionType), "spacetype buttons region"));
1033 BLI_addhead(&st->regiontypes, art);
1034
1035 /* Register the panel types from modifiers. The actual panels are built per modifier rather
1036 * than per modifier type. */
1037 for (int i = 0; i < NUM_MODIFIER_TYPES; i++) {
1039 if (mti != nullptr && mti->panel_register != nullptr) {
1040 mti->panel_register(art);
1041 }
1042 }
1043 for (int i = 0; i < NUM_SHADER_FX_TYPES; i++) {
1045 continue;
1046 }
1048 if (fxti != nullptr && fxti->panel_register != nullptr) {
1049 fxti->panel_register(art);
1050 }
1051 }
1052
1053 /* regions: header */
1054 art = static_cast<ARegionType *>(MEM_callocN(sizeof(ARegionType), "spacetype buttons region"));
1056 art->prefsizey = HEADERY;
1058
1062 BLI_addhead(&st->regiontypes, art);
1063
1064 /* regions: navigation bar */
1065 art = static_cast<ARegionType *>(
1066 MEM_callocN(sizeof(ARegionType), "spacetype nav buttons region"));
1068 art->prefsizex = AREAMINX;
1073 BLI_addhead(&st->regiontypes, art);
1074
1075 BKE_spacetype_register(std::move(st));
1076}
1077
SpaceProperties * CTX_wm_space_properties(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
@ IDWALK_CB_DIRECT_WEAK_LINK
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:120
@ IDWALK_READONLY
#define BKE_LIB_FOREACHID_PROCESS_ID(data_, id_, cb_flag_)
@ ID_REMAP_RESULT_SOURCE_REMAPPED
@ ID_REMAP_RESULT_SOURCE_UNASSIGNED
@ ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE
@ ID_REMAP_RESULT_SOURCE_UNAVAILABLE
@ ID_REMAP_APPLY_DEFAULT
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
void BKE_spacetype_register(std::unique_ptr< SpaceType > st)
Definition screen.cc:268
void BKE_area_region_free(SpaceType *st, ARegion *region)
Definition screen.cc:563
ARegion * BKE_area_region_copy(const SpaceType *st, const ARegion *region)
Definition screen.cc:335
@ PANEL_TYPE_LAYOUT_VERT_BAR
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition shader_fx.cc:131
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:41
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition BLI_bitmap.h:65
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition BLI_bitmap.h:103
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:90
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
#define STRNCPY(dst, src)
Definition BLI_string.h:593
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.c:909
#define ELEM(...)
#define BLO_write_struct(writer, struct_name, data_ptr)
@ NUM_MODIFIER_TYPES
#define HEADERY
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_TOP
#define AREAMINX
@ RGN_TYPE_CHANNELS
@ RGN_TYPE_WINDOW
@ RGN_TYPE_NAV_BAR
@ RGN_TYPE_HEADER
@ RGN_FLAG_SEARCH_FILTER_UPDATE
@ RGN_FLAG_NO_USER_RESIZE
@ RGN_FLAG_SEARCH_FILTER_ACTIVE
@ eShaderFxType_Light_deprecated
@ NUM_SHADER_FX_TYPES
@ SPACE_PROPERTIES
@ BCONTEXT_CONSTRAINT
@ BCONTEXT_COLLECTION
@ BCONTEXT_OUTPUT
@ BCONTEXT_VIEW_LAYER
@ BCONTEXT_MATERIAL
@ BCONTEXT_TOT
@ BCONTEXT_SHADERFX
@ BCONTEXT_MODIFIER
@ BCONTEXT_BONE
@ BCONTEXT_DATA
@ BCONTEXT_OBJECT
@ BCONTEXT_BONE_CONSTRAINT
@ BCONTEXT_PHYSICS
@ BCONTEXT_SCENE
@ BCONTEXT_WORLD
@ BCONTEXT_RENDER
@ BCONTEXT_TEXTURE
@ BCONTEXT_TOOL
@ BCONTEXT_PARTICLE
@ USER_HEADER_BOTTOM
@ V2D_LOCKZOOM_X
@ V2D_LOCKZOOM_Y
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:708
bool ED_region_property_search(const bContext *C, ARegion *region, ListBase *paneltypes, const char *contexts[], const char *category_override)
Definition area.cc:3419
void ED_region_header(const bContext *C, ARegion *region)
Definition area.cc:3646
void ED_region_header_init(ARegion *region)
Definition area.cc:3661
void ED_region_panels_layout_ex(const bContext *C, ARegion *region, ListBase *paneltypes, wmOperatorCallContext op_context, const char *contexts[], const char *category_override)
Definition area.cc:3099
void ED_region_panels_layout(const bContext *C, ARegion *region)
Definition area.cc:3271
void ED_region_panels_init(wmWindowManager *wm, ARegion *region)
Definition area.cc:3343
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:634
@ ED_KEYMAP_NAVBAR
Definition ED_screen.hh:734
@ ED_KEYMAP_UI
Definition ED_screen.hh:725
@ ED_KEYMAP_HEADER
Definition ED_screen.hh:731
@ ED_KEYMAP_VIEW2D
Definition ED_screen.hh:728
@ ED_KEYMAP_FRAMES
Definition ED_screen.hh:730
void ED_region_do_msg_notify_tag_redraw(bContext *C, wmMsgSubscribeKey *msg_key, wmMsgSubscribeValue *msg_val)
Definition area.cc:381
void ED_region_panels_draw(const bContext *C, ARegion *region)
Definition area.cc:3277
void ED_view3d_buttons_region_layout_ex(const bContext *C, ARegion *region, const char *category_override)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void UI_blocklist_free(const bContext *C, ARegion *region)
bool UI_panel_matches_search_filter(const Panel *panel)
bool UI_panel_is_active(const Panel *panel)
#define NC_WORLD
Definition WM_types.hh:354
#define ND_SHADING
Definition WM_types.hh:444
#define ND_WORLD
Definition WM_types.hh:419
#define NC_ID
Definition WM_types.hh:362
#define NC_NODE
Definition WM_types.hh:361
#define NC_GEOM
Definition WM_types.hh:360
#define ND_NLA_ACTCHANGE
Definition WM_types.hh:465
#define ND_SPACE_CHANGED
Definition WM_types.hh:504
#define ND_DRAW
Definition WM_types.hh:428
#define NC_BRUSH
Definition WM_types.hh:352
#define ND_OB_ACTIVE
Definition WM_types.hh:407
#define ND_RENDER_RESULT
Definition WM_types.hh:413
#define NC_WM
Definition WM_types.hh:341
#define ND_DATA
Definition WM_types.hh:475
#define NC_LINESTYLE
Definition WM_types.hh:367
#define ND_RENDER_OPTIONS
Definition WM_types.hh:402
#define NC_ANIMATION
Definition WM_types.hh:355
#define ND_SHADING_PREVIEW
Definition WM_types.hh:447
#define ND_VERTEX_GROUP
Definition WM_types.hh:476
#define NC_SCREEN
Definition WM_types.hh:344
#define ND_MODE
Definition WM_types.hh:412
#define ND_SPACE_PROPERTIES
Definition WM_types.hh:495
#define ND_KEYINGSET
Definition WM_types.hh:415
#define NC_SCENE
Definition WM_types.hh:345
#define NA_ADDED
Definition WM_types.hh:552
#define NC_GROUP
Definition WM_types.hh:350
#define ND_NODES
Definition WM_types.hh:403
#define ND_MODIFIER
Definition WM_types.hh:429
#define ND_POSE
Definition WM_types.hh:425
#define NA_EDITED
Definition WM_types.hh:550
#define ND_PARTICLE
Definition WM_types.hh:432
#define NC_MATERIAL
Definition WM_types.hh:347
#define NC_LAMP
Definition WM_types.hh:349
#define NC_IMAGE
Definition WM_types.hh:351
#define ND_CONSTRAINT
Definition WM_types.hh:431
#define NC_WORKSPACE
Definition WM_types.hh:343
#define ND_UNDO
Definition WM_types.hh:384
#define ND_FRAME
Definition WM_types.hh:401
#define NA_REMOVED
Definition WM_types.hh:553
#define ND_SELECT
Definition WM_types.hh:474
#define NC_GPENCIL
Definition WM_types.hh:366
#define NC_TEXTURE
Definition WM_types.hh:348
#define ND_BONE_ACTIVE
Definition WM_types.hh:426
#define ND_TRANSFORM
Definition WM_types.hh:423
#define ND_LAYER
Definition WM_types.hh:417
@ WM_OP_INVOKE_REGION_WIN
Definition WM_types.hh:219
#define ND_BONE_COLLECTION
Definition WM_types.hh:441
#define ND_KEYS
Definition WM_types.hh:430
#define NA_RENAME
Definition WM_types.hh:554
#define ND_SHADERFX
Definition WM_types.hh:438
#define NA_PAINTING
Definition WM_types.hh:557
#define ND_DRAW_ANIMVIZ
Definition WM_types.hh:440
#define ND_BONE_SELECT
Definition WM_types.hh:427
#define ND_KEYFRAME
Definition WM_types.hh:461
#define ND_LAYOUTSET
Definition WM_types.hh:393
#define NC_OBJECT
Definition WM_types.hh:346
#define ND_SHADING_LINKS
Definition WM_types.hh:446
#define ND_SHADING_DRAW
Definition WM_types.hh:445
#define NC_SPACE
Definition WM_types.hh:359
#define NA_SELECTED
Definition WM_types.hh:555
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
void buttons_context_register(ARegionType *art)
void BUTTONS_OT_toggle_pin(wmOperatorType *ot)
void BUTTONS_OT_context_menu(wmOperatorType *ot)
void BUTTONS_OT_directory_browse(wmOperatorType *ot)
void BUTTONS_OT_clear_filter(wmOperatorType *ot)
void BUTTONS_OT_file_browse(wmOperatorType *ot)
void BUTTONS_OT_start_filter(wmOperatorType *ot)
IDRemapperApplyResult apply(ID **r_id_ptr, IDRemapperApplyOptions options, ID *id_self=nullptr) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
PointerRNA RNA_id_pointer_create(ID *id)
static void buttons_main_region_layout(const bContext *C, ARegion *region)
int ED_buttons_search_string_length(SpaceProperties *sbuts)
void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
static void buttons_space_blend_write(BlendWriter *writer, SpaceLink *sl)
static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts)
static void buttons_header_region_draw(const bContext *C, ARegion *region)
static void buttons_main_region_property_search(const bContext *C, SpaceProperties *sbuts, ARegion *region)
const char * ED_buttons_search_string_get(SpaceProperties *sbuts)
static void buttons_navigation_bar_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
static const char * buttons_main_region_context_string(const short mainb)
static void buttons_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *region)
int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
static void buttons_init(wmWindowManager *, ScrArea *area)
static void buttons_main_region_init(wmWindowManager *wm, ARegion *region)
static void buttons_id_remap(ScrArea *, SpaceLink *slink, const blender::bke::id::IDRemapper &mappings)
void ED_spacetype_buttons()
static void buttons_navigation_bar_region_init(wmWindowManager *wm, ARegion *region)
static void buttons_main_region_listener(const wmRegionListenerParams *params)
static SpaceLink * buttons_create(const ScrArea *, const Scene *)
static void buttons_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
static void buttons_main_region_layout_properties(const bContext *C, SpaceProperties *sbuts, ARegion *region)
static void buttons_area_redraw(ScrArea *area, short buttons)
static void buttons_space_blend_read_after_liblink(BlendLibReader *, ID *, SpaceLink *sl)
static void buttons_operatortypes()
static void buttons_header_region_init(wmWindowManager *, ARegion *region)
static void buttons_space_blend_read_data(BlendDataReader *, SpaceLink *sl)
bool ED_buttons_tab_has_search_result(SpaceProperties *sbuts, const int index)
static void buttons_free(SpaceLink *sl)
static SpaceLink * buttons_duplicate(SpaceLink *sl)
static void buttons_keymap(wmKeyConfig *keyconf)
static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
static void property_search_move_to_next_tab_with_results(SpaceProperties *sbuts, const short *context_tabs_array, const int tabs_len)
static void property_search_all_tabs(const bContext *C, SpaceProperties *sbuts, ARegion *region_original, const short *context_tabs_array, const int tabs_len)
void(* message_subscribe)(const wmRegionMessageSubscribeParams *params)
void(* listener)(const wmRegionListenerParams *params)
void(* draw)(const bContext *C, ARegion *region)
void(* layout)(const bContext *C, ARegion *region)
void(* init)(wmWindowManager *wm, ARegion *region)
PointerRNA ptr[8]
struct ButsTextureUser * user
Definition DNA_ID.h:413
void(* panel_register)(ARegionType *region_type)
ID * owner_id
Definition RNA_types.hh:40
ListBase spacedata
struct SpaceType * type
void(* panel_register)(struct ARegionType *region_type)
BLI_bitmap * tab_search_results
char search_string[UI_MAX_NAME_STR]
struct SpaceProperties_Runtime * runtime
unsigned int data
Definition WM_types.hh:325
unsigned int action
Definition WM_types.hh:325
unsigned int category
Definition WM_types.hh:325
struct wmKeyConfig * defaultconf
wmEventHandler_Keymap * WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:897
#define WM_msg_subscribe_rna_anon_prop(mbus, type_, prop_, value)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))