From b1b7d58e9dfac1e44efb04879daddcb5e37a9366 Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Mon, 23 Nov 2020 21:25:10 +0000 Subject: [PATCH 01/14] transition: Add transparency support to transitions Added ShaderJobEvent to CrossDissolveTransition which sets alpha as required. app/node/block/transition/crossdissolve/crossdissolvetransition.cpp app/node/block/transition/crossdissolve/crossdissolvetransition.h --- .../transition/crossdissolve/crossdissolvetransition.cpp | 5 +++++ .../block/transition/crossdissolve/crossdissolvetransition.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp b/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp index 9ce1e3607..c37ac9715 100644 --- a/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp +++ b/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp @@ -59,6 +59,11 @@ ShaderCode CrossDissolveTransition::GetShaderCode(const QString &shader_id) cons return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/crossdissolve.frag"), QString()); } +void CrossDissolveTransition::ShaderJobEvent(NodeValueDatabase &value, ShaderJob &job) const +{ + job.SetAlphaChannelRequired(true); +} + void CrossDissolveTransition::SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const { for (int i=0; isample_count(); i++) { diff --git a/app/node/block/transition/crossdissolve/crossdissolvetransition.h b/app/node/block/transition/crossdissolve/crossdissolvetransition.h index f21d3fd7e..6b93042bf 100644 --- a/app/node/block/transition/crossdissolve/crossdissolvetransition.h +++ b/app/node/block/transition/crossdissolve/crossdissolvetransition.h @@ -43,6 +43,8 @@ public: virtual ShaderCode GetShaderCode(const QString& shader_id) const override; protected: + virtual void ShaderJobEvent(NodeValueDatabase& value, ShaderJob& job) const override; + virtual void SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const override; }; From d84a2721fb788b7c0b84f314bd441910b8f59b51 Mon Sep 17 00:00:00 2001 From: Alexandre Prokoudine Date: Tue, 24 Nov 2020 01:51:55 +0300 Subject: [PATCH 02/14] Update Russian translation --- app/ts/ru_RU.ts | 1566 +++++++++++++++++++++++++---------------------- 1 file changed, 840 insertions(+), 726 deletions(-) diff --git a/app/ts/ru_RU.ts b/app/ts/ru_RU.ts index a276780c7..c57675928 100644 --- a/app/ts/ru_RU.ts +++ b/app/ts/ru_RU.ts @@ -6,61 +6,61 @@ %1 Hz - + %1 Гц Mono - Моно + Моно Stereo - Стерео + Стерео 2.1 - 144p {2.1?} + 2.1 5.1 - 144p {5.1?} + 5.1 7.1 - 144p {7.1?} + 7.1 Unknown (0x%1) - + Неизвестно (0x%1) Config - + Error loading settings - + Ошибка при загрузке настроек - + Failed to load application settings. This session will use defaults. %1 - + Error saving settings - + Ошибка при сохранении настроек - - Failed to save application settings. The application may lack write permissions to this location. + + Failed to save application settings. The application may lack write permissions for this location. @@ -69,17 +69,17 @@ %1 FPS - + %1 к/с %1 Hz - + %1 Гц Filename: %1 - + Имя файла: %1 @@ -92,7 +92,7 @@ Don't ask me again - + Больше не спрашивать @@ -102,17 +102,17 @@ No sequence is currently open. Would you like to create one? - + Нет открытых последовательностей. Создать новую? Automatically Detect Parameters From Footage - + Автоматически определить Set Parameters Manually - + Указать вручную @@ -120,7 +120,7 @@ Move Item - + Переместить объект @@ -128,20 +128,20 @@ Error pasting nodes - + Ошибка при вставке нод Failed to paste nodes: %1 - + Не удалось вставить ноды: %1 NodeFactory - + None - + Нет @@ -149,7 +149,7 @@ %1... - + %1... @@ -157,32 +157,32 @@ Save Preset - + Сохранить профиль Set preset name: - + Название профиля: Invalid preset name - + Некорректное название профиля You must enter a preset name - + Введите название профиля Preset exists - + Профиль с таким названием уже существует A preset with this name already exists. Would you like to replace it? - + Уже есть профиль с таким названием. Заменить его? @@ -214,9 +214,9 @@ Sequence - + %1 FPS - + %1 к/с @@ -224,22 +224,22 @@ %1: Audio - %2 Channels, %3Hz - + %1: Звук - %2 каналов, %3 Гц %1: Unknown - + %1: неизвестно %1: Image - %2x%3 - + %1: Изображение - %2x%3 %1: Video - %2x%3 - + %1: Видео - %2x%3 @@ -259,32 +259,32 @@ Length: %4 Empty - + Пустота Bars - Испытательная таблица + Испытательная таблица Solid - + Заливка Title - Титры + Титры Tone - Звуковой сигнал + Звуковой сигнал Unknown - + Неизвестно @@ -312,12 +312,12 @@ Length: %4 Unknown (0x%1) - + Неизвестно (0x%1) %1 FPS - + %1 к/с @@ -353,39 +353,39 @@ Length: %4 main - + Show this help text - + Показать этот справочный текст - + Show application version - + Показать версию приложения - + Start in full-screen mode - + Запуститься в полноэкранном режиме - + Export only (No GUI) - + Только эксперт (без графического интерфейса) + + + + Override language with file + Запустить с локализацией из заданного файла - Override language with file - - - - qm-file - + файл qm - + Project to open on startup - + Какой проект открыть при запуске @@ -393,17 +393,17 @@ Length: %4 About %1 - + О программе %1 Olive is a non-linear video editor. This software is free and protected by the GNU GPL. - Olive — нелинейный видеоредактор. Эта программа является свободной и защищена GNU GPL. + Olive — нелинейный видеоредактор. Эта программа является свободной и защищена GNU GPL. Olive Team is obliged to inform users that Olive source code is available for download from its website. - Исходный код Olive доступен для скачивания на сайте программы. + Исходный код Olive доступен для скачивания на сайте программы. @@ -411,25 +411,7 @@ Length: %4 Search for action... - Найти действие… - - - - olive::AudioInput - - - Audio Input - - - - - Audio - Звук - - - - Import an audio footage stream. - + Найти действие… @@ -437,7 +419,7 @@ Length: %4 Audio Monitor - + Монитор звука @@ -445,7 +427,7 @@ Length: %4 Length - Длительность + Длительность @@ -455,12 +437,12 @@ Length: %4 Enabled - + Включено Speed - + Скорость @@ -468,47 +450,47 @@ Length: %4 Blur - + Размытие Blurs an image. - + Размывает изображение. Input - + Вход Method - + Способ Box - + По рамке Gaussian - + Гауссово Radius - + Радиус Horizontal - + По горизонтали Vertical - + По вертикали @@ -521,7 +503,7 @@ Length: %4 Clip - + Клип @@ -531,7 +513,7 @@ Length: %4 Buffer - + Буфер @@ -539,7 +521,7 @@ Length: %4 Select Color - + Выбрать цвет @@ -547,37 +529,37 @@ Length: %4 Color Management - + Управление цветом Input: - + Вход: Color Space: - + Пространство: Display: - + Дисплей: View: - + Вид: Look: - + Обработка: (None) - + (нет) @@ -585,17 +567,17 @@ Length: %4 Red - + Красный Green - + Зеленый Blue - + Синий @@ -603,12 +585,12 @@ Length: %4 Preview - + Предпросмотр Input - + Вход @@ -618,7 +600,7 @@ Length: %4 Display - + Дисплей @@ -664,7 +646,7 @@ Length: %4 No Active Project - + Нет активного проекта @@ -685,7 +667,7 @@ Length: %4 New Folder - Новая папка + Новая папка @@ -772,7 +754,7 @@ Length: %4 Save Project - Сохранить проект + Сохранить проект @@ -805,27 +787,27 @@ Make sure a sequence is loaded and it has a connected Viewer node. Save Project As - + Сохранить проект как Load Project - + Загрузка проекта Label Node - + Метка ноды Set node label - + Указать метку ноды Sequence %1 - + Последовательность %1 @@ -840,32 +822,32 @@ Make sure a sequence is loaded and it has a connected Viewer node. Unsaved Changes - + Несохраненные изменения The project '%1' has unsaved changes. Would you like to save them? - + В проекте '%1' остались несохраненные изменения. Сохранить их? Save - + Сохранить Save All - + Сохранить все Don't Save - + Не сохранять Don't Save All - + Не сохранять все @@ -880,7 +862,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Open Project - Открыть проект + Открыть проект @@ -888,7 +870,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Olive - + Olive @@ -903,17 +885,17 @@ Make sure a sequence is loaded and it has a connected Viewer node. Crash Report: - + Отчет о падении: Send Error Report - + Отправить отчет Don't Send - + Не отправлять @@ -941,17 +923,60 @@ Make sure a sequence is loaded and it has a connected Viewer node. + + olive::CropDistortNode + + + Texture + Текстура + + + + Left + Слева + + + + Top + Сверху + + + + Right + Справа + + + + Bottom + Снизу + + + + Feather + Растушевка + + + + Crop + Обрезка + + + + Crop the edges of an image. + Обрезать края кадра + + olive::CrossDissolveTransition Cross Dissolve - + Наплыв Smoothly transition between two clips. - + Плавный переход между двумя клипами. @@ -959,7 +984,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Curve Editor - + Редактор кривых @@ -975,17 +1000,17 @@ Make sure a sequence is loaded and it has a connected Viewer node. Linear - Линейный + Линейный Bezier - Безье + Безье Hold - Константа + Константа @@ -1006,44 +1031,44 @@ Make sure a sequence is loaded and it has a connected Viewer node. Disk Cache: %1 - + Дисковый кэш: %1 Disk Cache Settings - + Параметры кэша на диске Maximum Disk Cache: - + Макс. кэш на диске: %1 GB - + %1 Гбайт Clear Disk Cache - + Очистить дисковый кэш Automatically clear disk cache on close - + Автоматически стирать при закрытии Are you sure you want to clear the disk cache in '%1'? - + Вы действительно хотите стереть дисковый кэш в '%1'? Disk Cache Cleared - + Дисковый кэш очищен @@ -1053,7 +1078,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Disk Cache Partially Cleared - + Дисковый кэш частично очищен @@ -1062,7 +1087,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Disk Cache Error - + Ошибка дискового кэша @@ -1072,7 +1097,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Disk Cache - + Дисковый кэш @@ -1103,27 +1128,27 @@ Make sure a sequence is loaded and it has a connected Viewer node. Advanced - Дополнительно + Дополнительные параметры Pixel - + Пиксели Pixel Format: - Формат пикселей: + Формат: Performance - + Производительность Threads: - Потоков: + Потоков: @@ -1131,22 +1156,22 @@ Make sure a sequence is loaded and it has a connected Viewer node. Codec: - Кодек: + Кодек: Sample Rate: - Частота дискретизации: + Частота дискр.: Channel Layout: - + Схема каналов: Format: - Формат: + Формат: @@ -1154,62 +1179,62 @@ Make sure a sequence is loaded and it has a connected Viewer node. DNxHD - + DNxHD H.264 - + H.264 H.265 - + H.265 OpenEXR - + OpenEXR PNG - + PNG ProRes - + ProRes TIFF - + TIFF MP2 - + MP2 MP3 - + MP3 AAC - + AAC PCM (Uncompressed) - + PCM (несжатый) Unknown - + Неизвестно @@ -1217,7 +1242,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Filename: - Имя файла: + Имя файла: @@ -1227,7 +1252,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Preset: - Предстановка: + Профиль: @@ -1247,58 +1272,58 @@ Make sure a sequence is loaded and it has a connected Viewer node. Range: - Диапазон: + Диапазон: Entire Sequence - Вся последовательность + Вся последовательность In to Out - От входа от выхода + От входа от выхода Format: - Формат: + Формат: Export Video - + Экспорт видео Export Audio - + Экспорт звука Video - Видео + Видео Audio - Звук + Звук Export - Экспортировать + Экспортировать Preview - + Предпросмотр Invalid parameters - + Некорректные параметры @@ -1328,7 +1353,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Confirm Overwrite - + Подтвердить перезапись @@ -1338,7 +1363,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Invalid Parameters - + Некорректные параметры @@ -1351,42 +1376,42 @@ Make sure a sequence is loaded and it has a connected Viewer node. DNxHD - + DNxHD Matroska Video - + Matroska MPEG-4 Video - + MPEG-4 OpenEXR - + OpenEXR PNG - + PNG TIFF - + TIFF QuickTime - + QuickTime Unknown - + Неизвестно @@ -1394,17 +1419,17 @@ Make sure a sequence is loaded and it has a connected Viewer node. Exporting "%1" - + Экспортируется "%1" Failed to create encoder - + Не удалось создать кодировщик Failed to open file - + Не удалось открыть файл @@ -1417,77 +1442,77 @@ Make sure a sequence is loaded and it has a connected Viewer node. Basic - + Основные Width: - Ширина: + Ширина: Height: - Высота: + Высота: Maintain Aspect Ratio: - + Сохранить пропорции: Scaling Method: - + Тип масштабирования: Fit - Уместить + Уместить Stretch - + Растянуть Crop - + Обрезать Frame Rate: - Частота кадров: + Частота кадров: Pixel Aspect Ratio: - Соотношение сторон пикселя: + Пропорции пикселя: Interlacing: - Чересстрочность: + Чересстрочность: Quality: - + Качество: Codec - + Кодек Codec: - Кодек: + Кодек: Advanced - Дополнительно + Дополнительно @@ -1495,12 +1520,12 @@ Make sure a sequence is loaded and it has a connected Viewer node. %1 dB - + %1 Дб %1% - + %1% @@ -1508,17 +1533,17 @@ Make sure a sequence is loaded and it has a connected Viewer node. "%1" Properties - Свойства "%1" + Свойства "%1" Name: - Название: + Название: Tracks: - Дорожек: + Дорожек: @@ -1526,22 +1551,22 @@ Make sure a sequence is loaded and it has a connected Viewer node. Footage - + Видеоматериал Filename - + Имя файла Actions - + Действия Browse - Просмотр + Просмотр @@ -1556,15 +1581,15 @@ Make sure a sequence is loaded and it has a connected Viewer node. All Files - Все файлы + Все файлы olive::FootageViewerPanel - + Footage Viewer - + Просмотр видеоматериала @@ -1572,7 +1597,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Gap - + Интервал @@ -1585,17 +1610,17 @@ Make sure a sequence is loaded and it has a connected Viewer node. Target Bit Rate (Mbps): - + Целевая скорость потока (Мбит/с): Maximum Bit Rate (Mbps): - + Макс. скорость потока (Мбит/с): Two-Pass - + В два прохода @@ -1603,12 +1628,12 @@ Make sure a sequence is loaded and it has a connected Viewer node. Target File Size (MB): - Конечный размер файла (Мб): + Целевой размер файла (Мбайт): Two-Pass - + В два прохода @@ -1616,22 +1641,22 @@ Make sure a sequence is loaded and it has a connected Viewer node. Compression Method: - + Способ сжатия: Constant Rate Factor - + Постоянная скорость потока Target Bit Rate - + Целевая скорость потока Target File Size - + Целевой размер файла @@ -1639,7 +1664,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Image Sequence: - + Последовательность изображений: @@ -1647,7 +1672,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. None (Progressive) - Нет (прогрессивно) + Нет (прогрессивно) @@ -1665,32 +1690,32 @@ Make sure a sequence is loaded and it has a connected Viewer node. Keyframe Properties - + Свойства ключевого кадра In: - + Вход: Out: - + Выход: Linear - Линейный + Линейный Hold - Константа + Константа Bezier - Безье + Безье @@ -1698,38 +1723,38 @@ Make sure a sequence is loaded and it has a connected Viewer node. Linear - Линейный + Линейный Bezier - Безье + Безье Hold - Константа + Константа P&roperties - + С&войства olive::LoadOTIOTask - + Failed to load OpenTimelineIO from file "%1" - + Unknown OpenTimelineIO root element - + Failed to load clip @@ -1739,242 +1764,242 @@ Make sure a sequence is loaded and it has a connected Viewer node. &Save '%1' - + Со&хранить '%1' Save '%1' &As - + Сохранить '%1' к&ак Close '%1' - + Закрыть '%1' Close All Except '%1' - + Закрыть все кроме '%1' &Save Project - Со&хранить проект + &Сохранить проект Save Project &As - Сохранить проект &как + Сохранить проект &как Close Project - + Закрыть проект Close All Except Current Project - + Закрыть все проекты кроме текущего (None) - + (нет) &File - &Файл + &Файл &New - &Создать + &Создать &Open Project - &Открыть проект + &Открыть проект Open &Recent - + Открыть из &недавнего &Clear Recent List - + О&чистить список недавних Sa&ve All Projects - + Сохра&нить все проекты &Import... - &Импортировать… + &Импортировать… &Export - + &Экспортировать &Media... - + &Медиаданные… &Project Properties... - + С&войства проекта… Close All Projects - + Закрыть все проекты E&xit - В&ыход + В&ыход &Edit - + &Правка Insert - + Вставить Overwrite - + Переписать Select &All - Выд&елить всё + Выд&елить всё Deselect All - Снять выделение + Снять выделение Ripple to In Point - Сдвиг до точки входа + Сдвиг до точки входа Ripple to Out Point - Сдвиг до точки выхода + Сдвиг до точки выхода Edit to In Point - Правка до точки входа + Правка до точки входа Edit to Out Point - Правка до точки выхода + Правка до точки выхода Delete In/Out Point - Удалить точку входа/выхода + Удалить точку входа/выхода Ripple Delete In/Out Point - Удалить со сдвигом точку входа/выхода + Удалить со сдвигом точку входа/выхода Set/Edit Marker - Установить/Изменить маркер + Установить/Изменить маркер &View - &Вид + &Вид Zoom In - Приблизить + Приблизить Zoom Out - Отдалить + Отдалить Increase Track Height - Увеличить высоту дорожки + Увеличить высоту дорожки Decrease Track Height - Уменьшить высоту дорожки + Уменьшить высоту дорожки Toggle Show All - Показывать весь проект + Показывать весь проект Full Screen - Полноэкранный режим + Полноэкранный режим Full Screen Viewer - Просмотр в полноэкранном режиме + Просмотр в полноэкранном режиме &Playback - Вос&произведение + Вос&произведение Go to Start - К началу + К началу Previous Frame - К предыдущему кадру + К предыдущему кадру Play/Pause - Воспроизведение/Пауза + Воспроизведение/Пауза Play In to Out - Проиграть от входа до выхода + Проиграть от входа до выхода Next Frame - К следующему кадру + К следующему кадру Go to End - В конец + В конец @@ -1989,147 +2014,152 @@ Make sure a sequence is loaded and it has a connected Viewer node. Go to In Point - К точке входа + К точке входа Go to Out Point - К точке выхода + К точке выхода Shuttle Left - Уменьшить скорость + Уменьшить скорость Shuttle Stop - Пауза + Пауза Shuttle Right - Увеличить скорость + Увеличить скорость Loop - Петля + Петля &Sequence - П&оследовательность + П&оследовательность Cache Entire Sequence - + Закэшировать всю последовательность Cache Sequence In/Out - + Закэшировать вход/выход последовательности + + + + &Window + &Окно Maximize Panel - Развернуть панель + Развернуть панель Lock Panels - Закрепить панели + Закрепить панели Reset to Default Layout - Вернуть исходный вид панелей + Вернуть исходный вид панелей &Tools - &Инструменты + &Инструменты Pointer Tool - Указатель + Указатель Edit Tool - Выделение + Выделение Ripple Tool - Монтаж со сдвигом + Монтаж со сдвигом Rolling Tool - + Монтаж с совмещением Razor Tool - Подрезка + Подрезка Slip Tool - Прокрутка с совмещением + Прокрутка с совмещением Slide Tool - Прокрутка + Прокрутка Hand Tool - Навигация + Навигация Zoom Tool - + Масштаб Transition Tool - Переход + Переход Enable Snapping - Включить прилипание + Включить прилипание Preferences - Параметры + Параметры &Help - &Справка + &Справка A&ction Search - &Найти команду + &Найти команду Send &Feedback... - + &Дать обратную связь… &About... - &О программе… + &О программе… @@ -2137,11 +2167,11 @@ Make sure a sequence is loaded and it has a connected Viewer node. Welcome to %1 %2 - Приветствуем в %1 %2 + Приветствуем в %1 %2 - Running %1 background tasks + Running %1 background task(s) @@ -2150,7 +2180,7 @@ Make sure a sequence is loaded and it has a connected Viewer node. Driver Warning - + Предупреждение драйвера @@ -2163,42 +2193,42 @@ This driver is known to have stability and performance issues with Olive. It is olive::ManagedDisplayWidget - + Color Space - + Цветовое пространство - + No color manager connected - + Display - + Дисплей - + View - Вид + Вид - + Look - + Представление - + (None) - + (нет) - + OpenColorIO Error - + Ошибка OpenColorIO - + Failed to set color configuration: %1 @@ -2208,7 +2238,7 @@ This driver is known to have stability and performance issues with Olive. It is Display - + Дисплей @@ -2221,98 +2251,104 @@ This driver is known to have stability and performance issues with Olive. It is Math - + Математика Perform a mathematical operation between two values. - + Выполнить математическую операцию с двумя значениями Method - + Способ Value - + Значение Add - Добавить + Сложение Subtract - + Вычитание Multiply - + Умножение Divide - + Деление Power - + Степень olive::MatrixGenerator - + Orthographic Matrix - + Прямоугольная матрица - + Ortho - + Generate an orthographic matrix using position, rotation, and scale. - + Position - Позиция + Позиция + + + + Rotation + Вращение + + + + Scale + Масштаб + + + + Uniform Scale + Пропорции - Rotation - Вращение - - - - Scale - Масштаб - - - - Uniform Scale - Сохранять пропорции - - - Anchor Point - Точка привязки + Точка привязки olive::MediaInput - Footage + + Media + Медиа + + + + Import footage into the node graph. @@ -2321,32 +2357,32 @@ This driver is known to have stability and performance issues with Olive. It is &Project - &Проект + &Проект &Sequence - П&оследовательность + П&оследовательность &Folder - П&апка + П&апка Cu&t - В&ырезать + В&ырезать Cop&y - С&копировать + С&копировать &Paste - &Вставить + &Вставить @@ -2356,92 +2392,92 @@ This driver is known to have stability and performance issues with Olive. It is Duplicate - + Сделать копию Delete - Удалить + Удалить Ripple Delete - Удалить со сдвигом + Удалить со сдвигом Split - Разделить + Разделить Set In Point - Установить точку входа + Установить точку входа Set Out Point - Установить точку выхода + Установить точку выхода Reset In Point - Сбросить точку входа + Сбросить точку входа Reset Out Point - Сбросить точку выхода + Сбросить точку выхода Clear In/Out Point - Очистить точку входа/выхода + Очистить точки входа/выхода Add Default Transition - Добавить переход по умолчанию + Добавить переход по умолчанию Link/Unlink - Связать/Убрать связь + Связать/Убрать связь Enable/Disable - Включить/Отключить + Включить/Отключить Nest - Вложить + Вложить Frames - Кадры + Кадры Drop Frame - С пропуском кадров + С пропуском кадров Non-Drop Frame - Без пропуска кадров + Без пропуска кадров Milliseconds - Миллисекунды + Миллисекунды Seconds - + Секунды @@ -2449,80 +2485,113 @@ This driver is known to have stability and performance issues with Olive. It is Merge - + Объединение Merge two textures together. - + Объединить две текстуры. Base - + Основа Blend + Совмещение + + + + olive::MosaicFilterNode + + + Texture + Текстура + + + + Horizontal + По горизонтали + + + + Vertical + По вертикали + + + + Mosaic + Мозаика + + + + Apply a pixelated mosaic filter to video. olive::Node - - - Input - - - Output - + Input + Вход - General - Общие + Output + Выход - Math - + General + Общие - Color - Цвет + Distort + - Filter - + Math + Математика - Timeline - Монтажный стол + Color + Цвет - Generator - + Filter + Фильтр - Channel - + Timeline + Монтажный стол - Transition - + Generator + Генератор - + + Channel + Канал + + + + Transition + Переход + + + Uncategorized - + Без категории @@ -2530,7 +2599,7 @@ This driver is known to have stability and performance issues with Olive. It is Input - + Вход @@ -2538,7 +2607,7 @@ This driver is known to have stability and performance issues with Olive. It is Output - + Выход @@ -2546,7 +2615,7 @@ This driver is known to have stability and performance issues with Olive. It is Node Editor - + Редактор нод @@ -2554,12 +2623,12 @@ This driver is known to have stability and performance issues with Olive. It is Value - + Значение None - + Нет @@ -2609,7 +2678,7 @@ This driver is known to have stability and performance issues with Olive. It is Texture - + Текстура @@ -2619,7 +2688,7 @@ This driver is known to have stability and performance issues with Olive. It is Footage - + Видеоматериал @@ -2639,7 +2708,7 @@ This driver is known to have stability and performance issues with Olive. It is Unknown - + Неизвестно @@ -2647,7 +2716,7 @@ This driver is known to have stability and performance issues with Olive. It is + - + + @@ -2660,17 +2729,17 @@ This driver is known to have stability and performance issues with Olive. It is Connected to - + Соединено с Nothing - + ничем Disconnect - + Отсоединить @@ -2678,7 +2747,7 @@ This driver is known to have stability and performance issues with Olive. It is %1 (%2) - + %1 (%2) @@ -2686,7 +2755,7 @@ This driver is known to have stability and performance issues with Olive. It is %1: - + %1: @@ -2694,7 +2763,7 @@ This driver is known to have stability and performance issues with Olive. It is Warning - + Предупреждение @@ -2707,7 +2776,7 @@ This driver is known to have stability and performance issues with Olive. It is Table View - + Просмотр таблицей @@ -2715,12 +2784,12 @@ This driver is known to have stability and performance issues with Olive. It is Type - Тип + Тип Source - + Источник @@ -2745,7 +2814,7 @@ This driver is known to have stability and performance issues with Olive. It is (unknown) - (неизвестно) + (неизвестно) @@ -2753,7 +2822,7 @@ This driver is known to have stability and performance issues with Olive. It is Nodes - + Ноды @@ -2761,62 +2830,62 @@ This driver is known to have stability and performance issues with Olive. It is Label - + Метка Auto-Position - + Автопозиционирование Smooth Edges - + Плавные края Filter - + Фильтр Show All - + Показывать все Show Selected Blocks Only - + Показывать только выбранные блоки Direction - + Направление Top to Bottom - + Сверху вниз Bottom to Top - + Снизу вверх Left to Right - + Слева направо Right to Left - + Справа налево Add - Добавить + Добавить @@ -2851,17 +2920,17 @@ This driver is known to have stability and performance issues with Olive. It is Parameter Editor - + Редактор параметров (none) - (нет) + (нет) (multiple) - (больше одного) + (больше одного) @@ -2869,7 +2938,7 @@ This driver is known to have stability and performance issues with Olive. It is Browse - Просмотр + Просмотр @@ -2952,12 +3021,12 @@ This driver is known to have stability and performance issues with Olive. It is Theme - Тема + Тема Node Color Scheme - + Цветовая схема нод @@ -2965,47 +3034,47 @@ This driver is known to have stability and performance issues with Olive. It is Output Device: - Устройство выхода: + Устройство выхода: Input Device: - Устройство входа: + Устройство входа: Sample Rate: - Частота дискретизации: + Частота дискретизации: Audio Recording: - Запись звука: + Запись звука: Mono - Моно + Моно Stereo - Стерео + Стерео Refresh Devices - + Обновить список устройств Please wait... - + Подождите, пожалуйста… Default - По умолчанию + По умолчанию @@ -3013,12 +3082,12 @@ This driver is known to have stability and performance issues with Olive. It is Behavior - Поведение + Поведение General - Общие + Общие @@ -3043,7 +3112,7 @@ This driver is known to have stability and performance issues with Olive. It is Audio - Звук + Звук @@ -3053,7 +3122,7 @@ This driver is known to have stability and performance issues with Olive. It is Timeline - Монтажный стол + Монтажный стол @@ -3103,12 +3172,12 @@ This driver is known to have stability and performance issues with Olive. It is Playback - Воспроизведение + Воспроизведение Ask For Name When Setting Marker - Спрашивать имя маркера при добавлении + Спрашивать имя маркера при добавлении @@ -3118,7 +3187,7 @@ This driver is known to have stability and performance issues with Olive. It is Project - Проект + Проект @@ -3128,17 +3197,17 @@ This driver is known to have stability and performance issues with Olive. It is Nodes - + Ноды Add Default Effects to New Clips - Добавлять эффекты по умолчанию в новые клипы + Добавлять эффекты по умолчанию в новые клипы Auto-Scale By Default - Автоматически масштабировать по умолчанию + Автоматически масштабировать по умолчанию @@ -3156,37 +3225,37 @@ This driver is known to have stability and performance issues with Olive. It is Preferences - Параметры + Параметры General - Общие + Общие Appearance - Внешний вид + Внешний вид Behavior - Поведение + Поведение Disk - + Диск Audio - Звук + Звук Keyboard - Клавиатурные комбинации + Клавиатурные комбинации @@ -3194,22 +3263,22 @@ This driver is known to have stability and performance issues with Olive. It is Disk Management - + Управление диском Disk Cache Location: - + Размещение кэша на диске: Disk Cache Settings - + Параметры кэша на диске Cache Behavior - + Поведение кэша @@ -3230,7 +3299,7 @@ This driver is known to have stability and performance issues with Olive. It is Disk Cache - + Дисковый кэш @@ -3243,27 +3312,27 @@ This driver is known to have stability and performance issues with Olive. It is Language: - Язык: + Язык: Auto-Scroll Method: - + Способ автопрокрутки: None - + Нет Page Scrolling - + Целыми страницами Smooth Scrolling - + Плавной прокруткой @@ -3283,7 +3352,7 @@ This driver is known to have stability and performance issues with Olive. It is %1 (%2) - + %1 (%2) @@ -3291,63 +3360,63 @@ This driver is known to have stability and performance issues with Olive. It is Search for action or shortcut - Искать действие или комбинацию клавиш + Искать действие или комбинацию клавиш Action - Действие + Действие Shortcut - Комбинация + Комбинация Import - Импортировать + Импортировать Export - Экспортировать + Экспортировать Reset Selected - Сбросить выбранное + Сбросить выбранное Reset All - Сбросить все + Сбросить все Confirm Reset All Shortcuts - Подтвердите действие + Подтвердите действие Are you sure you wish to reset all keyboard shortcuts to their defaults? - Вы действительно хотите сбросить все клавиатурные комбинации к исходным значениям? + Вы действительно хотите сбросить все клавиатурные комбинации к исходным значениям? Import Keyboard Shortcuts - Импортировать клавиатурные комбинации + Импортировать клавиатурные комбинации Error saving shortcuts - Ошибка при сохранении клавиатурных комбинаций + Ошибка при сохранении клавиатурных комбинаций Failed to open file for reading - Не удалось открыть файл для чтения + Не удалось открыть файл для чтения @@ -3357,7 +3426,7 @@ This driver is known to have stability and performance issues with Olive. It is Export Shortcuts - Экспортировать клавиатурные комбинации + Экспортировать клавиатурные комбинации @@ -3375,7 +3444,7 @@ This driver is known to have stability and performance issues with Olive. It is Cancel - Отмена + Отмена @@ -3392,27 +3461,27 @@ This driver is known to have stability and performance issues with Olive. It is &New - &Создать + &Создать &Import... - &Импортировать… + &Импортировать… &Project Properties... - + С&войства проекта… Open in New Tab - + Открыть в новой вкладке Open in New Window - + Открыть в новом окне @@ -3447,7 +3516,7 @@ This driver is known to have stability and performance issues with Olive. It is P&roperties - + С&войства @@ -3470,7 +3539,7 @@ What would you like to do with these clips? Delete Clips - + Удалить клипы @@ -3499,7 +3568,7 @@ What would you like to do with these clips? Importing %1 files - + Импортируется %1 файлов @@ -3507,24 +3576,24 @@ What would you like to do with these clips? Loading '%1' - + Загружается '%1' olive::ProjectLoadTask - + This project is newer than this version of Olive and cannot be opened. - - + + This project is from a version of Olive that is no longer supported in this version. - + Failed to read file "%1" for reading. @@ -3534,17 +3603,17 @@ What would you like to do with these clips? Folder - + Папка Project - Проект + Проект (none) - (нет) + (нет) @@ -3552,52 +3621,52 @@ What would you like to do with these clips? Project Properties for '%1' - + Свойства проекта '%1' OpenColorIO Configuration: - + Конфигурация OpenColorIO: (default) - + (по умолчанию) Default Input Color Space: - + Пространство входа по умолчанию: Browse - Просмотр + Просмотр Color Management - + Управление цветом Use Default Location - + Использовать обычное размещение Store Alongside Project - + Хранить рядом с проектом Use Custom Location: - + Размещать где-то еще: Disk Cache Settings - + Параметры кэша на диске @@ -3608,12 +3677,12 @@ What would you like to do with these clips? Disk Cache - + Дисковый кэш OpenColorIO Config Error - + Ошибка в конфгурации OpenColorIO @@ -3633,7 +3702,7 @@ What would you like to do with these clips? Browse for OpenColorIO configuration - + Указать файл конфигурации OpenColorIO @@ -3641,12 +3710,12 @@ What would you like to do with these clips? Saving '%1' - + Сохраняется '%1' Failed to write XML data - + Не удалось записать данные XML @@ -3664,47 +3733,47 @@ What would you like to do with these clips? New... - + Создать… Open Project - Открыть проект + Открыть проект Save Project - Сохранить проект + Сохранить проект Undo - Отменить + Отменить Redo - Вернуть + Вернуть Search media, markers, etc. - Искать файлы, маркеры и т.д. + Искать файлы, маркеры и т.д. Switch to Tree View - + Переключиться на древовидное представление Switch to List View - + Переключиться на список Switch to Icon View - + Переключиться на миниатюры @@ -3712,22 +3781,22 @@ What would you like to do with these clips? Name - Название + Название Duration - Длительность + Длительность Rate - Частота + Частота Move Items - + Переместить объекты @@ -3748,52 +3817,52 @@ What would you like to do with these clips? B - + Ж Bold - + Полужирный I - + К Italic - + Курсив U - + П Underline - + Подчеркивание S - + В Strikethrough - + Вычеркнутый Font Family - + Гарнитура Font Size - + Кегль шрифта @@ -3859,17 +3928,17 @@ What would you like to do with these clips? Waveform - + Волновая форма Histogram - + Гистограмма Scope - + Анализатор @@ -3877,27 +3946,27 @@ What would you like to do with these clips? Name: - Название: + Название: New Sequence - Новая последовательность + Новая последовательность Editing "%1" - Правка "%1" + Правка "%1" Error editing Sequence - + Ошибка при редактировании последовательности Please enter a name for this Sequence. - + Введите название этой последовательности @@ -3905,72 +3974,72 @@ What would you like to do with these clips? Video - Видео + Видео Width: - Ширина: + Ширина: Height: - Высота: + Высота: Frame Rate: - Частота кадров: + Частота кадров: Pixel Aspect Ratio: - Соотношение сторон пикселя: + Соотн. сторон пикселя: Interlacing: - Чересстрочность: + Чересстрочность: Audio - Звук + Звук Sample Rate: - Частота дискретизации: + Частота дискр.: Channels: - + Каналов: Preview - + Предпросмотр Resolution: - + Разрешение: Quality: - + Качество: Save Preset - + Сохранить профиль (%1x%2) - + (%1x%2) @@ -3978,62 +4047,62 @@ What would you like to do with these clips? Preset - + Профиль My Presets - + Мои профили 4K UHD - + 4K UHD 1080p - 1080p + 1080p 720p - 720p + 720p NTSC - + NTSC PAL - + PAL %1 23.976 FPS - + %1 23,976 к/с %1 25 FPS - + %1 25 к/с %1 29.97 FPS - + %1 29,97 к/с %1 50 FPS - + %1 50 к/с %1 59.94 FPS - + %1 59,94 к/с @@ -4048,7 +4117,7 @@ What would you like to do with these clips? Delete Preset - + Удалить профиль @@ -4056,7 +4125,7 @@ What would you like to do with these clips? Sequence Viewer - Просмотр последовательностей + Монитор последовательностей @@ -4113,7 +4182,7 @@ What would you like to do with these clips? Input - + Вход @@ -4123,7 +4192,7 @@ What would you like to do with these clips? Radius - + Радиус @@ -4141,12 +4210,12 @@ What would you like to do with these clips? Task - + Задача Unknown error - + Неизвестная ошибка @@ -4154,7 +4223,7 @@ What would you like to do with these clips? Task Failed - + Не удалось выполнить задачу @@ -4162,7 +4231,7 @@ What would you like to do with these clips? Task Manager - + Управление задачами @@ -4170,7 +4239,7 @@ What would you like to do with these clips? Error: %1 - + Ошибка: %1 @@ -4178,53 +4247,53 @@ What would you like to do with these clips? Sample Text - Образец текста + Образец текста Text - Текст + Текст Generate rich text. - + Создать форматированный текст. Font - Шрифт + Шрифт Font Size - + Кегль шрифта Color - Цвет + Цвет Vertical Align - + Верт. выравнивание Top - Сверху + Сверху Center - По центру + По центру Bottom - Снизу + Снизу @@ -4232,7 +4301,7 @@ What would you like to do with these clips? (none) - (нет) + (нет) @@ -4240,12 +4309,12 @@ What would you like to do with these clips? Set Marker - Установить маркер + Установить маркер Marker name: - + Название маркера: @@ -4253,7 +4322,7 @@ What would you like to do with these clips? Time - + Время @@ -4266,19 +4335,19 @@ What would you like to do with these clips? Timeline - Монтажный стол + Монтажный стол olive::TimelineWidget - - + + Properties - Свойства + Свойства - + Use Audio Time Units @@ -4288,7 +4357,7 @@ What would you like to do with these clips? Tools - + Инструменты @@ -4296,57 +4365,57 @@ What would you like to do with these clips? Pointer Tool - Указатель + Указатель Edit Tool - Выделение + Выделение Ripple Tool - Монтаж со сдвигом + Монтаж со сдвигом Rolling Tool - + Монтаж с совмещением Razor Tool - Подрезка + Подрезка Slip Tool - Прокрутка с совмещением + Прокрутка с совмещением Slide Tool - Прокрутка + Прокрутка Hand Tool - Навигация + Навигация Zoom Tool - + Масштаб Transition Tool - Переход + Переход Record Tool - + Запись @@ -4356,7 +4425,7 @@ What would you like to do with these clips? Toggle Snapping - + Переключить прилипание @@ -4364,7 +4433,7 @@ What would you like to do with these clips? Track - + Дорожка @@ -4381,25 +4450,25 @@ What would you like to do with these clips? Muted - - - Video %1 - - - Audio %1 - + Video %1 + Видео %1 - Subtitle %1 - + Audio %1 + Звук %1 - + + Subtitle %1 + Субтитры %1 + + + Track %1 - + Дорожка %1 @@ -4407,11 +4476,74 @@ What would you like to do with these clips? M - + М L + Б + + + + olive::TransformDistortNode + + + Auto-Scale + Автомасштаб + + + + Texture + Текстура + + + + Interpolation + Интерполяция + + + + None + Нет + + + + Fit + Уместить + + + + Fill + Заполнить + + + + Stretch + Растянуть + + + + Nearest Neighbor + + + + + Bilinear + + + + + Mipmapped Bilinear + + + + + Transform + Трансформация + + + + Transform an image in 2D space. Equivalent to multiplying by an orthographic matrix. @@ -4420,17 +4552,17 @@ What would you like to do with these clips? From - + От To - + До Curve - + Кривая @@ -4453,62 +4585,62 @@ What would you like to do with these clips? Trigonometry - + Тригонометрия Perform a trigonometry operation on a value. - + Произвести тригонометрическую операцию над значением Sine - Синусоида + Синус Cosine - + Косинус Tangent - + Тангенс Inverse Sine - + Инверт. синус Inverse Cosine - + Инверт. косинус Inverse Tangent - + Инверт. тангенс Hyperbolic Sine - + Гипербол. синус Hyperbolic Cosine - + Гипербол. косинус Hyperbolic Tangent - + Гипербол. тангенс Method - + Способ @@ -4521,25 +4653,7 @@ What would you like to do with these clips? 1/%1 - 144p {1/%1?} - - - - olive::VideoInput - - - Video Input - - - - - Video - Видео - - - - Import a video footage stream. - + 144p {1/%1?} @@ -4547,22 +4661,22 @@ What would you like to do with these clips? Pixel Aspect: - + Пропорции пикселей: Interlacing: - Чересстрочность: + Чересстрочность: Color Space: - + Пространство: Default (%1) - + По умолчанию (%1) @@ -4572,27 +4686,27 @@ What would you like to do with these clips? Image Sequence - + Последовательность изображений Start Index: - + Начало индекса: End Index: - + Конец индекса: Frame Rate: - Частота кадров: + Частота кадров: Invalid Configuration - + Некорректная конфигурация @@ -4605,7 +4719,7 @@ What would you like to do with these clips? Viewer - + Монитор @@ -4615,7 +4729,7 @@ What would you like to do with these clips? Texture - + Текстура @@ -4625,17 +4739,17 @@ What would you like to do with these clips? Video Tracks - + Видеодорожки Audio Tracks - + Звуковые дорожки Subtitle Tracks - + Дорожки субтитров @@ -4643,7 +4757,7 @@ What would you like to do with these clips? Viewer - + Монитор @@ -4651,7 +4765,7 @@ What would you like to do with these clips? Error - Ошибка + Ошибка @@ -4662,32 +4776,32 @@ What would you like to do with these clips? Safe Margins - + Безопасная область Zoom - Масштаб + Масштаб Fit - Уместить + Уместить %1% - + %1% Full Screen - Полноэкранный режим + Полноэкранный режим Screen %1: %2x%3 - Экран %1: %2×%3 + Экран %1: %2×%3 @@ -4697,52 +4811,52 @@ What would you like to do with these clips? Scopes - + Анализаторы Cache - + Кэш Auto-Cache - + Автокэширование Pause Auto-Cache During Playback - + Приостанавливать автокэширование при воспроизведении Cache Entire Sequence - + Закэшировать всю последовательность Cache Sequence In/Out - + Закэшировать вход/выход последовательности Off - Выкл. + Выкл. On - + Вкл Custom Aspect - + Другое соотношение Show Audio Waveform - + Показывать волновую форму @@ -4751,7 +4865,7 @@ What would you like to do with these clips? Volume - Громкость + Громкость From 827c9f93ccfef262fbf8b1cefad39595d656ebf9 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 24 Nov 2020 11:02:42 +1100 Subject: [PATCH 03/14] AudioVisualWaveform: implement same size check as AudioPlaybackCache to prevent index out of bounds crashes --- app/audio/audiovisualwaveform.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/audio/audiovisualwaveform.cpp b/app/audio/audiovisualwaveform.cpp index 2fc07b683..ec99aed9d 100644 --- a/app/audio/audiovisualwaveform.cpp +++ b/app/audio/audiovisualwaveform.cpp @@ -151,6 +151,10 @@ void AudioVisualWaveform::Shift(const rational &from, const rational &to) return; } + if (from_index > data_.size()) { + return; + } + if (from_index > to_index) { // Shifting backwards <- int copy_sz = data_.size() - from_index; From 1400c313ca23167b6a765e79a989645d234004f1 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 24 Nov 2020 11:04:33 +1100 Subject: [PATCH 04/14] timeline: correctly use ptr to qvector rather than qlist Fixes copy/paste crash --- app/widget/timelinewidget/timelinewidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 6f913b8e6..51360ce7c 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -299,7 +299,7 @@ void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n) void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata) { // Cache the earliest in point so all copied clips have a "relative" in point that can be pasted anywhere - QList& selected = *static_cast*>(userdata); + QVector& selected = *static_cast*>(userdata); rational earliest_in = RATIONAL_MAX; foreach (TimelineViewBlockItem* item, selected) { @@ -329,7 +329,7 @@ void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void void TimelineWidget::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData& xml_node_data, void *userdata) { - QList& paste_data = *static_cast*>(userdata); + QVector& paste_data = *static_cast*>(userdata); while (XMLReadNextStartElement(reader)) { if (reader->name() == QStringLiteral("block")) { From 1254726079cdb78e2218f1a0c2468a3f17b6a35f Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 08:57:55 +1100 Subject: [PATCH 05/14] transform: set alpha channel required always true for now --- app/node/distort/transform/transformdistortnode.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/node/distort/transform/transformdistortnode.cpp b/app/node/distort/transform/transformdistortnode.cpp index dcc74eb05..9235ac603 100644 --- a/app/node/distort/transform/transformdistortnode.cpp +++ b/app/node/distort/transform/transformdistortnode.cpp @@ -83,6 +83,10 @@ NodeValueTable TransformDistortNode::Value(NodeValueDatabase &value) const job.InsertValue(QStringLiteral("ove_mvpmat"), ShaderValue(real_matrix, NodeParam::kMatrix)); job.SetInterpolation(QStringLiteral("ove_maintex"), static_cast(value[interpolation_input_].Get(NodeParam::kCombo).toInt())); + // FIXME: This should be optimized, we can use matrix math to determine if this operation will + // end up with gaps in the screen that will require an alpha channel. + job.SetAlphaChannelRequired(true); + table.Push(NodeParam::kShaderJob, QVariant::fromValue(job), this); } } From 0eda91a0cbcc857e1fcd500a87903739c10d1845 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 08:59:14 +1100 Subject: [PATCH 06/14] renderer: destroy surface in main thread --- app/render/opengl/openglrenderer.cpp | 14 +++++++++----- app/render/opengl/openglrenderer.h | 2 ++ app/render/renderer.h | 2 ++ app/render/rendererthreadwrapper.cpp | 4 +++- app/render/rendererthreadwrapper.h | 3 +++ app/render/rendermanager.cpp | 1 + app/widget/manageddisplay/manageddisplay.cpp | 1 + 7 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index b07b7cf30..a92bb10f2 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -82,6 +82,7 @@ OpenGLRenderer::OpenGLRenderer(QObject* parent) : OpenGLRenderer::~OpenGLRenderer() { Destroy(); + PostDestroy(); } void OpenGLRenderer::Init(QOpenGLContext *existing_ctx) @@ -114,6 +115,14 @@ bool OpenGLRenderer::Init() return true; } +void OpenGLRenderer::PostDestroy() +{ + // Destroy surface if we created it + if (surface_.isValid()) { + surface_.destroy(); + } +} + void OpenGLRenderer::PostInit() { // Make context current on that surface @@ -142,11 +151,6 @@ void OpenGLRenderer::DestroyInternal() delete context_; } context_ = nullptr; - - // Destroy surface if we created it - if (surface_.isValid()) { - surface_.destroy(); - } } } diff --git a/app/render/opengl/openglrenderer.h b/app/render/opengl/openglrenderer.h index ef58578c8..49aa07252 100644 --- a/app/render/opengl/openglrenderer.h +++ b/app/render/opengl/openglrenderer.h @@ -44,6 +44,8 @@ public: virtual bool Init() override; + virtual void PostDestroy() override; + public slots: virtual void PostInit() override; diff --git a/app/render/renderer.h b/app/render/renderer.h index e7f450737..724c76b22 100644 --- a/app/render/renderer.h +++ b/app/render/renderer.h @@ -67,6 +67,8 @@ public: void Destroy(); + virtual void PostDestroy() = 0; + public slots: virtual void PostInit() = 0; diff --git a/app/render/rendererthreadwrapper.cpp b/app/render/rendererthreadwrapper.cpp index 9aba561d8..2b86c1539 100644 --- a/app/render/rendererthreadwrapper.cpp +++ b/app/render/rendererthreadwrapper.cpp @@ -58,12 +58,14 @@ void RendererThreadWrapper::DestroyInternal() { if (thread_) { QMetaObject::invokeMethod(inner_, "DestroyInternal", Qt::BlockingQueuedConnection); - inner_ = nullptr; thread_->quit(); thread_->wait(); delete thread_; thread_ = nullptr; + + // Destroy in main thread + inner_->PostDestroy(); } } diff --git a/app/render/rendererthreadwrapper.h b/app/render/rendererthreadwrapper.h index c984ed560..875a86d74 100644 --- a/app/render/rendererthreadwrapper.h +++ b/app/render/rendererthreadwrapper.h @@ -35,11 +35,14 @@ public: virtual ~RendererThreadWrapper() override { Destroy(); + PostDestroy(); delete inner_; } virtual bool Init() override; + virtual void PostDestroy() override {} + public slots: virtual void PostInit() override; diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index f771502b5..567b841d6 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -75,6 +75,7 @@ RenderManager::~RenderManager() delete still_cache_; context_->Destroy(); + context_->PostDestroy(); delete context_; } } diff --git a/app/widget/manageddisplay/manageddisplay.cpp b/app/widget/manageddisplay/manageddisplay.cpp index bbea5112f..1ac964fd7 100644 --- a/app/widget/manageddisplay/manageddisplay.cpp +++ b/app/widget/manageddisplay/manageddisplay.cpp @@ -208,6 +208,7 @@ void ManagedDisplayWidget::MenuColorspaceSelect(QAction *action) void ManagedDisplayWidget::OnDestroy() { attached_renderer_->Destroy(); + attached_renderer_->PostDestroy(); } void ManagedDisplayWidget::SetColorTransform(const ColorTransform &transform) From 7cc64927b88c4fbb9d3ff3e8bd1f8075bc79ce23 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 09:04:15 +1100 Subject: [PATCH 07/14] mainwindow: when maximizing panels, fallback to focused panel if hovered panel is null Fixes #1403 --- app/window/mainwindow/mainwindow.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 8426fa8cf..d9d14ec1f 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -274,9 +274,14 @@ void MainWindow::ToggleMaximizedPanel() // Find the currently focused panel PanelWidget* currently_hovered = PanelManager::instance()->CurrentlyHovered(); - // If no panel is hovered, do nothing - if (currently_hovered == nullptr) { - return; + // If no panel is hovered, fallback to the currently active panel + if (!currently_hovered) { + currently_hovered = PanelManager::instance()->CurrentlyFocused(); + + // If no panel is hovered or focused, do nothing + if (!currently_hovered) { + return; + } } // If this panel is not actually on the main window, this is a no-op From bd2b3f7a7cb5489f089839c9f9c69cd78d502f5e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 09:42:30 +1100 Subject: [PATCH 08/14] gizmos: detect generated images like titles Fixes #1413 --- app/widget/viewer/gizmotraverser.cpp | 9 ++++++++- app/widget/viewer/gizmotraverser.h | 8 +++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/widget/viewer/gizmotraverser.cpp b/app/widget/viewer/gizmotraverser.cpp index 6277b2226..8105a7338 100644 --- a/app/widget/viewer/gizmotraverser.cpp +++ b/app/widget/viewer/gizmotraverser.cpp @@ -38,7 +38,14 @@ QVariant GizmoTraverser::ProcessShader(const Node *node, const TimeRange &range, Q_UNUSED(range) Q_UNUSED(job) - return size_; + return GenerateResolution(); } +QVariant GizmoTraverser::ProcessFrameGeneration(const Node *node, const GenerateJob &job) +{ + Q_UNUSED(node) + Q_UNUSED(job) + + return GenerateResolution(); +} } diff --git a/app/widget/viewer/gizmotraverser.h b/app/widget/viewer/gizmotraverser.h index f7334b9f9..3f3e5b715 100644 --- a/app/widget/viewer/gizmotraverser.h +++ b/app/widget/viewer/gizmotraverser.h @@ -34,15 +34,17 @@ public: } protected: - virtual QVariant ProcessVideoFootage(StreamPtr stream, const rational &input_time); + virtual QVariant ProcessVideoFootage(StreamPtr stream, const rational &input_time) override; - virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job); + virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job) override; - virtual QVector2D GenerateResolution() const + virtual QVector2D GenerateResolution() const override { return size_; } + virtual QVariant ProcessFrameGeneration(const Node *node, const GenerateJob& job) override; + // FIXME: Do something about audio? private: From c7f5af953478e59aae8e928192096cc8d879d238 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 10:00:57 +1100 Subject: [PATCH 09/14] moved autoscroll code to TimeBasedWidget rather than TimelineViewBase Better place for it. Fixes #1406 --- app/widget/curvewidget/curvewidget.cpp | 1 - app/widget/nodeparamview/nodeparamview.cpp | 1 - app/widget/timebased/timebased.cpp | 29 +++++++++++++++++++ app/widget/timebased/timebased.h | 8 +++++ app/widget/timelinewidget/timelinewidget.cpp | 1 - .../timelinewidget/view/timelineviewbase.cpp | 28 ------------------ .../timelinewidget/view/timelineviewbase.h | 10 ------- 7 files changed, 37 insertions(+), 41 deletions(-) diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index 75d481ad9..b8dcd1a1d 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -89,7 +89,6 @@ CurveWidget::CurveWidget(QWidget *parent) : ruler_view_layout->addWidget(ruler()); view_ = new CurveView(); - connect(view_, &CurveView::RequestCenterScrollOnPlayhead, this, &CurveWidget::CenterScrollOnPlayhead); ConnectTimelineView(view_); ruler_view_layout->addWidget(view_); diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 2a734a718..597ef7d61 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -85,7 +85,6 @@ NodeParamView::NodeParamView(QWidget *parent) : keyframe_view_ = new KeyframeView(); keyframe_view_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ConnectTimelineView(keyframe_view_); - connect(keyframe_view_, &KeyframeView::RequestCenterScrollOnPlayhead, this, &NodeParamView::CenterScrollOnPlayhead); keyframe_area_layout->addWidget(keyframe_view_); // Connect ruler and keyframe view together diff --git a/app/widget/timebased/timebased.cpp b/app/widget/timebased/timebased.cpp index ea894768e..6d09dfe8b 100644 --- a/app/widget/timebased/timebased.cpp +++ b/app/widget/timebased/timebased.cpp @@ -23,6 +23,7 @@ #include #include +#include "common/autoscroll.h" #include "common/timecodefunctions.h" #include "config/config.h" #include "core.h" @@ -155,6 +156,22 @@ void TimeBasedWidget::ScrollBarResized(const double &multiplier) SetScale(GetScale() * corrected_scale); } +void TimeBasedWidget::PageScrollToPlayhead() +{ + int playhead_pos = qRound(TimeToScene(GetTime())); + + int viewport_width = ruler()->width(); + int viewport_padding = viewport_width / 16; + + if (playhead_pos < scrollbar()->value()) { + // Anchor the playhead to the RIGHT of where we scroll to + scrollbar()->setValue(playhead_pos - viewport_width + viewport_padding); + } else if (playhead_pos > scrollbar()->value() + viewport_width) { + // Anchor the playhead to the LEFT of where we scroll to + scrollbar()->setValue(playhead_pos - viewport_padding); + } +} + TimeRuler *TimeBasedWidget::ruler() const { return ruler_; @@ -224,6 +241,18 @@ void TimeBasedWidget::SetTimestamp(int64_t timestamp) { ruler_->SetTime(timestamp); + switch (static_cast(Config::Current()["Autoscroll"].toInt())) { + case AutoScroll::kNone: + // Do nothing + break; + case AutoScroll::kPage: + QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection); + break; + case AutoScroll::kSmooth: + QMetaObject::invokeMethod(this, "CenterScrollOnPlayhead", Qt::QueuedConnection); + break; + } + TimeChangedEvent(timestamp); } diff --git a/app/widget/timebased/timebased.h b/app/widget/timebased/timebased.h index 6fdfad8e0..2689feba4 100644 --- a/app/widget/timebased/timebased.h +++ b/app/widget/timebased/timebased.h @@ -204,6 +204,14 @@ private slots: void ScrollBarResized(const double& multiplier); + /** + * @brief Slot to handle page scrolling of the playhead + * + * If the playhead is outside the current scroll bounds, this function will scroll to where it is. Otherwise it will + * do nothing. + */ + void PageScrollToPlayhead(); + }; } diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 51360ce7c..86d5856d4 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -131,7 +131,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) : connect(view, &TimelineView::customContextMenuRequested, this, &TimelineWidget::ShowContextMenu); connect(scrollbar(), &QScrollBar::valueChanged, view->horizontalScrollBar(), &QScrollBar::setValue); connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, scrollbar(), &QScrollBar::setValue); - connect(view, &TimelineView::RequestCenterScrollOnPlayhead, this, &TimelineWidget::CenterScrollOnPlayhead); connect(view, &TimelineView::MousePressed, this, &TimelineWidget::ViewMousePressed); connect(view, &TimelineView::MouseMoved, this, &TimelineWidget::ViewMouseMoved); diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp index 45a836b64..a252a867a 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.cpp +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -25,7 +25,6 @@ #include #include -#include "common/autoscroll.h" #include "common/timecodefunctions.h" #include "config/config.h" @@ -115,18 +114,6 @@ void TimelineViewBase::SetTime(const int64_t time) { playhead_ = time; - switch (static_cast(Config::Current()["Autoscroll"].toInt())) { - case AutoScroll::kNone: - // Do nothing - break; - case AutoScroll::kPage: - QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection); - break; - case AutoScroll::kSmooth: - emit RequestCenterScrollOnPlayhead(); - break; - } - // Force redraw for playhead viewport()->update(); } @@ -257,21 +244,6 @@ void TimelineViewBase::UpdateSceneRect() } } -void TimelineViewBase::PageScrollToPlayhead() -{ - int playhead_pos = qRound(GetPlayheadX()); - - int viewport_padding = viewport()->width() / 16; - - if (playhead_pos < horizontalScrollBar()->value()) { - // Anchor the playhead to the RIGHT of where we scroll to - horizontalScrollBar()->setValue(playhead_pos - viewport()->width() + viewport_padding); - } else if (playhead_pos > horizontalScrollBar()->value() + viewport()->width()) { - // Anchor the playhead to the LEFT of where we scroll to - horizontalScrollBar()->setValue(playhead_pos - viewport_padding); - } -} - void TimelineViewBase::resizeEvent(QResizeEvent *event) { QGraphicsView::resizeEvent(event); diff --git a/app/widget/timelinewidget/view/timelineviewbase.h b/app/widget/timelinewidget/view/timelineviewbase.h index 1b14744e3..4ae847391 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.h +++ b/app/widget/timelinewidget/view/timelineviewbase.h @@ -60,8 +60,6 @@ signals: void ScaleChanged(double scale); - void RequestCenterScrollOnPlayhead(); - protected: virtual void drawForeground(QPainter *painter, const QRectF &rect) override; @@ -124,14 +122,6 @@ private slots: */ void UpdateSceneRect(); - /** - * @brief Slot to handle page scrolling of the playhead - * - * If the playhead is outside the current scroll bounds, this function will scroll to where it is. Otherwise it will - * do nothing. - */ - void PageScrollToPlayhead(); - }; } From c35005d1bf1784ed8ca031a061dc0988e71396a6 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 11:45:42 +1100 Subject: [PATCH 10/14] renderer: only use different footage dividers on smaller footage --- app/render/renderprocessor.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 01a2a2046..b2d558064 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -270,11 +270,12 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational & ColorManager* color_manager = Node::ValueToPtr(ticket_->property("colormanager")); - // Calculate footage divider that still fits in the divider chosen - int footage_divider = 1; - while (VideoParams::GetScaledDimension(video_stream->width(), footage_divider) > video_params.effective_width() - || VideoParams::GetScaledDimension(video_stream->height(), footage_divider) > video_params.effective_height()) { - footage_divider++; + // See if we can make this divider larger (i.e. if the fooage is smaller) + int footage_divider = video_params.divider(); + while (footage_divider > 1 + && VideoParams::GetScaledDimension(video_stream->width(), footage_divider-1) < video_params.effective_width() + && VideoParams::GetScaledDimension(video_stream->height(), footage_divider-1) < video_params.effective_height()) { + footage_divider--; } StillImageCache::EntryPtr want_entry = std::make_shared( From b5cc13c10e7459c87258251229f886dace9b3482 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 11:46:41 +1100 Subject: [PATCH 11/14] timeline: snap pointer and import operations to timebase If frame rates are mixed, ensures that video doesn't end up falling or ending on half frames which potentially make the entire sequence awkward --- app/widget/timelinewidget/timelinewidget.cpp | 13 ++++---- app/widget/timelinewidget/timelinewidget.h | 4 +-- app/widget/timelinewidget/tool/import.cpp | 11 +++++-- app/widget/timelinewidget/tool/pointer.cpp | 30 +++++++++++++++---- app/widget/timelinewidget/tool/slip.cpp | 5 ++-- app/widget/timelinewidget/tool/tool.cpp | 19 ++++++++++++ app/widget/timelinewidget/tool/tool.h | 2 ++ app/widget/timelinewidget/undo/undo.cpp | 7 ++++- .../timelinewidget/view/timelineview.cpp | 7 +++-- .../view/timelineviewghostitem.cpp | 11 ------- 10 files changed, 75 insertions(+), 34 deletions(-) diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 86d5856d4..449f876de 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -353,14 +353,6 @@ void TimelineWidget::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, X } } -rational TimelineWidget::GetToolTipTimebase() const -{ - if (GetConnectedNode() && use_audio_time_units_) { - return GetConnectedNode()->audio_params().time_base(); - } - return timebase(); -} - void TimelineWidget::SelectAll() { QVector newly_selected_blocks; @@ -1211,6 +1203,11 @@ TimelineView *TimelineWidget::GetFirstTimelineView() return views_.first()->view(); } +rational TimelineWidget::GetTimebaseForTrackType(Timeline::TrackType type) +{ + return views_.at(type)->view()->timebase(); +} + const QRect& TimelineWidget::GetRubberBandGeometry() const { return rubberband_.geometry(); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 3eb0d94d4..7c0ec3a2b 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -154,8 +154,6 @@ public: return !ghost_items_.isEmpty(); } - rational GetToolTipTimebase() const; - bool IsBlockSelected(Block* b) const { return selected_blocks_.contains(b); @@ -167,6 +165,8 @@ public: TimelineView* GetFirstTimelineView(); + rational GetTimebaseForTrackType(Timeline::TrackType type); + const QRect &GetRubberBandGeometry() const; /** diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index 930d7f71d..da9aa2bb1 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -149,9 +149,10 @@ void ImportTool::DragMove(TimelineViewMouseEvent *event) } // Generate tooltip (showing earliest in point of imported clip) - int64_t earliest_timestamp = Timecode::time_to_timestamp(earliest_ghost, parent()->GetToolTipTimebase()); + rational tooltip_timebase = parent()->GetTimebaseForTrackType(event->GetTrack().type()); + int64_t earliest_timestamp = Timecode::time_to_timestamp(earliest_ghost, tooltip_timebase); QString tooltip_text = Timecode::timestamp_to_timecode(earliest_timestamp, - parent()->GetToolTipTimebase(), + tooltip_timebase, Core::instance()->GetTimecodeDisplay()); // Force tooltip to update (otherwise the tooltip won't move as written in the documentation, and could get in the way @@ -271,6 +272,12 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QList(); } + // Snap footage duration to timebase + rational snap_mvmt = SnapMovementToTimebase(footage_duration, 0, dest_tb); + if (!snap_mvmt.isNull()) { + footage_duration += snap_mvmt; + } + foreach (TimelineViewGhostItem* ghost, footage_ghosts) { ghost->SetIn(ghost_start); ghost->SetOut(ghost_start + footage_duration); diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index 4edf6eed9..768483bcd 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -469,7 +469,7 @@ void PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos) } // Validate ghosts that are being moved (clips from other track types do NOT get moved) - { + if (track_movement != 0) { QVector validate_track_ghosts = parent()->GetGhostItems(); for (int i=0;iGetTrack().type() != drag_track_type_) { @@ -508,10 +508,11 @@ void PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos) // Regenerate tooltip and force it to update (otherwise the tooltip won't move as written in the // documentation, and could get in the way of the cursor) + rational tooltip_timebase = parent()->GetTimebaseForTrackType(drag_start_.GetTrack().type()); QToolTip::hideText(); QToolTip::showText(QCursor::pos(), - Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, parent()->GetToolTipTimebase()), - parent()->GetToolTipTimebase(), + Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, tooltip_timebase), + tooltip_timebase, Core::instance()->GetTimecodeDisplay(), true), parent()); @@ -872,6 +873,8 @@ bool PointerTool::AddMovingTransitionsToClipGhost(Block* block, rational PointerTool::ValidateInTrimming(rational movement) { + bool first_ghost = true; + foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { if (ghost->GetMode() != Timeline::kTrimIn) { continue; @@ -880,8 +883,11 @@ rational PointerTool::ValidateInTrimming(rational movement) rational earliest_in = RATIONAL_MIN; rational latest_in = ghost->GetOut(); + rational ghost_timebase = parent()->GetTimebaseForTrackType(ghost->GetTrack().type()); + + // If the ghost must be at least one frame in size, limit the latest allowed in point if (!ghost->CanHaveZeroLength()) { - latest_in -= parent()->timebase(); + latest_in -= ghost_timebase; } // Clamp adjusted value between the earliest and latest values @@ -891,6 +897,11 @@ rational PointerTool::ValidateInTrimming(rational movement) if (clamped != adjusted) { movement = clamped - ghost->GetIn(); } + + if (first_ghost) { + movement = SnapMovementToTimebase(ghost->GetIn(), movement, ghost_timebase); + first_ghost = false; + } } return movement; @@ -898,6 +909,8 @@ rational PointerTool::ValidateInTrimming(rational movement) rational PointerTool::ValidateOutTrimming(rational movement) { + bool first_ghost = true; + foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { if (ghost->GetMode() != Timeline::kTrimOut) { continue; @@ -906,8 +919,10 @@ rational PointerTool::ValidateOutTrimming(rational movement) // Determine earliest and latest out points rational earliest_out = ghost->GetIn(); + rational ghost_timebase = parent()->GetTimebaseForTrackType(ghost->GetTrack().type()); + if (!ghost->CanHaveZeroLength()) { - earliest_out += parent()->timebase(); + earliest_out += ghost_timebase; } rational latest_out = RATIONAL_MAX; @@ -919,6 +934,11 @@ rational PointerTool::ValidateOutTrimming(rational movement) if (clamped != adjusted) { movement = clamped - ghost->GetOut(); } + + if (first_ghost) { + movement = SnapMovementToTimebase(ghost->GetOut(), movement, ghost_timebase); + first_ghost = false; + } } return movement; diff --git a/app/widget/timelinewidget/tool/slip.cpp b/app/widget/timelinewidget/tool/slip.cpp index edf788138..1570791df 100644 --- a/app/widget/timelinewidget/tool/slip.cpp +++ b/app/widget/timelinewidget/tool/slip.cpp @@ -54,10 +54,11 @@ void SlipTool::ProcessDrag(const TimelineCoordinate &mouse_pos) // Generate tooltip and force it to to update (otherwise the tooltip won't move as written in the // documentation, and could get in the way of the cursor) + rational tooltip_timebase = parent()->GetTimebaseForTrackType(drag_start_.GetTrack().type()); QToolTip::hideText(); QToolTip::showText(QCursor::pos(), - Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, parent()->GetToolTipTimebase()), - parent()->GetToolTipTimebase(), + Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, tooltip_timebase), + tooltip_timebase, Core::instance()->GetTimecodeDisplay(), true), parent()); diff --git a/app/widget/timelinewidget/tool/tool.cpp b/app/widget/timelinewidget/tool/tool.cpp index 633bd5c5b..082054443 100644 --- a/app/widget/timelinewidget/tool/tool.cpp +++ b/app/widget/timelinewidget/tool/tool.cpp @@ -53,8 +53,22 @@ Timeline::MovementMode TimelineTool::FlipTrimMode(const Timeline::MovementMode & return trim_mode; } +rational TimelineTool::SnapMovementToTimebase(const rational &start, rational movement, const rational &timebase) +{ + rational proposed_position = start + movement; + rational snapped = Timecode::snap_time_to_timebase(proposed_position, timebase); + + if (proposed_position != snapped) { + movement += snapped - proposed_position; + } + + return movement; +} + rational TimelineTool::ValidateTimeMovement(rational movement) { + bool first_ghost = true; + foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { if (ghost->GetMode() != Timeline::kMove) { continue; @@ -63,6 +77,11 @@ rational TimelineTool::ValidateTimeMovement(rational movement) // Prevents any ghosts from going below 0:00:00 time if (ghost->GetIn() + movement < 0) { movement = -ghost->GetIn(); + } else if (first_ghost) { + // Ensure ghost is snapped to a grid + movement = SnapMovementToTimebase(ghost->GetIn(), movement, parent()->GetTimebaseForTrackType(ghost->GetTrack().type())); + + first_ghost = false; } } diff --git a/app/widget/timelinewidget/tool/tool.h b/app/widget/timelinewidget/tool/tool.h index 544fe7be9..ffb5f185b 100644 --- a/app/widget/timelinewidget/tool/tool.h +++ b/app/widget/timelinewidget/tool/tool.h @@ -53,6 +53,8 @@ public: static Timeline::MovementMode FlipTrimMode(const Timeline::MovementMode& trim_mode); + static rational SnapMovementToTimebase(const rational& start, rational movement, const rational& timebase); + protected: /** * @brief Validates Ghosts that are moving horizontally (time-based) diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index 5f987d234..32edcefd1 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -165,6 +165,7 @@ TrackRippleRemoveAreaCommand::TrackRippleRemoveAreaCommand(TrackOutput *track, r in_(in), out_(out), splice_(false), + splice_split_command_(nullptr), trim_out_(nullptr), trim_in_(nullptr), insert_(nullptr) @@ -305,7 +306,6 @@ void TrackRippleRemoveAreaCommand::undo_internal() trim_out_->set_length_and_media_out(trim_out_old_length_); splice_split_command_->undo(); - delete splice_split_command_; } else { @@ -344,6 +344,11 @@ void TrackRippleRemoveAreaCommand::undo_internal() track_->Node::InvalidateCache(TimeRange(in_, insert_ ? out_ : RATIONAL_MAX), track_->block_input(), track_->block_input()); + + if (splice_split_command_) { + delete splice_split_command_; + splice_split_command_ = nullptr; + } } TrackPlaceBlockCommand::TrackPlaceBlockCommand(TrackList *timeline, int track, Block *block, rational in, QUndoCommand *parent) : diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index d9cd2ced8..841a02b0b 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -115,13 +115,13 @@ void TimelineView::wheelEvent(QWheelEvent *event) return; } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) - + QPoint angle_delta = event->angleDelta(); if (Config::Current()["InvertTimelineScrollAxes"].toBool()) { angle_delta = QPoint(angle_delta.y(), angle_delta.x()); } - + QWheelEvent e( #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) event->position(), @@ -255,7 +255,8 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) painter->setBrush(Qt::NoBrush); foreach (TimelineViewGhostItem* ghost, (*ghosts_)) { - if (ghost->GetTrack().type() == connected_track_list_->type()) { + if (ghost->GetTrack().type() == connected_track_list_->type() + && !ghost->IsInvisible()) { int track_index = ghost->GetAdjustedTrack().index(); painter->drawRect(TimeToScene(ghost->GetAdjustedIn()), diff --git a/app/widget/timelinewidget/view/timelineviewghostitem.cpp b/app/widget/timelinewidget/view/timelineviewghostitem.cpp index e816094d8..7762fbafb 100644 --- a/app/widget/timelinewidget/view/timelineviewghostitem.cpp +++ b/app/widget/timelinewidget/view/timelineviewghostitem.cpp @@ -74,17 +74,6 @@ void TimelineViewGhostItem::SetCanMoveTracks(bool e) can_move_tracks_ = e; } -/*void TimelineViewGhostItem::SetInvisible(bool invisible) -{ - setBrush(Qt::NoBrush); - - if (invisible) { - setPen(Qt::NoPen); - } else { - setPen(QPen(Qt::yellow, 2)); // FIXME: Make customizable via CSS - } -}*/ - const rational &TimelineViewGhostItem::GetIn() const { return in_; From a043a686c637189554ad46eab245a49073176b8e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 11:53:56 +1100 Subject: [PATCH 12/14] timeline: started record tool --- app/widget/timelinewidget/timelinewidget.cpp | 3 +- app/widget/timelinewidget/tool/CMakeLists.txt | 2 ++ app/widget/timelinewidget/tool/record.cpp | 11 ++++++ app/widget/timelinewidget/tool/record.h | 36 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 app/widget/timelinewidget/tool/record.cpp create mode 100644 app/widget/timelinewidget/tool/record.h diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 449f876de..0ff33241a 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -35,6 +35,7 @@ #include "tool/edit.h" #include "tool/pointer.h" #include "tool/razor.h" +#include "tool/record.h" #include "tool/ripple.h" #include "tool/rolling.h" #include "tool/slide.h" @@ -96,7 +97,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : tools_.replace(olive::Tool::kSlide, new SlideTool(this)); tools_.replace(olive::Tool::kZoom, new ZoomTool(this)); tools_.replace(olive::Tool::kTransition, new TransitionTool(this)); - //tools_.replace(olive::Tool::kRecord, new PointerTool(this)); FIXME: Implement + tools_.replace(olive::Tool::kRecord, new RecordTool(this)); tools_.replace(olive::Tool::kAdd, new AddTool(this)); import_tool_ = new ImportTool(this); diff --git a/app/widget/timelinewidget/tool/CMakeLists.txt b/app/widget/timelinewidget/tool/CMakeLists.txt index 8f9a1d8e0..78d2a061d 100644 --- a/app/widget/timelinewidget/tool/CMakeLists.txt +++ b/app/widget/timelinewidget/tool/CMakeLists.txt @@ -28,6 +28,8 @@ set(OLIVE_SOURCES widget/timelinewidget/tool/pointer.h widget/timelinewidget/tool/razor.cpp widget/timelinewidget/tool/razor.h + widget/timelinewidget/tool/record.cpp + widget/timelinewidget/tool/record.h widget/timelinewidget/tool/ripple.cpp widget/timelinewidget/tool/ripple.h widget/timelinewidget/tool/rolling.cpp diff --git a/app/widget/timelinewidget/tool/record.cpp b/app/widget/timelinewidget/tool/record.cpp new file mode 100644 index 000000000..4a904fb14 --- /dev/null +++ b/app/widget/timelinewidget/tool/record.cpp @@ -0,0 +1,11 @@ +#include "record.h" + +namespace olive { + +RecordTool::RecordTool(TimelineWidget *parent) : + BeamTool(parent) +{ + +} + +} diff --git a/app/widget/timelinewidget/tool/record.h b/app/widget/timelinewidget/tool/record.h new file mode 100644 index 000000000..4ad234245 --- /dev/null +++ b/app/widget/timelinewidget/tool/record.h @@ -0,0 +1,36 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2020 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef RECORDTIMELINETOOL_H +#define RECORDTIMELINETOOL_H + +#include "beam.h" + +namespace olive { + +class RecordTool : public BeamTool +{ +public: + RecordTool(TimelineWidget* parent); +}; + +} + +#endif // RECORDTOOL_H From afa31e1df88ef7989846a9e8889fd182d483e667 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 17:16:35 +1100 Subject: [PATCH 13/14] timeline: don't flip scroll axes on apple trackpads --- app/widget/timelinewidget/view/timelineview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 841a02b0b..cfd4bd7ce 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -118,7 +118,8 @@ void TimelineView::wheelEvent(QWheelEvent *event) QPoint angle_delta = event->angleDelta(); - if (Config::Current()["InvertTimelineScrollAxes"].toBool()) { + if (Config::Current()["InvertTimelineScrollAxes"].toBool() // Check if config is set to invert timeline axes + && event->source() != Qt::MouseEventSynthesizedBySystem) { // Never flip axes on Apple trackpads though angle_delta = QPoint(angle_delta.y(), angle_delta.x()); } From 210417a5f299e401ed586286a101bac675b944ec Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Nov 2020 17:17:13 +1100 Subject: [PATCH 14/14] enable undo/redo on node param text editor --- app/widget/nodeparamview/nodeparamviewrichtext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/app/widget/nodeparamview/nodeparamviewrichtext.cpp b/app/widget/nodeparamview/nodeparamviewrichtext.cpp index b6545dfaa..1d122b68e 100644 --- a/app/widget/nodeparamview/nodeparamviewrichtext.cpp +++ b/app/widget/nodeparamview/nodeparamviewrichtext.cpp @@ -35,6 +35,7 @@ NodeParamViewRichText::NodeParamViewRichText(QWidget *parent) : layout->setMargin(0); line_edit_ = new QTextEdit(); + line_edit_->setUndoRedoEnabled(true); connect(line_edit_, &QTextEdit::textChanged, this, &NodeParamViewRichText::InnerWidgetTextChanged); layout->addWidget(line_edit_);