Skip to content

Commit dbaa731

Browse files
authored
Add media reference to inspector (#68)
Signed-off-by: jspadafora <jspadafora@ilm.com>
1 parent f41b498 commit dbaa731

4 files changed

Lines changed: 187 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33

44
build
5+
.vscode
56
*.DS_Store

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ This will also clone and initialize all of the submodules that this project depe
3131

3232
## Building (macOS, Windows, Linux)
3333

34-
Spin up your favourite terminal and follow these steps:
34+
Spin up your favorite terminal and follow these steps:
3535

3636
```shell
3737
git clone --recursive https://github.com/OpenTimelineIO/raven.git

app.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ struct AppState {
127127
char message[1024]; // single-line message displayed in main window
128128
bool message_is_error = false;
129129

130+
// Store the currently selected MediaReference index for the inspector.
131+
int selected_reference_index = -1;
132+
130133
// Toggles for Dear ImGui windows
131134
bool show_main_window = true;
132135
bool show_style_editor = false;

inspector.cpp

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
#include <opentimelineio/anyDictionary.h>
1111
#include <opentimelineio/clip.h>
1212
#include <opentimelineio/composition.h>
13-
#include <opentimelineio/effect.h>
13+
#include <opentimelineio/externalReference.h>
1414
#include <opentimelineio/gap.h>
15+
#include <opentimelineio/imageSequenceReference.h>
1516
#include <opentimelineio/linearTimeWarp.h>
1617
#include <opentimelineio/marker.h>
18+
#include <opentimelineio/mediaReference.h>
19+
#include <opentimelineio/missingReference.h>
1720
#include <opentimelineio/track.h>
1821
#include <opentimelineio/transition.h>
1922

@@ -85,6 +88,10 @@ void UpdateJSONInspector() {
8588
json_edited = false;
8689
json_error_message = "";
8790
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;
8895
}
8996

9097
void SetJSONErrorMessage(std::string message) {
@@ -126,6 +133,65 @@ void SetJSONErrorMessage(std::string message) {
126133
ErrorMessage("%s", json_error_message.c_str());
127134
}
128135

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+
129195
void DrawJSONApplyEditButtons() {
130196
if (ImGui::Button("Apply")) {
131197
otio::ErrorStatus error_status;
@@ -704,6 +770,121 @@ void DrawInspector() {
704770

705771
DrawMetadataTable(metadata);
706772
}
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+
}
707888
}
708889

709890
void DrawMarkersInspector() {

0 commit comments

Comments
 (0)