77#include " Runtime/MovieScene/Public/MovieSceneNameableTrack.h"
88#include " Runtime/LevelSequence/Public/LevelSequence.h"
99
10+ #if WITH_EDITOR
11+ #include " Editor/Sequencer/Public/ISequencer.h"
12+ #include " Editor/Sequencer/Public/ISequencerModule.h"
13+ #endif
14+
15+ static void movie_update (UMovieSceneSequence *movie) {
16+ #if WITH_EDITOR
17+ ISequencerModule& sequencer_module = FModuleManager::LoadModuleChecked<ISequencerModule>(" Sequencer" );
18+ FSequencerInitParams sequencer_params;
19+ sequencer_params.RootSequence = movie;
20+ TSharedRef<ISequencer> sequencer = sequencer_module.CreateSequencer (sequencer_params);
21+ sequencer->NotifyMovieSceneDataChanged (EMovieSceneDataChangeType::Unknown);
22+ #endif
23+ }
24+
1025PyObject *py_ue_sequencer_possessable_tracks (ue_PyUObject *self, PyObject * args) {
1126
1227 ue_py_check (self);
@@ -73,15 +88,92 @@ PyObject *py_ue_sequencer_find_possessable(ue_PyUObject *self, PyObject * args)
7388 UObject *u_obj = seq->FindPossessableObject (f_guid, seq);
7489 if (!u_obj)
7590 return PyErr_Format (PyExc_Exception, " unable to find uobject with GUID \" %s\" " , guid);
76-
77- PyObject *ret = (PyObject *) ue_get_python_wrapper (u_obj);
91+
92+ PyObject *ret = (PyObject *)ue_get_python_wrapper (u_obj);
7893 if (!ret)
7994 return PyErr_Format (PyExc_Exception, " PyUObject is in invalid state" );
8095
8196 Py_INCREF (ret);
8297 return ret;
8398}
8499
100+ PyObject *py_ue_sequencer_add_possessable (ue_PyUObject *self, PyObject * args) {
101+
102+ ue_py_check (self);
103+
104+ PyObject *py_obj;
105+ if (!PyArg_ParseTuple (args, " O:sequencer_add_possessable" , &py_obj)) {
106+ return NULL ;
107+ }
108+
109+ if (!self->ue_object ->IsA <ULevelSequence>())
110+ return PyErr_Format (PyExc_Exception, " uobject is not a LevelSequence" );
111+
112+ ue_PyUObject *py_ue_obj = ue_is_pyuobject (py_obj);
113+ if (!py_ue_obj)
114+ return PyErr_Format (PyExc_Exception, " argument is not a uobject" );
115+
116+ ULevelSequence *seq = (ULevelSequence *)self->ue_object ;
117+
118+ FString name = py_ue_obj->ue_object ->GetName ();
119+ AActor *actor = Cast<AActor>(py_ue_obj->ue_object );
120+ if (actor)
121+ name = actor->GetActorLabel ();
122+
123+ FGuid new_guid = seq->MovieScene ->AddPossessable (name, py_ue_obj->ue_object ->GetClass ());
124+ if (!new_guid.IsValid ()) {
125+ return PyErr_Format (PyExc_Exception, " unable to possess object" );
126+ }
127+
128+ seq->BindPossessableObject (new_guid, *(py_ue_obj->ue_object ), py_ue_obj->ue_object ->GetWorld ());
129+
130+ movie_update (seq);
131+
132+ return PyUnicode_FromString (TCHAR_TO_UTF8 (*new_guid.ToString ()));
133+ }
134+
135+ PyObject *py_ue_sequencer_add_actor (ue_PyUObject *self, PyObject * args) {
136+
137+ ue_py_check (self);
138+
139+ PyObject *py_obj;
140+ if (!PyArg_ParseTuple (args, " O:sequencer_add_actor" , &py_obj)) {
141+ return NULL ;
142+ }
143+
144+ if (!self->ue_object ->IsA <ULevelSequence>())
145+ return PyErr_Format (PyExc_Exception, " uobject is not a LevelSequence" );
146+
147+ ue_PyUObject *py_ue_obj = ue_is_pyuobject (py_obj);
148+ if (!py_ue_obj)
149+ return PyErr_Format (PyExc_Exception, " argument is not a uobject" );
150+
151+ if (!py_ue_obj->ue_object ->IsA <AActor>())
152+ return PyErr_Format (PyExc_Exception, " argument is not an actor" );
153+
154+ ULevelSequence *seq = (ULevelSequence *)self->ue_object ;
155+
156+ TArray<TWeakObjectPtr<AActor>> actors;
157+ actors.Add ((AActor *)py_ue_obj->ue_object );
158+
159+ ISequencerModule& sequencer_module = FModuleManager::LoadModuleChecked<ISequencerModule>(" Sequencer" );
160+ FSequencerInitParams sequencer_params;
161+ sequencer_params.RootSequence = seq;
162+ sequencer_params.bEditWithinLevelEditor = false ;
163+ sequencer_params.ToolkitHost = nullptr ;
164+
165+ FSequencerViewParams view_params;
166+ view_params.InitialScrubPosition = 0 ;
167+ sequencer_params.ViewParams = view_params;
168+
169+ TSharedRef<ISequencer> sequencer = sequencer_module.CreateSequencer (sequencer_params);
170+
171+ sequencer->AddActors (actors);
172+
173+ Py_INCREF (Py_None);
174+ return Py_None;
175+ }
176+
85177PyObject *py_ue_sequencer_master_tracks (ue_PyUObject *self, PyObject * args) {
86178
87179 ue_py_check (self);
@@ -119,19 +211,9 @@ PyObject *py_ue_sequencer_possessables(ue_PyUObject *self, PyObject * args) {
119211 UMovieScene *scene = seq->GetMovieScene ();
120212
121213 PyObject *py_possessables = PyList_New (0 );
122- for (int32 i = 0 ; i < scene->GetPossessableCount ();i++) {
214+ for (int32 i = 0 ; i < scene->GetPossessableCount (); i++) {
123215 FMovieScenePossessable possessable = scene->GetPossessable (i);
124- PyObject *py_possessable = PyTuple_New (3 );
125- PyTuple_SetItem (py_possessable, 0 , PyUnicode_FromString (TCHAR_TO_UTF8 (*possessable.GetGuid ().ToString ())));
126- PyTuple_SetItem (py_possessable, 1 , PyUnicode_FromString (TCHAR_TO_UTF8 (*possessable.GetName ())));
127- UClass *u_class = (UClass *)possessable.GetPossessedObjectClass ();
128- ue_PyUObject *ret = ue_get_python_wrapper (u_class);
129- if (!ret) {
130- // here we will leak memory :(
131- Py_DECREF (py_possessables);
132- return PyErr_Format (PyExc_Exception, " PyUObject is in invalid state" );
133- }
134- PyTuple_SetItem (py_possessable, 2 , (PyObject *)ret);
216+ PyObject *py_possessable = py_ue_new_uscriptstruct (possessable.StaticStruct (), (uint8 *)&possessable);
135217 PyList_Append (py_possessables, py_possessable);
136218 }
137219
@@ -217,6 +299,37 @@ PyObject *py_ue_sequencer_track_sections(ue_PyUObject *self, PyObject * args) {
217299 return py_sections;
218300}
219301
302+ PyObject *py_ue_sequencer_track_add_section (ue_PyUObject *self, PyObject * args) {
303+
304+ ue_py_check (self);
305+
306+ PyObject *obj;
307+ if (!PyArg_ParseTuple (args, " O:sequencer_track_add_section" , &obj)) {
308+ return NULL ;
309+ }
310+
311+ if (!self->ue_object ->IsA <UMovieSceneTrack>())
312+ return PyErr_Format (PyExc_Exception, " uobject is not a UMovieSceneTrack" );
313+
314+ UMovieSceneTrack *track = (UMovieSceneTrack *)self->ue_object ;
315+
316+ ue_PyUObject *py_obj = ue_is_pyuobject (obj);
317+ if (!py_obj)
318+ return PyErr_Format (PyExc_Exception, " argument is not a uobject" );
319+
320+ if (!py_obj->ue_object ->IsA <UMovieSceneSection>())
321+ return PyErr_Format (PyExc_Exception, " uobject is not a UMovieSceneSection" );
322+
323+ UMovieSceneSection *new_section = (UMovieSceneSection *)py_obj->ue_object ;
324+
325+ track->AddSection (*new_section);
326+
327+ movie_update ((UMovieSceneSequence *)track->GetOuter ());
328+
329+ Py_INCREF (Py_None);
330+ return Py_None;
331+ }
332+
220333PyObject *py_ue_sequencer_add_master_track (ue_PyUObject *self, PyObject * args) {
221334
222335 ue_py_check (self);
@@ -252,6 +365,54 @@ PyObject *py_ue_sequencer_add_master_track(ue_PyUObject *self, PyObject * args)
252365 if (!ret)
253366 return PyErr_Format (PyExc_Exception, " PyUObject is in invalid state" );
254367
368+ movie_update (seq);
369+
370+ Py_INCREF (ret);
371+ return ret;
372+ }
373+
374+ PyObject *py_ue_sequencer_add_track (ue_PyUObject *self, PyObject * args) {
375+
376+ ue_py_check (self);
377+
378+ PyObject *obj;
379+ char *guid;
380+ if (!PyArg_ParseTuple (args, " Os:sequencer_add_track" , &obj, &guid)) {
381+ return NULL ;
382+ }
383+
384+ if (!self->ue_object ->IsA <ULevelSequence>())
385+ return PyErr_Format (PyExc_Exception, " uobject is not a LevelSequence" );
386+
387+ ULevelSequence *seq = (ULevelSequence *)self->ue_object ;
388+ UMovieScene *scene = seq->GetMovieScene ();
389+
390+ ue_PyUObject *py_obj = ue_is_pyuobject (obj);
391+ if (!py_obj)
392+ return PyErr_Format (PyExc_Exception, " argument is not a uobject" );
393+
394+ if (!py_obj->ue_object ->IsA <UClass>())
395+ return PyErr_Format (PyExc_Exception, " uobject is not a UClass" );
396+
397+ UClass *u_class = (UClass *)py_obj->ue_object ;
398+
399+ if (!u_class->IsChildOf <UMovieSceneTrack>())
400+ return PyErr_Format (PyExc_Exception, " uobject is not a UMovieSceneTrack class" );
401+
402+ FGuid f_guid;
403+ if (!FGuid::Parse (FString (guid), f_guid)) {
404+ return PyErr_Format (PyExc_Exception, " invalid guid" );
405+ }
406+ UMovieSceneTrack *track = scene->AddTrack (u_class, f_guid);
407+ if (!track)
408+ return PyErr_Format (PyExc_Exception, " unable to create new track" );
409+
410+ PyObject *ret = (PyObject *)ue_get_python_wrapper (track);
411+ if (!ret)
412+ return PyErr_Format (PyExc_Exception, " PyUObject is in invalid state" );
413+
414+ movie_update (seq);
415+
255416 Py_INCREF (ret);
256417 return ret;
257418}
@@ -275,6 +436,8 @@ PyObject *py_ue_sequencer_set_display_name(ue_PyUObject *self, PyObject * args)
275436 return PyErr_Format (PyExc_Exception, " the uobject does not expose the SetDisplayName() method" );
276437 }
277438
439+ // movie_update((UMovieSceneSequence *)track->GetOuter());
440+
278441 Py_INCREF (Py_None);
279442 return Py_None;
280443}
@@ -288,7 +451,7 @@ PyObject *py_ue_sequencer_get_display_name(ue_PyUObject *self, PyObject * args)
288451 FText name = track->GetDefaultDisplayName ();
289452 return PyUnicode_FromString (TCHAR_TO_UTF8 (*name.ToString ()));
290453 }
291-
454+
292455 return PyErr_Format (PyExc_Exception, " the uobject does not expose the GetDefaultDisplayName() method" );
293456}
294457#endif
0 commit comments