Blender V5.0
sequencer/intern/modifiers/modifier.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012-2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_array.hh"
10#include "BLI_hash.hh"
11#include "BLI_listbase.h"
12#include "BLI_rand.hh"
13#include "BLI_set.hh"
14#include "BLI_string_utf8.h"
15#include "BLI_string_utils.hh"
16#include "BLI_task.hh"
17
18#include "BLT_translation.hh"
19
20#include "DNA_mask_types.h"
21#include "DNA_sequence_types.h"
22#include "DNA_space_types.h"
23
24#include "BKE_colortools.hh"
25#include "BKE_screen.hh"
26
28
29#include "RNA_access.hh"
30#include "RNA_prototypes.hh"
31
32#include "SEQ_modifier.hh"
33#include "SEQ_modifiertypes.hh"
34#include "SEQ_render.hh"
35#include "SEQ_select.hh"
36#include "SEQ_sequencer.hh"
37#include "SEQ_time.hh"
38#include "SEQ_transform.hh"
39#include "SEQ_utils.hh"
40
41#include "UI_interface.hh"
43
44#include "BLO_read_write.hh"
45
46#include "WM_api.hh"
47
48#include "modifier.hh"
49#include "render.hh"
50
51namespace blender::seq {
52
53/* -------------------------------------------------------------------- */
54
55static bool modifier_has_persistent_uid(const Strip &strip, int uid)
56{
58 if (smd->persistent_uid == uid) {
59 return true;
60 }
61 }
62 return false;
63}
64
66{
69 while (true) {
70 const int new_uid = rng.get_int32();
71 if (new_uid <= 0) {
72 continue;
73 }
74 if (modifier_has_persistent_uid(strip, new_uid)) {
75 continue;
76 }
77 smd.persistent_uid = new_uid;
78 break;
79 }
80}
81
83{
84 Set<int> uids;
85 int modifiers_num = 0;
87 if (smd->persistent_uid <= 0) {
88 return false;
89 }
90 uids.add(smd->persistent_uid);
91 modifiers_num++;
92 }
93 if (uids.size() != modifiers_num) {
94 return false;
95 }
96 return true;
97}
98
99static void modifier_panel_header(const bContext * /*C*/, Panel *panel)
100{
101 uiLayout *row, *sub, *name_row;
102 uiLayout *layout = panel->layout;
103
104 /* Don't use #modifier_panel_get_property_pointers, we don't want to lock the header. */
106 StripModifierData *smd = reinterpret_cast<StripModifierData *>(ptr->data);
107
108 UI_panel_context_pointer_set(panel, "modifier", ptr);
109
110 /* Modifier Icon. */
111 sub = &layout->row(true);
113 PointerRNA active_op_ptr = sub->op(
114 "SEQUENCER_OT_strip_modifier_set_active", "", RNA_struct_ui_icon(ptr->type));
115 RNA_string_set(&active_op_ptr, "modifier", smd->name);
116
117 row = &layout->row(true);
118
119 /* Modifier Name.
120 * Count how many buttons are added to the header to check if there is enough space. */
121 int buttons_number = 0;
122 name_row = &row->row(true);
123
124 sub = &row->row(true);
125 sub->prop(ptr, "enable", UI_ITEM_NONE, "", ICON_NONE);
126 buttons_number++;
127
128 /* Delete button. */
129 sub = &row->row(false);
131 PointerRNA remove_op_ptr = sub->op("SEQUENCER_OT_strip_modifier_remove", "", ICON_X);
132 RNA_string_set(&remove_op_ptr, "name", smd->name);
133 buttons_number++;
134
135 bool display_name = (panel->sizex / UI_UNIT_X - buttons_number > 5) || (panel->sizex == 0);
136 if (display_name) {
137 name_row->prop(ptr, "name", UI_ITEM_NONE, "", ICON_NONE);
138 }
139 else {
141 }
142
143 /* Extra padding for delete button. */
144 layout->separator();
145}
146
148{
149 Scene *sequencer_scene = CTX_data_sequencer_scene(C);
150 Editing *ed = seq::editing_get(sequencer_scene);
151 uiLayout *row, *col;
152
153 const int input_mask_type = RNA_enum_get(ptr, "input_mask_type");
154
155 layout->use_property_split_set(true);
156
157 col = &layout->column(false);
158 row = &col->row(true);
159 row->prop(ptr, "input_mask_type", UI_ITEM_R_EXPAND, IFACE_("Type"), ICON_NONE);
160
161 if (input_mask_type == STRIP_MASK_INPUT_STRIP) {
163 PointerRNA sequences_object;
164 if (ms) {
165 sequences_object = RNA_pointer_create_discrete(
166 &sequencer_scene->id, &RNA_MetaStrip, ms->parent_strip);
167 }
168 else {
169 sequences_object = RNA_pointer_create_discrete(
170 &sequencer_scene->id, &RNA_SequenceEditor, ed);
171 }
172 col->prop_search(
173 ptr, "input_mask_strip", &sequences_object, "strips", IFACE_("Mask"), ICON_NONE);
174 }
175 else {
176 col->prop(ptr, "input_mask_id", UI_ITEM_NONE, std::nullopt, ICON_NONE);
177 row = &col->row(true);
178 row->prop(ptr, "mask_time", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
179 }
180}
181
182bool modifier_ui_poll(const bContext *C, PanelType * /*pt*/)
183{
184 Scene *sequencer_scene = CTX_data_sequencer_scene(C);
185 if (!sequencer_scene) {
186 return false;
187 }
188 Strip *active_strip = seq::select_active_get(sequencer_scene);
189 return active_strip != nullptr;
190}
191
195static void modifier_reorder(bContext *C, Panel *panel, const int new_index)
196{
197 PointerRNA *smd_ptr = UI_panel_custom_data_get(panel);
198 StripModifierData *smd = reinterpret_cast<StripModifierData *>(smd_ptr->data);
199
200 PointerRNA props_ptr;
201 wmOperatorType *ot = WM_operatortype_find("SEQUENCER_OT_strip_modifier_move_to_index", false);
203 RNA_string_set(&props_ptr, "modifier", smd->name);
204 RNA_int_set(&props_ptr, "index", new_index);
206 WM_operator_properties_free(&props_ptr);
207}
208
209static short get_strip_modifier_expand_flag(const bContext * /*C*/, Panel *panel)
210{
211 PointerRNA *smd_ptr = UI_panel_custom_data_get(panel);
212 StripModifierData *smd = reinterpret_cast<StripModifierData *>(smd_ptr->data);
213 return smd->ui_expand_flag;
214}
215
216static void set_strip_modifier_expand_flag(const bContext * /*C*/, Panel *panel, short expand_flag)
217{
218 PointerRNA *smd_ptr = UI_panel_custom_data_get(panel);
219 StripModifierData *smd = reinterpret_cast<StripModifierData *>(smd_ptr->data);
220 smd->ui_expand_flag = expand_flag;
221}
222
224 const eStripModifierType type,
226{
227 PanelType *panel_type = MEM_callocN<PanelType>(__func__);
228
229 modifier_type_panel_id(type, panel_type->idname);
230 STRNCPY_UTF8(panel_type->label, "");
232 STRNCPY_UTF8(panel_type->active_property, "is_active");
233 STRNCPY_UTF8(panel_type->context, "strip_modifier");
234
236 panel_type->draw = draw;
237 panel_type->poll = modifier_ui_poll;
238
239 /* Give the panel the special flag that says it was built here and corresponds to a
240 * modifier rather than a #PanelType. */
242 panel_type->reorder = modifier_reorder;
245
246 BLI_addtail(&region_type->paneltypes, panel_type);
247
248 return panel_type;
249}
250
251/* -------------------------------------------------------------------- */
252
254{
255 float4 res;
257 return res;
258}
259
261{
262 return float4(ptr);
263}
264
269
271{
272 *reinterpret_cast<float4 *>(ptr) = pix;
273}
274
276{
277 float4 res;
279 return res;
280}
281
283{
284 return float4(ptr);
285}
286
288{
290}
291
292void store_pixel_raw(float4 pix, float *ptr)
293{
294 *reinterpret_cast<float4 *>(ptr) = pix;
295}
296
302 int mask_input_type,
303 Strip *mask_strip,
304 Mask *mask_id,
305 int timeline_frame,
306 int fra_offset)
307{
308 ImBuf *mask_input = nullptr;
309
310 if (mask_input_type == STRIP_MASK_INPUT_STRIP) {
311 if (mask_strip) {
312 mask_input = seq_render_strip(&context, &state, mask_strip, timeline_frame);
313 }
314 }
315 else if (mask_input_type == STRIP_MASK_INPUT_ID) {
316 /* Note that we do not request mask to be float image: if it is that is
317 * fine, but if it is a byte image then we also just take that without
318 * extra memory allocations or conversions. All modifiers are expected
319 * to handle mask being either type. */
320 mask_input = seq_render_mask(context.depsgraph,
321 context.rectx,
322 context.recty,
323 mask_id,
324 timeline_frame - fra_offset,
325 false);
326 }
327
328 return mask_input;
329}
330
331/* -------------------------------------------------------------------- */
334
336
338{
339#define INIT_TYPE(typeName) (types[eSeqModifierType_##typeName] = &seqModifierType_##typeName)
341 INIT_TYPE(BrightContrast);
342 INIT_TYPE(ColorBalance);
343 INIT_TYPE(Compositor);
345 INIT_TYPE(HueCorrect);
347 INIT_TYPE(SoundEqualizer);
348 INIT_TYPE(Tonemap);
349 INIT_TYPE(WhiteBalance);
350#undef INIT_TYPE
351}
352
357
359{
360 if (type <= 0 || type >= NUM_STRIP_MODIFIER_TYPES) {
361 return nullptr;
362 }
363 return modifiersTypes[type];
364}
365
366StripModifierData *modifier_new(Strip *strip, const char *name, int type)
367{
370
371 smd = static_cast<StripModifierData *>(MEM_callocN(smti->struct_size, "sequence modifier"));
372
373 smd->type = type;
376
377 if (!name || !name[0]) {
379 }
380 else {
381 STRNCPY_UTF8(smd->name, name);
382 }
383
384 BLI_addtail(&strip->modifiers, smd);
385
386 modifier_unique_name(strip, smd);
387
388 if (smti->init_data) {
389 smti->init_data(smd);
390 }
391
392 modifier_set_active(strip, smd);
393
394 return smd;
395}
396
398{
399 if (BLI_findindex(&strip->modifiers, smd) == -1) {
400 return false;
401 }
402
403 BLI_remlink(&strip->modifiers, smd);
404 modifier_free(smd);
405
406 return true;
407}
408
410{
411 StripModifierData *smd, *smd_next;
412
413 for (smd = static_cast<StripModifierData *>(strip->modifiers.first); smd; smd = smd_next) {
414 smd_next = smd->next;
415 modifier_free(smd);
416 }
417
419}
420
422{
424
425 if (smti && smti->free_data) {
426 smti->free_data(smd);
427 }
428
429 MEM_freeN(smd);
430}
431
433{
435
437 smd,
439 '.',
441 sizeof(smd->name));
442}
443
445{
446 return static_cast<StripModifierData *>(
448}
449
450static bool skip_modifier(Scene *scene, const StripModifierData *smd, int timeline_frame)
451{
452 using namespace blender::seq;
453
454 if (smd->mask_strip == nullptr) {
455 return false;
456 }
457 const bool strip_has_ended_skip = smd->mask_input_type == STRIP_MASK_INPUT_STRIP &&
460 scene, smd->mask_strip, timeline_frame);
461 const bool missing_data_skip = !strip_has_valid_data(smd->mask_strip) ||
463
464 return strip_has_ended_skip || missing_data_skip;
465}
466
467void modifier_apply_stack(ModifierApplyContext &context, int timeline_frame)
468{
469 if (context.strip.modifiers.first == nullptr) {
470 return;
471 }
472
473 if (context.strip.flag & SEQ_USE_LINEAR_MODIFIERS) {
474 render_imbuf_from_sequencer_space(context.render_data.scene, context.image);
475 }
476
477 LISTBASE_FOREACH (StripModifierData *, smd, &context.strip.modifiers) {
478 const StripModifierTypeInfo *smti = modifier_type_info_get(smd->type);
479
480 /* could happen if modifier is being removed or not exists in current version of blender */
481 if (!smti) {
482 continue;
483 }
484
485 /* modifier is muted, do nothing */
486 if (smd->flag & STRIP_MODIFIER_FLAG_MUTE) {
487 continue;
488 }
489
490 if (smti->apply && !skip_modifier(context.render_data.scene, smd, timeline_frame)) {
491 int frame_offset;
492 if (smd->mask_time == STRIP_MASK_TIME_RELATIVE) {
493 frame_offset = context.strip.start;
494 }
495 else /* if (smd->mask_time == STRIP_MASK_TIME_ABSOLUTE) */ {
496 frame_offset = smd->mask_id ? ((Mask *)smd->mask_id)->sfra : 0;
497 }
498
499 ImBuf *mask = modifier_render_mask_input(context.render_data,
500 context.render_state,
501 smd->mask_input_type,
502 smd->mask_strip,
503 smd->mask_id,
504 timeline_frame,
505 frame_offset);
506 smti->apply(context, smd, mask);
507 if (mask) {
509 }
510 }
511 }
512
513 if (context.strip.flag & SEQ_USE_LINEAR_MODIFIERS) {
514 seq_imbuf_to_sequencer_space(context.render_data.scene, context.image, false);
515 }
516}
517
519{
520 const StripModifierTypeInfo *smti = modifier_type_info_get(mod_src->type);
521 StripModifierData *mod_new = static_cast<StripModifierData *>(MEM_dupallocN(mod_src));
522
523 if (smti && smti->copy_data) {
524 smti->copy_data(mod_new, mod_src);
525 }
526
527 BLI_addtail(&strip_dst.modifiers, mod_new);
528 BLI_uniquename(&strip_dst.modifiers,
529 mod_new,
530 "Strip Modifier",
531 '.',
534 return mod_new;
535}
536
537void modifier_list_copy(Strip *strip_new, Strip *strip)
538{
540 modifier_copy(*strip_new, smd);
541 }
542}
543
545{
546 return (strip->type != STRIP_TYPE_SOUND_RAM);
547}
548
549bool modifier_move_to_index(Strip *strip, StripModifierData *smd, const int new_index)
550{
551 const int current_index = BLI_findindex(&strip->modifiers, smd);
552 return BLI_listbase_move_index(&strip->modifiers, current_index, new_index);
553}
554
556{
557 /* In debug mode, check for only one active modifier. */
558#ifndef NDEBUG
559 int active_count = 0;
561 if (smd->flag & STRIP_MODIFIER_FLAG_ACTIVE) {
562 active_count++;
563 }
564 }
565 BLI_assert(ELEM(active_count, 0, 1));
566#endif
567
569 if (smd->flag & STRIP_MODIFIER_FLAG_ACTIVE) {
570 return smd;
571 }
572 }
573
574 return nullptr;
575}
576
578{
579 LISTBASE_FOREACH (StripModifierData *, smd_iter, &strip->modifiers) {
580 smd_iter->flag &= ~STRIP_MODIFIER_FLAG_ACTIVE;
581 }
582
583 if (smd != nullptr) {
584 BLI_assert(BLI_findindex(&strip->modifiers, smd) != -1);
586 }
587}
588
590{
594}
595
596void foreach_strip_modifier_id(Strip *strip, const FunctionRef<void(ID *)> fn)
597{
599 if (smd->mask_id) {
600 fn(reinterpret_cast<ID *>(smd->mask_id));
601 }
602 if (smd->type == eSeqModifierType_Compositor) {
603 auto *modifier_data = reinterpret_cast<SequencerCompositorModifierData *>(smd);
604 if (modifier_data->node_group) {
605 fn(reinterpret_cast<ID *>(modifier_data->node_group));
606 }
607 }
608 }
609}
610
612
613/* -------------------------------------------------------------------- */
616
618{
619 LISTBASE_FOREACH (StripModifierData *, smd, modbase) {
620 const StripModifierTypeInfo *smti = modifier_type_info_get(smd->type);
621
622 if (smti) {
623 BLO_write_struct_by_name(writer, smti->struct_name, smd);
624 if (smti->blend_write) {
625 smti->blend_write(writer, smd);
626 }
627 }
628 else {
630 }
631 }
632}
633
635{
637
639 if (smd->mask_strip) {
640 BLO_read_struct(reader, Strip, &smd->mask_strip);
641 }
642
643 const StripModifierTypeInfo *smti = modifier_type_info_get(smd->type);
644 if (smti && smti->blend_read) {
645 smti->blend_read(reader, smd);
646 }
647 }
648}
649
651
652} // namespace blender::seq
Scene * CTX_data_sequencer_scene(const bContext *C)
@ PANEL_TYPE_INSTANCED
@ PANEL_TYPE_HEADER_EXPAND
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
bool BLI_listbase_move_index(ListBase *listbase, int from, int to) ATTR_NONNULL()
Definition listbase.cc:467
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
MINLINE void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
MINLINE void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
#define STRNCPY_UTF8(dst, src)
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
#define BLI_string_join(...)
unsigned char uchar
#define ELEM(...)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define BLT_I18NCONTEXT_ID_SEQUENCE
#define CTX_DATA_(context, msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
@ UI_PANEL_DATA_EXPAND_ROOT
@ STRIP_MASK_TIME_RELATIVE
eStripModifierType
@ eSeqModifierType_Compositor
@ NUM_STRIP_MODIFIER_TYPES
@ STRIP_TYPE_SOUND_RAM
@ STRIP_MASK_INPUT_ID
@ STRIP_MASK_INPUT_STRIP
@ SEQ_USE_LINEAR_MODIFIERS
@ STRIP_MODIFIER_FLAG_EXPANDED
@ STRIP_MODIFIER_FLAG_MUTE
@ STRIP_MODIFIER_FLAG_ACTIVE
void IMB_freeImBuf(ImBuf *ibuf)
#define C
Definition RandGen.cpp:29
#define UI_UNIT_X
PointerRNA * UI_panel_custom_data_get(const Panel *panel)
void UI_panel_context_pointer_set(Panel *panel, const char *name, PointerRNA *ptr)
@ UI_ITEM_R_EXPAND
#define UI_ITEM_NONE
unsigned long long int uint64_t
int64_t size() const
Definition BLI_set.hh:587
bool add(const Key &key)
Definition BLI_set.hh:248
#define offsetof(t, d)
uint col
#define INIT_TYPE(_id_code)
static char ** types
Definition makesdna.cc:71
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static ulong state[N]
void foreach_strip_modifier_id(Strip *strip, const FunctionRef< void(ID *)> fn)
static void modifier_reorder(bContext *C, Panel *panel, const int new_index)
bool modifier_move_to_index(Strip *strip, StripModifierData *smd, const int new_index)
void store_pixel_raw(float4 pix, uchar *ptr)
void seq_imbuf_to_sequencer_space(const Scene *scene, ImBuf *ibuf, bool make_float)
Definition render.cc:115
StripModifierData * modifier_copy(Strip &strip_dst, StripModifierData *mod_src)
void modifier_type_panel_id(eStripModifierType type, char *r_idname)
bool media_presence_is_missing(Scene *scene, const Strip *strip)
void modifier_persistent_uid_init(const Strip &strip, StripModifierData &smd)
static void set_strip_modifier_expand_flag(const bContext *, Panel *panel, short expand_flag)
void draw_mask_input_type_settings(const bContext *C, uiLayout *layout, PointerRNA *ptr)
static constexpr char STRIP_MODIFIER_TYPE_PANEL_PREFIX[]
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
void modifier_unique_name(Strip *strip, StripModifierData *smd)
static StripModifierTypeInfo * modifiersTypes[NUM_STRIP_MODIFIER_TYPES]
void store_pixel_premul(float4 pix, uchar *ptr)
StripModifierData * modifier_find_by_name(Strip *strip, const char *name)
static ImBuf * modifier_render_mask_input(const RenderData &context, SeqRenderState &state, int mask_input_type, Strip *mask_strip, Mask *mask_id, int timeline_frame, int fra_offset)
int sequence_supports_modifiers(Strip *strip)
MetaStack * meta_stack_active_get(const Editing *ed)
Definition sequencer.cc:454
Strip * select_active_get(const Scene *scene)
bool strip_has_valid_data(const Strip *strip)
void modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
bool time_strip_intersects_frame(const Scene *scene, const Strip *strip, const int timeline_frame)
bool modifier_persistent_uids_are_valid(const Strip &strip)
void modifier_free(StripModifierData *smd)
bool modifier_remove(Strip *strip, StripModifierData *smd)
const StripModifierTypeInfo * modifier_type_info_get(int type)
float4 load_pixel_raw(const uchar *ptr)
void modifier_set_active(Strip *strip, StripModifierData *smd)
static void modifier_panel_header(const bContext *, Panel *panel)
static short get_strip_modifier_expand_flag(const bContext *, Panel *panel)
float4 load_pixel_premul(const uchar *ptr)
StripModifierData * modifier_new(Strip *strip, const char *name, int type)
static bool skip_modifier(Scene *scene, const StripModifierData *smd, int timeline_frame)
void modifier_list_copy(Strip *strip_new, Strip *strip)
void modifier_apply_stack(ModifierApplyContext &context, int timeline_frame)
bool modifier_ui_poll(const bContext *C, PanelType *)
void render_imbuf_from_sequencer_space(const Scene *scene, ImBuf *ibuf)
Definition render.cc:167
void(*)(const bContext *, Panel *) PanelDrawFn
Definition modifier.hh:70
ImBuf * seq_render_mask(Depsgraph *depsgraph, int width, int height, const Mask *mask, float frame_index, bool make_float)
Definition render.cc:1297
static bool modifier_has_persistent_uid(const Strip &strip, int uid)
static void modifier_types_init(StripModifierTypeInfo *types[])
ImBuf * seq_render_strip(const RenderData *context, SeqRenderState *state, Strip *strip, float timeline_frame)
Definition render.cc:1791
PanelType * modifier_panel_register(ARegionType *region_type, const eStripModifierType type, PanelDrawFn draw)
void modifier_blend_write(BlendWriter *writer, ListBase *modbase)
StripModifierData * modifier_get_active(const Strip *strip)
VecBase< float, 4 > float4
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
#define hash
Definition noise_c.cc:154
const char * name
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
int RNA_struct_ui_icon(const StructRNA *type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
ListBase paneltypes
Definition DNA_ID.h:414
void * first
void(* reorder)(bContext *C, Panel *pa, int new_index)
void(* set_list_data_expand_flag)(const bContext *C, Panel *pa, short expand_flag)
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char context[BKE_ST_MAXNAME]
char translation_context[BKE_ST_MAXNAME]
char active_property[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
short(* get_list_data_expand_flag)(const bContext *C, Panel *pa)
void(* draw_header)(const bContext *C, Panel *panel)
struct uiLayout * layout
void * data
Definition RNA_types.hh:53
struct StripModifierData * next
struct Strip * mask_strip
ListBase modifiers
void(* free_data)(StripModifierData *smd)
void(* init_data)(StripModifierData *smd)
void(* copy_data)(StripModifierData *smd, StripModifierData *target)
void(* blend_read)(BlendDataReader *reader, StripModifierData *smd)
void(* blend_write)(BlendWriter *writer, const StripModifierData *smd)
void(* apply)(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
void alignment_set(blender::ui::LayoutAlign alignment)
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
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)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
wmOperatorStatus WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, blender::wm::OpCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_free(PointerRNA *ptr)