R8: finish app/ pure C ABI migration (P3-P9) and make OTIO required
- app/ no longer includes engine C++ headers nor holds engine C++ types: engine access goes through the oakengine C ABI plus C++ wrappers (oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types (tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes, subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp) - engine: new C ABI functions for block/track/clip/transition navigation and predicates, links, caches, waveform/playback, disk folder, sequence_track_list, node_free, footage_is_valid, block_get_track, get_brush; loadotio/saveotio ported to the current engine API - OTIO is now a required dependency: CI and CD build it on every platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps include requirement silently disabled OTIO everywhere), runtime libraries are bundled into packages and copied next to macOS binaries (oak_copy_otio_runtime) - fix ProjectViewModel drag&drop mime read/write size mismatch (segfault) - unify color label naming (k_olive -> "Oak") in the app-side mirror - docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh) - gtest suite: 1925 passed, 0 failed
This commit is contained in:
@@ -21,8 +21,10 @@
|
||||
|
||||
#include "razor.h"
|
||||
|
||||
#include "oakengine/node.h"
|
||||
#include "oakengine/timeline.h"
|
||||
#include "widget/timelinewidget/timelinewidget.h"
|
||||
#include "widget/timelinewidget/trackhandle.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -47,7 +49,7 @@ void RazorTool::mouse_move(TimelineViewMouseEvent *event)
|
||||
}
|
||||
|
||||
// Split at the current cursor track
|
||||
Track::Reference split_track = event->get_track();
|
||||
TrackReference split_track = event->get_track();
|
||||
|
||||
if (!split_tracks_.contains(split_track)) {
|
||||
split_tracks_.append(split_track);
|
||||
@@ -61,29 +63,42 @@ void RazorTool::mouse_release(TimelineViewMouseEvent *event)
|
||||
// Always split at the same time
|
||||
Rational split_time = drag_start_.get_frame();
|
||||
|
||||
QVector<Block *> blocks_to_split;
|
||||
QVector<OakEngineBlock *> blocks_to_split;
|
||||
|
||||
foreach (const Track::Reference &track_ref, split_tracks_) {
|
||||
Track *track = parent()->get_track_from_reference(track_ref);
|
||||
foreach (const TrackReference &track_ref, split_tracks_) {
|
||||
OakEngineTrack *track = parent()->get_track_from_reference(track_ref);
|
||||
|
||||
if (track == nullptr || track->is_locked()) {
|
||||
if (track == nullptr || track_is_locked(track)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Block *block_at_time = track->nearest_block_before(split_time);
|
||||
OakEngineBlock *block_at_time = oakengine_track_nearest_block_before(
|
||||
track,
|
||||
Timecode::time_to_timestamp(split_time, parent()->timebase(),
|
||||
Timecode::k_round));
|
||||
|
||||
// Ensure there's a valid block here
|
||||
ClipBlock *clip_at_time;
|
||||
if (block_at_time && block_at_time->out() != split_time &&
|
||||
(clip_at_time = dynamic_cast<ClipBlock *>(block_at_time)) &&
|
||||
!blocks_to_split.contains(block_at_time)) {
|
||||
blocks_to_split.append(block_at_time);
|
||||
if (block_at_time &&
|
||||
oakengine_node_is_clip(
|
||||
reinterpret_cast<OakEngineNode *>(block_at_time))) {
|
||||
int out_num = 0, out_den = 1;
|
||||
oakengine_block_get_out_rational(
|
||||
reinterpret_cast<const OakEngineNode *>(block_at_time),
|
||||
&out_num, &out_den);
|
||||
if (Rational(out_num, out_den) != split_time &&
|
||||
!blocks_to_split.contains(block_at_time)) {
|
||||
blocks_to_split.append(block_at_time);
|
||||
|
||||
// Add links if no alt is held
|
||||
if (!(event->get_modifiers() & Qt::AltModifier)) {
|
||||
foreach (Block *link, clip_at_time->block_links()) {
|
||||
if (!blocks_to_split.contains(link)) {
|
||||
blocks_to_split.append(link);
|
||||
// Add links if no alt is held
|
||||
if (!(event->get_modifiers() & Qt::AltModifier)) {
|
||||
const int link_count =
|
||||
oakengine_block_link_count(block_at_time);
|
||||
for (int i = 0; i < link_count; i++) {
|
||||
OakEngineBlock *link =
|
||||
oakengine_block_link_at(block_at_time, i);
|
||||
if (!blocks_to_split.contains(link)) {
|
||||
blocks_to_split.append(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,13 +113,13 @@ void RazorTool::mouse_release(TimelineViewMouseEvent *event)
|
||||
// app-side BlockSplitPreservingLinksCommand push.
|
||||
QVector<OakEngineClip *> clips;
|
||||
clips.reserve(blocks_to_split.size());
|
||||
foreach (Block *b, blocks_to_split) {
|
||||
if (ClipBlock *clip = dynamic_cast<ClipBlock *>(b)) {
|
||||
clips.append(reinterpret_cast<OakEngineClip *>(clip));
|
||||
foreach (OakEngineBlock *b, blocks_to_split) {
|
||||
if (oakengine_node_is_clip(reinterpret_cast<OakEngineNode *>(b))) {
|
||||
clips.append(reinterpret_cast<OakEngineClip *>(b));
|
||||
}
|
||||
}
|
||||
oakengine_sequence_split_clips(
|
||||
reinterpret_cast<OakEngineSequence *>(parent()->sequence()),
|
||||
parent()->sequence(),
|
||||
clips.data(), clips.size(),
|
||||
Timecode::time_to_timestamp(split_time, parent()->timebase(),
|
||||
Timecode::k_round));
|
||||
|
||||
Reference in New Issue
Block a user