diff --git a/mrv2/docs/HISTORY.md b/mrv2/docs/HISTORY.md index ec71cd376..7ba7bcd1c 100644 --- a/mrv2/docs/HISTORY.md +++ b/mrv2/docs/HISTORY.md @@ -56,7 +56,13 @@ v0.8.0 - Fixed Creation of EDL Playlist with image sequences. - Fixed annotations copying from source clip to EDL Playlist when adding the clip to the playlist. -- Some UI fixes: +- Adding a clip to an EDL playlist will now positiong the current time at the + frame of the new clip, instead of resetting it to 0. +- Session files also save and load the timeline viewport options (ie. Edit mode, + size of thumbnails, transitions and markers). +- Thumbnail above the timeline no longer appears when there's no clip loaded + after it was shown once. +- Some UI fixes and improvements: * The Zoom factor in the Pixel Toolbar keeps its value when selecting it from the pulldown. * All buttons and displays have the same size on both the timeline and diff --git a/mrv2/lib/mrvFl/mrvCallbacks.cpp b/mrv2/lib/mrvFl/mrvCallbacks.cpp index 15a0677f6..c6134e81d 100644 --- a/mrv2/lib/mrvFl/mrvCallbacks.cpp +++ b/mrv2/lib/mrvFl/mrvCallbacks.cpp @@ -45,6 +45,7 @@ #include "mrvNetwork/mrvTCP.h" #include "mrvNetwork/mrvCypher.h" #include "mrvNetwork/mrvFilesModelItem.h" +#include "mrvNetwork/mrvTimelineItemOptions.h" #include "mrvApp/mrvSettingsObject.h" #include "mrvApp/App.h" @@ -1298,7 +1299,7 @@ namespace mrv void annotation_clear_cb(Fl_Menu_*, ViewerUI* ui) { - const auto& player = ui->uiView->getTimelinePlayer(); + const auto player = ui->uiView->getTimelinePlayer(); if (!player) return; if (ui->uiPrefs->SendAnnotations->value()) @@ -1310,7 +1311,7 @@ namespace mrv void annotation_clear_all_cb(Fl_Menu_*, ViewerUI* ui) { - const auto& player = ui->uiView->getTimelinePlayer(); + const auto player = ui->uiView->getTimelinePlayer(); if (!player) return; if (ui->uiPrefs->SendAnnotations->value()) @@ -1325,6 +1326,11 @@ namespace mrv { auto options = ui->uiTimeline->getItemOptions(); options.thumbnails = false; + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); @@ -1336,6 +1342,11 @@ namespace mrv Fl_Menu_Item* item = const_cast< Fl_Menu_Item* >(m->mvalue()); bool editable = (bool)item->checked(); ui->uiTimeline->setEditable(editable); + Message msg; + msg["command"] = "setTimelineEditable"; + msg["value"] = editable; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiMain->fill_menu(ui->uiMenuBar); } @@ -1344,6 +1355,11 @@ namespace mrv Fl_Menu_Item* item = const_cast< Fl_Menu_Item* >(m->mvalue()); auto options = ui->uiTimeline->getItemOptions(); options.editAssociatedClips = item->checked(); + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); ui->uiMain->fill_menu(ui->uiMenuBar); } @@ -1353,6 +1369,11 @@ namespace mrv Fl_Menu_Item* item = const_cast< Fl_Menu_Item* >(m->mvalue()); auto options = ui->uiTimeline->getItemOptions(); options.showMarkers = item->checked(); + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); @@ -1364,6 +1385,11 @@ namespace mrv Fl_Menu_Item* item = const_cast< Fl_Menu_Item* >(m->mvalue()); auto options = ui->uiTimeline->getItemOptions(); options.showTransitions = item->checked(); + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); @@ -1376,6 +1402,11 @@ namespace mrv options.thumbnails = true; options.thumbnailHeight = 100; options.waveformHeight = options.thumbnailHeight / 2; + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); @@ -1388,6 +1419,11 @@ namespace mrv options.thumbnails = true; options.thumbnailHeight = 200; options.waveformHeight = options.thumbnailHeight / 2; + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); @@ -1400,6 +1436,11 @@ namespace mrv options.thumbnails = true; options.thumbnailHeight = 300; options.waveformHeight = options.thumbnailHeight / 2; + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + if (ui->uiPrefs->SendUI->value()) + tcp->pushMessage(msg); ui->uiTimeline->setItemOptions(options); if (editMode != EditMode::kTimeline) set_edit_mode_cb(EditMode::kFull, ui); diff --git a/mrv2/lib/mrvFl/mrvSession.cpp b/mrv2/lib/mrvFl/mrvSession.cpp index ec5f07576..d3a7a2477 100644 --- a/mrv2/lib/mrvFl/mrvSession.cpp +++ b/mrv2/lib/mrvFl/mrvSession.cpp @@ -11,9 +11,10 @@ #include "mrvNetwork/mrvMessage.h" #include "mrvNetwork/mrvCypher.h" -#include "mrvNetwork/mrvFilesModelItem.h" #include "mrvNetwork/mrvCompareOptions.h" #include "mrvNetwork/mrvDisplayOptions.h" +#include "mrvNetwork/mrvFilesModelItem.h" +#include "mrvNetwork/mrvTimelineItemOptions.h" #include "mrvFl/mrvCallbacks.h" #include "mrvPanels/mrvPanelsCallbacks.h" @@ -34,7 +35,7 @@ namespace { const char* kModule = "mrv2s"; - const int kSessionVersion = 8; + const int kSessionVersion = 9; } // namespace namespace @@ -286,6 +287,10 @@ namespace mrv Message background = ui->uiView->getBackgroundOptions(); int stereoIndex = model->observeStereoIndex()->get(); + auto options = ui->uiTimeline->getItemOptions(); + Message timelineViewport = options; + timelineViewport["editable"] = ui->uiTimeline->isEditable(); + session["ui"] = bars; session["panels"] = panels; session["timeline"] = timeline; @@ -300,6 +305,7 @@ namespace mrv session["displayOptions"] = display; session["editMode"] = editMode; session["metadata"] = sessionMetadata; + session["timelineViewport"] = timelineViewport; std::ofstream ofs(fileName); if (!ofs.is_open()) @@ -347,270 +353,293 @@ namespace mrv return false; } - Message session; enable_cypher(false); - ifs >> session; - - if (ifs.fail()) + try { - LOG_ERROR(_("Failed to write to the file.")); - return false; - } - if (ifs.bad()) - { - LOG_ERROR(_("The stream is in an unrecoverable error state.")); - return false; - } - ifs.close(); + Message session; - // Get session version - int version = session["version"]; + ifs >> session; - // Decode session file - close_all_cb(nullptr, ui); + if (ifs.fail()) + { + LOG_ERROR(_("Failed to write to the file.")); + return false; + } + if (ifs.bad()) + { + LOG_ERROR( + _("The stream is in an unrecoverable error state.")); + return false; + } + ifs.close(); - for (const auto& j : session["files"]) - { - FilesModelItem item; - j.get_to(item); + // Get session version + int version = session["version"]; - std::string path = item.path.get(); - std::string audioPath = item.audioPath.get(); + // Decode session file + close_all_cb(nullptr, ui); - replace_path(path); - if (!audioPath.empty()) - replace_path(audioPath); + for (const auto& j : session["files"]) + { + FilesModelItem item; + j.get_to(item); - app->open(path, audioPath); + std::string path = item.path.get(); + std::string audioPath = item.audioPath.get(); - // Copy annotations to both item and player - auto Aitem = model->observeA()->get(); - Aitem->annotations = item.annotations; - Aitem->videoLayer = item.videoLayer; - Aitem->currentTime = item.currentTime; + replace_path(path); + if (!audioPath.empty()) + replace_path(audioPath); - ui->uiColorChannel->value(item.videoLayer); - ui->uiColorChannel->do_callback(); + app->open(path, audioPath); - auto player = view->getTimelinePlayer(); - if (player) - { - player->setAllAnnotations(item.annotations); - player->seek(Aitem->currentTime); - } - } + // Copy annotations to both item and player + auto Aitem = model->observeA()->get(); + Aitem->annotations = item.annotations; + Aitem->videoLayer = item.videoLayer; + Aitem->currentTime = item.currentTime; - if (version >= 2) - { - int Aindex = session["Aindex"]; - model->setA(Aindex); + ui->uiColorChannel->value(item.videoLayer); + ui->uiColorChannel->do_callback(); - std::vector Bindexes = session["Bindexes"]; - model->clearB(); - for (auto i : Bindexes) - model->setB(i, true); + auto player = view->getTimelinePlayer(); + if (player) + { + player->setAllAnnotations(item.annotations); + player->seek(Aitem->currentTime); + } + } - Message j = session["timeline"]; + if (version >= 2) + { + int Aindex = session["Aindex"]; + model->setA(Aindex); - auto tmp = j["annotations"]; + std::vector Bindexes = session["Bindexes"]; + model->clearB(); + for (auto i : Bindexes) + model->setB(i, true); - std::vector< std::shared_ptr > annotations; - for (const auto& value : tmp) - { - auto annotation = draw::messageToAnnotation(value); - annotations.push_back(annotation); - } + Message j = session["timeline"]; - auto player = view->getTimelinePlayer(); - if (player) - { - player->setAllAnnotations(annotations); + auto tmp = j["annotations"]; - if (version >= 3) + std::vector< std::shared_ptr > + annotations; + for (const auto& value : tmp) { - timeline::Playback playback; - if (j["playback"].type() == - nlohmann::json::value_t::string) - { - j.at("playback").get_to(playback); - } - else + auto annotation = draw::messageToAnnotation(value); + annotations.push_back(annotation); + } + + auto player = view->getTimelinePlayer(); + if (player) + { + player->setAllAnnotations(annotations); + + if (version >= 3) { - int v; - j.at("playback").get_to(v); - playback = static_cast(v); + timeline::Playback playback; + if (j["playback"].type() == + nlohmann::json::value_t::string) + { + j.at("playback").get_to(playback); + } + else + { + int v; + j.at("playback").get_to(v); + playback = static_cast(v); + } + player->setPlayback(playback); } - player->setPlayback(playback); - } - otime::RationalTime time; - j["time"].get_to(time); - player->seek(time); + otime::RationalTime time; + j["time"].get_to(time); + player->seek(time); + } } - ui->uiTimeline->redraw(); - ui->uiMain->fill_menu(ui->uiMenuBar); - } - - Message j = session["ui"]; + Message j = session["ui"]; - // Decode bars - toggle_widget(ui->uiMenuGroup, j["menu_bar"]); - toggle_widget(ui->uiTopBar, j["top_bar"]); - toggle_widget(ui->uiPixelBar, j["pixel_bar"]); - toggle_widget(ui->uiBottomBar, j["bottom_bar"]); - toggle_widget(ui->uiStatusBar, j["status_bar"]); - toggle_widget(ui->uiToolsGroup, j["action_bar"]); + // Decode bars + toggle_widget(ui->uiMenuGroup, j["menu_bar"]); + toggle_widget(ui->uiTopBar, j["top_bar"]); + toggle_widget(ui->uiPixelBar, j["pixel_bar"]); + toggle_widget(ui->uiBottomBar, j["bottom_bar"]); + toggle_widget(ui->uiStatusBar, j["status_bar"]); + toggle_widget(ui->uiToolsGroup, j["action_bar"]); - if ((j["secondary_window"] && !ui->uiSecondary) || - (!j["secondary_window"] && ui->uiSecondary)) - { - toggle_secondary_cb(nullptr, ui); - } + if ((j["secondary_window"] && !ui->uiSecondary) || + (!j["secondary_window"] && ui->uiSecondary)) + { + toggle_secondary_cb(nullptr, ui); + } - // Decode ICS - if (version >= 2) - { - // - // Handle color channel layer - // - int layer = session["layer"]; - ui->uiColorChannel->value(layer); - ui->uiColorChannel->do_callback(); + // Decode ICS + if (version >= 2) + { + // + // Handle color channel layer + // + int layer = session["layer"]; + ui->uiColorChannel->value(layer); + ui->uiColorChannel->do_callback(); - // - // Handle OCIO - // - j = session["ocio"]; - std::string config = j["config"]; + // + // Handle OCIO + // + j = session["ocio"]; + std::string config = j["config"]; - replace_path(config); + replace_path(config); - ui->uiPrefs->uiPrefsOCIOConfig->value(config.c_str()); + ui->uiPrefs->uiPrefsOCIOConfig->value(config.c_str()); - Preferences::OCIO(ui); + Preferences::OCIO(ui); - int value = j["ics"]; - ui->uiICS->value(value); - value = j["view"]; - ui->OCIOView->value(value); - ui->uiView->updateColorConfigOptions(); + int value = j["ics"]; + ui->uiICS->value(value); + value = j["view"]; + ui->OCIOView->value(value); + ui->uiView->updateColorConfigOptions(); - // Hide Panels and Windows - removePanels(ui); - removeWindows(ui); + // Hide Panels and Windows + removePanels(ui); + removeWindows(ui); - j = session["settings"]; + j = session["settings"]; - auto settingsObject = app->settingsObject(); + auto settingsObject = app->settingsObject(); - for (const auto& item : j.items()) - { - const std::string& key = item.key(); - Message value = item.value(); - Message::value_t type = value.type(); - switch (type) - { - case Message::value_t::boolean: - settingsObject->setValue(key, value.get()); - continue; - case Message::value_t::number_unsigned: + for (const auto& item : j.items()) { - int v = value.get(); - settingsObject->setValue(key, v); - continue; - } - case Message::value_t::number_integer: - settingsObject->setValue(key, value.get()); - continue; - case Message::value_t::number_float: - { - std_any val = settingsObject->value(key); - if (!std_any_empty(val)) + const std::string& key = item.key(); + Message value = item.value(); + Message::value_t type = value.type(); + switch (type) + { + case Message::value_t::boolean: + settingsObject->setValue(key, value.get()); + continue; + case Message::value_t::number_unsigned: { - try + int v = value.get(); + settingsObject->setValue(key, v); + continue; + } + case Message::value_t::number_integer: + settingsObject->setValue(key, value.get()); + continue; + case Message::value_t::number_float: + { + std_any val = settingsObject->value(key); + if (!std_any_empty(val)) { - double v = std::any_cast(val); - settingsObject->setValue( - key, value.get()); + try + { + double v = std::any_cast(val); + settingsObject->setValue( + key, value.get()); + } + catch (const std::bad_cast& e) + { + settingsObject->setValue( + key, value.get()); + } } - catch (const std::bad_cast& e) + else { settingsObject->setValue( key, value.get()); } + continue; } - else - { - settingsObject->setValue(key, value.get()); + case Message::value_t::string: + settingsObject->setValue( + key, value.get()); + continue; + default: + LOG_ERROR( + "Unknown Message::value_t for key " << key); } - continue; - } - case Message::value_t::string: - settingsObject->setValue(key, value.get()); - continue; - default: - LOG_ERROR("Unknown Message::value_t for key " << key); } } - } - // Decode panels - j = session["panels"]; - const WindowCallback* wc = kWindowCallbacks; - for (; wc->name; ++wc) - { - Message value = j[wc->name]; - bool shown = false; - if (!value.is_null()) - shown = value; - if (shown) + // Decode panels + j = session["panels"]; + const WindowCallback* wc = kWindowCallbacks; + for (; wc->name; ++wc) { - show_window_cb(_(wc->name), ui); + Message value = j[wc->name]; + bool shown = false; + if (!value.is_null()) + shown = value; + if (shown) + { + show_window_cb(_(wc->name), ui); + } } - } - if (version >= 3) - { - EnvironmentMapOptions env = session["environmentMapOptions"]; - view->setEnvironmentMapOptions(env); + if (version >= 3) + { + EnvironmentMapOptions env = + session["environmentMapOptions"]; + view->setEnvironmentMapOptions(env); - timeline::CompareOptions compare = session["compareOptions"]; - model->setCompareOptions(compare); + timeline::CompareOptions compare = + session["compareOptions"]; + model->setCompareOptions(compare); - int stereoIndex = session["stereoIndex"]; - model->setStereo(stereoIndex); + int stereoIndex = session["stereoIndex"]; + model->setStereo(stereoIndex); - Stereo3DOptions stereo = session["stereo3DOptions"]; - model->setStereo3DOptions(stereo); - } + Stereo3DOptions stereo = session["stereo3DOptions"]; + model->setStereo3DOptions(stereo); + } - if (version >= 4) - { - timeline::DisplayOptions display = session["displayOptions"]; - app->setDisplayOptions(display); - } + if (version >= 4) + { + timeline::DisplayOptions display = + session["displayOptions"]; + app->setDisplayOptions(display); + } - if (version >= 6) - { - EditMode editMode = session["editMode"]; - set_edit_mode_cb(editMode, ui); - } + if (version >= 7) + { + session["metadata"].get_to(sessionMetadata); + } - if (version >= 7) - { - session["metadata"].get_to(sessionMetadata); - } + if (version >= 8) + { + timeline::BackgroundOptions background = + session["backgroundOptions"]; + view->setBackgroundOptions(background); + } + + if (version >= 9) + { + Message timelineViewport = session["timelineViewport"]; + auto options = timelineViewport; + bool isEditable = timelineViewport["editable"]; + ui->uiTimeline->setEditable(isEditable); + ui->uiTimeline->setItemOptions(options); + } - if (version >= 8) + if (version >= 6) + { + EditMode editMode = session["editMode"]; + set_edit_mode_cb(editMode, ui); + } + } + catch (const std::exception& e) { - timeline::BackgroundOptions background = - session["backgroundOptions"]; - view->setBackgroundOptions(background); + LOG_ERROR(e.what()); } enable_cypher(true); + ui->uiTimeline->redraw(); ui->uiMain->fill_menu(ui->uiMenuBar); // Change current session filename. diff --git a/mrv2/lib/mrvGL/mrvTimelineWidget.cpp b/mrv2/lib/mrvGL/mrvTimelineWidget.cpp index 754232b2c..2bc091973 100644 --- a/mrv2/lib/mrvGL/mrvTimelineWidget.cpp +++ b/mrv2/lib/mrvGL/mrvTimelineWidget.cpp @@ -1207,7 +1207,7 @@ namespace mrv return 1; case FL_ENTER: cursor(FL_CURSOR_DEFAULT); - if (p.thumbnailWindow && + if (p.thumbnailWindow && p.player && p.ui->uiPrefs->uiPrefsTimelineThumbnails->value()) { p.thumbnailWindow->show(); diff --git a/mrv2/lib/mrvNetwork/CMakeLists.txt b/mrv2/lib/mrvNetwork/CMakeLists.txt index c7344057d..e0a24c3d8 100644 --- a/mrv2/lib/mrvNetwork/CMakeLists.txt +++ b/mrv2/lib/mrvNetwork/CMakeLists.txt @@ -13,6 +13,7 @@ set(HEADERS mrvInsertData.h mrvLUTOptions.h mrvTCP.h + mrvTimelineItemOptions.h mrvMessage.h ) @@ -26,6 +27,7 @@ set(SOURCES mrvInsertData.cpp mrvLUTOptions.cpp mrvTCP.cpp + mrvTimelineItemOptions.cpp ) diff --git a/mrv2/lib/mrvNetwork/mrvCommandInterpreter.cpp b/mrv2/lib/mrvNetwork/mrvCommandInterpreter.cpp index 4543c69f5..f30d04aa9 100644 --- a/mrv2/lib/mrvNetwork/mrvCommandInterpreter.cpp +++ b/mrv2/lib/mrvNetwork/mrvCommandInterpreter.cpp @@ -25,6 +25,7 @@ #include "mrvNetwork/mrvInsertData.h" #include "mrvNetwork/mrvImageOptions.h" #include "mrvNetwork/mrvLUTOptions.h" +#include "mrvNetwork/mrvTimelineItemOptions.h" #include "mrvNetwork/mrvProtocolVersion.h" #include "mrViewer.h" @@ -1244,6 +1245,28 @@ namespace mrv if ((!value && stereo3DPanel) || (value && !stereo3DPanel)) stereo3D_panel_cb(nullptr, ui); } + else if (c == "setTimelineItemOptions") + { + bool receive = prefs->ReceiveUI->value(); + if (!receive) + { + tcp->unlock(); + return; + } + timelineui::ItemOptions value = message["value"]; + ui->uiTimeline->setItemOptions(value); + } + else if (c == "setTimelineEditable") + { + bool receive = prefs->ReceiveUI->value(); + if (!receive) + { + tcp->unlock(); + return; + } + bool value = message["value"]; + ui->uiTimeline->setEditable(value); + } else if (c == "Clear Frame Annotations") { annotation_clear_cb(nullptr, ui); diff --git a/mrv2/lib/mrvNetwork/mrvSyncUI.cpp b/mrv2/lib/mrvNetwork/mrvSyncUI.cpp index f64612bd1..91d35e1d8 100644 --- a/mrv2/lib/mrvNetwork/mrvSyncUI.cpp +++ b/mrv2/lib/mrvNetwork/mrvSyncUI.cpp @@ -7,6 +7,7 @@ #include "mrViewer.h" #include "mrvNetwork/mrvFilesModelItem.h" +#include "mrvNetwork/mrvTimelineItemOptions.h" #include "mrvNetwork/mrvProtocolVersion.h" #include "mrvNetwork/mrvConnectionHandler.h" @@ -44,5 +45,15 @@ namespace mrv "Status Bar", static_cast(ui->uiStatusBar->visible())); tcp->pushMessage( "Action Bar", static_cast(ui->uiToolsGroup->visible())); + + auto options = ui->uiTimeline->getItemOptions(); + Message msg; + msg["command"] = "setTimelineItemOptions"; + msg["value"] = options; + + bool editable = ui->uiTimeline->isEditable(); + msg["command"] = "setTimelineEditable"; + msg["value"] = options; + tcp->pushMessage(msg); } } // namespace mrv diff --git a/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.cpp b/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.cpp new file mode 100644 index 000000000..73db979e2 --- /dev/null +++ b/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.cpp @@ -0,0 +1,32 @@ + + +#include + +namespace tl +{ + namespace timelineui + { + void to_json(nlohmann::json& j, const ItemOptions& value) + { + j["editAssociatedClips"] = value.editAssociatedClips; + j["thumbnails"] = value.thumbnails; + j["thumbnailHeight"] = value.thumbnailHeight; + j["waveformWidth"] = value.waveformHeight; + j["waveformHeight"] = value.waveformHeight; + j["showTransitions"] = value.showTransitions; + j["showMarkers"] = value.showMarkers; + } + + void from_json(const nlohmann::json& j, ItemOptions& value) + { + j.at("editAssociatedClips").get_to(value.editAssociatedClips); + j.at("thumbnails").get_to(value.thumbnails); + j.at("thumbnailHeight").get_to(value.thumbnailHeight); + j.at("waveformWidth").get_to(value.waveformWidth); + j.at("waveformHeight").get_to(value.waveformHeight); + j.at("showTransitions").get_to(value.showTransitions); + j.at("showMarkers").get_to(value.showMarkers); + } + }; // namespace timelineui + +} // namespace tl diff --git a/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.h b/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.h new file mode 100644 index 000000000..dbe89e92a --- /dev/null +++ b/mrv2/lib/mrvNetwork/mrvTimelineItemOptions.h @@ -0,0 +1,15 @@ + +#pragma once + +#include + +namespace tl +{ + namespace timelineui + { + void to_json(nlohmann::json& j, const ItemOptions& value); + + void from_json(const nlohmann::json& j, ItemOptions& value); + }; // namespace timelineui + +} // namespace tl