Blender V4.3
screen_context.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdio>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
15#include "DNA_anim_types.h"
16#include "DNA_armature_types.h"
19#include "DNA_object_types.h"
20#include "DNA_scene_types.h"
21#include "DNA_screen_types.h"
22#include "DNA_sequence_types.h"
23#include "DNA_space_types.h"
25#include "DNA_workspace_types.h"
26
27#include "BLI_ghash.h"
28#include "BLI_listbase.h"
29#include "BLI_utildefines.h"
30
31#include "BKE_action.hh"
32#include "BKE_armature.hh"
33#include "BKE_blender.hh"
34#include "BKE_context.hh"
35#include "BKE_gpencil_legacy.h"
36#include "BKE_layer.hh"
37#include "BKE_object.hh"
38#include "BKE_tracking.h"
39
40#include "RNA_access.hh"
41#include "RNA_prototypes.hh"
42
43#include "ED_anim_api.hh"
44#include "ED_armature.hh"
45#include "ED_clip.hh"
46#include "ED_gpencil_legacy.hh"
47
48#include "SEQ_channels.hh"
49#include "SEQ_select.hh"
50#include "SEQ_sequencer.hh"
51#include "SEQ_transform.hh"
52
53#include "UI_interface.hh"
54#include "WM_api.hh"
55
57
58#include "screen_intern.hh"
59
60using blender::Vector;
61
62const char *screen_context_dir[] = {
63 "scene",
64 "view_layer",
65 "visible_objects",
66 "selectable_objects",
67 "selected_objects",
68 "editable_objects",
69 "selected_editable_objects",
70 "objects_in_mode",
71 "objects_in_mode_unique_data",
72 "visible_bones",
73 "editable_bones",
74 "selected_bones",
75 "selected_editable_bones",
76 "visible_pose_bones",
77 "selected_pose_bones",
78 "selected_pose_bones_from_active_object",
79 "active_bone",
80 "active_pose_bone",
81 "active_object",
82 "object",
83 "edit_object",
84 "sculpt_object",
85 "vertex_paint_object",
86 "weight_paint_object",
87 "image_paint_object",
88 "particle_edit_object",
89 "pose_object",
90 "active_sequence_strip",
91 "sequences",
92 "selected_sequences",
93 "selected_editable_sequences", /* sequencer */
94 "active_nla_track",
95 "active_nla_strip",
96 "selected_nla_strips", /* nla editor */
97 "selected_movieclip_tracks",
98 /* Legacy Grease Pencil */
99 "annotation_data",
100 "annotation_data_owner",
101 "active_annotation_layer",
102 /* Grease Pencil v3 */
103 "grease_pencil",
104 "active_operator",
105 "active_action",
106 "selected_visible_actions",
107 "selected_editable_actions",
108 "visible_fcurves",
109 "editable_fcurves",
110 "selected_visible_fcurves",
111 "selected_editable_fcurves",
112 "active_editable_fcurve",
113 "selected_editable_keyframes",
114 "ui_list",
115 "property",
116 "asset_library_reference",
117 nullptr,
118};
119
120/* Each function `screen_ctx_XXX()` will be called when the screen context "XXX" is requested.
121 * ensure_ed_screen_context_functions() is responsible for creating the hash map from context
122 * member name to function. */
123
132{
133 wmWindow *win = CTX_wm_window(C);
134 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
135 Scene *scene = WM_window_get_active_scene(win);
137 BKE_view_layer_synced_ensure(scene, view_layer);
138
140 if (BASE_VISIBLE(v3d, base)) {
141 CTX_data_id_list_add(result, &base->object->id);
142 }
143 }
145 return CTX_RESULT_OK;
146}
148{
149 wmWindow *win = CTX_wm_window(C);
150 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
151 Scene *scene = WM_window_get_active_scene(win);
153 BKE_view_layer_synced_ensure(scene, view_layer);
154
156 if (BASE_SELECTABLE(v3d, base)) {
157 CTX_data_id_list_add(result, &base->object->id);
158 }
159 }
161 return CTX_RESULT_OK;
162}
164{
165 wmWindow *win = CTX_wm_window(C);
166 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
167 Scene *scene = WM_window_get_active_scene(win);
169 BKE_view_layer_synced_ensure(scene, view_layer);
170
172 if (BASE_SELECTED(v3d, base)) {
173 CTX_data_id_list_add(result, &base->object->id);
174 }
175 }
177 return CTX_RESULT_OK;
178}
181{
182 wmWindow *win = CTX_wm_window(C);
183 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
184 Scene *scene = WM_window_get_active_scene(win);
186 BKE_view_layer_synced_ensure(scene, view_layer);
187
189 if (BASE_SELECTED_EDITABLE(v3d, base)) {
190 CTX_data_id_list_add(result, &base->object->id);
191 }
192 }
194 return CTX_RESULT_OK;
195}
197{
198 wmWindow *win = CTX_wm_window(C);
199 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
200 Scene *scene = WM_window_get_active_scene(win);
202 BKE_view_layer_synced_ensure(scene, view_layer);
203
204 /* Visible + Editable, but not necessarily selected */
206 if (BASE_EDITABLE(v3d, base)) {
207 CTX_data_id_list_add(result, &base->object->id);
208 }
209 }
211 return CTX_RESULT_OK;
212}
214{
215 wmWindow *win = CTX_wm_window(C);
216 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
217 const Scene *scene = WM_window_get_active_scene(win);
219 BKE_view_layer_synced_ensure(scene, view_layer);
220 Object *obact = BKE_view_layer_active_object_get(view_layer);
221
222 if (obact && (obact->mode != OB_MODE_OBJECT)) {
223 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
224 CTX_data_id_list_add(result, &ob_iter->id);
225 }
227 }
229 return CTX_RESULT_OK;
230}
233{
234 wmWindow *win = CTX_wm_window(C);
235 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
236 const Scene *scene = WM_window_get_active_scene(win);
238 BKE_view_layer_synced_ensure(scene, view_layer);
239 Object *obact = BKE_view_layer_active_object_get(view_layer);
240
241 if (obact && (obact->mode != OB_MODE_OBJECT)) {
242 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
243 ob_iter->id.tag |= ID_TAG_DOIT;
244 }
246 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
247 if (ob_iter->id.tag & ID_TAG_DOIT) {
248 ob_iter->id.tag &= ~ID_TAG_DOIT;
249 CTX_data_id_list_add(result, &ob_iter->id);
250 }
251 }
253 }
255 return CTX_RESULT_OK;
256}
259 const bool editable_bones)
260{
261 wmWindow *win = CTX_wm_window(C);
262 const Scene *scene = WM_window_get_active_scene(win);
264 BKE_view_layer_synced_ensure(scene, view_layer);
265 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
266
267 bArmature *arm = static_cast<bArmature *>(
268 (obedit && obedit->type == OB_ARMATURE) ? obedit->data : nullptr);
269 EditBone *flipbone = nullptr;
270
271 if (arm && arm->edbo) {
273 scene, view_layer, CTX_wm_view3d(C));
274 for (Object *ob : objects) {
275 arm = static_cast<bArmature *>(ob->data);
276
277 /* Attention: X-Axis Mirroring is also handled here... */
278 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
279 /* first and foremost, bone must be visible and selected */
280 if (EBONE_VISIBLE(arm, ebone)) {
281 /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
282 * so that most users of this data don't need to explicitly check for it themselves.
283 *
284 * We need to make sure that these mirrored copies are not selected, otherwise some
285 * bones will be operated on twice.
286 */
287 if (arm->flag & ARM_MIRROR_EDIT) {
288 flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
289 }
290
291 /* if we're filtering for editable too, use the check for that instead,
292 * as it has selection check too */
293 if (editable_bones) {
294 /* only selected + editable */
295 if (EBONE_EDITABLE(ebone)) {
296 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
297
298 if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) {
299 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
300 }
301 }
302 }
303 else {
304 /* only include bones if visible */
305 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
306
307 if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0) {
308 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
309 }
310 }
311 }
312 }
313 }
314
316 return CTX_RESULT_OK;
317 }
318 return CTX_RESULT_NO_DATA;
319}
330 const bool selected_editable_bones)
331{
332 wmWindow *win = CTX_wm_window(C);
333 const Scene *scene = WM_window_get_active_scene(win);
335 BKE_view_layer_synced_ensure(scene, view_layer);
336 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
337 bArmature *arm = static_cast<bArmature *>(
338 (obedit && obedit->type == OB_ARMATURE) ? obedit->data : nullptr);
339 EditBone *flipbone = nullptr;
340
341 if (arm && arm->edbo) {
343 scene, view_layer, CTX_wm_view3d(C));
344 for (Object *ob : objects) {
345 arm = static_cast<bArmature *>(ob->data);
346
347 /* Attention: X-Axis Mirroring is also handled here... */
348 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
349 /* first and foremost, bone must be visible and selected */
350 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
351 /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
352 * so that most users of this data don't need to explicitly check for it themselves.
353 *
354 * We need to make sure that these mirrored copies are not selected, otherwise some
355 * bones will be operated on twice.
356 */
357 if (arm->flag & ARM_MIRROR_EDIT) {
358 flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
359 }
360
361 /* if we're filtering for editable too, use the check for that instead,
362 * as it has selection check too */
363 if (selected_editable_bones) {
364 /* only selected + editable */
365 if (EBONE_EDITABLE(ebone)) {
366 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
367
368 if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) {
369 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
370 }
371 }
372 }
373 else {
374 /* only include bones if selected */
375 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
376
377 if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) {
378 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
379 }
380 }
381 }
382 }
383 }
384
386 return CTX_RESULT_OK;
387 }
388 return CTX_RESULT_NO_DATA;
389}
400{
401 wmWindow *win = CTX_wm_window(C);
402 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
403 const Scene *scene = WM_window_get_active_scene(win);
405 BKE_view_layer_synced_ensure(scene, view_layer);
406 Object *obact = BKE_view_layer_active_object_get(view_layer);
407 Object *obpose = BKE_object_pose_armature_get(obact);
408 if (obpose && obpose->pose && obpose->data) {
409 if (obpose != obact) {
411 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
412 }
414 }
415 else if (obact->mode & OB_MODE_POSE) {
416 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
418 CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
419 }
421 }
423 }
425 return CTX_RESULT_OK;
426 }
427 return CTX_RESULT_NO_DATA;
428}
430{
431 wmWindow *win = CTX_wm_window(C);
432 View3D *v3d = CTX_wm_view3d(C); /* This may be nullptr in a lot of cases. */
433 const Scene *scene = WM_window_get_active_scene(win);
435 Object *obact = BKE_view_layer_active_object_get(view_layer);
436 Object *obpose = BKE_object_pose_armature_get(obact);
437 if (obpose && obpose->pose && obpose->data) {
438 if (obpose != obact) {
440 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
441 }
443 }
444 else if (obact->mode & OB_MODE_POSE) {
445 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
447 CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
448 }
450 }
452 }
454 return CTX_RESULT_OK;
455 }
456 return CTX_RESULT_NO_DATA;
457}
460{
461 wmWindow *win = CTX_wm_window(C);
462 const Scene *scene = WM_window_get_active_scene(win);
464 BKE_view_layer_synced_ensure(scene, view_layer);
465 Object *obact = BKE_view_layer_active_object_get(view_layer);
466 Object *obpose = BKE_object_pose_armature_get(obact);
467 if (obpose && obpose->pose && obpose->data) {
468 if (obpose != obact) {
470 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
471 }
473 }
474 else if (obact->mode & OB_MODE_POSE) {
476 CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan);
477 }
479 }
481 return CTX_RESULT_OK;
482 }
483 return CTX_RESULT_NO_DATA;
484}
486{
487 wmWindow *win = CTX_wm_window(C);
488 const Scene *scene = WM_window_get_active_scene(win);
490 BKE_view_layer_synced_ensure(scene, view_layer);
491 Object *obact = BKE_view_layer_active_object_get(view_layer);
492 if (obact && obact->type == OB_ARMATURE) {
493 bArmature *arm = static_cast<bArmature *>(obact->data);
494 if (arm->edbo) {
495 if (arm->act_edbone) {
496 CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
497 return CTX_RESULT_OK;
498 }
499 }
500 else {
501 if (arm->act_bone) {
502 CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
503 return CTX_RESULT_OK;
504 }
505 }
506 }
507 return CTX_RESULT_NO_DATA;
508}
510{
511 wmWindow *win = CTX_wm_window(C);
512 const Scene *scene = WM_window_get_active_scene(win);
514 BKE_view_layer_synced_ensure(scene, view_layer);
515 Object *obact = BKE_view_layer_active_object_get(view_layer);
516 Object *obpose = BKE_object_pose_armature_get(obact);
517
519 if (pchan) {
520 CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
521 return CTX_RESULT_OK;
522 }
523 return CTX_RESULT_NO_DATA;
524}
526{
527 wmWindow *win = CTX_wm_window(C);
528 const Scene *scene = WM_window_get_active_scene(win);
530 BKE_view_layer_synced_ensure(scene, view_layer);
531 Object *obact = BKE_view_layer_active_object_get(view_layer);
532
533 if (obact) {
535 }
536
537 return CTX_RESULT_OK;
538}
539
541{
543 PropertyRNA *prop;
544 int index;
545
546 UI_context_active_but_prop_get(C, &ptr, &prop, &index);
547 if (ptr.data && prop) {
548 /* UI_context_active_but_prop_get returns an index of 0 if the property is not
549 * an array, but other functions expect -1 for non-arrays. */
550 if (!RNA_property_array_check(prop)) {
551 index = -1;
552 }
553
556 CTX_data_prop_set(result, prop, index);
557 }
558
559 return CTX_RESULT_OK;
560}
561
563{
564 wmWindow *win = CTX_wm_window(C);
565 const Scene *scene = WM_window_get_active_scene(win);
567 BKE_view_layer_synced_ensure(scene, view_layer);
568 Object *obact = BKE_view_layer_active_object_get(view_layer);
569
570 if (obact) {
572 }
573
574 return CTX_RESULT_OK;
575}
577{
578 wmWindow *win = CTX_wm_window(C);
579 Scene *scene = WM_window_get_active_scene(win);
581 BKE_view_layer_synced_ensure(scene, view_layer);
582 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
583 /* convenience for now, 1 object per scene in editmode */
584 if (obedit) {
586 }
587
588 return CTX_RESULT_OK;
589}
591{
592 wmWindow *win = CTX_wm_window(C);
593 const Scene *scene = WM_window_get_active_scene(win);
595 BKE_view_layer_synced_ensure(scene, view_layer);
596 Object *obact = BKE_view_layer_active_object_get(view_layer);
597
598 if (obact && (obact->mode & OB_MODE_SCULPT)) {
600 }
601
602 return CTX_RESULT_OK;
603}
605{
606 wmWindow *win = CTX_wm_window(C);
607 const Scene *scene = WM_window_get_active_scene(win);
609 BKE_view_layer_synced_ensure(scene, view_layer);
610 Object *obact = BKE_view_layer_active_object_get(view_layer);
611 if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) {
613 }
614
615 return CTX_RESULT_OK;
616}
618{
619 wmWindow *win = CTX_wm_window(C);
620 const Scene *scene = WM_window_get_active_scene(win);
622 BKE_view_layer_synced_ensure(scene, view_layer);
623 Object *obact = BKE_view_layer_active_object_get(view_layer);
624 if (obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
626 }
627
628 return CTX_RESULT_OK;
629}
631{
632 wmWindow *win = CTX_wm_window(C);
633 const Scene *scene = WM_window_get_active_scene(win);
635 BKE_view_layer_synced_ensure(scene, view_layer);
636 Object *obact = BKE_view_layer_active_object_get(view_layer);
637 if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) {
639 }
640
641 return CTX_RESULT_OK;
642}
645{
646 wmWindow *win = CTX_wm_window(C);
647 const Scene *scene = WM_window_get_active_scene(win);
649 BKE_view_layer_synced_ensure(scene, view_layer);
650 Object *obact = BKE_view_layer_active_object_get(view_layer);
651 if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
653 }
654
655 return CTX_RESULT_OK;
656}
658{
659 wmWindow *win = CTX_wm_window(C);
660 const Scene *scene = WM_window_get_active_scene(win);
662 BKE_view_layer_synced_ensure(scene, view_layer);
663 Object *obact = BKE_view_layer_active_object_get(view_layer);
664 Object *obpose = BKE_object_pose_armature_get(obact);
665 if (obpose) {
667 }
668 return CTX_RESULT_OK;
669}
672{
673 wmWindow *win = CTX_wm_window(C);
674 Scene *scene = WM_window_get_active_scene(win);
675 Sequence *seq = SEQ_select_active_get(scene);
676 if (seq) {
677 CTX_data_pointer_set(result, &scene->id, &RNA_Sequence, seq);
678 return CTX_RESULT_OK;
679 }
680 return CTX_RESULT_NO_DATA;
681}
683{
684 wmWindow *win = CTX_wm_window(C);
685 Scene *scene = WM_window_get_active_scene(win);
686 Editing *ed = SEQ_editing_get(scene);
687 if (ed) {
688 LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
689 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
690 }
692 return CTX_RESULT_OK;
693 }
694 return CTX_RESULT_NO_DATA;
695}
697{
698 wmWindow *win = CTX_wm_window(C);
699 Scene *scene = WM_window_get_active_scene(win);
700 Editing *ed = SEQ_editing_get(scene);
701 if (ed) {
702 LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
703 if (seq->flag & SELECT) {
704 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
705 }
706 }
708 return CTX_RESULT_OK;
709 }
710 return CTX_RESULT_NO_DATA;
711}
714{
715 wmWindow *win = CTX_wm_window(C);
716 Scene *scene = WM_window_get_active_scene(win);
717 Editing *ed = SEQ_editing_get(scene);
718 if (ed == nullptr) {
719 return CTX_RESULT_NO_DATA;
720 }
721
723 LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
724 if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) {
725 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
726 }
727 }
729 return CTX_RESULT_OK;
730}
731
751{
752 bAnimContext ac;
753 if (ANIM_animdata_get_context(C, &ac) != 0) {
754 ListBase anim_data = {nullptr, nullptr};
755
757 &ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac.data, eAnimCont_Types(ac.datatype));
758 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
759 if (ale->datatype != ALE_NLASTRIP) {
760 continue;
761 }
762 NlaTrack *nlt = (NlaTrack *)ale->data;
763 LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
764 if (strip->flag & NLASTRIP_FLAG_SELECT) {
765 CTX_data_list_add(result, ale->id, &RNA_NlaStrip, strip);
766 }
767 }
768 }
769 ANIM_animdata_freelist(&anim_data);
770
772 return CTX_RESULT_OK;
773 }
774 return CTX_RESULT_NO_DATA;
775}
778{
779 SpaceClip *space_clip = CTX_wm_space_clip(C);
780 if (space_clip == nullptr) {
781 return CTX_RESULT_NO_DATA;
782 }
783 MovieClip *clip = ED_space_clip_get_clip(space_clip);
784 if (clip == nullptr) {
785 return CTX_RESULT_NO_DATA;
786 }
787
788 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
789 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
790 if (!TRACK_SELECTED(track)) {
791 continue;
792 }
793 CTX_data_list_add(result, &clip->id, &RNA_MovieTrackingTrack, track);
794 }
795
797 return CTX_RESULT_OK;
798}
799
801{
802 wmWindow *win = CTX_wm_window(C);
803 bScreen *screen = CTX_wm_screen(C);
804 ScrArea *area = CTX_wm_area(C);
805 Scene *scene = WM_window_get_active_scene(win);
806 bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene);
807
808 if (gpd) {
810 return CTX_RESULT_OK;
811 }
812 return CTX_RESULT_NO_DATA;
813}
816{
817 wmWindow *win = CTX_wm_window(C);
818 bScreen *screen = CTX_wm_screen(C);
819 ScrArea *area = CTX_wm_area(C);
820 Scene *scene = WM_window_get_active_scene(win);
821
822 /* Pointer to which data/datablock owns the reference to the Grease Pencil data being used. */
824 bGPdata **gpd_ptr = ED_annotation_data_get_pointers_direct((ID *)screen, area, scene, &ptr);
825
826 if (gpd_ptr) {
828 return CTX_RESULT_OK;
829 }
830 return CTX_RESULT_NO_DATA;
831}
834{
835 wmWindow *win = CTX_wm_window(C);
836 bScreen *screen = CTX_wm_screen(C);
837 ScrArea *area = CTX_wm_area(C);
838 Scene *scene = WM_window_get_active_scene(win);
839 bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene);
840
841 if (gpd) {
843
844 if (gpl) {
845 CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
846 return CTX_RESULT_OK;
847 }
848 }
849 return CTX_RESULT_NO_DATA;
850}
852{
853 wmWindow *win = CTX_wm_window(C);
854 const Scene *scene = WM_window_get_active_scene(win);
856 BKE_view_layer_synced_ensure(scene, view_layer);
857 Object *obact = BKE_view_layer_active_object_get(view_layer);
858 if (obact && obact->type == OB_GREASE_PENCIL) {
859 GreasePencil *grease_pencil = static_cast<GreasePencil *>(obact->data);
860 CTX_data_id_pointer_set(result, &grease_pencil->id);
861 return CTX_RESULT_OK;
862 }
863 return CTX_RESULT_NO_DATA;
864}
866{
867 wmOperator *op = nullptr;
868
869 SpaceFile *sfile = CTX_wm_space_file(C);
870 if (sfile) {
871 op = sfile->op;
872 }
873 else if ((op = UI_context_active_operator_get(C))) {
874 /* do nothing */
875 }
876 else {
877 /* NOTE: this checks poll, could be a problem, but this also
878 * happens for the toolbar */
880 }
881 /* TODO: get the operator from popup's. */
882
883 if (op && op->ptr) {
884 CTX_data_pointer_set(result, nullptr, &RNA_Operator, op);
885 return CTX_RESULT_OK;
886 }
887 return CTX_RESULT_NO_DATA;
888}
891 bool active_only,
892 bool editable)
893{
894 bAnimContext ac;
896 return CTX_RESULT_NO_DATA;
897 }
898
899 /* In the Action and Shape Key editor always use the action field at the top. */
900 if (ac.spacetype == SPACE_ACTION) {
901 SpaceAction *saction = (SpaceAction *)ac.sl;
902
903 if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY)) {
904 if (active_only) {
906 }
907 else {
908 if (saction->action && !(editable && !ID_IS_EDITABLE(saction->action))) {
910 }
911
913 }
914
915 return CTX_RESULT_OK;
916 }
917 }
918
919 /* Search for selected animation data items. */
920 ListBase anim_data = {nullptr, nullptr};
921
923 bool check_selected = false;
924
925 switch (ac.spacetype) {
926 case SPACE_GRAPH:
928 (active_only ? ANIMFILTER_ACTIVE : ANIMFILTER_SEL);
929 break;
930
931 case SPACE_ACTION:
933 check_selected = true;
934 break;
935 default:
937 }
938
940 &ac, &anim_data, eAnimFilter_Flags(filter), ac.data, eAnimCont_Types(ac.datatype));
941
942 GSet *seen_set = active_only ? nullptr : BLI_gset_ptr_new("seen actions");
943
944 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
945 /* In dopesheet check selection status of individual items, skipping
946 * if not selected or has no selection flag. This is needed so that
947 * selecting action or group rows without any channels works. */
948 if (check_selected && ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_SELECT) <= 0) {
949 continue;
950 }
951
952 bAction *action = ANIM_channel_action_get(ale);
953 if (!action) {
954 continue;
955 }
956
957 if (active_only) {
959 break;
960 }
961 if (editable && !ID_IS_EDITABLE(action)) {
962 continue;
963 }
964
965 /* Add the action to the output list if not already added. */
966 if (BLI_gset_add(seen_set, action)) {
967 CTX_data_id_list_add(result, &action->id);
968 }
969 }
970
971 ANIM_animdata_freelist(&anim_data);
972
973 if (!active_only) {
974 BLI_gset_free(seen_set, nullptr);
976 }
977
978 return CTX_RESULT_OK;
979}
996 const int extra_filter)
997{
998 bAnimContext ac;
1000 ListBase anim_data = {nullptr, nullptr};
1001
1003 (ac.spacetype == SPACE_GRAPH ?
1006 extra_filter;
1007
1009 &ac, &anim_data, eAnimFilter_Flags(filter), ac.data, eAnimCont_Types(ac.datatype));
1010
1011 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
1012 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
1013 CTX_data_list_add(result, ale->fcurve_owner_id, &RNA_FCurve, ale->data);
1014 }
1015 }
1016
1017 ANIM_animdata_freelist(&anim_data);
1018
1020 return CTX_RESULT_OK;
1021 }
1022 return CTX_RESULT_NO_DATA;
1023}
1044{
1045 bAnimContext ac;
1047 ListBase anim_data = {nullptr, nullptr};
1048
1051
1053 &ac, &anim_data, eAnimFilter_Flags(filter), ac.data, eAnimCont_Types(ac.datatype));
1054
1055 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
1056 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
1057 CTX_data_pointer_set(result, ale->fcurve_owner_id, &RNA_FCurve, ale->data);
1058 break;
1059 }
1060 }
1061
1062 ANIM_animdata_freelist(&anim_data);
1063 return CTX_RESULT_OK;
1064 }
1065 return CTX_RESULT_NO_DATA;
1066}
1069{
1070 bAnimContext ac;
1072 ListBase anim_data = {nullptr, nullptr};
1073
1074 /* Use keyframes from editable selected FCurves. */
1077 (ac.spacetype == SPACE_GRAPH ?
1080
1082 &ac, &anim_data, eAnimFilter_Flags(filter), ac.data, eAnimCont_Types(ac.datatype));
1083
1084 int i;
1085 FCurve *fcurve;
1086 BezTriple *bezt;
1087 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
1088 if (!ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
1089 continue;
1090 }
1091
1092 fcurve = (FCurve *)ale->data;
1093 if (fcurve->bezt == nullptr) {
1094 /* Skip baked FCurves. */
1095 continue;
1096 }
1097
1098 for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) {
1099 if ((bezt->f2 & SELECT) == 0) {
1100 continue;
1101 }
1102
1103 CTX_data_list_add(result, ale->fcurve_owner_id, &RNA_Keyframe, bezt);
1104 }
1105 }
1106
1107 ANIM_animdata_freelist(&anim_data);
1108
1110 return CTX_RESULT_OK;
1111 }
1112 return CTX_RESULT_NO_DATA;
1113}
1114
1116{
1117 WorkSpace *workspace = CTX_wm_workspace(C);
1119 result, &workspace->id, &RNA_AssetLibraryReference, &workspace->asset_library_ref);
1120 return CTX_RESULT_OK;
1121}
1122
1124{
1125 wmWindow *win = CTX_wm_window(C);
1126 ARegion *region = CTX_wm_region(C);
1127 if (region) {
1128 uiList *list = UI_list_find_mouse_over(region, win->eventstate);
1129 if (list) {
1130 CTX_data_pointer_set(result, nullptr, &RNA_UIList, list);
1131 return CTX_RESULT_OK;
1132 }
1133 }
1134 return CTX_RESULT_NO_DATA;
1135}
1136
1137/* Registry of context callback functions. */
1138
1141
1142static void free_context_function_ghash(void * /*user_data*/)
1143{
1145}
1146static inline void register_context_function(const char *member, context_callback function)
1147{
1149 ed_screen_context_functions, (void *)member, reinterpret_cast<void *>(function));
1150}
1151
1153{
1154 if (ed_screen_context_functions != nullptr) {
1155 return;
1156 }
1157
1158 /* Murmur hash is faster for smaller strings (according to BLI_hash_mm2). */
1161
1163
1178 register_context_function("selected_pose_bones_from_active_object",
1213 register_context_function("asset_library_reference", screen_ctx_asset_library);
1216}
1217
1218int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
1219{
1220 if (CTX_data_dir(member)) {
1222 return CTX_RESULT_OK;
1223 }
1224
1226 context_callback callback = reinterpret_cast<context_callback>(
1228 if (callback == nullptr) {
1230 }
1231
1232 return callback(C, result);
1233}
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_active_if_bonecoll_visible(Object *ob) ATTR_WARN_UNUSED_RESULT
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END
#define FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN(_ob, _pchan)
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan)
#define FOREACH_PCHAN_VISIBLE_IN_OBJECT_END
Blender util stuff.
void BKE_blender_atexit_register(void(*func)(void *user_data), void *user_data)
Definition blender.cc:466
WorkSpace * CTX_wm_workspace(const bContext *C)
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
void CTX_data_id_list_add(bContextDataResult *result, ID *id)
bScreen * CTX_wm_screen(const bContext *C)
void CTX_data_prop_set(bContextDataResult *result, PropertyRNA *prop, int index)
void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
bool CTX_data_dir(const char *member)
void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
SpaceFile * CTX_wm_space_file(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
eContextResult
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_RESULT_NO_DATA
void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
SpaceClip * CTX_wm_space_clip(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
@ CTX_DATA_TYPE_PROPERTY
@ CTX_DATA_TYPE_COLLECTION
void CTX_data_type_set(bContextDataResult *result, short type)
View3D * CTX_wm_view3d(const bContext *C)
struct bGPDlayer * BKE_gpencil_layer_active_get(struct bGPdata *gpd)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
#define FOREACH_OBJECT_IN_MODE_END
Definition BKE_layer.hh:382
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
#define FOREACH_OBJECT_IN_MODE_BEGIN(_scene, _view_layer, _v3d, _object_type, _object_mode, _instance)
Definition BKE_layer.hh:377
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
General operations, lookup, etc. for blender objects.
Object * BKE_object_pose_armature_get(Object *ob)
#define TRACK_SELECTED(track)
struct MovieTrackingObject * BKE_tracking_object_get_active(const struct MovieTracking *tracking)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
struct GSet GSet
Definition BLI_ghash.h:341
bool BLI_ghashutil_strcmp(const void *a, const void *b)
GSet * BLI_gset_ptr_new(const char *info)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:686
unsigned int BLI_ghashutil_strhash_p_murmur(const void *ptr)
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:1034
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.c:966
#define LISTBASE_FOREACH(type, var, list)
#define ELEM(...)
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ SACTCONT_ACTION
@ SACTCONT_SHAPEKEY
@ NLASTRIP_FLAG_SELECT
@ BONE_SELECTED
@ ARM_MIRROR_EDIT
#define OB_MODE_ALL_WEIGHT_PAINT
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
@ OB_GREASE_PENCIL
@ OB_ARMATURE
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTED_EDITABLE(v3d, base)
#define BASE_EDITABLE(v3d, base)
#define BASE_SELECTABLE(v3d, base)
#define BASE_VISIBLE(v3d, base)
@ SPACE_ACTION
@ SPACE_GRAPH
@ ANIMTYPE_NLACURVE
@ ANIMTYPE_FCURVE
@ ALE_NLASTRIP
eAnimCont_Types
@ ACHANNEL_SETTING_SELECT
bool ANIM_nla_context_strip_ptr(const bContext *C, PointerRNA *r_ptr)
bool ANIM_nla_context_track_ptr(const bContext *C, PointerRNA *r_ptr)
eAnimFilter_Flags
@ ANIMFILTER_ACTIVE
@ ANIMFILTER_FOREDIT
@ ANIMFILTER_DATA_VISIBLE
@ ANIMFILTER_CURVE_VISIBLE
@ ANIMFILTER_LIST_VISIBLE
@ ANIMFILTER_LIST_CHANNELS
@ ANIMFILTER_NODUPLIS
@ ANIMFILTER_FCURVESONLY
@ ANIMFILTER_SEL
#define EBONE_VISIBLE(arm, ebone)
#define EBONE_EDITABLE(ebone)
MovieClip * ED_space_clip_get_clip(const SpaceClip *sc)
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
#define C
Definition RandGen.cpp:29
uiList * UI_list_find_mouse_over(const ARegion *region, const wmEvent *event)
uiBut * UI_context_active_but_prop_get(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
wmOperator * UI_context_active_operator_get(const bContext *C)
bAction * ANIM_channel_action_get(const bAnimListElem *ale)
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition anim_deps.cc:457
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, const eAnimFilter_Flags filter_mode, void *data, const eAnimCont_Types datatype)
EditBone * ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition channels.cc:23
#define SELECT
bGPdata * ED_annotation_data_get_active_direct(ID *screen_id, ScrArea *area, Scene *scene)
bGPdata ** ED_annotation_data_get_pointers_direct(ID *screen_id, ScrArea *area, Scene *scene, PointerRNA *r_ptr)
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
bool RNA_property_array_check(PropertyRNA *prop)
static eContextResult screen_ctx_selected_pose_bones(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_objects_in_mode_unique_data(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_objects(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_operator(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_sel_edit_fcurves_(const bContext *C, bContextDataResult *result, const int extra_filter)
static eContextResult screen_ctx_asset_library(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_ui_list(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_property(const bContext *C, bContextDataResult *result)
const char * screen_context_dir[]
static void free_context_function_ghash(void *)
static eContextResult screen_ctx_selected_objects(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_bones(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_sequence_strip(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_nla_strips(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_editable_objects(const bContext *C, bContextDataResult *result)
static GHash * ed_screen_context_functions
static eContextResult screen_ctx_selected_sequences(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_annotation_layer(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_visible_pose_bones(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_pose_object(const bContext *C, bContextDataResult *result)
eContextResult(*)(const bContext *C, bContextDataResult *result) context_callback
static eContextResult screen_ctx_selected_visible_fcurves(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_annotation_data(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_edit_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_bone(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_objects_in_mode(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selectable_objects(const bContext *C, bContextDataResult *result)
static void register_context_function(const char *member, context_callback function)
static eContextResult screen_ctx_annotation_data_owner(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_visible_actions(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_visible_fcurves(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_editable_fcurves(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_actions(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_particle_edit_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_bones(const bContext *C, bContextDataResult *result)
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
static eContextResult screen_ctx_visible_objects(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_editable_bones(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_keyframes(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_editable_fcurves(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_sel_actions_impl(const bContext *C, bContextDataResult *result, bool active_only, bool editable)
static eContextResult screen_ctx_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_editable_fcurve(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_bones_(const bContext *C, bContextDataResult *result, const bool selected_editable_bones)
static eContextResult screen_ctx_grease_pencil_data(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_pose_bones_from_active_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_visible_bones(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_sequences(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_vertex_paint_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_pose_bone(const bContext *C, bContextDataResult *result)
static void ensure_ed_screen_context_functions()
static eContextResult screen_ctx_sculpt_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_nla_strip(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_visible_or_editable_bones_(const bContext *C, bContextDataResult *result, const bool editable_bones)
static eContextResult screen_ctx_active_nla_track(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_image_paint_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_scene(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_weight_paint_object(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_active_action(const bContext *C, bContextDataResult *result)
static eContextResult screen_ctx_selected_movieclip_tracks(const bContext *C, bContextDataResult *result)
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
Sequence * SEQ_select_active_get(const Scene *scene)
bool SEQ_transform_is_locked(ListBase *channels, const Sequence *seq)
ListBase * seqbasep
BezTriple * bezt
Definition DNA_ID.h:413
struct MovieTracking tracking
ListBase strips
struct bPose * pose
struct wmOperator * op
AssetLibraryReference asset_library_ref
SpaceLink * sl
eAnimCont_Types datatype
eSpace_Type spacetype
struct EditBone * act_edbone
ListBase * edbo
struct PointerRNA * ptr
struct wmEvent * eventstate
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperator * WM_operator_last_redo(const bContext *C)
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)