mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-25 06:19:02 -06:00
improve look and feel of scenegraph node property documentation
This commit is contained in:
@@ -49,6 +49,10 @@
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.documentation-small {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Start Bootstrap - Simple Sidebar (http://startbootstrap.com/)
|
||||
|
||||
41
data/web/properties/main.hbs
Normal file
41
data/web/properties/main.hbs
Normal file
@@ -0,0 +1,41 @@
|
||||
<div id="wrapper">
|
||||
<div id="sidebar-wrapper">
|
||||
<ul class="sidebar-nav">
|
||||
<li class="sidebar-brand">
|
||||
<a href="#">
|
||||
OpenSpace Scene Properties
|
||||
</a>
|
||||
</li>
|
||||
{{#each propertyOwners}}
|
||||
<li>
|
||||
<a href="#{{name}}">{{name}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="page-content-wrapper">
|
||||
<div class="container-fluid documentation-container">
|
||||
<h1>OpenSpace Scene Properties</h1>
|
||||
<p>Version: {{version.[0]}}.{{version.[1]}}.{{version.[2]}}</p>
|
||||
<p>Scene name: {{sceneFilename}}</p>
|
||||
<p>Generated: {{generationTime}}</p>
|
||||
|
||||
{{#each propertyOwners}}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h2><a class="documentation-name" href="#{{name}}" name="{{name}}">{{name}}</a></h2>
|
||||
{{#each properties}}
|
||||
{{> property}}
|
||||
{{/each}}
|
||||
{{#each propertyOwners}}
|
||||
{{> propertyOwner}}
|
||||
{{else}}
|
||||
<p>{{name}} has no property owners</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
15
data/web/properties/property.hbs
Normal file
15
data/web/properties/property.hbs
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="documentation-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-12" title="{{guiName}}">
|
||||
<p>
|
||||
<a href="#{{fullyQualifiedId}}" name="{{fullyQualifiedId}}">
|
||||
<span class="documentation-type">{{type}}</span>
|
||||
<span class="documentation-key">{{id}}</span>
|
||||
</a>
|
||||
</p>
|
||||
<p class="documentation-description">{{fullyQualifiedId}}
|
||||
<a class="documentation-small" onclick="copyTextToClipboard('{{fullyQualifiedId}}')">copy</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
18
data/web/properties/propertyowner.hbs
Normal file
18
data/web/properties/propertyowner.hbs
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="documentation-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<p>
|
||||
<a href="#{{urlify name}}" name="{{urlify name}}">
|
||||
<span class="documentation-key">{{name}}</span>
|
||||
</a>
|
||||
</p>
|
||||
{{#each properties}}
|
||||
{{> property}}
|
||||
{{/each}}
|
||||
{{#each propertyOwners}}
|
||||
{{> propertyOwner}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
58
data/web/properties/script.js
Normal file
58
data/web/properties/script.js
Normal file
@@ -0,0 +1,58 @@
|
||||
function copyTextToClipboard(text) {
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.top = 0;
|
||||
textArea.style.left = 0;
|
||||
|
||||
textArea.style.width = '2em';
|
||||
textArea.style.height = '2em';
|
||||
|
||||
textArea.style.padding = 0;
|
||||
|
||||
textArea.style.border = 'none';
|
||||
textArea.style.outline = 'none';
|
||||
textArea.style.boxShadow = 'none';
|
||||
|
||||
textArea.style.background = 'transparent';
|
||||
textArea.value = text;
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
|
||||
textArea.select();
|
||||
document.execCommand('copy');
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
var mainTemplateElement = document.getElementById('mainTemplate');
|
||||
var mainTemplate = Handlebars.compile(mainTemplateElement.innerHTML);
|
||||
|
||||
var propertyOwnerTemplateElement = document.getElementById('propertyOwnerTemplate');
|
||||
Handlebars.registerPartial('propertyOwner', propertyOwnerTemplateElement.innerHTML);
|
||||
|
||||
var propertyTemplateElement = document.getElementById('propertyTemplate');
|
||||
Handlebars.registerPartial('property', propertyTemplateElement.innerHTML);
|
||||
|
||||
Handlebars.registerHelper('urlify', function(options, context) {
|
||||
var data = context.data;
|
||||
var identifier = options.replace(" ", "-").toLowerCase();
|
||||
|
||||
while (data = data._parent) {
|
||||
if (data.key !== undefined) {
|
||||
identifier = data.key + "-" + identifier;
|
||||
}
|
||||
}
|
||||
return identifier;
|
||||
});
|
||||
|
||||
var data = {
|
||||
propertyOwners: propertyOwners,
|
||||
version: version,
|
||||
sceneFilename: sceneFilename,
|
||||
generationTime: generationTime
|
||||
}
|
||||
|
||||
var contents = mainTemplate(data);
|
||||
document.body.innerHTML = contents;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
private:
|
||||
bool loadSceneInternal(const std::string& sceneDescriptionFilePath);
|
||||
|
||||
void writePropertyDocumentation(const std::string& filename, const std::string& type);
|
||||
void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename);
|
||||
|
||||
std::string _focus;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
@@ -68,6 +69,14 @@ namespace {
|
||||
const std::string KeyFocusObject = "Focus";
|
||||
const std::string KeyPositionObject = "Position";
|
||||
const std::string KeyViewOffset = "Offset";
|
||||
|
||||
const std::string MainTemplateFilename = "${OPENSPACE_DATA}/web/properties/main.hbs";
|
||||
const std::string PropertyOwnerTemplateFilename = "${OPENSPACE_DATA}/web/properties/propertyowner.hbs";
|
||||
const std::string PropertyTemplateFilename = "${OPENSPACE_DATA}/web/properties/property.hbs";
|
||||
const std::string HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const std::string JsFilename = "${OPENSPACE_DATA}/web/properties/script.js";
|
||||
const std::string BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const std::string CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -268,7 +277,7 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
|
||||
OsEng.configurationManager().getValue(KeyPropertyDocumentationFile, propertyDocumentationFile);
|
||||
|
||||
propertyDocumentationFile = absPath(propertyDocumentationFile);
|
||||
writePropertyDocumentation(propertyDocumentationFile, propertyDocumentationType);
|
||||
writePropertyDocumentation(propertyDocumentationFile, propertyDocumentationType, sceneDescriptionFilePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -442,7 +451,7 @@ SceneGraph& Scene::sceneGraph() {
|
||||
return _graph;
|
||||
}
|
||||
|
||||
void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type) {
|
||||
void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename) {
|
||||
LDEBUG("Writing documentation for properties");
|
||||
if (type == "text") {
|
||||
std::ofstream file;
|
||||
@@ -469,7 +478,37 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(filename);
|
||||
|
||||
#ifdef JSON
|
||||
|
||||
std::ifstream handlebarsInput(absPath(HandlebarsFilename));
|
||||
std::ifstream jsInput(absPath(JsFilename));
|
||||
|
||||
std::string jsContent;
|
||||
std::back_insert_iterator<std::string> jsInserter(jsContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
|
||||
std::ifstream bootstrapInput(absPath(BootstrapFilename));
|
||||
std::ifstream cssInput(absPath(CssFilename));
|
||||
|
||||
std::string cssContent;
|
||||
std::back_insert_iterator<std::string> cssInserter(cssContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
|
||||
std::ifstream mainTemplateInput(absPath(MainTemplateFilename));
|
||||
std::string mainTemplateContent{ std::istreambuf_iterator<char>{mainTemplateInput},
|
||||
std::istreambuf_iterator<char>{} };
|
||||
|
||||
std::ifstream propertyOwnerTemplateInput(absPath(PropertyOwnerTemplateFilename));
|
||||
std::string propertyOwnerTemplateContent{ std::istreambuf_iterator<char>{propertyOwnerTemplateInput},
|
||||
std::istreambuf_iterator<char>{} };
|
||||
|
||||
std::ifstream propertyTemplateInput(absPath(PropertyTemplateFilename));
|
||||
std::string propertyTemplateContent{ std::istreambuf_iterator<char>{propertyTemplateInput},
|
||||
std::istreambuf_iterator<char>{} };
|
||||
|
||||
// Create JSON
|
||||
std::function<std::string(properties::PropertyOwner*)> createJson =
|
||||
[&createJson](properties::PropertyOwner* owner) -> std::string
|
||||
@@ -479,22 +518,30 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
|
||||
json << "\"name\": \"" << owner->name() << "\",";
|
||||
|
||||
json << "\"properties\": [";
|
||||
for (properties::Property* p : owner->properties()) {
|
||||
auto properties = owner->properties();
|
||||
for (properties::Property* p : properties) {
|
||||
json << "{";
|
||||
json << "\"id\": \"" << p->identifier() << "\",";
|
||||
json << "\"type\": \"" << p->className() << "\",";
|
||||
json << "\"fullyQualifiedId\": \"" << p->fullyQualifiedIdentifier() << "\",";
|
||||
json << "\"guiName\": \"" << p->guiName() << "\",";
|
||||
json << "},";
|
||||
json << "\"guiName\": \"" << p->guiName() << "\"";
|
||||
json << "}";
|
||||
if (p != properties.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
json << "],";
|
||||
|
||||
json << "\"propertyOwner\": [";
|
||||
for (properties::PropertyOwner* o : owner->propertySubOwners()) {
|
||||
json << "\"propertyOwners\": [";
|
||||
auto propertyOwners = owner->propertySubOwners();
|
||||
for (properties::PropertyOwner* o : propertyOwners) {
|
||||
json << createJson(o);
|
||||
if (o != propertyOwners.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
json << "],";
|
||||
json << "},";
|
||||
json << "]";
|
||||
json << "}";
|
||||
|
||||
return json.str();
|
||||
};
|
||||
@@ -502,15 +549,56 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
|
||||
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
auto nodes = _graph.nodes();
|
||||
for (SceneGraphNode* node : nodes) {
|
||||
json << createJson(node);
|
||||
if (node != nodes.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
|
||||
json << "]";
|
||||
|
||||
std::string jsonText = json.str();
|
||||
#else
|
||||
std::string jsonString = "";
|
||||
for (const char& c : json.str()) {
|
||||
if (c == '\'') {
|
||||
jsonString += "\\'";
|
||||
} else {
|
||||
jsonString += c;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream html;
|
||||
html << "<!DOCTYPE html>\n"
|
||||
<< "<html>\n"
|
||||
<< "\t<head>\n"
|
||||
<< "\t\t<script id=\"mainTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< mainTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t\t<script id=\"propertyOwnerTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< propertyOwnerTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t\t<script id=\"propertyTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< propertyTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t<script>\n"
|
||||
<< "var propertyOwners = JSON.parse('" << jsonString << "');\n"
|
||||
<< "var version = [" << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << ", " << OPENSPACE_VERSION_PATCH << "];\n"
|
||||
<< "var sceneFilename = '" << sceneFilename << "';\n"
|
||||
<< "var generationTime = '" << Time::now().ISO8601() << "';\n"
|
||||
<< jsContent << "\n"
|
||||
<< "\t</script>\n"
|
||||
<< "\t<style type=\"text/css\">\n"
|
||||
<< cssContent << "\n"
|
||||
<< "\t</style>\n"
|
||||
<< "\t\t<title>Documentation</title>\n"
|
||||
<< "\t</head>\n"
|
||||
<< "\t<body>\n"
|
||||
<< "\t<body>\n"
|
||||
<< "</html>\n";
|
||||
|
||||
/*
|
||||
|
||||
html << "<html>\n"
|
||||
<< "\t<head>\n"
|
||||
<< "\t\t<title>Properties</title>\n"
|
||||
@@ -546,9 +634,8 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
|
||||
<< "</table>\n"
|
||||
<< "</html>;";
|
||||
|
||||
*/
|
||||
file << html.str();
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
LERROR("Undefined type '" << type << "' for Property documentation");
|
||||
|
||||
@@ -158,8 +158,7 @@ void FactoryManager::writeDocumentation(const std::string& file, const std::stri
|
||||
for (const char& c : json.str()) {
|
||||
if (c == '\'') {
|
||||
jsonString += "\\'";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
jsonString += c;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user