Blender  V3.3
space_buttons.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2008 Blender Foundation. All rights reserved. */
3 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_bitmap.h"
14 #include "BLI_blenlib.h"
15 #include "BLI_utildefines.h"
16 
17 #include "BKE_context.h"
18 #include "BKE_gpencil_modifier.h" /* Types for registering panels. */
19 #include "BKE_lib_remap.h"
20 #include "BKE_modifier.h"
21 #include "BKE_screen.h"
22 #include "BKE_shader_fx.h"
23 
24 #include "ED_buttons.h"
25 #include "ED_screen.h"
26 #include "ED_space_api.h"
27 #include "ED_view3d.h" /* To draw toolbar UI. */
28 
29 #include "WM_api.h"
30 #include "WM_message.h"
31 #include "WM_types.h"
32 
33 #include "RNA_access.h"
34 #include "RNA_define.h"
35 #include "RNA_enum_types.h"
36 
37 #include "UI_interface.h"
38 #include "UI_resources.h"
39 
40 #include "buttons_intern.h" /* own include */
41 
42 /* -------------------------------------------------------------------- */
47 {
48  ARegion *region;
49  SpaceProperties *sbuts;
50 
51  sbuts = MEM_callocN(sizeof(SpaceProperties), "initbuts");
52  sbuts->spacetype = SPACE_PROPERTIES;
53 
54  sbuts->mainb = sbuts->mainbuser = BCONTEXT_OBJECT;
55 
56  /* header */
57  region = MEM_callocN(sizeof(ARegion), "header for buts");
58 
59  BLI_addtail(&sbuts->regionbase, region);
60  region->regiontype = RGN_TYPE_HEADER;
62 
63  /* navigation bar */
64  region = MEM_callocN(sizeof(ARegion), "navigation bar for buts");
65 
66  BLI_addtail(&sbuts->regionbase, region);
67  region->regiontype = RGN_TYPE_NAV_BAR;
68  region->alignment = RGN_ALIGN_LEFT;
69 
70 #if 0
71  /* context region */
72  region = MEM_callocN(sizeof(ARegion), "context region for buts");
73  BLI_addtail(&sbuts->regionbase, region);
74  region->regiontype = RGN_TYPE_CHANNELS;
75  region->alignment = RGN_ALIGN_TOP;
76 #endif
77 
78  /* main region */
79  region = MEM_callocN(sizeof(ARegion), "main region for buts");
80 
81  BLI_addtail(&sbuts->regionbase, region);
82  region->regiontype = RGN_TYPE_WINDOW;
83 
84  return (SpaceLink *)sbuts;
85 }
86 
87 /* not spacelink itself */
88 static void buttons_free(SpaceLink *sl)
89 {
90  SpaceProperties *sbuts = (SpaceProperties *)sl;
91 
92  if (sbuts->path) {
93  MEM_freeN(sbuts->path);
94  }
95 
96  if (sbuts->texuser) {
97  ButsContextTexture *ct = sbuts->texuser;
98  BLI_freelistN(&ct->users);
99  MEM_freeN(ct);
100  }
101 
102  if (sbuts->runtime != NULL) {
104  MEM_freeN(sbuts->runtime);
105  }
106 }
107 
108 /* spacetype; init callback */
109 static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
110 {
111  SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
112 
113  if (sbuts->runtime == NULL) {
114  sbuts->runtime = MEM_mallocN(sizeof(SpaceProperties_Runtime), __func__);
115  sbuts->runtime->search_string[0] = '\0';
116  sbuts->runtime->tab_search_results = BLI_BITMAP_NEW(BCONTEXT_TOT * 2, __func__);
117  }
118 }
119 
121 {
122  SpaceProperties *sfile_old = (SpaceProperties *)sl;
123  SpaceProperties *sbutsn = MEM_dupallocN(sl);
124 
125  /* clear or remove stuff from old */
126  sbutsn->path = NULL;
127  sbutsn->texuser = NULL;
128  if (sfile_old->runtime != NULL) {
129  sbutsn->runtime = MEM_dupallocN(sfile_old->runtime);
130  sbutsn->runtime->search_string[0] = '\0';
132  }
133 
134  return (SpaceLink *)sbutsn;
135 }
136 
137 /* add handlers, stuff you only do once or on area/region changes */
139 {
140  wmKeyMap *keymap;
141 
142  ED_region_panels_init(wm, region);
143 
144  keymap = WM_keymap_ensure(wm->defaultconf, "Property Editor", SPACE_PROPERTIES, 0);
145  WM_event_add_keymap_handler(&region->handlers, keymap);
146 }
147 
150 /* -------------------------------------------------------------------- */
154 int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
155 {
156  int length = 0;
157  if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
158  context_tabs_array[length] = BCONTEXT_TOOL;
159  length++;
160  }
161  if (length != 0) {
162  context_tabs_array[length] = -1;
163  length++;
164  }
165  if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
166  context_tabs_array[length] = BCONTEXT_RENDER;
167  length++;
168  }
169  if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
170  context_tabs_array[length] = BCONTEXT_OUTPUT;
171  length++;
172  }
173  if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
174  context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
175  length++;
176  }
177  if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
178  context_tabs_array[length] = BCONTEXT_SCENE;
179  length++;
180  }
181  if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
182  context_tabs_array[length] = BCONTEXT_WORLD;
183  length++;
184  }
185  if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
186  if (length != 0) {
187  context_tabs_array[length] = -1;
188  length++;
189  }
190  context_tabs_array[length] = BCONTEXT_COLLECTION;
191  length++;
192  }
193  if (length != 0) {
194  context_tabs_array[length] = -1;
195  length++;
196  }
197  if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
198  context_tabs_array[length] = BCONTEXT_OBJECT;
199  length++;
200  }
201  if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
202  context_tabs_array[length] = BCONTEXT_MODIFIER;
203  length++;
204  }
205  if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
206  context_tabs_array[length] = BCONTEXT_SHADERFX;
207  length++;
208  }
209  if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
210  context_tabs_array[length] = BCONTEXT_PARTICLE;
211  length++;
212  }
213  if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
214  context_tabs_array[length] = BCONTEXT_PHYSICS;
215  length++;
216  }
217  if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
218  context_tabs_array[length] = BCONTEXT_CONSTRAINT;
219  length++;
220  }
221  if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
222  context_tabs_array[length] = BCONTEXT_DATA;
223  length++;
224  }
225  if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
226  context_tabs_array[length] = BCONTEXT_BONE;
227  length++;
228  }
229  if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
230  context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT;
231  length++;
232  }
233  if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
234  context_tabs_array[length] = BCONTEXT_MATERIAL;
235  length++;
236  }
237  if (length != 0) {
238  context_tabs_array[length] = -1;
239  length++;
240  }
241  if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
242  context_tabs_array[length] = BCONTEXT_TEXTURE;
243  length++;
244  }
245 
246  return length;
247 }
248 
249 static const char *buttons_main_region_context_string(const short mainb)
250 {
251  switch (mainb) {
252  case BCONTEXT_SCENE:
253  return "scene";
254  case BCONTEXT_RENDER:
255  return "render";
256  case BCONTEXT_OUTPUT:
257  return "output";
258  case BCONTEXT_VIEW_LAYER:
259  return "view_layer";
260  case BCONTEXT_WORLD:
261  return "world";
262  case BCONTEXT_COLLECTION:
263  return "collection";
264  case BCONTEXT_OBJECT:
265  return "object";
266  case BCONTEXT_DATA:
267  return "data";
268  case BCONTEXT_MATERIAL:
269  return "material";
270  case BCONTEXT_TEXTURE:
271  return "texture";
272  case BCONTEXT_PARTICLE:
273  return "particle";
274  case BCONTEXT_PHYSICS:
275  return "physics";
276  case BCONTEXT_BONE:
277  return "bone";
278  case BCONTEXT_MODIFIER:
279  return "modifier";
280  case BCONTEXT_SHADERFX:
281  return "shaderfx";
282  case BCONTEXT_CONSTRAINT:
283  return "constraint";
285  return "bone_constraint";
286  case BCONTEXT_TOOL:
287  return "tool";
288  }
289 
290  /* All the cases should be handled. */
291  BLI_assert(false);
292  return "";
293 }
294 
296  SpaceProperties *sbuts,
297  ARegion *region)
298 {
299  buttons_context_compute(C, sbuts);
300 
301  const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL};
302 
303  ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
304 }
305 
308 /* -------------------------------------------------------------------- */
313 {
314  return sbuts->runtime->search_string;
315 }
316 
318 {
319  return BLI_strnlen(sbuts->runtime->search_string, sizeof(sbuts->runtime->search_string));
320 }
321 
322 void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
323 {
324  BLI_strncpy(sbuts->runtime->search_string, value, sizeof(sbuts->runtime->search_string));
325 }
326 
328 {
329  return BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, index);
330 }
331 
334 /* -------------------------------------------------------------------- */
338 static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts)
339 {
340  const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL};
341 
342  if (sbuts->mainb == BCONTEXT_TOOL) {
343  return false;
344  }
345 
346  buttons_context_compute(C, sbuts);
347  return ED_region_property_search(C, region, &region->type->paneltypes, contexts, NULL);
348 }
349 
351  const short *context_tabs_array,
352  const int tabs_len)
353 {
354  /* As long as all-tab search in the tool is disabled in the tool context, don't move from it. */
355  if (sbuts->mainb == BCONTEXT_TOOL) {
356  return;
357  }
358 
359  int current_tab_index = 0;
360  for (int i = 0; i < tabs_len; i++) {
361  if (sbuts->mainb == context_tabs_array[i]) {
362  current_tab_index = i;
363  break;
364  }
365  }
366 
367  /* Try the tabs after the current tab. */
368  for (int i = current_tab_index; i < tabs_len; i++) {
369  if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
370  sbuts->mainbuser = context_tabs_array[i];
371  return;
372  }
373  }
374 
375  /* Try the tabs before the current tab. */
376  for (int i = 0; i < current_tab_index; i++) {
377  if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
378  sbuts->mainbuser = context_tabs_array[i];
379  return;
380  }
381  }
382 }
383 
385  SpaceProperties *sbuts,
386  ARegion *region_original,
387  const short *context_tabs_array,
388  const int tabs_len)
389 {
390  /* Use local copies of the area and duplicate the region as a mainly-paranoid protection
391  * against changing any of the space / region data while running the search. */
392  ScrArea *area_original = CTX_wm_area(C);
393  ScrArea area_copy = *area_original;
394  ARegion *region_copy = BKE_area_region_copy(area_copy.type, region_original);
395  /* Set the region visible field. Otherwise some layout code thinks we're drawing in a popup.
396  * This likely isn't necessary, but it's nice to emulate a "real" region where possible. */
397  region_copy->visible = true;
398  CTX_wm_area_set((bContext *)C, &area_copy);
399  CTX_wm_region_set((bContext *)C, region_copy);
400 
401  SpaceProperties sbuts_copy = *sbuts;
402  sbuts_copy.path = NULL;
403  sbuts_copy.texuser = NULL;
404  sbuts_copy.runtime = MEM_dupallocN(sbuts->runtime);
405  sbuts_copy.runtime->tab_search_results = NULL;
406  BLI_listbase_clear(&area_copy.spacedata);
407  BLI_addtail(&area_copy.spacedata, &sbuts_copy);
408 
409  /* Loop through the tabs added to the properties editor. */
410  for (int i = 0; i < tabs_len; i++) {
411  /* -1 corresponds to a spacer. */
412  if (context_tabs_array[i] == -1) {
413  continue;
414  }
415 
416  /* Handle search for the current tab in the normal layout pass. */
417  if (context_tabs_array[i] == sbuts->mainb) {
418  continue;
419  }
420 
421  sbuts_copy.mainb = sbuts_copy.mainbo = sbuts_copy.mainbuser = context_tabs_array[i];
422 
423  /* Actually do the search and store the result in the bitmap. */
425  i,
426  property_search_for_context(C, region_copy, &sbuts_copy));
427 
428  UI_blocklist_free(C, region_copy);
429  }
430 
431  BKE_area_region_free(area_copy.type, region_copy);
432  MEM_freeN(region_copy);
433  buttons_free((SpaceLink *)&sbuts_copy);
434 
435  CTX_wm_area_set((bContext *)C, area_original);
436  CTX_wm_region_set((bContext *)C, region_original);
437 }
438 
444  SpaceProperties *sbuts,
445  ARegion *region)
446 {
447  /* Theoretical maximum of every context shown with a spacer between every tab. */
448  short context_tabs_array[BCONTEXT_TOT * 2];
449  int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array);
450 
451  property_search_all_tabs(C, sbuts, region, context_tabs_array, tabs_len);
452 
453  /* Check whether the current tab has a search match. */
454  bool current_tab_has_search_match = false;
455  LISTBASE_FOREACH (Panel *, panel, &region->panels) {
456  if (UI_panel_is_active(panel) && UI_panel_matches_search_filter(panel)) {
457  current_tab_has_search_match = true;
458  }
459  }
460 
461  /* Find which index in the list the current tab corresponds to. */
462  int current_tab_index = -1;
463  for (int i = 0; i < tabs_len; i++) {
464  if (context_tabs_array[i] == sbuts->mainb) {
465  current_tab_index = i;
466  }
467  }
468  BLI_assert(current_tab_index != -1);
469 
470  /* Update the tab search match flag for the current tab. */
472  sbuts->runtime->tab_search_results, current_tab_index, current_tab_has_search_match);
473 
474  /* Move to the next tab with a result */
475  if (!current_tab_has_search_match) {
476  if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
477  property_search_move_to_next_tab_with_results(sbuts, context_tabs_array, tabs_len);
478  }
479  }
480 }
481 
484 /* -------------------------------------------------------------------- */
488 static void buttons_main_region_layout(const bContext *C, ARegion *region)
489 {
490  /* draw entirely, view changes should be handled here */
492 
493  if (sbuts->mainb == BCONTEXT_TOOL) {
494  ED_view3d_buttons_region_layout_ex(C, region, "Tool");
495  }
496  else {
498  }
499 
500  if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
501  buttons_main_region_property_search(C, sbuts, region);
502  }
503 
504  sbuts->mainbo = sbuts->mainb;
505 }
506 
508 {
509  ARegion *region = params->region;
510  wmNotifier *wmn = params->notifier;
511 
512  /* context changes */
513  switch (wmn->category) {
514  case NC_SCREEN:
515  if (ELEM(wmn->data, ND_LAYER)) {
516  ED_region_tag_redraw(region);
517  }
518  break;
519  }
520 }
521 
522 static void buttons_operatortypes(void)
523 {
530 }
531 
532 static void buttons_keymap(struct wmKeyConfig *keyconf)
533 {
534  WM_keymap_ensure(keyconf, "Property Editor", SPACE_PROPERTIES, 0);
535 }
536 
539 /* -------------------------------------------------------------------- */
543 /* add handlers, stuff you only do once or on area/region changes */
545 {
546  ED_region_header_init(region);
547 }
548 
549 static void buttons_header_region_draw(const bContext *C, ARegion *region)
550 {
552 
553  /* Needed for RNA to get the good values! */
554  buttons_context_compute(C, sbuts);
555 
556  ED_region_header(C, region);
557 }
558 
560 {
561  struct wmMsgBus *mbus = params->message_bus;
562  ScrArea *area = params->area;
563  ARegion *region = params->region;
564  SpaceProperties *sbuts = area->spacedata.first;
565 
566  wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
567  .owner = region,
568  .user_data = region,
570  };
571 
572  /* Don't check for SpaceProperties.mainb here, we may toggle between view-layers
573  * where one has no active object, so that available contexts changes. */
574  WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
575 
577  WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
578  }
579 
580  if (sbuts->mainb == BCONTEXT_TOOL) {
581  WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
582  }
583 }
584 
587 /* -------------------------------------------------------------------- */
592 {
594 
595  ED_region_panels_init(wm, region);
597 }
598 
600 {
601  LISTBASE_FOREACH (PanelType *, pt, &region->type->paneltypes) {
602  pt->flag |= PANEL_TYPE_LAYOUT_VERT_BAR;
603  }
604 
605  ED_region_panels_layout(C, region);
606  /* ED_region_panels_layout adds vertical scrollbars, we don't want them. */
607  region->v2d.scroll &= ~V2D_SCROLL_VERTICAL;
608  ED_region_panels_draw(C, region);
609 }
610 
613 {
614  struct wmMsgBus *mbus = params->message_bus;
615  ARegion *region = params->region;
616 
617  wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
618  .owner = region,
619  .user_data = region,
621  };
622 
623  WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
624 }
625 
626 /* draw a certain button set only if properties area is currently
627  * showing that button set, to reduce unnecessary drawing. */
628 static void buttons_area_redraw(ScrArea *area, short buttons)
629 {
630  SpaceProperties *sbuts = area->spacedata.first;
631 
632  /* if the area's current button set is equal to the one to redraw */
633  if (sbuts->mainb == buttons) {
635  }
636 }
637 
640 /* -------------------------------------------------------------------- */
644 /* reused! */
646 {
647  ScrArea *area = params->area;
648  wmNotifier *wmn = params->notifier;
649  SpaceProperties *sbuts = area->spacedata.first;
650 
651  /* context changes */
652  switch (wmn->category) {
653  case NC_SCENE:
654  switch (wmn->data) {
655  case ND_RENDER_OPTIONS:
659  break;
660  case ND_WORLD:
662  sbuts->preview = 1;
663  break;
664  case ND_FRAME:
665  /* any buttons area can have animated properties so redraw all */
667  sbuts->preview = 1;
668  break;
669  case ND_OB_ACTIVE:
671  sbuts->preview = 1;
672  break;
673  case ND_KEYINGSET:
675  break;
676  case ND_RENDER_RESULT:
677  break;
678  case ND_MODE:
679  case ND_LAYER:
680  default:
682  break;
683  }
684  break;
685  case NC_OBJECT:
686  switch (wmn->data) {
687  case ND_TRANSFORM:
689  buttons_area_redraw(area, BCONTEXT_DATA); /* autotexpace flag */
690  break;
691  case ND_POSE:
692  case ND_BONE_ACTIVE:
693  case ND_BONE_SELECT:
697  break;
698  case ND_MODIFIER:
699  if (wmn->action == NA_RENAME) {
701  }
702  else {
704  }
706  break;
707  case ND_CONSTRAINT:
710  break;
711  case ND_SHADERFX:
713  break;
714  case ND_PARTICLE:
715  if (wmn->action == NA_EDITED) {
717  }
718  sbuts->preview = 1;
719  break;
720  case ND_DRAW:
724  /* Needed to refresh context path when changing active particle system index. */
727  break;
728  case ND_DRAW_ANIMVIZ:
730  break;
731  default:
732  /* Not all object RNA props have a ND_ notifier (yet) */
734  break;
735  }
736  break;
737  case NC_GEOM:
738  switch (wmn->data) {
739  case ND_SELECT:
740  case ND_DATA:
741  case ND_VERTEX_GROUP:
743  break;
744  }
745  break;
746  case NC_MATERIAL:
748  switch (wmn->data) {
749  case ND_SHADING:
750  case ND_SHADING_DRAW:
751  case ND_SHADING_LINKS:
752  case ND_SHADING_PREVIEW:
753  case ND_NODES:
754  /* currently works by redraws... if preview is set, it (re)starts job */
755  sbuts->preview = 1;
756  break;
757  }
758  break;
759  case NC_WORLD:
761  sbuts->preview = 1;
762  break;
763  case NC_LAMP:
765  sbuts->preview = 1;
766  break;
767  case NC_GROUP:
769  break;
770  case NC_BRUSH:
773  sbuts->preview = 1;
774  break;
775  case NC_TEXTURE:
776  case NC_IMAGE:
777  if (wmn->action != NA_PAINTING) {
779  sbuts->preview = 1;
780  }
781  break;
782  case NC_WORKSPACE:
784  break;
785  case NC_SPACE:
786  if (wmn->data == ND_SPACE_PROPERTIES) {
788  }
789  else if (wmn->data == ND_SPACE_CHANGED) {
791  sbuts->preview = 1;
792  }
793  break;
794  case NC_ID:
795  if (wmn->action == NA_RENAME) {
797  }
798  break;
799  case NC_ANIMATION:
800  switch (wmn->data) {
801  case ND_NLA_ACTCHANGE:
803  break;
804  case ND_KEYFRAME:
805  if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
807  }
808  break;
809  }
810  break;
811  case NC_GPENCIL:
812  switch (wmn->data) {
813  case ND_DATA:
816  }
817  break;
818  }
819  break;
820  case NC_NODE:
821  if (wmn->action == NA_SELECTED) {
823  /* new active node, update texture preview */
824  if (sbuts->mainb == BCONTEXT_TEXTURE) {
825  sbuts->preview = 1;
826  }
827  }
828  break;
829  /* Listener for preview render, when doing an global undo. */
830  case NC_WM:
831  if (wmn->data == ND_UNDO) {
833  sbuts->preview = 1;
834  }
835  break;
836  case NC_SCREEN:
837  if (wmn->data == ND_LAYOUTSET) {
839  sbuts->preview = 1;
840  }
841  break;
842 #ifdef WITH_FREESTYLE
843  case NC_LINESTYLE:
845  sbuts->preview = 1;
846  break;
847 #endif
848  }
849 
850  if (wmn->data == ND_KEYS) {
852  }
853 }
854 
856  SpaceLink *slink,
857  const struct IDRemapper *mappings)
858 {
859  SpaceProperties *sbuts = (SpaceProperties *)slink;
860 
861  if (BKE_id_remapper_apply(mappings, &sbuts->pinid, ID_REMAP_APPLY_DEFAULT) ==
863  sbuts->flag &= ~SB_PIN_CONTEXT;
864  }
865 
866  if (sbuts->path) {
867  ButsContextPath *path = sbuts->path;
868  for (int i = 0; i < path->len; i++) {
869  switch (BKE_id_remapper_apply(mappings, &path->ptr[i].owner_id, ID_REMAP_APPLY_DEFAULT)) {
871  path->len = i;
872  if (i != 0) {
873  /* If the first item in the path is cleared, the whole path is cleared, so no need to
874  * clear further items here, see also at the end of this block. */
875  memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
876  }
877  break;
878  }
880  RNA_id_pointer_create(path->ptr[i].owner_id, &path->ptr[i]);
881  /* There is no easy way to check/make path downwards valid, just nullify it.
882  * Next redraw will rebuild this anyway. */
883  i++;
884  memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
885  path->len = i;
886  break;
887  }
888 
891  /* Nothing to do. */
892  break;
893  }
894  }
895  }
896  if (path->len == 0) {
897  MEM_SAFE_FREE(sbuts->path);
898  }
899  }
900 
901  if (sbuts->texuser) {
902  ButsContextTexture *ct = sbuts->texuser;
904  BLI_freelistN(&ct->users);
905  ct->user = NULL;
906  }
907 }
908 
911 /* -------------------------------------------------------------------- */
916 {
917  SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype buttons");
918  ARegionType *art;
919 
920  st->spaceid = SPACE_PROPERTIES;
921  strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
922 
923  st->create = buttons_create;
924  st->free = buttons_free;
925  st->init = buttons_init;
926  st->duplicate = buttons_duplicate;
927  st->operatortypes = buttons_operatortypes;
928  st->keymap = buttons_keymap;
929  st->listener = buttons_area_listener;
930  st->context = buttons_context;
931  st->id_remap = buttons_id_remap;
932 
933  /* regions: main window */
934  art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
935  art->regionid = RGN_TYPE_WINDOW;
942  BLI_addhead(&st->regiontypes, art);
943 
944  /* Register the panel types from modifiers. The actual panels are built per modifier rather
945  * than per modifier type. */
946  for (ModifierType i = 0; i < NUM_MODIFIER_TYPES; i++) {
947  const ModifierTypeInfo *mti = BKE_modifier_get_info(i);
948  if (mti != NULL && mti->panelRegister != NULL) {
949  mti->panelRegister(art);
950  }
951  }
952  for (int i = 0; i < NUM_GREASEPENCIL_MODIFIER_TYPES; i++) {
954  if (mti != NULL && mti->panelRegister != NULL) {
955  mti->panelRegister(art);
956  }
957  }
958  for (int i = 0; i < NUM_SHADER_FX_TYPES; i++) {
960  continue;
961  }
962  const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(i);
963  if (fxti != NULL && fxti->panelRegister != NULL) {
964  fxti->panelRegister(art);
965  }
966  }
967 
968  /* regions: header */
969  art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
970  art->regionid = RGN_TYPE_HEADER;
971  art->prefsizey = HEADERY;
973 
977  BLI_addhead(&st->regiontypes, art);
978 
979  /* regions: navigation bar */
980  art = MEM_callocN(sizeof(ARegionType), "spacetype nav buttons region");
981  art->regionid = RGN_TYPE_NAV_BAR;
982  art->prefsizex = AREAMINX - 3; /* XXX Works and looks best,
983  * should we update AREAMINX accordingly? */
988  BLI_addhead(&st->regiontypes, art);
989 
991 }
992 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:1009
struct SpaceProperties * CTX_wm_space_properties(const bContext *C)
Definition: context.c:833
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:997
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
@ 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
IDRemapperApplyResult BKE_id_remapper_apply(const struct IDRemapper *id_remapper, struct ID **r_id_ptr, IDRemapperApplyOptions options)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
@ PANEL_TYPE_LAYOUT_VERT_BAR
Definition: BKE_screen.h:283
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:53
void BKE_area_region_free(struct SpaceType *st, struct ARegion *region)
Definition: screen.c:626
void BKE_spacetype_register(struct SpaceType *st)
Definition: screen.c:391
struct ARegion * BKE_area_region_copy(const struct SpaceType *st, const struct ARegion *region)
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:139
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition: BLI_bitmap.h:102
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:899
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
#define ELEM(...)
@ NUM_GREASEPENCIL_MODIFIER_TYPES
ModifierType
@ NUM_MODIFIER_TYPES
#define HEADERY
@ RGN_FLAG_SEARCH_FILTER_UPDATE
@ RGN_FLAG_PREFSIZE_OR_HIDDEN
@ RGN_FLAG_SEARCH_FILTER_ACTIVE
#define AREAMINX
@ RGN_TYPE_CHANNELS
@ RGN_TYPE_WINDOW
@ RGN_TYPE_NAV_BAR
@ RGN_TYPE_HEADER
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_TOP
@ eShaderFxType_Light_deprecated
@ NUM_SHADER_FX_TYPES
@ SPACE_PROPERTIES
@ SB_PIN_CONTEXT
@ 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
@ V2D_SCROLL_VERTICAL
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:729
@ ED_KEYMAP_NAVBAR
Definition: ED_screen.h:700
@ ED_KEYMAP_UI
Definition: ED_screen.h:691
@ ED_KEYMAP_HEADER
Definition: ED_screen.h:697
@ ED_KEYMAP_VIEW2D
Definition: ED_screen.h:694
@ ED_KEYMAP_FRAMES
Definition: ED_screen.h:696
void ED_region_header(const struct bContext *C, struct ARegion *region)
void ED_region_do_msg_notify_tag_redraw(struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val)
void ED_region_panels_draw(const struct bContext *C, struct ARegion *region)
bool ED_region_property_search(const struct bContext *C, struct ARegion *region, struct ListBase *paneltypes, const char *contexts[], const char *category_override)
void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *region)
Definition: area.c:3153
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
void ED_region_header_init(struct ARegion *region)
Definition: area.c:3417
void ED_region_panels_layout_ex(const struct bContext *C, struct ARegion *region, struct ListBase *paneltypes, const char *contexts[], const char *category_override)
void ED_region_panels_layout(const struct bContext *C, struct ARegion *region)
void ED_view3d_buttons_region_layout_ex(const struct bContext *C, struct ARegion *region, const char *category_override)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
void UI_blocklist_free(const struct bContext *C, struct ARegion *region)
bool UI_panel_is_active(const struct Panel *panel)
bool UI_panel_matches_search_filter(const struct Panel *panel)
#define NC_WORLD
Definition: WM_types.h:337
#define ND_SHADING
Definition: WM_types.h:425
#define ND_WORLD
Definition: WM_types.h:401
#define NC_ID
Definition: WM_types.h:345
#define NC_NODE
Definition: WM_types.h:344
#define NC_GEOM
Definition: WM_types.h:343
#define ND_NLA_ACTCHANGE
Definition: WM_types.h:446
#define ND_SPACE_CHANGED
Definition: WM_types.h:481
#define ND_DRAW
Definition: WM_types.h:410
#define NC_BRUSH
Definition: WM_types.h:335
#define ND_OB_ACTIVE
Definition: WM_types.h:388
#define ND_RENDER_RESULT
Definition: WM_types.h:394
#define NC_WM
Definition: WM_types.h:324
#define ND_DATA
Definition: WM_types.h:456
#define NC_LINESTYLE
Definition: WM_types.h:350
#define ND_RENDER_OPTIONS
Definition: WM_types.h:383
#define NC_ANIMATION
Definition: WM_types.h:338
#define ND_SHADING_PREVIEW
Definition: WM_types.h:428
#define ND_VERTEX_GROUP
Definition: WM_types.h:457
#define NC_SCREEN
Definition: WM_types.h:327
#define ND_MODE
Definition: WM_types.h:393
#define ND_SPACE_PROPERTIES
Definition: WM_types.h:472
#define ND_KEYINGSET
Definition: WM_types.h:396
#define NC_SCENE
Definition: WM_types.h:328
#define NA_ADDED
Definition: WM_types.h:525
#define NC_GROUP
Definition: WM_types.h:333
#define ND_NODES
Definition: WM_types.h:384
#define ND_MODIFIER
Definition: WM_types.h:411
#define ND_POSE
Definition: WM_types.h:407
#define NA_EDITED
Definition: WM_types.h:523
#define ND_PARTICLE
Definition: WM_types.h:414
#define NC_MATERIAL
Definition: WM_types.h:330
#define NC_LAMP
Definition: WM_types.h:332
#define NC_IMAGE
Definition: WM_types.h:334
#define ND_CONSTRAINT
Definition: WM_types.h:413
#define NC_WORKSPACE
Definition: WM_types.h:326
#define ND_UNDO
Definition: WM_types.h:365
#define ND_FRAME
Definition: WM_types.h:382
#define NA_REMOVED
Definition: WM_types.h:526
#define ND_SELECT
Definition: WM_types.h:455
#define NC_GPENCIL
Definition: WM_types.h:349
#define NC_TEXTURE
Definition: WM_types.h:331
#define ND_BONE_ACTIVE
Definition: WM_types.h:408
#define ND_TRANSFORM
Definition: WM_types.h:405
#define ND_LAYER
Definition: WM_types.h:398
#define ND_KEYS
Definition: WM_types.h:412
#define NA_RENAME
Definition: WM_types.h:527
#define ND_SHADERFX
Definition: WM_types.h:420
#define NA_PAINTING
Definition: WM_types.h:530
#define ND_DRAW_ANIMVIZ
Definition: WM_types.h:422
#define ND_BONE_SELECT
Definition: WM_types.h:409
#define ND_KEYFRAME
Definition: WM_types.h:442
#define ND_LAYOUTSET
Definition: WM_types.h:374
#define NC_OBJECT
Definition: WM_types.h:329
#define ND_SHADING_LINKS
Definition: WM_types.h:427
#define ND_SHADING_DRAW
Definition: WM_types.h:426
#define NC_SPACE
Definition: WM_types.h:342
#define NA_SELECTED
Definition: WM_types.h:528
unsigned int U
Definition: btGjkEpa3.h:78
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_context_menu(struct wmOperatorType *ot)
Definition: buttons_ops.c:156
void BUTTONS_OT_directory_browse(struct wmOperatorType *ot)
Definition: buttons_ops.c:371
void BUTTONS_OT_toggle_pin(struct wmOperatorType *ot)
Definition: buttons_ops.c:127
void BUTTONS_OT_file_browse(struct wmOperatorType *ot)
Definition: buttons_ops.c:345
void BUTTONS_OT_start_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:61
void BUTTONS_OT_clear_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:86
Scene scene
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void area(int d1, int d2, int e1, int e2, float weights[2])
T length(const vec_base< T, Size > &a)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
static void buttons_main_region_layout(const bContext *C, ARegion *region)
void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts)
static void buttons_header_region_draw(const bContext *C, ARegion *region)
void ED_spacetype_buttons(void)
static void buttons_main_region_property_search(const bContext *C, SpaceProperties *sbuts, ARegion *region)
static void buttons_navigation_bar_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *region)
static void buttons_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
static void buttons_main_region_init(wmWindowManager *wm, ARegion *region)
static SpaceLink * buttons_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
Definition: space_buttons.c:46
static void buttons_navigation_bar_region_init(wmWindowManager *wm, ARegion *region)
static void buttons_main_region_listener(const wmRegionListenerParams *params)
static void buttons_operatortypes(void)
static void buttons_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
static const char * buttons_main_region_context_string(const short mainb)
static void buttons_main_region_layout_properties(const bContext *C, SpaceProperties *sbuts, ARegion *region)
static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
static void buttons_area_redraw(ScrArea *area, short buttons)
bool ED_buttons_tab_has_search_result(SpaceProperties *sbuts, const int index)
static void buttons_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, const struct IDRemapper *mappings)
static void buttons_free(SpaceLink *sl)
Definition: space_buttons.c:88
static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
static SpaceLink * buttons_duplicate(SpaceLink *sl)
const char * ED_buttons_search_string_get(SpaceProperties *sbuts)
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)
static void buttons_keymap(struct wmKeyConfig *keyconf)
int ED_buttons_search_string_length(struct SpaceProperties *sbuts)
void(* draw)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:151
void(* message_subscribe)(const wmRegionMessageSubscribeParams *params)
Definition: BKE_screen.h:167
void(* listener)(const wmRegionListenerParams *params)
Definition: BKE_screen.h:165
int keymapflag
Definition: BKE_screen.h:208
void(* layout)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:161
void(* init)(struct wmWindowManager *wm, struct ARegion *region)
Definition: BKE_screen.h:147
ListBase paneltypes
Definition: BKE_screen.h:198
ListBase panels
ListBase handlers
short alignment
short regiontype
struct ARegionType * type
PointerRNA ptr[8]
struct ButsTextureUser * user
struct Tex * texture
void(* panelRegister)(struct ARegionType *region_type)
Definition: DNA_ID.h:368
void(* panelRegister)(struct ARegionType *region_type)
Definition: BKE_modifier.h:358
struct ID * owner_id
Definition: RNA_types.h:36
ListBase spacedata
struct SpaceType * type
void(* panelRegister)(struct ARegionType *region_type)
BLI_bitmap * tab_search_results
char search_string[UI_MAX_NAME_STR]
struct SpaceProperties_Runtime * runtime
short keepzoom
short scroll
unsigned int data
Definition: WM_types.h:308
unsigned int action
Definition: WM_types.h:308
unsigned int category
Definition: WM_types.h:308
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.c:852
#define WM_msg_subscribe_rna_anon_prop(mbus, type_, prop_, value)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))