Blender  V2.93
space_buttons.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_bitmap.h"
30 #include "BLI_blenlib.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_context.h"
34 #include "BKE_gpencil_modifier.h" /* Types for registering panels. */
35 #include "BKE_modifier.h"
36 #include "BKE_screen.h"
37 #include "BKE_shader_fx.h"
38 
39 #include "ED_buttons.h"
40 #include "ED_screen.h"
41 #include "ED_space_api.h"
42 #include "ED_view3d.h" /* To draw toolbar UI. */
43 
44 #include "WM_api.h"
45 #include "WM_message.h"
46 #include "WM_types.h"
47 
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50 #include "RNA_enum_types.h"
51 
52 #include "UI_interface.h"
53 #include "UI_resources.h"
54 
55 #include "buttons_intern.h" /* own include */
56 
57 /* -------------------------------------------------------------------- */
62 {
63  ARegion *region;
64  SpaceProperties *sbuts;
65 
66  sbuts = MEM_callocN(sizeof(SpaceProperties), "initbuts");
67  sbuts->spacetype = SPACE_PROPERTIES;
68 
69  sbuts->mainb = sbuts->mainbuser = BCONTEXT_OBJECT;
70 
71  /* header */
72  region = MEM_callocN(sizeof(ARegion), "header for buts");
73 
74  BLI_addtail(&sbuts->regionbase, region);
75  region->regiontype = RGN_TYPE_HEADER;
77 
78  /* navigation bar */
79  region = MEM_callocN(sizeof(ARegion), "navigation bar for buts");
80 
81  BLI_addtail(&sbuts->regionbase, region);
82  region->regiontype = RGN_TYPE_NAV_BAR;
83  region->alignment = RGN_ALIGN_LEFT;
84 
85 #if 0
86  /* context region */
87  region = MEM_callocN(sizeof(ARegion), "context region for buts");
88  BLI_addtail(&sbuts->regionbase, region);
89  region->regiontype = RGN_TYPE_CHANNELS;
90  region->alignment = RGN_ALIGN_TOP;
91 #endif
92 
93  /* main region */
94  region = MEM_callocN(sizeof(ARegion), "main region for buts");
95 
96  BLI_addtail(&sbuts->regionbase, region);
97  region->regiontype = RGN_TYPE_WINDOW;
98 
99  return (SpaceLink *)sbuts;
100 }
101 
102 /* not spacelink itself */
103 static void buttons_free(SpaceLink *sl)
104 {
105  SpaceProperties *sbuts = (SpaceProperties *)sl;
106 
107  if (sbuts->path) {
108  MEM_freeN(sbuts->path);
109  }
110 
111  if (sbuts->texuser) {
112  ButsContextTexture *ct = sbuts->texuser;
113  BLI_freelistN(&ct->users);
114  MEM_freeN(ct);
115  }
116 
117  if (sbuts->runtime != NULL) {
119  MEM_freeN(sbuts->runtime);
120  }
121 }
122 
123 /* spacetype; init callback */
124 static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
125 {
126  SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
127 
128  if (sbuts->runtime == NULL) {
129  sbuts->runtime = MEM_mallocN(sizeof(SpaceProperties_Runtime), __func__);
130  sbuts->runtime->search_string[0] = '\0';
131  sbuts->runtime->tab_search_results = BLI_BITMAP_NEW(BCONTEXT_TOT * 2, __func__);
132  }
133 }
134 
136 {
137  SpaceProperties *sfile_old = (SpaceProperties *)sl;
138  SpaceProperties *sbutsn = MEM_dupallocN(sl);
139 
140  /* clear or remove stuff from old */
141  sbutsn->path = NULL;
142  sbutsn->texuser = NULL;
143  if (sfile_old->runtime != NULL) {
144  sbutsn->runtime = MEM_dupallocN(sfile_old->runtime);
145  sbutsn->runtime->search_string[0] = '\0';
147  }
148 
149  return (SpaceLink *)sbutsn;
150 }
151 
152 /* add handlers, stuff you only do once or on area/region changes */
154 {
155  wmKeyMap *keymap;
156 
157  ED_region_panels_init(wm, region);
158 
159  keymap = WM_keymap_ensure(wm->defaultconf, "Property Editor", SPACE_PROPERTIES, 0);
160  WM_event_add_keymap_handler(&region->handlers, keymap);
161 }
162 
165 /* -------------------------------------------------------------------- */
174 int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
175 {
176  int length = 0;
177  if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
178  context_tabs_array[length] = BCONTEXT_TOOL;
179  length++;
180  }
181  if (length != 0) {
182  context_tabs_array[length] = -1;
183  length++;
184  }
185  if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
186  context_tabs_array[length] = BCONTEXT_RENDER;
187  length++;
188  }
189  if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
190  context_tabs_array[length] = BCONTEXT_OUTPUT;
191  length++;
192  }
193  if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
194  context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
195  length++;
196  }
197  if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
198  context_tabs_array[length] = BCONTEXT_SCENE;
199  length++;
200  }
201  if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
202  context_tabs_array[length] = BCONTEXT_WORLD;
203  length++;
204  }
205  if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
206  if (length != 0) {
207  context_tabs_array[length] = -1;
208  length++;
209  }
210  context_tabs_array[length] = BCONTEXT_COLLECTION;
211  length++;
212  }
213  if (length != 0) {
214  context_tabs_array[length] = -1;
215  length++;
216  }
217  if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
218  context_tabs_array[length] = BCONTEXT_OBJECT;
219  length++;
220  }
221  if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
222  context_tabs_array[length] = BCONTEXT_MODIFIER;
223  length++;
224  }
225  if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
226  context_tabs_array[length] = BCONTEXT_SHADERFX;
227  length++;
228  }
229  if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
230  context_tabs_array[length] = BCONTEXT_PARTICLE;
231  length++;
232  }
233  if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
234  context_tabs_array[length] = BCONTEXT_PHYSICS;
235  length++;
236  }
237  if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
238  context_tabs_array[length] = BCONTEXT_CONSTRAINT;
239  length++;
240  }
241  if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
242  context_tabs_array[length] = BCONTEXT_DATA;
243  length++;
244  }
245  if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
246  context_tabs_array[length] = BCONTEXT_BONE;
247  length++;
248  }
249  if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
250  context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT;
251  length++;
252  }
253  if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
254  context_tabs_array[length] = BCONTEXT_MATERIAL;
255  length++;
256  }
257  if (length != 0) {
258  context_tabs_array[length] = -1;
259  length++;
260  }
261  if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
262  context_tabs_array[length] = BCONTEXT_TEXTURE;
263  length++;
264  }
265 
266  return length;
267 }
268 
269 static const char *buttons_main_region_context_string(const short mainb)
270 {
271  switch (mainb) {
272  case BCONTEXT_SCENE:
273  return "scene";
274  case BCONTEXT_RENDER:
275  return "render";
276  case BCONTEXT_OUTPUT:
277  return "output";
278  case BCONTEXT_VIEW_LAYER:
279  return "view_layer";
280  case BCONTEXT_WORLD:
281  return "world";
282  case BCONTEXT_COLLECTION:
283  return "collection";
284  case BCONTEXT_OBJECT:
285  return "object";
286  case BCONTEXT_DATA:
287  return "data";
288  case BCONTEXT_MATERIAL:
289  return "material";
290  case BCONTEXT_TEXTURE:
291  return "texture";
292  case BCONTEXT_PARTICLE:
293  return "particle";
294  case BCONTEXT_PHYSICS:
295  return "physics";
296  case BCONTEXT_BONE:
297  return "bone";
298  case BCONTEXT_MODIFIER:
299  return "modifier";
300  case BCONTEXT_SHADERFX:
301  return "shaderfx";
302  case BCONTEXT_CONSTRAINT:
303  return "constraint";
305  return "bone_constraint";
306  case BCONTEXT_TOOL:
307  return "tool";
308  }
309 
310  /* All the cases should be handled. */
311  BLI_assert(false);
312  return "";
313 }
314 
316  SpaceProperties *sbuts,
317  ARegion *region)
318 {
319  buttons_context_compute(C, sbuts);
320 
321  const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL};
322 
323  ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
324 }
325 
328 /* -------------------------------------------------------------------- */
333 {
334  return sbuts->runtime->search_string;
335 }
336 
338 {
339  return BLI_strnlen(sbuts->runtime->search_string, sizeof(sbuts->runtime->search_string));
340 }
341 
342 void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
343 {
344  BLI_strncpy(sbuts->runtime->search_string, value, sizeof(sbuts->runtime->search_string));
345 }
346 
348 {
349  return BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, index);
350 }
351 
354 /* -------------------------------------------------------------------- */
358 static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts)
359 {
360  const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL};
361 
362  if (sbuts->mainb == BCONTEXT_TOOL) {
363  return false;
364  }
365 
366  buttons_context_compute(C, sbuts);
367  return ED_region_property_search(C, region, &region->type->paneltypes, contexts, NULL);
368 }
369 
371  const short *context_tabs_array,
372  const int tabs_len)
373 {
374  /* As long as all-tab search in the tool is disabled in the tool context, don't move from it. */
375  if (sbuts->mainb == BCONTEXT_TOOL) {
376  return;
377  }
378 
379  int current_tab_index = 0;
380  for (int i = 0; i < tabs_len; i++) {
381  if (sbuts->mainb == context_tabs_array[i]) {
382  current_tab_index = i;
383  break;
384  }
385  }
386 
387  /* Try the tabs after the current tab. */
388  for (int i = current_tab_index; i < tabs_len; i++) {
389  if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
390  sbuts->mainbuser = context_tabs_array[i];
391  return;
392  }
393  }
394 
395  /* Try the tabs before the current tab. */
396  for (int i = 0; i < current_tab_index; i++) {
397  if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
398  sbuts->mainbuser = context_tabs_array[i];
399  return;
400  }
401  }
402 }
403 
405  SpaceProperties *sbuts,
406  ARegion *region_original,
407  const short *context_tabs_array,
408  const int tabs_len)
409 {
410  /* Use local copies of the area and duplicate the region as a mainly-paranoid protection
411  * against changing any of the space / region data while running the search. */
412  ScrArea *area_original = CTX_wm_area(C);
413  ScrArea area_copy = *area_original;
414  ARegion *region_copy = BKE_area_region_copy(area_copy.type, region_original);
415  /* Set the region visible field. Otherwise some layout code thinks we're drawing in a popup.
416  * This likely isn't necessary, but it's nice to emulate a "real" region where possible. */
417  region_copy->visible = true;
418  CTX_wm_area_set((bContext *)C, &area_copy);
419  CTX_wm_region_set((bContext *)C, region_copy);
420 
421  SpaceProperties sbuts_copy = *sbuts;
422  sbuts_copy.path = NULL;
423  sbuts_copy.texuser = NULL;
424  sbuts_copy.runtime = MEM_dupallocN(sbuts->runtime);
425  sbuts_copy.runtime->tab_search_results = NULL;
426  BLI_listbase_clear(&area_copy.spacedata);
427  BLI_addtail(&area_copy.spacedata, &sbuts_copy);
428 
429  /* Loop through the tabs added to the properties editor. */
430  for (int i = 0; i < tabs_len; i++) {
431  /* -1 corresponds to a spacer. */
432  if (context_tabs_array[i] == -1) {
433  continue;
434  }
435 
436  /* Handle search for the current tab in the normal layout pass. */
437  if (context_tabs_array[i] == sbuts->mainb) {
438  continue;
439  }
440 
441  sbuts_copy.mainb = sbuts_copy.mainbo = sbuts_copy.mainbuser = context_tabs_array[i];
442 
443  /* Actually do the search and store the result in the bitmap. */
445  i,
446  property_search_for_context(C, region_copy, &sbuts_copy));
447 
448  UI_blocklist_free(C, &region_copy->uiblocks);
449  }
450 
451  BKE_area_region_free(area_copy.type, region_copy);
452  MEM_freeN(region_copy);
453  buttons_free((SpaceLink *)&sbuts_copy);
454 
455  CTX_wm_area_set((bContext *)C, area_original);
456  CTX_wm_region_set((bContext *)C, region_original);
457 }
458 
464  SpaceProperties *sbuts,
465  ARegion *region)
466 {
467  /* Theoretical maximum of every context shown with a spacer between every tab. */
468  short context_tabs_array[BCONTEXT_TOT * 2];
469  int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array);
470 
471  property_search_all_tabs(C, sbuts, region, context_tabs_array, tabs_len);
472 
473  /* Check whether the current tab has a search match. */
474  bool current_tab_has_search_match = false;
475  LISTBASE_FOREACH (Panel *, panel, &region->panels) {
476  if (UI_panel_is_active(panel) && UI_panel_matches_search_filter(panel)) {
477  current_tab_has_search_match = true;
478  }
479  }
480 
481  /* Find which index in the list the current tab corresponds to. */
482  int current_tab_index = -1;
483  for (int i = 0; i < tabs_len; i++) {
484  if (context_tabs_array[i] == sbuts->mainb) {
485  current_tab_index = i;
486  }
487  }
488  BLI_assert(current_tab_index != -1);
489 
490  /* Update the tab search match flag for the current tab. */
492  sbuts->runtime->tab_search_results, current_tab_index, current_tab_has_search_match);
493 
494  /* Move to the next tab with a result */
495  if (!current_tab_has_search_match) {
496  if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
497  property_search_move_to_next_tab_with_results(sbuts, context_tabs_array, tabs_len);
498  }
499  }
500 }
501 
504 /* -------------------------------------------------------------------- */
508 static void buttons_main_region_layout(const bContext *C, ARegion *region)
509 {
510  /* draw entirely, view changes should be handled here */
512 
513  if (sbuts->mainb == BCONTEXT_TOOL) {
514  ED_view3d_buttons_region_layout_ex(C, region, "Tool");
515  }
516  else {
518  }
519 
520  if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
521  buttons_main_region_property_search(C, sbuts, region);
522  }
523 
524  sbuts->mainbo = sbuts->mainb;
525 }
526 
528 {
529  ARegion *region = params->region;
530  wmNotifier *wmn = params->notifier;
531 
532  /* context changes */
533  switch (wmn->category) {
534  case NC_SCREEN:
535  if (ELEM(wmn->data, ND_LAYER)) {
536  ED_region_tag_redraw(region);
537  }
538  break;
539  }
540 }
541 
542 static void buttons_operatortypes(void)
543 {
550 }
551 
552 static void buttons_keymap(struct wmKeyConfig *keyconf)
553 {
554  WM_keymap_ensure(keyconf, "Property Editor", SPACE_PROPERTIES, 0);
555 }
556 
559 /* -------------------------------------------------------------------- */
563 /* add handlers, stuff you only do once or on area/region changes */
565 {
566  ED_region_header_init(region);
567 }
568 
569 static void buttons_header_region_draw(const bContext *C, ARegion *region)
570 {
572 
573  /* Needed for RNA to get the good values! */
574  buttons_context_compute(C, sbuts);
575 
576  ED_region_header(C, region);
577 }
578 
580 {
581  struct wmMsgBus *mbus = params->message_bus;
582  ScrArea *area = params->area;
583  ARegion *region = params->region;
584  SpaceProperties *sbuts = area->spacedata.first;
585 
586  wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
587  .owner = region,
588  .user_data = region,
590  };
591 
592  /* Don't check for SpaceProperties.mainb here, we may toggle between view-layers
593  * where one has no active object, so that available contexts changes. */
594  WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
595 
597  WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
598  }
599 
600  if (sbuts->mainb == BCONTEXT_TOOL) {
601  WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
602  }
603 }
604 
607 /* -------------------------------------------------------------------- */
612 {
614 
615  ED_region_panels_init(wm, region);
617 }
618 
620 {
621  LISTBASE_FOREACH (PanelType *, pt, &region->type->paneltypes) {
622  pt->flag |= PANEL_TYPE_LAYOUT_VERT_BAR;
623  }
624 
625  ED_region_panels_layout(C, region);
626  /* ED_region_panels_layout adds vertical scrollbars, we don't want them. */
627  region->v2d.scroll &= ~V2D_SCROLL_VERTICAL;
628  ED_region_panels_draw(C, region);
629 }
630 
633 {
634  struct wmMsgBus *mbus = params->message_bus;
635  ARegion *region = params->region;
636 
637  wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
638  .owner = region,
639  .user_data = region,
641  };
642 
643  WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
644 }
645 
646 /* draw a certain button set only if properties area is currently
647  * showing that button set, to reduce unnecessary drawing. */
648 static void buttons_area_redraw(ScrArea *area, short buttons)
649 {
650  SpaceProperties *sbuts = area->spacedata.first;
651 
652  /* if the area's current button set is equal to the one to redraw */
653  if (sbuts->mainb == buttons) {
655  }
656 }
657 
660 /* -------------------------------------------------------------------- */
664 /* reused! */
666 {
667  ScrArea *area = params->area;
668  wmNotifier *wmn = params->notifier;
669  SpaceProperties *sbuts = area->spacedata.first;
670 
671  /* context changes */
672  switch (wmn->category) {
673  case NC_SCENE:
674  switch (wmn->data) {
675  case ND_RENDER_OPTIONS:
679  break;
680  case ND_WORLD:
682  sbuts->preview = 1;
683  break;
684  case ND_FRAME:
685  /* any buttons area can have animated properties so redraw all */
687  sbuts->preview = 1;
688  break;
689  case ND_OB_ACTIVE:
691  sbuts->preview = 1;
692  break;
693  case ND_KEYINGSET:
695  break;
696  case ND_RENDER_RESULT:
697  break;
698  case ND_MODE:
699  case ND_LAYER:
700  default:
702  break;
703  }
704  break;
705  case NC_OBJECT:
706  switch (wmn->data) {
707  case ND_TRANSFORM:
709  buttons_area_redraw(area, BCONTEXT_DATA); /* autotexpace flag */
710  break;
711  case ND_POSE:
712  case ND_BONE_ACTIVE:
713  case ND_BONE_SELECT:
717  break;
718  case ND_MODIFIER:
719  if (wmn->action == NA_RENAME) {
721  }
722  else {
724  }
726  break;
727  case ND_CONSTRAINT:
730  break;
731  case ND_SHADERFX:
733  break;
734  case ND_PARTICLE:
735  if (wmn->action == NA_EDITED) {
737  }
738  sbuts->preview = 1;
739  break;
740  case ND_DRAW:
744  /* Needed to refresh context path when changing active particle system index. */
746  break;
747  default:
748  /* Not all object RNA props have a ND_ notifier (yet) */
750  break;
751  }
752  break;
753  case NC_GEOM:
754  switch (wmn->data) {
755  case ND_SELECT:
756  case ND_DATA:
757  case ND_VERTEX_GROUP:
759  break;
760  }
761  break;
762  case NC_MATERIAL:
764  switch (wmn->data) {
765  case ND_SHADING:
766  case ND_SHADING_DRAW:
767  case ND_SHADING_LINKS:
768  case ND_SHADING_PREVIEW:
769  case ND_NODES:
770  /* currently works by redraws... if preview is set, it (re)starts job */
771  sbuts->preview = 1;
772  break;
773  }
774  break;
775  case NC_WORLD:
777  sbuts->preview = 1;
778  break;
779  case NC_LAMP:
781  sbuts->preview = 1;
782  break;
783  case NC_GROUP:
785  break;
786  case NC_BRUSH:
789  sbuts->preview = 1;
790  break;
791  case NC_TEXTURE:
792  case NC_IMAGE:
793  if (wmn->action != NA_PAINTING) {
795  sbuts->preview = 1;
796  }
797  break;
798  case NC_SPACE:
799  if (wmn->data == ND_SPACE_PROPERTIES) {
801  }
802  else if (wmn->data == ND_SPACE_CHANGED) {
804  sbuts->preview = 1;
805  }
806  break;
807  case NC_ID:
808  if (wmn->action == NA_RENAME) {
810  }
811  break;
812  case NC_ANIMATION:
813  switch (wmn->data) {
814  case ND_KEYFRAME:
815  if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
817  }
818  break;
819  }
820  break;
821  case NC_GPENCIL:
822  switch (wmn->data) {
823  case ND_DATA:
826  }
827  break;
828  }
829  break;
830  case NC_NODE:
831  if (wmn->action == NA_SELECTED) {
833  /* new active node, update texture preview */
834  if (sbuts->mainb == BCONTEXT_TEXTURE) {
835  sbuts->preview = 1;
836  }
837  }
838  break;
839  /* Listener for preview render, when doing an global undo. */
840  case NC_WM:
841  if (wmn->data == ND_UNDO) {
843  sbuts->preview = 1;
844  }
845  break;
846  case NC_SCREEN:
847  if (wmn->data == ND_LAYOUTSET) {
849  sbuts->preview = 1;
850  }
851  break;
852 #ifdef WITH_FREESTYLE
853  case NC_LINESTYLE:
855  sbuts->preview = 1;
856  break;
857 #endif
858  }
859 
860  if (wmn->data == ND_KEYS) {
862  }
863 }
864 
865 static void buttons_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
866 {
867  SpaceProperties *sbuts = (SpaceProperties *)slink;
868 
869  if (sbuts->pinid == old_id) {
870  sbuts->pinid = new_id;
871  if (new_id == NULL) {
872  sbuts->flag &= ~SB_PIN_CONTEXT;
873  }
874  }
875 
876  if (sbuts->path) {
877  ButsContextPath *path = sbuts->path;
878 
879  int i;
880  for (i = 0; i < path->len; i++) {
881  if (path->ptr[i].owner_id == old_id) {
882  break;
883  }
884  }
885 
886  if (i == path->len) {
887  /* pass */
888  }
889  else if (new_id == NULL) {
890  if (i == 0) {
891  MEM_SAFE_FREE(sbuts->path);
892  }
893  else {
894  memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
895  path->len = i;
896  }
897  }
898  else {
899  RNA_id_pointer_create(new_id, &path->ptr[i]);
900  /* There is no easy way to check/make path downwards valid, just nullify it.
901  * Next redraw will rebuild this anyway. */
902  i++;
903  memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
904  path->len = i;
905  }
906  }
907 
908  if (sbuts->texuser) {
909  ButsContextTexture *ct = sbuts->texuser;
910  if ((ID *)ct->texture == old_id) {
911  ct->texture = (Tex *)new_id;
912  }
913  BLI_freelistN(&ct->users);
914  ct->user = NULL;
915  }
916 }
917 
920 /* -------------------------------------------------------------------- */
924 /* only called once, from space/spacetypes.c */
926 {
927  SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype buttons");
928  ARegionType *art;
929 
931  strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
932 
933  st->create = buttons_create;
934  st->free = buttons_free;
935  st->init = buttons_init;
938  st->keymap = buttons_keymap;
940  st->context = buttons_context;
942 
943  /* regions: main window */
944  art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
945  art->regionid = RGN_TYPE_WINDOW;
952  BLI_addhead(&st->regiontypes, art);
953 
954  /* Register the panel types from modifiers. The actual panels are built per modifier rather
955  * than per modifier type. */
956  for (ModifierType i = 0; i < NUM_MODIFIER_TYPES; i++) {
957  const ModifierTypeInfo *mti = BKE_modifier_get_info(i);
958  if (mti != NULL && mti->panelRegister != NULL) {
959  mti->panelRegister(art);
960  }
961  }
962  for (int i = 0; i < NUM_GREASEPENCIL_MODIFIER_TYPES; i++) {
964  if (mti != NULL && mti->panelRegister != NULL) {
965  mti->panelRegister(art);
966  }
967  }
968  for (int i = 0; i < NUM_SHADER_FX_TYPES; i++) {
970  continue;
971  }
972  const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(i);
973  if (fxti != NULL && fxti->panelRegister != NULL) {
974  fxti->panelRegister(art);
975  }
976  }
977 
978  /* regions: header */
979  art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
980  art->regionid = RGN_TYPE_HEADER;
981  art->prefsizey = HEADERY;
983 
987  BLI_addhead(&st->regiontypes, art);
988 
989  /* regions: navigation bar */
990  art = MEM_callocN(sizeof(ARegionType), "spacetype nav buttons region");
991  art->regionid = RGN_TYPE_NAV_BAR;
992  art->prefsizex = AREAMINX - 3; /* XXX Works and looks best,
993  * should we update AREAMINX accordingly? */
998  BLI_addhead(&st->regiontypes, art);
999 
1001 }
1002 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:985
struct SpaceProperties * CTX_wm_space_properties(const bContext *C)
Definition: context.c:809
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:973
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:68
void BKE_area_region_free(struct SpaceType *st, struct ARegion *region)
Definition: screen.c:663
void BKE_spacetype_register(struct SpaceType *st)
Definition: screen.c:420
struct ARegion * BKE_area_region_copy(const struct SpaceType *st, const struct ARegion *region)
@ PANEL_TYPE_LAYOUT_VERT_BAR
Definition: BKE_screen.h:301
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:157
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:63
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition: BLI_bitmap.h:93
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:878
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define ELEM(...)
@ NUM_GREASEPENCIL_MODIFIER_TYPES
ModifierType
@ NUM_MODIFIER_TYPES
#define HEADERY
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_TOP
#define AREAMINX
@ RGN_FLAG_SEARCH_FILTER_UPDATE
@ RGN_FLAG_PREFSIZE_OR_HIDDEN
@ RGN_FLAG_SEARCH_FILTER_ACTIVE
@ RGN_TYPE_CHANNELS
@ RGN_TYPE_WINDOW
@ RGN_TYPE_NAV_BAR
@ RGN_TYPE_HEADER
@ 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_SCROLL_VERTICAL
@ V2D_LOCKZOOM_X
@ V2D_LOCKZOOM_Y
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
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:3090
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
void ED_region_header_init(struct ARegion *region)
Definition: area.c:3358
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)
@ ED_KEYMAP_NAVBAR
Definition: ED_screen.h:449
@ ED_KEYMAP_UI
Definition: ED_screen.h:440
@ ED_KEYMAP_HEADER
Definition: ED_screen.h:446
@ ED_KEYMAP_VIEW2D
Definition: ED_screen.h:443
@ ED_KEYMAP_FRAMES
Definition: ED_screen.h:445
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:39
void UI_blocklist_free(const struct bContext *C, struct ListBase *lb)
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:288
#define ND_SHADING
Definition: WM_types.h:377
#define ND_WORLD
Definition: WM_types.h:353
#define NC_ID
Definition: WM_types.h:296
#define NC_NODE
Definition: WM_types.h:295
#define NC_GEOM
Definition: WM_types.h:294
#define ND_SPACE_CHANGED
Definition: WM_types.h:432
#define ND_DRAW
Definition: WM_types.h:362
#define NC_BRUSH
Definition: WM_types.h:286
#define ND_OB_ACTIVE
Definition: WM_types.h:340
#define ND_RENDER_RESULT
Definition: WM_types.h:346
#define NC_WM
Definition: WM_types.h:276
#define ND_DATA
Definition: WM_types.h:408
#define NC_LINESTYLE
Definition: WM_types.h:301
#define ND_RENDER_OPTIONS
Definition: WM_types.h:335
#define NC_ANIMATION
Definition: WM_types.h:289
#define ND_SHADING_PREVIEW
Definition: WM_types.h:380
#define ND_VERTEX_GROUP
Definition: WM_types.h:409
#define NC_SCREEN
Definition: WM_types.h:278
#define ND_MODE
Definition: WM_types.h:345
#define ND_SPACE_PROPERTIES
Definition: WM_types.h:424
#define ND_KEYINGSET
Definition: WM_types.h:348
#define NC_SCENE
Definition: WM_types.h:279
#define NA_ADDED
Definition: WM_types.h:464
#define NC_GROUP
Definition: WM_types.h:284
#define ND_NODES
Definition: WM_types.h:336
#define ND_MODIFIER
Definition: WM_types.h:363
#define ND_POSE
Definition: WM_types.h:359
#define NA_EDITED
Definition: WM_types.h:462
#define ND_PARTICLE
Definition: WM_types.h:366
#define NC_MATERIAL
Definition: WM_types.h:281
#define NC_LAMP
Definition: WM_types.h:283
#define NC_IMAGE
Definition: WM_types.h:285
#define ND_CONSTRAINT
Definition: WM_types.h:365
#define ND_UNDO
Definition: WM_types.h:316
#define ND_FRAME
Definition: WM_types.h:334
#define NA_REMOVED
Definition: WM_types.h:465
#define ND_SELECT
Definition: WM_types.h:407
#define NC_GPENCIL
Definition: WM_types.h:300
#define NC_TEXTURE
Definition: WM_types.h:282
#define ND_BONE_ACTIVE
Definition: WM_types.h:360
#define ND_TRANSFORM
Definition: WM_types.h:357
#define ND_LAYER
Definition: WM_types.h:350
#define ND_KEYS
Definition: WM_types.h:364
#define NA_RENAME
Definition: WM_types.h:466
#define ND_SHADERFX
Definition: WM_types.h:372
#define NA_PAINTING
Definition: WM_types.h:469
#define ND_BONE_SELECT
Definition: WM_types.h:361
#define ND_KEYFRAME
Definition: WM_types.h:394
#define ND_LAYOUTSET
Definition: WM_types.h:326
#define NC_OBJECT
Definition: WM_types.h:280
#define ND_SHADING_LINKS
Definition: WM_types.h:379
#define ND_SHADING_DRAW
Definition: WM_types.h:378
#define NC_SPACE
Definition: WM_types.h:293
#define NA_SELECTED
Definition: WM_types.h:467
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
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:171
void BUTTONS_OT_directory_browse(struct wmOperatorType *ot)
Definition: buttons_ops.c:385
void BUTTONS_OT_toggle_pin(struct wmOperatorType *ot)
Definition: buttons_ops.c:142
void BUTTONS_OT_file_browse(struct wmOperatorType *ot)
Definition: buttons_ops.c:358
void BUTTONS_OT_start_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:76
void BUTTONS_OT_clear_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:101
Scene scene
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
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_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
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:61
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_free(SpaceLink *sl)
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:169
void(* message_subscribe)(const wmRegionMessageSubscribeParams *params)
Definition: BKE_screen.h:185
void(* listener)(const wmRegionListenerParams *params)
Definition: BKE_screen.h:183
int keymapflag
Definition: BKE_screen.h:226
void(* layout)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:179
void(* init)(struct wmWindowManager *wm, struct ARegion *region)
Definition: BKE_screen.h:165
ListBase paneltypes
Definition: BKE_screen.h:216
ListBase panels
ListBase handlers
short alignment
short regiontype
struct ARegionType * type
ListBase uiblocks
PointerRNA ptr[8]
struct ButsTextureUser * user
struct Tex * texture
void(* panelRegister)(struct ARegionType *region_type)
Definition: DNA_ID.h:273
void(* panelRegister)(struct ARegionType *region_type)
Definition: BKE_modifier.h:379
struct ID * owner_id
Definition: RNA_types.h:50
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
struct SpaceLink *(* duplicate)(struct SpaceLink *sl)
Definition: BKE_screen.h:104
ListBase regiontypes
Definition: BKE_screen.h:130
void(* keymap)(struct wmKeyConfig *keyconf)
Definition: BKE_screen.h:109
void(* operatortypes)(void)
Definition: BKE_screen.h:107
void(* free)(struct SpaceLink *sl)
Definition: BKE_screen.h:88
struct SpaceLink *(* create)(const struct ScrArea *area, const struct Scene *scene)
Definition: BKE_screen.h:86
void(* listener)(const wmSpaceTypeListenerParams *params)
Definition: BKE_screen.h:95
void(* init)(struct wmWindowManager *wm, struct ScrArea *area)
Definition: BKE_screen.h:91
int spaceid
Definition: BKE_screen.h:81
bContextDataCallback context
Definition: BKE_screen.h:117
void(* id_remap)(struct ScrArea *area, struct SpaceLink *sl, struct ID *old_id, struct ID *new_id)
Definition: BKE_screen.h:120
char name[BKE_ST_MAXNAME]
Definition: BKE_screen.h:80
short keepzoom
short scroll
unsigned int data
Definition: WM_types.h:260
unsigned int action
Definition: WM_types.h:260
unsigned int category
Definition: WM_types.h:260
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 *))