|
10 | 10 | #include <opentimelineio/anyDictionary.h> |
11 | 11 | #include <opentimelineio/clip.h> |
12 | 12 | #include <opentimelineio/composition.h> |
13 | | -#include <opentimelineio/effect.h> |
| 13 | +#include <opentimelineio/externalReference.h> |
14 | 14 | #include <opentimelineio/gap.h> |
| 15 | +#include <opentimelineio/imageSequenceReference.h> |
15 | 16 | #include <opentimelineio/linearTimeWarp.h> |
16 | 17 | #include <opentimelineio/marker.h> |
| 18 | +#include <opentimelineio/mediaReference.h> |
| 19 | +#include <opentimelineio/missingReference.h> |
17 | 20 | #include <opentimelineio/track.h> |
18 | 21 | #include <opentimelineio/transition.h> |
19 | 22 |
|
@@ -85,6 +88,10 @@ void UpdateJSONInspector() { |
85 | 88 | json_edited = false; |
86 | 89 | json_error_message = ""; |
87 | 90 | json_error_line = -1; |
| 91 | + |
| 92 | + // When the user selects a new clip, we need to update the selected reference index |
| 93 | + // this allows the inspector to show the correct reference when the user selects a clip |
| 94 | + appState.selected_reference_index = -1; |
88 | 95 | } |
89 | 96 |
|
90 | 97 | void SetJSONErrorMessage(std::string message) { |
@@ -126,6 +133,65 @@ void SetJSONErrorMessage(std::string message) { |
126 | 133 | ErrorMessage("%s", json_error_message.c_str()); |
127 | 134 | } |
128 | 135 |
|
| 136 | +void DrawAvailableImageBounds( |
| 137 | + char const* label, |
| 138 | + otio::MediaReference* media_reference) { |
| 139 | + /* |
| 140 | + * Draw the widgets for viewing and modifying the available image bounds. |
| 141 | + * |
| 142 | + * @parm label: The label to display above the widgets. |
| 143 | + * @parm media_reference: The media reference to get the available image bounds from |
| 144 | + * and set the new bounds to. |
| 145 | + */ |
| 146 | + |
| 147 | + auto available_image_bounds = media_reference->available_image_bounds(); |
| 148 | + |
| 149 | + ImGui::Text("%s", label); |
| 150 | + ImGui::Indent(); |
| 151 | + |
| 152 | + Imath_3_2::Box2d bounds = available_image_bounds.value(); |
| 153 | + |
| 154 | + ImGui::Text("Min:"); |
| 155 | + ImGui::SameLine(); |
| 156 | + ImGui::PushItemWidth(100); |
| 157 | + float min_x = static_cast<float>(available_image_bounds->min.x); |
| 158 | + if (ImGui::InputFloat("##min_x", &min_x)) { |
| 159 | + bounds.min.x = static_cast<double>(min_x); |
| 160 | + }; |
| 161 | + ImGui::SameLine(); |
| 162 | + |
| 163 | + float min_y = static_cast<float>(available_image_bounds->min.y); |
| 164 | + if (ImGui::InputFloat("##min_y", &min_y)) { |
| 165 | + bounds.min.y = static_cast<double>(min_y); |
| 166 | + }; |
| 167 | + |
| 168 | + ImGui::PopItemWidth(); |
| 169 | + |
| 170 | + ImGui::Text("Max:"); |
| 171 | + ImGui::SameLine(); |
| 172 | + ImGui::PushItemWidth(100); |
| 173 | + |
| 174 | + float max_x = static_cast<float>(available_image_bounds->max.x); |
| 175 | + if (ImGui::InputFloat("##max_x", &max_x)) { |
| 176 | + bounds.max.x = static_cast<double>(max_x); |
| 177 | + }; |
| 178 | + ImGui::SameLine(); |
| 179 | + |
| 180 | + float max_y = static_cast<float>(available_image_bounds->max.y); |
| 181 | + if (ImGui::InputFloat("##max_y", &max_y)) { |
| 182 | + bounds.max.y = static_cast<double>(max_y); |
| 183 | + }; |
| 184 | + ImGui::PopItemWidth(); |
| 185 | + ImGui::Unindent(); |
| 186 | + |
| 187 | + if (bounds != available_image_bounds.value()) { |
| 188 | + // Ensure that the min is less than the max on the x and y |
| 189 | + if (bounds.min.x < bounds.max.x && bounds.min.y < bounds.max.y) { |
| 190 | + media_reference->set_available_image_bounds(bounds); |
| 191 | + } |
| 192 | + } |
| 193 | +} |
| 194 | + |
129 | 195 | void DrawJSONApplyEditButtons() { |
130 | 196 | if (ImGui::Button("Apply")) { |
131 | 197 | otio::ErrorStatus error_status; |
@@ -704,6 +770,121 @@ void DrawInspector() { |
704 | 770 |
|
705 | 771 | DrawMetadataTable(metadata); |
706 | 772 | } |
| 773 | + |
| 774 | + // Draw Reference Media Information |
| 775 | + if (const auto& clip = dynamic_cast<otio::Clip*>(selected_object)) { |
| 776 | + ImGui::Dummy(ImVec2(0.0f, 20.0f)); |
| 777 | + ImGui::Text("Selected media reference:"); |
| 778 | + |
| 779 | + const auto& media_references = clip->media_references(); |
| 780 | + |
| 781 | + // Array of names and corresponding MediaReference pointers |
| 782 | + std::vector<const char*> reference_names; |
| 783 | + otio::MediaReference** reference_objects = new otio::MediaReference*[media_references.size()]; |
| 784 | + |
| 785 | + size_t i = 0; |
| 786 | + for (const auto& media_reference : media_references) { |
| 787 | + reference_names.push_back(media_reference.first.c_str()); |
| 788 | + reference_objects[i] = media_reference.second; |
| 789 | + i++; |
| 790 | + } |
| 791 | + int num_references = static_cast<int>(media_references.size()); |
| 792 | + |
| 793 | + std::string current_reference_name = clip->active_media_reference_key(); |
| 794 | + |
| 795 | + // Select the active media reference if it is not already set in the appState. |
| 796 | + if (appState.selected_reference_index == -1) { |
| 797 | + for (int i = 0; i < num_references; i++) { |
| 798 | + if (current_reference_name == reference_names[i]) { |
| 799 | + appState.selected_reference_index = i; |
| 800 | + break; |
| 801 | + } |
| 802 | + } |
| 803 | + } |
| 804 | + |
| 805 | + // Set the active media ref key based on user selection |
| 806 | + if (ImGui::Combo("", &appState.selected_reference_index, reference_names.data(), num_references)) { |
| 807 | + if (appState.selected_reference_index >= 0 && appState.selected_reference_index < num_references) { |
| 808 | + clip->set_active_media_reference_key(reference_names[appState.selected_reference_index]); |
| 809 | + } |
| 810 | + } |
| 811 | + |
| 812 | + // Retrieve the selected MediaReference object |
| 813 | + otio::MediaReference* selected_reference = nullptr; |
| 814 | + if (appState.selected_reference_index >= 0 && appState.selected_reference_index < num_references) { |
| 815 | + selected_reference = reference_objects[appState.selected_reference_index]; |
| 816 | + } else { |
| 817 | + std::cerr << "Error: Selected reference index is out of range." << std::endl; |
| 818 | + } |
| 819 | + |
| 820 | + if (selected_reference) { |
| 821 | + ImGui::Indent(); |
| 822 | + ImGui::Dummy(ImVec2(0.0f, 5.0f)); |
| 823 | + |
| 824 | + if (auto external_ref = dynamic_cast<otio::ExternalReference*>(selected_reference)) { |
| 825 | + ImGui::Text("Type: External Media"); |
| 826 | + snprintf(tmp_str, sizeof(tmp_str), "%s", external_ref->target_url().c_str()); |
| 827 | + if (ImGui::InputText("Target", tmp_str, sizeof(tmp_str))) { |
| 828 | + external_ref->set_target_url(tmp_str); |
| 829 | + } |
| 830 | + |
| 831 | + auto available_range = external_ref->available_range(); |
| 832 | + if (available_range && DrawTimeRange("Available range", &(*available_range), false)) { |
| 833 | + external_ref->set_available_range(available_range); |
| 834 | + } |
| 835 | + |
| 836 | + auto available_image_bounds = external_ref->available_image_bounds(); |
| 837 | + if (available_image_bounds) { |
| 838 | + DrawAvailableImageBounds("Available image bounds", external_ref); |
| 839 | + } |
| 840 | + |
| 841 | + ImGui::Text("Metadata:"); |
| 842 | + DrawMetadataTable(external_ref->metadata()); |
| 843 | + |
| 844 | + } else if (auto missing_ref = dynamic_cast<otio::MissingReference*>(selected_reference)) { |
| 845 | + ImGui::Text("Type: Missing Media"); |
| 846 | + |
| 847 | + auto available_range = missing_ref->available_range(); |
| 848 | + if (available_range && DrawTimeRange("Available range", &(*available_range), false)) { |
| 849 | + missing_ref->set_available_range(available_range); |
| 850 | + } |
| 851 | + |
| 852 | + auto available_image_bounds = missing_ref->available_image_bounds(); |
| 853 | + if (available_image_bounds) { |
| 854 | + DrawAvailableImageBounds("Available image bounds", missing_ref); |
| 855 | + } |
| 856 | + |
| 857 | + ImGui::Text("Metadata:"); |
| 858 | + DrawMetadataTable(missing_ref->metadata()); |
| 859 | + } else if (auto imageSeqRef = dynamic_cast<otio::ImageSequenceReference*>(selected_reference)) { |
| 860 | + ImGui::Text("Type: Image Sequence"); |
| 861 | + |
| 862 | + auto target_url = imageSeqRef->target_url_base(); |
| 863 | + if (ImGui::InputText("Target url base", tmp_str, sizeof(tmp_str))) { |
| 864 | + imageSeqRef->set_target_url_base(tmp_str); |
| 865 | + } |
| 866 | + |
| 867 | + auto available_range = imageSeqRef->available_range(); |
| 868 | + if (available_range && DrawTimeRange("Available range", &(*available_range), false)) { |
| 869 | + imageSeqRef->set_available_range(available_range); |
| 870 | + } |
| 871 | + |
| 872 | + auto available_image_bounds = imageSeqRef->available_image_bounds(); |
| 873 | + if (available_image_bounds) { |
| 874 | + DrawAvailableImageBounds("Available image bounds", imageSeqRef); |
| 875 | + } |
| 876 | + |
| 877 | + ImGui::Text("Metadata:"); |
| 878 | + DrawMetadataTable(imageSeqRef->metadata()); |
| 879 | + |
| 880 | + } else { |
| 881 | + ImGui::Text("Type: The selected media type is not yet supported in the inspector."); |
| 882 | + } |
| 883 | + ImGui::Unindent(); |
| 884 | + } else { |
| 885 | + ImGui::Text("No media reference found."); |
| 886 | + } |
| 887 | + } |
707 | 888 | } |
708 | 889 |
|
709 | 890 | void DrawMarkersInspector() { |
|
0 commit comments