Blender V5.0
buttons_context.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
15#include "BLI_listbase.h"
16#include "BLI_string_utf8.h"
17#include "BLI_utildefines.h"
18
19#include "BLT_translation.hh"
20
21#include "DNA_armature_types.h"
23#include "DNA_linestyle_types.h"
24#include "DNA_material_types.h"
25#include "DNA_node_types.h"
26#include "DNA_scene_types.h"
27#include "DNA_sequence_types.h"
29#include "DNA_world_types.h"
30
31#include "BKE_action.hh"
32#include "BKE_context.hh"
33#include "BKE_layer.hh"
34#include "BKE_linestyle.h"
35#include "BKE_material.hh"
36#include "BKE_modifier.hh"
37#include "BKE_object.hh"
38#include "BKE_paint.hh"
39#include "BKE_particle.h"
40#include "BKE_screen.hh"
41
42#include "SEQ_modifier.hh"
43#include "SEQ_select.hh"
44
45#include "RNA_access.hh"
46#include "RNA_prototypes.hh"
47
48#include "ED_buttons.hh"
49#include "ED_physics.hh"
50#include "ED_screen.hh"
51
52#include "UI_interface.hh"
54#include "UI_resources.hh"
55
56#include "WM_api.hh"
57
58#include "buttons_intern.hh" /* own include */
59
61{
62 for (int i = 0; i < path->len; i++) {
63 PointerRNA *ptr = &path->ptr[i];
64
65 if (RNA_struct_is_a(ptr->type, type)) {
67 return CTX_RESULT_OK;
68 }
69 }
70
72}
73
75{
76 for (int i = 0; i < path->len; i++) {
77 PointerRNA *ptr = &path->ptr[i];
78
79 if (RNA_struct_is_a(ptr->type, type)) {
80 return ptr;
81 }
82 }
83
84 return nullptr;
85}
86
87/************************* Creating the Path ************************/
88
90{
91 PointerRNA *ptr = &path->ptr[path->len - 1];
92
93 /* this one just verifies */
94 return RNA_struct_is_a(ptr->type, &RNA_Scene);
95}
96
98{
99 PointerRNA *ptr = &path->ptr[path->len - 1];
100
101 /* View Layer may have already been resolved in a previous call
102 * (e.g. in buttons_context_path_linestyle). */
103 if (RNA_struct_is_a(ptr->type, &RNA_ViewLayer)) {
104 return true;
105 }
106
107 if (buttons_context_path_scene(path)) {
108 Scene *scene = static_cast<Scene *>(path->ptr[path->len - 1].data);
109 ViewLayer *view_layer = (win->scene == scene) ? WM_window_get_active_view_layer(win) :
111
112 path->ptr[path->len] = RNA_pointer_create_discrete(&scene->id, &RNA_ViewLayer, view_layer);
113 path->len++;
114 return true;
115 }
116
117 return false;
118}
119
120/* NOTE: this function can return true without adding a world to the path
121 * so the buttons stay visible, but be sure to check the ID type if a ID_WO */
123{
124 PointerRNA *ptr = &path->ptr[path->len - 1];
125
126 /* if we already have a (pinned) world, we're done */
127 if (RNA_struct_is_a(ptr->type, &RNA_World)) {
128 return true;
129 }
130 /* if we have a scene, use the scene's world */
131 if (buttons_context_path_scene(path)) {
132 Scene *scene = static_cast<Scene *>(path->ptr[path->len - 1].data);
133 World *world = scene->world;
134
135 if (world) {
136 path->ptr[path->len] = RNA_id_pointer_create(&scene->world->id);
137 path->len++;
138 return true;
139 }
140
141 return true;
142 }
143
144 /* no path to a world possible */
145 return false;
146}
147
149 ButsContextPath *path,
150 wmWindow *window)
151{
152 PointerRNA *ptr = &path->ptr[path->len - 1];
153
154 /* if we already have a (pinned) collection, we're done */
155 if (RNA_struct_is_a(ptr->type, &RNA_Collection)) {
156 return true;
157 }
158
159 Scene *scene = CTX_data_scene(C);
160
161 /* if we have a view layer, use the view layer's active collection */
162 if (buttons_context_path_view_layer(path, window)) {
163 ViewLayer *view_layer = static_cast<ViewLayer *>(path->ptr[path->len - 1].data);
164 BKE_view_layer_synced_ensure(scene, view_layer);
166
167 /* Do not show collection tab for master collection. */
168 if (c == scene->master_collection) {
169 return false;
170 }
171
172 if (c) {
173 path->ptr[path->len] = RNA_id_pointer_create(&c->id);
174 path->len++;
175 return true;
176 }
177 }
178
179 /* no path to a collection possible */
180 return false;
181}
182
184{
185 PointerRNA *ptr = &path->ptr[path->len - 1];
186
187 /* if we already have a (pinned) linestyle, we're done */
188 if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
189 return true;
190 }
191 /* if we have a view layer, use the lineset's linestyle */
192 if (buttons_context_path_view_layer(path, window)) {
193 ViewLayer *view_layer = static_cast<ViewLayer *>(path->ptr[path->len - 1].data);
195 if (linestyle) {
196 path->ptr[path->len] = RNA_id_pointer_create(&linestyle->id);
197 path->len++;
198 return true;
199 }
200 }
201
202 /* no path to a linestyle possible */
203 return false;
204}
205
207{
208 PointerRNA *ptr = &path->ptr[path->len - 1];
209
210 /* if we already have a (pinned) object, we're done */
211 if (RNA_struct_is_a(ptr->type, &RNA_Object)) {
212 return true;
213 }
214 if (!RNA_struct_is_a(ptr->type, &RNA_ViewLayer)) {
215 return false;
216 }
217
218 ViewLayer *view_layer = static_cast<ViewLayer *>(ptr->data);
220
221 if (ob) {
222 path->ptr[path->len] = RNA_id_pointer_create(&ob->id);
223 path->len++;
224
225 return true;
226 }
227
228 /* no path to a object possible */
229 return false;
230}
231
232static bool buttons_context_path_data(ButsContextPath *path, int type)
233{
234 PointerRNA *ptr = &path->ptr[path->len - 1];
235
236 /* if we already have a data, we're done */
237 if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && ELEM(type, -1, OB_MESH)) {
238 return true;
239 }
240 if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
241 (type == -1 || ELEM(type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)))
242 {
243 return true;
244 }
245 if (RNA_struct_is_a(ptr->type, &RNA_Armature) && ELEM(type, -1, OB_ARMATURE)) {
246 return true;
247 }
248 if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && ELEM(type, -1, OB_MBALL)) {
249 return true;
250 }
251 if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && ELEM(type, -1, OB_LATTICE)) {
252 return true;
253 }
254 if (RNA_struct_is_a(ptr->type, &RNA_Camera) && ELEM(type, -1, OB_CAMERA)) {
255 return true;
256 }
257 if (RNA_struct_is_a(ptr->type, &RNA_Light) && ELEM(type, -1, OB_LAMP)) {
258 return true;
259 }
260 if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && ELEM(type, -1, OB_SPEAKER)) {
261 return true;
262 }
263 if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && ELEM(type, -1, OB_LIGHTPROBE)) {
264 return true;
265 }
266 if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && ELEM(type, -1, OB_GREASE_PENCIL)) {
267 return true;
268 }
269 if (RNA_struct_is_a(ptr->type, &RNA_Curves) && ELEM(type, -1, OB_CURVES)) {
270 return true;
271 }
272 if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && ELEM(type, -1, OB_POINTCLOUD)) {
273 return true;
274 }
275 if (RNA_struct_is_a(ptr->type, &RNA_Volume) && ELEM(type, -1, OB_VOLUME)) {
276 return true;
277 }
278 /* try to get an object in the path, no pinning supported here */
279 if (buttons_context_path_object(path)) {
280 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
281
282 if (ob && ELEM(type, -1, ob->type)) {
283 path->ptr[path->len] = RNA_id_pointer_create(static_cast<ID *>(ob->data));
284 path->len++;
285
286 return true;
287 }
288 }
289
290 /* no path to data possible */
291 return false;
292}
293
295{
296 if (buttons_context_path_object(path)) {
297 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
298
299 if (ELEM(ob->type,
300 OB_MESH,
302 OB_FONT,
303 OB_SURF,
306 OB_CURVES,
308 OB_VOLUME))
309 {
311 if (md != nullptr) {
312 path->ptr[path->len] = RNA_pointer_create_discrete(&ob->id, &RNA_Modifier, md);
313 path->len++;
314 }
315
316 return true;
317 }
318 }
319
320 return false;
321}
322
324{
325 if (buttons_context_path_object(path)) {
326 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
327
328 if (ob && ob->type == OB_GREASE_PENCIL) {
329 return true;
330 }
331 }
332
333 return false;
334}
335
337{
338 PointerRNA *ptr = &path->ptr[path->len - 1];
339
340 /* if we already have a (pinned) material, we're done */
341 if (RNA_struct_is_a(ptr->type, &RNA_Material)) {
342 return true;
343 }
344 /* if we have an object, use the object material slot */
345 if (buttons_context_path_object(path)) {
346 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
347
348 if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
350
351 const int slot = blender::math::max(ob->actcol - 1, 0);
352 if (ob->matbits && ob->matbits[slot] == 0) {
353 /* When material from active slot is stored in object data, include it in context path, see
354 * !134968. */
356 }
357 if (ma != nullptr) {
358 path->ptr[path->len] = RNA_id_pointer_create(&ma->id);
359 path->len++;
360 }
361 return true;
362 }
363 }
364
365 /* no path to a material possible */
366 return false;
367}
368
370{
371 /* if we have an armature, get the active bone */
373 bArmature *arm = static_cast<bArmature *>(path->ptr[path->len - 1].data);
374
375 if (arm->edbo) {
376 if (arm->act_edbone) {
377 EditBone *edbo = arm->act_edbone;
378 path->ptr[path->len] = RNA_pointer_create_discrete(&arm->id, &RNA_EditBone, edbo);
379 path->len++;
380 return true;
381 }
382 }
383 else {
384 if (arm->act_bone) {
385 path->ptr[path->len] = RNA_pointer_create_discrete(&arm->id, &RNA_Bone, arm->act_bone);
386 path->len++;
387 return true;
388 }
389 }
390 }
391
392 /* no path to a bone possible */
393 return false;
394}
395
397{
398 PointerRNA *ptr = &path->ptr[path->len - 1];
399
400 /* if we already have a (pinned) PoseBone, we're done */
401 if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
402 return true;
403 }
404
405 /* if we have an armature, get the active bone */
406 if (buttons_context_path_object(path)) {
407 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
408 bArmature *arm = static_cast<bArmature *>(
409 ob->data); /* path->ptr[path->len-1].data - works too */
410
411 if (ob->type != OB_ARMATURE || arm->edbo) {
412 return false;
413 }
414
415 if (arm->act_bone) {
417 if (pchan) {
418 path->ptr[path->len] = RNA_pointer_create_discrete(&ob->id, &RNA_PoseBone, pchan);
419 path->len++;
420 return true;
421 }
422 }
423 }
424
425 /* no path to a bone possible */
426 return false;
427}
428
430{
431 PointerRNA *ptr = &path->ptr[path->len - 1];
432
433 /* if we already have (pinned) particle settings, we're done */
434 if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) {
435 return true;
436 }
437 /* if we have an object, get the active particle system */
438 if (buttons_context_path_object(path)) {
439 Object *ob = static_cast<Object *>(path->ptr[path->len - 1].data);
440
441 if (ob && ob->type == OB_MESH) {
443 if (psys != nullptr) {
444 path->ptr[path->len] = RNA_pointer_create_discrete(&ob->id, &RNA_ParticleSystem, psys);
445 path->len++;
446 }
447 return true;
448 }
449 }
450
451 /* no path to a particle system possible */
452 return false;
453}
454
456{
457 PointerRNA *ptr = &path->ptr[path->len - 1];
458
459 /* if we already have a (pinned) brush, we're done */
460 if (RNA_struct_is_a(ptr->type, &RNA_Brush)) {
461 return true;
462 }
463 /* If we have a scene, use the tool-settings brushes. */
464 if (buttons_context_path_scene(path)) {
465 Scene *scene = static_cast<Scene *>(path->ptr[path->len - 1].data);
466
467 Brush *br = nullptr;
468 if (scene) {
469 wmWindow *window = CTX_wm_window(C);
470 ViewLayer *view_layer = WM_window_get_active_view_layer(window);
471 br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer));
472 }
473
474 if (br) {
475 path->ptr[path->len] = RNA_id_pointer_create((ID *)br);
476 path->len++;
477
478 return true;
479 }
480 }
481
482 /* no path to a brush possible */
483 return false;
484}
485
487 ButsContextPath *path,
489{
490 PointerRNA *ptr = &path->ptr[path->len - 1];
491
492 if (!ct) {
493 return false;
494 }
495
496 /* if we already have a (pinned) texture, we're done */
497 if (RNA_struct_is_a(ptr->type, &RNA_Texture)) {
498 return true;
499 }
500
501 if (!ct->user) {
502 return false;
503 }
504
505 ID *id = ct->user->id;
506
507 if (id) {
508 if (GS(id->name) == ID_BR) {
510 }
511 else if (GS(id->name) == ID_PA) {
513 }
514 else if (GS(id->name) == ID_OB) {
516 }
517 else if (GS(id->name) == ID_LS) {
519 }
520 }
521
522 if (ct->texture) {
523 path->ptr[path->len] = RNA_id_pointer_create(&ct->texture->id);
524 path->len++;
525 }
526
527 return true;
528}
529
531{
532 PointerRNA *ptr = &path->ptr[path->len - 1];
533 /* If we already have a (pinned) strip, we're done. */
534 if (RNA_struct_is_a(ptr->type, &RNA_Strip)) {
535 return true;
536 }
537
538 if (buttons_context_path_scene(path)) {
539 Scene *scene = static_cast<Scene *>(path->ptr[path->len - 1].data);
540 Strip *active_strip = blender::seq::select_active_get(scene);
541 if (active_strip == nullptr) {
542 return false;
543 }
544
545 path->ptr[path->len] = RNA_pointer_create_discrete(&scene->id, &RNA_Strip, active_strip);
546 path->len++;
547 return true;
548 }
549
550 return false;
551}
552
554{
555 if (sequencer_scene && buttons_context_path_strip(path)) {
556 Strip *active_strip = static_cast<Strip *>(path->ptr[path->len - 1].data);
557
559 if (smd) {
560 path->ptr[path->len] = RNA_pointer_create_discrete(
561 &sequencer_scene->id, &RNA_StripModifier, smd);
562 path->len++;
563 }
564 return true;
565 }
566
567 return false;
568}
569
570#ifdef WITH_FREESTYLE
571static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *view_layer)
572{
573 wmWindow *window = CTX_wm_window(C);
574 Scene *scene = WM_window_get_active_scene(window);
575
576 /* if Freestyle is disabled in the scene */
577 if ((scene->r.mode & R_EDGE_FRS) == 0) {
578 return false;
579 }
580 /* if Freestyle is not in the Parameter Editor mode */
581 FreestyleConfig *config = &view_layer->freestyle_config;
582 if (config->mode != FREESTYLE_CONTROL_EDITOR_MODE) {
583 return false;
584 }
585 /* if the scene has already been pinned */
587 if (sbuts->pinid && sbuts->pinid == &scene->id) {
588 return false;
589 }
590 return true;
591}
592#endif
593
595 const bContext *C, SpaceProperties *sbuts, ButsContextPath *path, int mainb, int flag)
596{
597 /* Note we don't use CTX_data here, instead we get it from the window.
598 * Otherwise there is a loop reading the context that we are setting. */
599 wmWindow *window = CTX_wm_window(C);
600 Scene *scene = WM_window_get_active_scene(window);
601 WorkSpace *workspace = WM_window_get_active_workspace(window);
602 Scene *sequencer_scene = workspace->sequencer_scene;
603 ViewLayer *view_layer = WM_window_get_active_view_layer(window);
604
605 *path = {};
606 path->flag = flag;
607
608 /* If some ID datablock is pinned, set the root pointer. */
609 if (sbuts->pinid) {
610 ID *id = sbuts->pinid;
611
612 path->ptr[0] = RNA_id_pointer_create(id);
613 path->len++;
614 }
615 /* No pinned root, use scene as initial root. */
616 else if (mainb != BCONTEXT_TOOL) {
618 if (!sequencer_scene) {
619 return false;
620 }
621 path->ptr[0] = RNA_id_pointer_create(&sequencer_scene->id);
622 }
623 else {
624 path->ptr[0] = RNA_id_pointer_create(&scene->id);
625 }
626
627 path->len++;
628
629 if (!ELEM(mainb,
637 {
638 path->ptr[path->len] = RNA_pointer_create_discrete(nullptr, &RNA_ViewLayer, view_layer);
639 path->len++;
640 }
641 }
642
643 /* now for each buttons context type, we try to construct a path,
644 * tracing back recursively */
645 bool found;
646 switch (mainb) {
647 case BCONTEXT_SCENE:
648 case BCONTEXT_RENDER:
649 case BCONTEXT_OUTPUT:
650 found = buttons_context_path_scene(path);
651 break;
653#ifdef WITH_FREESTYLE
654 if (buttons_context_linestyle_pinnable(C, view_layer)) {
655 found = buttons_context_path_linestyle(path, window);
656 if (found) {
657 break;
658 }
659 }
660#endif
661 found = buttons_context_path_view_layer(path, window);
662 break;
663 case BCONTEXT_WORLD:
664 found = buttons_context_path_world(path);
665 break;
666 case BCONTEXT_COLLECTION: /* This is for Line Art collection flags */
667 found = buttons_context_path_collection(C, path, window);
668 break;
669 case BCONTEXT_TOOL:
670 found = true;
671 break;
672 case BCONTEXT_OBJECT:
673 case BCONTEXT_PHYSICS:
675 found = buttons_context_path_object(path);
676 break;
678 found = buttons_context_path_modifier(path);
679 break;
681 found = buttons_context_path_shaderfx(path);
682 break;
683 case BCONTEXT_DATA:
684 found = buttons_context_path_data(path, -1);
685 break;
687 found = buttons_context_path_particle(path);
688 break;
690 found = buttons_context_path_material(path);
691 break;
692 case BCONTEXT_TEXTURE:
694 C, path, static_cast<ButsContextTexture *>(sbuts->texuser));
695 break;
696 case BCONTEXT_BONE:
697 found = buttons_context_path_bone(path);
698 if (!found) {
700 }
701 break;
703 found = buttons_context_path_pose_bone(path);
704 break;
705 case BCONTEXT_STRIP:
706 found = buttons_context_path_strip(path);
707 break;
709 found = buttons_context_path_strip_modifier(sequencer_scene, path);
710 break;
711 default:
712 found = false;
713 break;
714 }
715
716 return found;
717}
718
719static bool buttons_shading_context(const bContext *C, int mainb)
720{
721 wmWindow *window = CTX_wm_window(C);
722 const Scene *scene = WM_window_get_active_scene(window);
723 ViewLayer *view_layer = WM_window_get_active_view_layer(window);
724 BKE_view_layer_synced_ensure(scene, view_layer);
726
728 return true;
729 }
730 if (mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA)) {
731 return true;
732 }
733
734 return false;
735}
736
738{
739 wmWindow *window = CTX_wm_window(C);
740 const Scene *scene = WM_window_get_active_scene(window);
741 ViewLayer *view_layer = WM_window_get_active_view_layer(window);
742 BKE_view_layer_synced_ensure(scene, view_layer);
744
745 if (flag & (1 << BCONTEXT_MATERIAL)) {
746 return BCONTEXT_MATERIAL;
747 }
748 if (ob && ELEM(ob->type, OB_LAMP, OB_CAMERA) && (flag & (1 << BCONTEXT_DATA))) {
749 return BCONTEXT_DATA;
750 }
751 if (flag & (1 << BCONTEXT_WORLD)) {
752 return BCONTEXT_WORLD;
753 }
754
755 return BCONTEXT_RENDER;
756}
757
759{
760 if (!sbuts->path) {
761 sbuts->path = MEM_new<ButsContextPath>("ButsContextPath");
762 }
763
764 ButsContextPath *path = static_cast<ButsContextPath *>(sbuts->path);
765
766 int pflag = 0;
767 int flag = 0;
768
769 /* Set scene path. */
770 buttons_context_path(C, sbuts, path, BCONTEXT_SCENE, pflag);
771
773
774 /* for each context, see if we can compute a valid path to it, if
775 * this is the case, we know we have to display the button */
776 for (int i = 0; i < BCONTEXT_TOT; i++) {
777 if (buttons_context_path(C, sbuts, path, i, pflag)) {
778 flag |= (1 << i);
779
780 /* setting icon for data context */
781 if (i == BCONTEXT_DATA) {
782 PointerRNA *ptr = &path->ptr[path->len - 1];
783
784 if (ptr->type) {
785 if (RNA_struct_is_a(ptr->type, &RNA_Light)) {
786 sbuts->dataicon = ICON_OUTLINER_DATA_LIGHT;
787 }
788 else {
789 sbuts->dataicon = RNA_struct_ui_icon(ptr->type);
790 }
791 }
792 else {
793 sbuts->dataicon = ICON_EMPTY_DATA;
794 }
795 }
796 }
797 }
798
799 /* always try to use the tab that was explicitly
800 * set to the user, so that once that context comes
801 * back, the tab is activated again */
802 sbuts->mainb = sbuts->mainbuser;
803
804 /* in case something becomes invalid, change */
805 if ((flag & (1 << sbuts->mainb)) == 0) {
806 if (sbuts->flag & SB_SHADING_CONTEXT) {
807 /* try to keep showing shading related buttons */
809 }
810 else if (flag & BCONTEXT_OBJECT) {
811 sbuts->mainb = BCONTEXT_OBJECT;
812 }
813 else {
814 for (int i = 0; i < BCONTEXT_TOT; i++) {
815 if (flag & (1 << i)) {
816 sbuts->mainb = i;
817 break;
818 }
819 }
820 }
821 }
822
823 buttons_context_path(C, sbuts, path, sbuts->mainb, pflag);
824
825 if (!(flag & (1 << sbuts->mainb))) {
826 if (flag & (1 << BCONTEXT_OBJECT)) {
827 sbuts->mainb = BCONTEXT_OBJECT;
828 }
829 else {
830 sbuts->mainb = BCONTEXT_SCENE;
831 }
832 }
833
834 if (buttons_shading_context(C, sbuts->mainb)) {
835 sbuts->flag |= SB_SHADING_CONTEXT;
836 }
837 else {
838 sbuts->flag &= ~SB_SHADING_CONTEXT;
839 }
840
841 sbuts->pathflag = flag;
842}
843
845{
846 for (int i = 0; i < path->len; ++i) {
847 if (ptr->owner_id == path->ptr[i].owner_id) {
848 return true;
849 }
850 }
851 return false;
852}
853
855 const SpaceProperties *sbuts,
856 ScrArea *area)
857{
858 ScrArea *active_area = CTX_wm_area(C);
859 const bool auto_sync = ED_area_has_shared_border(active_area, area) &&
861 return auto_sync || sbuts->outliner_sync == PROPERTIES_SYNC_ALWAYS;
862}
863
865 SpaceProperties *sbuts,
867 const int context)
868{
869 ButsContextPath path;
870 if (buttons_context_path(C, sbuts, &path, context, 0) && is_pointer_in_path(&path, ptr)) {
871 sbuts->mainbuser = context;
872 sbuts->mainb = sbuts->mainbuser;
873 }
874}
875
876/************************* Context Callback ************************/
877
878const char *buttons_context_dir[] = {
879 "texture_slot",
880 "scene",
881 "world",
882 "object",
883 "mesh",
884 "armature",
885 "lattice",
886 "curve",
887 "meta_ball",
888 "light",
889 "speaker",
890 "lightprobe",
891 "camera",
892 "material",
893 "material_slot",
894 "texture",
895 "texture_user",
896 "texture_user_property",
897 "texture_node",
898 "bone",
899 "edit_bone",
900 "pose_bone",
901 "particle_system",
902 "particle_system_editable",
903 "particle_settings",
904 "cloth",
905 "soft_body",
906 "fluid",
907 "collision",
908 "brush",
909 "dynamic_paint",
910 "line_style",
911 "collection",
912 "gpencil",
913 "grease_pencil",
914 "curves",
915 "pointcloud",
916 "volume",
917 "strip",
918 "strip_modifier",
919 nullptr,
920};
921
922int /*eContextResult*/ buttons_context(const bContext *C,
923 const char *member,
925{
927 if (sbuts && sbuts->path == nullptr) {
928 /* path is cleared for #SCREEN_OT_redo_last, when global undo does a file-read which clears the
929 * path (see lib_link_workspace_layout_restore). */
931 }
932 ButsContextPath *path = static_cast<ButsContextPath *>(sbuts ? sbuts->path : nullptr);
933
934 if (!path) {
936 }
937
938 if (sbuts->mainb == BCONTEXT_TOOL) {
940 }
941
942 /* here we handle context, getting data from precomputed path */
943 if (CTX_data_dir(member)) {
944 /* in case of new shading system we skip texture_slot, complex python
945 * UI script logic depends on checking if this is available */
946 if (sbuts->texuser) {
948 }
949 else {
951 }
952 return CTX_RESULT_OK;
953 }
954 if (CTX_data_equals(member, "scene")) {
955 /* Do not return one here if scene is not found in path,
956 * in this case we want to get default context scene! */
957 return set_pointer_type(path, result, &RNA_Scene);
958 }
959 if (CTX_data_equals(member, "world")) {
960 set_pointer_type(path, result, &RNA_World);
961 return CTX_RESULT_OK;
962 }
963 if (CTX_data_equals(member, "collection")) {
964 /* Do not return one here if collection is not found in path,
965 * in this case we want to get default context collection! */
966 return set_pointer_type(path, result, &RNA_Collection);
967 }
968 if (CTX_data_equals(member, "object")) {
969 set_pointer_type(path, result, &RNA_Object);
970 return CTX_RESULT_OK;
971 }
972 if (CTX_data_equals(member, "mesh")) {
973 set_pointer_type(path, result, &RNA_Mesh);
974 return CTX_RESULT_OK;
975 }
976 if (CTX_data_equals(member, "armature")) {
977 set_pointer_type(path, result, &RNA_Armature);
978 return CTX_RESULT_OK;
979 }
980 if (CTX_data_equals(member, "lattice")) {
981 set_pointer_type(path, result, &RNA_Lattice);
982 return CTX_RESULT_OK;
983 }
984 if (CTX_data_equals(member, "curve")) {
985 set_pointer_type(path, result, &RNA_Curve);
986 return CTX_RESULT_OK;
987 }
988 if (CTX_data_equals(member, "meta_ball")) {
989 set_pointer_type(path, result, &RNA_MetaBall);
990 return CTX_RESULT_OK;
991 }
992 if (CTX_data_equals(member, "light")) {
993 set_pointer_type(path, result, &RNA_Light);
994 return CTX_RESULT_OK;
995 }
996 if (CTX_data_equals(member, "camera")) {
997 set_pointer_type(path, result, &RNA_Camera);
998 return CTX_RESULT_OK;
999 }
1000 if (CTX_data_equals(member, "speaker")) {
1001 set_pointer_type(path, result, &RNA_Speaker);
1002 return CTX_RESULT_OK;
1003 }
1004 if (CTX_data_equals(member, "lightprobe")) {
1005 set_pointer_type(path, result, &RNA_LightProbe);
1006 return CTX_RESULT_OK;
1007 }
1008 if (CTX_data_equals(member, "curves")) {
1009 set_pointer_type(path, result, &RNA_Curves);
1010 return CTX_RESULT_OK;
1011 }
1012 if (CTX_data_equals(member, "pointcloud")) {
1013 set_pointer_type(path, result, &RNA_PointCloud);
1014 return CTX_RESULT_OK;
1015 }
1016 if (CTX_data_equals(member, "volume")) {
1017 set_pointer_type(path, result, &RNA_Volume);
1018 return CTX_RESULT_OK;
1019 }
1020 if (CTX_data_equals(member, "material")) {
1021 set_pointer_type(path, result, &RNA_Material);
1022 return CTX_RESULT_OK;
1023 }
1024 if (CTX_data_equals(member, "texture")) {
1025 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
1026
1027 if (ct) {
1028 if (ct->texture == nullptr) {
1029 return CTX_RESULT_NO_DATA;
1030 }
1031
1032 CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture);
1033 }
1034
1035 return CTX_RESULT_OK;
1036 }
1037 if (CTX_data_equals(member, "material_slot")) {
1038 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1039
1040 if (ptr) {
1041 Object *ob = static_cast<Object *>(ptr->data);
1042
1043 if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type) && ob->totcol) {
1044 /* a valid actcol isn't ensured #27526. */
1045 int matnr = ob->actcol - 1;
1046 matnr = std::max(matnr, 0);
1047 /* Keep aligned with rna_Object_material_slots_get. */
1049 result, &ob->id, &RNA_MaterialSlot, (void *)(matnr + uintptr_t(&ob->id)));
1050 }
1051 }
1052
1053 return CTX_RESULT_OK;
1054 }
1055 if (CTX_data_equals(member, "texture_user")) {
1056 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
1057
1058 if (!ct) {
1059 return CTX_RESULT_NO_DATA;
1060 }
1061
1062 if (ct->user && ct->user->ptr.data) {
1063 ButsTextureUser *user = ct->user;
1065 }
1066
1067 return CTX_RESULT_OK;
1068 }
1069 if (CTX_data_equals(member, "texture_user_property")) {
1070 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
1071
1072 if (!ct) {
1073 return CTX_RESULT_NO_DATA;
1074 }
1075
1076 if (ct->user && ct->user->ptr.data) {
1077 ButsTextureUser *user = ct->user;
1078 CTX_data_pointer_set(result, nullptr, &RNA_Property, user->prop);
1079 }
1080
1081 return CTX_RESULT_OK;
1082 }
1083 if (CTX_data_equals(member, "texture_node")) {
1084 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
1085
1086 if (ct) {
1087 /* new shading system */
1088 if (ct->user && ct->user->node) {
1089 CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node);
1090 }
1091
1092 return CTX_RESULT_OK;
1093 }
1094 return CTX_RESULT_NO_DATA;
1095 }
1096 if (CTX_data_equals(member, "texture_slot")) {
1097 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
1098 PointerRNA *ptr;
1099
1100 /* Particles slots are used in both old and new textures handling. */
1101 if ((ptr = get_pointer_type(path, &RNA_ParticleSystem))) {
1102 ParticleSettings *part = ((ParticleSystem *)ptr->data)->part;
1103
1104 if (part) {
1106 result, &part->id, &RNA_ParticleSettingsTextureSlot, part->mtex[int(part->texact)]);
1107 }
1108 }
1109 else if (ct) {
1110 return CTX_RESULT_MEMBER_NOT_FOUND; /* new shading system */
1111 }
1112 else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) {
1113 FreestyleLineStyle *ls = static_cast<FreestyleLineStyle *>(ptr->data);
1114
1115 if (ls) {
1117 result, &ls->id, &RNA_LineStyleTextureSlot, ls->mtex[int(ls->texact)]);
1118 }
1119 }
1120
1121 return CTX_RESULT_OK;
1122 }
1123 if (CTX_data_equals(member, "bone")) {
1124 set_pointer_type(path, result, &RNA_Bone);
1125 return CTX_RESULT_OK;
1126 }
1127 if (CTX_data_equals(member, "edit_bone")) {
1128 set_pointer_type(path, result, &RNA_EditBone);
1129 return CTX_RESULT_OK;
1130 }
1131 if (CTX_data_equals(member, "pose_bone")) {
1132 set_pointer_type(path, result, &RNA_PoseBone);
1133 return CTX_RESULT_OK;
1134 }
1135 if (CTX_data_equals(member, "particle_system")) {
1136 set_pointer_type(path, result, &RNA_ParticleSystem);
1137 return CTX_RESULT_OK;
1138 }
1139 if (CTX_data_equals(member, "particle_system_editable")) {
1140 if (PE_poll((bContext *)C)) {
1141 set_pointer_type(path, result, &RNA_ParticleSystem);
1142 }
1143 else {
1144 CTX_data_pointer_set(result, nullptr, &RNA_ParticleSystem, nullptr);
1145 }
1146 return CTX_RESULT_OK;
1147 }
1148 if (CTX_data_equals(member, "particle_settings")) {
1149 /* only available when pinned */
1150 PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSettings);
1151
1152 if (ptr && ptr->data) {
1154 return CTX_RESULT_OK;
1155 }
1156
1157 /* get settings from active particle system instead */
1158 ptr = get_pointer_type(path, &RNA_ParticleSystem);
1159
1160 if (ptr && ptr->data) {
1161 ParticleSettings *part = ((ParticleSystem *)ptr->data)->part;
1162 CTX_data_pointer_set(result, ptr->owner_id, &RNA_ParticleSettings, part);
1163 return CTX_RESULT_OK;
1164 }
1165
1166 set_pointer_type(path, result, &RNA_ParticleSettings);
1167 return CTX_RESULT_OK;
1168 }
1169 if (CTX_data_equals(member, "cloth")) {
1170 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1171
1172 if (ptr && ptr->data) {
1173 Object *ob = static_cast<Object *>(ptr->data);
1175 CTX_data_pointer_set(result, &ob->id, &RNA_ClothModifier, md);
1176 return CTX_RESULT_OK;
1177 }
1178 return CTX_RESULT_NO_DATA;
1179 }
1180 if (CTX_data_equals(member, "soft_body")) {
1181 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1182
1183 if (ptr && ptr->data) {
1184 Object *ob = static_cast<Object *>(ptr->data);
1186 CTX_data_pointer_set(result, &ob->id, &RNA_SoftBodyModifier, md);
1187 return CTX_RESULT_OK;
1188 }
1189 return CTX_RESULT_NO_DATA;
1190 }
1191
1192 if (CTX_data_equals(member, "fluid")) {
1193 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1194
1195 if (ptr && ptr->data) {
1196 Object *ob = static_cast<Object *>(ptr->data);
1198 CTX_data_pointer_set(result, &ob->id, &RNA_FluidModifier, md);
1199 return CTX_RESULT_OK;
1200 }
1201 return CTX_RESULT_NO_DATA;
1202 }
1203 if (CTX_data_equals(member, "collision")) {
1204 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1205
1206 if (ptr && ptr->data) {
1207 Object *ob = static_cast<Object *>(ptr->data);
1209 CTX_data_pointer_set(result, &ob->id, &RNA_CollisionModifier, md);
1210 return CTX_RESULT_OK;
1211 }
1212 return CTX_RESULT_NO_DATA;
1213 }
1214 if (CTX_data_equals(member, "brush")) {
1215 set_pointer_type(path, result, &RNA_Brush);
1216 return CTX_RESULT_OK;
1217 }
1218 if (CTX_data_equals(member, "dynamic_paint")) {
1219 PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
1220
1221 if (ptr && ptr->data) {
1222 Object *ob = static_cast<Object *>(ptr->data);
1224 CTX_data_pointer_set(result, &ob->id, &RNA_DynamicPaintModifier, md);
1225 return CTX_RESULT_OK;
1226 }
1227 return CTX_RESULT_NO_DATA;
1228 }
1229 if (CTX_data_equals(member, "line_style")) {
1230 set_pointer_type(path, result, &RNA_FreestyleLineStyle);
1231 return CTX_RESULT_OK;
1232 }
1233 if (CTX_data_equals(member, "gpencil")) {
1234 set_pointer_type(path, result, &RNA_Annotation);
1235 return CTX_RESULT_OK;
1236 }
1237 if (CTX_data_equals(member, "grease_pencil")) {
1238 set_pointer_type(path, result, &RNA_GreasePencil);
1239 return CTX_RESULT_OK;
1240 }
1241 if (CTX_data_equals(member, "strip")) {
1242 set_pointer_type(path, result, &RNA_Strip);
1243 return CTX_RESULT_OK;
1244 }
1245 if (CTX_data_equals(member, "strip_modifier")) {
1246 set_pointer_type(path, result, &RNA_StripModifier);
1247 return CTX_RESULT_OK;
1248 }
1250}
1251
1252/************************* Drawing the Path ************************/
1253
1254static bool buttons_panel_context_poll(const bContext *C, PanelType * /*pt*/)
1255{
1257 return sbuts->mainb != BCONTEXT_TOOL;
1258}
1259
1260static void buttons_panel_context_draw(const bContext *C, Panel *panel)
1261{
1263 ButsContextPath *path = static_cast<ButsContextPath *>(sbuts->path);
1264
1265 if (!path) {
1266 return;
1267 }
1268
1269 uiLayout *row = &panel->layout->row(true);
1271
1272 bool first = true;
1273 for (int i = 0; i < path->len; i++) {
1274 PointerRNA *ptr = &path->ptr[i];
1275
1276 /* Skip scene and view layer to save space. */
1277 if (!ELEM(sbuts->mainb,
1285 ptr->type == &RNA_Scene)
1286 {
1287 continue;
1288 }
1289 if (!ELEM(sbuts->mainb,
1294 BCONTEXT_WORLD) &&
1295 ptr->type == &RNA_ViewLayer)
1296 {
1297 continue;
1298 }
1299
1300 if (ptr->data == nullptr) {
1301 continue;
1302 }
1303
1304 /* Add > triangle. */
1305 if (!first) {
1306 row->label("", ICON_RIGHTARROW);
1307 }
1308
1309 /* Add icon and name. */
1310 int icon = RNA_struct_ui_icon(ptr->type);
1311 char namebuf[128];
1312 char *name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), nullptr);
1313
1314 if (name) {
1315 uiItemLDrag(row, ptr, name, icon);
1316
1317 if (name != namebuf) {
1318 MEM_freeN(name);
1319 }
1320 }
1321 else {
1322 row->label("", icon);
1323 }
1324
1325 first = false;
1326 }
1327
1328 uiLayout *pin_row = &row->row(false);
1330 pin_row->separator_spacer();
1332 pin_row->op(
1333 "BUTTONS_OT_toggle_pin", "", (sbuts->flag & SB_PIN_CONTEXT) ? ICON_PINNED : ICON_UNPINNED);
1334}
1335
1337{
1338 PanelType *pt = MEM_callocN<PanelType>("spacetype buttons panel context");
1339 STRNCPY_UTF8(pt->idname, "PROPERTIES_PT_context");
1340 STRNCPY_UTF8(pt->label, N_("Context")); /* XXX C panels unavailable through RNA bpy.types! */
1345 BLI_addtail(&art->paneltypes, pt);
1346}
1347
1349{
1351 ButsContextPath *path = static_cast<ButsContextPath *>(sbuts->path);
1352
1353 if (path->len == 0) {
1354 return nullptr;
1355 }
1356
1357 for (int i = path->len - 1; i >= 0; i--) {
1358 PointerRNA *ptr = &path->ptr[i];
1359
1360 /* Pin particle settings instead of system, since only settings are an ID-block. */
1361 if (sbuts->mainb == BCONTEXT_PARTICLE && sbuts->flag & SB_PIN_CONTEXT) {
1362 if (ptr->type == &RNA_ParticleSystem && ptr->data) {
1363 ParticleSystem *psys = static_cast<ParticleSystem *>(ptr->data);
1364 return &psys->part->id;
1365 }
1366 }
1367
1368 /* There is no valid image ID panel, Image Empty objects need this workaround. */
1369 if (sbuts->mainb == BCONTEXT_DATA && sbuts->flag & SB_PIN_CONTEXT) {
1370 if (ptr->type == &RNA_Image && ptr->data) {
1371 continue;
1372 }
1373 }
1374
1375 if (ptr->owner_id) {
1376 return ptr->owner_id;
1377 }
1378 }
1379
1380 return nullptr;
1381}
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
bool CTX_data_equals(const char *member, const char *str)
void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
bool CTX_data_dir(const char *member)
SpaceProperties * CTX_wm_space_properties(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_RESULT_NO_DATA
Scene * CTX_data_scene(const bContext *C)
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
LayerCollection * BKE_view_layer_active_collection_get(ViewLayer *view_layer)
ViewLayer * BKE_view_layer_default_view(const Scene *scene)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
Blender kernel freestyle line style functionality.
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
Definition linestyle.cc:714
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
ModifierData * BKE_object_active_modifier(const Object *ob)
Paint * BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
Definition paint.cc:437
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
struct ParticleSystem * psys_get_current(struct Object *ob)
Definition particle.cc:538
@ PANEL_TYPE_NO_HEADER
@ PANEL_TYPE_NO_SEARCH
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
#define STRNCPY_UTF8(dst, src)
#define ELEM(...)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
@ ID_LS
@ ID_BR
@ ID_OB
@ ID_PA
Object groups, one object can be in many groups at once.
@ FREESTYLE_CONTROL_EDITOR_MODE
@ eModifierType_Cloth
@ eModifierType_Fluid
@ eModifierType_Collision
@ eModifierType_DynamicPaint
@ eModifierType_Softbody
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ OB_LIGHTPROBE
#define OB_TYPE_SUPPORT_MATERIAL(_type)
@ R_EDGE_FRS
@ SB_SHADING_CONTEXT
@ SB_PIN_CONTEXT
@ PROPERTIES_SYNC_ALWAYS
@ PROPERTIES_SYNC_AUTO
@ BCONTEXT_STRIP
@ 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_STRIP_MODIFIER
@ BCONTEXT_TEXTURE
@ BCONTEXT_TOOL
@ BCONTEXT_PARTICLE
bool PE_poll(bContext *C)
bool ED_area_has_shared_border(ScrArea *a, ScrArea *b)
Definition area.cc:2085
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, blender::StringRef name, int icon)
static bool buttons_context_path(const bContext *C, SpaceProperties *sbuts, ButsContextPath *path, int mainb, int flag)
static bool buttons_context_path_shaderfx(ButsContextPath *path)
static bool buttons_context_path_bone(ButsContextPath *path)
static bool buttons_context_path_scene(ButsContextPath *path)
static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type)
static bool buttons_context_path_data(ButsContextPath *path, int type)
const char * buttons_context_dir[]
int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
void ED_buttons_set_context(const bContext *C, SpaceProperties *sbuts, PointerRNA *ptr, const int context)
static PointerRNA * get_pointer_type(ButsContextPath *path, StructRNA *type)
void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
void buttons_context_register(ARegionType *art)
static bool buttons_context_path_material(ButsContextPath *path)
static bool buttons_context_path_texture(const bContext *C, ButsContextPath *path, ButsContextTexture *ct)
static bool buttons_context_path_pose_bone(ButsContextPath *path)
static bool buttons_context_path_object(ButsContextPath *path)
static int buttons_shading_new_context(const bContext *C, int flag)
static bool buttons_context_path_strip_modifier(Scene *sequencer_scene, ButsContextPath *path)
static bool buttons_context_path_particle(ButsContextPath *path)
bool ED_buttons_should_sync_with_outliner(const bContext *C, const SpaceProperties *sbuts, ScrArea *area)
static bool buttons_context_path_view_layer(ButsContextPath *path, wmWindow *win)
static bool buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
static bool buttons_shading_context(const bContext *C, int mainb)
static bool is_pointer_in_path(ButsContextPath *path, PointerRNA *ptr)
static bool buttons_context_path_brush(const bContext *C, ButsContextPath *path)
static bool buttons_context_path_collection(const bContext *C, ButsContextPath *path, wmWindow *window)
static bool buttons_context_path_world(ButsContextPath *path)
ID * buttons_context_id_path(const bContext *C)
static void buttons_panel_context_draw(const bContext *C, Panel *panel)
static bool buttons_context_path_modifier(ButsContextPath *path)
static bool buttons_panel_context_poll(const bContext *C, PanelType *)
static bool buttons_context_path_strip(ButsContextPath *path)
void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts)
#define GS(x)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
T max(const T &a, const T &b)
Strip * select_active_get(const Scene *scene)
StripModifierData * modifier_get_active(const Strip *strip)
const char * name
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
int RNA_struct_ui_icon(const StructRNA *type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PointerRNA RNA_id_pointer_create(ID *id)
ListBase paneltypes
char name[64]
PointerRNA ptr[8]
struct ButsTextureUser * user
bNodeTree * ntree
PropertyRNA * prop
struct MTex * mtex[18]
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct Collection * collection
struct bPose * pose
char * matbits
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char translation_context[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
struct uiLayout * layout
struct MTex * mtex[18]
ParticleSettings * part
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
struct Collection * master_collection
struct RenderData r
struct World * world
struct FreestyleConfig freestyle_config
struct Scene * sequencer_scene
struct EditBone * act_edbone
ListBase * edbo
void alignment_set(blender::ui::LayoutAlign alignment)
void separator_spacer()
void label(blender::StringRef name, int icon)
uiLayout & row(bool align)
void emboss_set(blender::ui::EmbossType emboss)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
struct Scene * scene
i
Definition text_draw.cc:230
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4238
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
uint8_t flag
Definition wm_window.cc:145