diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 2509e50807..66b39145a8 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -125,7 +125,8 @@ Graph::Graph(const std::string& materialFilename, const mx::FileSearchPath& searchPath, const mx::FilePathVec& libraryFolders, int viewWidth, - int viewHeight) : + int viewHeight, + float previewWidth) : _materialFilename(materialFilename), _searchPath(searchPath), _libraryFolders(libraryFolders), @@ -143,6 +144,7 @@ Graph::Graph(const std::string& materialFilename, _autoLayout(false), _frameCount(INT_MIN), _fontScale(1.0f), + _previewSize(previewWidth), _saveNodePositions(true) { loadStandardLibraries(); @@ -903,12 +905,60 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr input, const mx } else if (input->getType() == "filename") { - mx::ValuePtr val = input->getValue(); + mx::ValuePtr val = input->getResolvedValue(); if (val && val->isA()) { std::string prev, temp; prev = temp = val->asA(); + mx::FilePath filePath(temp); + + bool drawPreview = _previewSize > 0; + if (drawPreview) + { + float previewSize = _previewSize; + // Clamp preview size to width of panel + float panelWidth = ImGui::GetContentRegionAvail().x; + if (previewSize > panelWidth) + { + previewSize = panelWidth; + } + + ImGui::BeginChild("imagePreview", ImVec2(previewSize, previewSize), false, + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); + + // Show image preview if file exists and is an image + if (!temp.empty()) + { + mx::ImageHandlerPtr imageHandler = _renderer ? _renderer->getImageHandler() : nullptr; + if (imageHandler) + { + unsigned int textureId = 0; + int width = 0, height = 0; + mx::ImagePtr image = imageHandler->acquireImage(filePath); + if (image) + { + textureId = image->getResourceId(); + width = image->getWidth(); + height = image->getHeight(); + } + else + { + std::cout << "Image file not loaded: " << temp << std::endl; + } + if (textureId) + { + float aspect = (height > 0) ? (float)width / (float)height : 1.0f; + ImVec2 imagePreviewSize(previewSize, previewSize / aspect); + + ImGui::Image((void*)(intptr_t)textureId, imagePreviewSize); + } + } + } + ImGui::EndChild(); + //ImGui::PopItemWidth(); + } + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.15f, .15f, .15f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.2f, .4f, .6f, 1.0f)); @@ -923,7 +973,8 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr input, const mx } ImGui::PopItemWidth(); ImGui::SameLine(); - ImGui::Text("%s", mx::FilePath(temp).getBaseName().c_str()); + ImGui::Text("%s", filePath.getBaseName().c_str()); + ImGui::PopStyleColor(); ImGui::PopStyleColor(); @@ -3382,23 +3433,32 @@ void Graph::propertyEditor() { _currUiNode->setShowAllInputs(showAllInputs); } - bool showOutputsInEditor = _currUiNode->getShowOutputsInEditor(); - if (ImGui::Checkbox("Show output connections", &showOutputsInEditor)) + + int count = 0; + float totalImagePadding = 0.0f; + float imagePadding = 0.0f; + if (_previewSize > 0.0f) { - _currUiNode->setShowOutputsInEditor(showOutputsInEditor); + imagePadding = (_previewSize > availableWidth) ? availableWidth : _previewSize; } - int count = 0; for (UiPinPtr input : _currUiNode->getInputPins()) { if (_currUiNode->getShowAllInputs() || (input->getConnected() || _currUiNode->getNode()->getInput(input->getName()))) { count++; + + // Add space for image previews + if (imagePadding > 0.0f && input->getInput()->getType() == "filename") + { + totalImagePadding += imagePadding; + } } } if (count) { - ImVec2 tableSize(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)); + float baseHeight = TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count); + ImVec2 tableSize(0.0f, baseHeight + totalImagePadding); bool haveTable = ImGui::BeginTable("inputs_node_table", 2, tableFlags, tableSize); if (haveTable) { diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 31c9f186e5..1688cf8fa4 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -92,7 +92,8 @@ class Graph const mx::FileSearchPath& searchPath, const mx::FilePathVec& libraryFolders, int viewWidth, - int viewHeight); + int viewHeight, + float previewWidth); ~Graph() = default; mx::DocumentPtr loadDocument(const mx::FilePath& filename); @@ -344,6 +345,9 @@ class Graph // Layout engine Layout _layout; + // Preview area size + float _previewSize; + // Options bool _saveNodePositions; }; diff --git a/source/MaterialXGraphEditor/Main.cpp b/source/MaterialXGraphEditor/Main.cpp index 2a1aedf1df..4d17e925fc 100644 --- a/source/MaterialXGraphEditor/Main.cpp +++ b/source/MaterialXGraphEditor/Main.cpp @@ -34,6 +34,7 @@ const std::string options = " --font [FILENAME] Specify the name of the custom font file to use. If not specified the default font will be used.\n" " --fontSize [SIZE] Specify font size to use for the custom font. If not specified a default of 18 will be used.\n" " --captureFilename [FILENAME] Specify the filename to which the first rendered frame should be written\n" + " --previewWidth [WIDTH] Specify the width for image previews\n" " --help Display the complete list of command-line options\n"; template void parseToken(std::string token, std::string type, T& res) @@ -72,6 +73,7 @@ int main(int argc, char* const argv[]) float uiScale = 0.0f; std::string fontFilename; int fontSize = 18; + float previewWidth = 256.0f; std::string captureFilename; for (size_t i = 0; i < tokens.size(); i++) @@ -115,6 +117,10 @@ int main(int argc, char* const argv[]) { parseToken(nextToken, "integer", fontSize); } + else if (token == "--previewWidth") + { + parseToken(nextToken, "float", previewWidth); + } else if (token == "--captureFilename") { parseToken(nextToken, "string", captureFilename); @@ -224,7 +230,8 @@ int main(int argc, char* const argv[]) searchPath, libraryFolders, viewWidth, - viewHeight); + viewHeight, + previewWidth); if (!captureFilename.empty()) { graph->getRenderer()->requestFrameCapture(captureFilename);