13 May 2018
Property Inspector for the Viewer
The Viewer does not show all the information available for the selected item. It also does not show references between database items (those properties have the type = 11 / DbKey) - property types are listed here: https://stackoverflow.com/questions/46619701/how-to-get-property-types
However, it could be useful to see everything, and being able to traverse the properties across references as well.
This is what the following code allows you to do. It shows all the available properties for a given item, and also lets you jump to the item referenced by a given property. It also keeps track of your path by showing dbId breadcrumbs in the property palette's title. You can click on either a property with name including [dbId] or on the breadcrumb items in the title to jump to the referenced database item - see highlighted items in the above picture.
function showAllProperties(viewer) {
function ModelSummaryPanel (viewer, container, id, title, options) {
this.viewer = viewer;
this.breadcrumbsItems = [];
Autodesk.Viewing.UI.PropertyPanel.call(this, container, id, title, options);
this.showBreadcrumbs = function () {
// Create it if not there yet
if (!this.breadcrumbs) {
this.breadcrumbs = document.createElement('span');
this.title.appendChild(this.breadcrumbs);
} else {
while (this.breadcrumbs.firstChild) {
this.breadcrumbs.removeChild(this.breadcrumbs.firstChild);
}
}
// Fill it with items
this.breadcrumbs.appendChild(document.createTextNode(' ['));
this.breadcrumbsItems.forEach(dbId => {
if (this.breadcrumbs.children.length > 0) {
var text = document.createTextNode(' > ');
this.breadcrumbs.appendChild(text);
}
var item = document.createElement('a');
item.innerText = dbId;
item.style.cursor = "pointer";
item.onclick = this.onBreadcrumbClick.bind(this);
this.breadcrumbs.appendChild(item);
});
this.breadcrumbs.appendChild(document.createTextNode(']'));
}; // showBreadcrumbs
this.showProperties = function (dbId) {
this.removeAllProperties();
var that = this;
this.viewer.getProperties(dbId, props => {
props.properties.forEach(prop => {
that.addProperty(
prop.displayName + ((prop.type === 11) ? "[dbId]" : ""),
prop.displayValue,
prop.displayCategory
);
});
});
this.breadcrumbsItems.push(dbId);
this.showBreadcrumbs();
}; // showProperties
this.onBreadcrumbClick = function (event) {
var dbId = parseInt(event.currentTarget.text);
var index = this.breadcrumbsItems.indexOf(dbId)
this.breadcrumbsItems = this.breadcrumbsItems.splice(0, index);
this.showProperties(dbId);
}; // onBreadcrumbClicked
// This is overriding the default property click handler
// of Autodesk.Viewing.UI.PropertyPanel
this.onPropertyClick = function (property) {
if (!property.name.includes("[dbId]")) {
return;
}
var dbId = property.value;
this.showProperties(dbId);
}; // onPropertyClick
this.onSelectionChanged = function (event) {
var dbId = event.dbIdArray[0];
if (!dbId) {
dbId = this.viewer.model.getRootId();
}
this.breadcrumbsItems = [];
this.showProperties(dbId);
} // onSelectionChanged
viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
this.onSelectionChanged.bind(this)
);
}; // ModelSummaryPanel
ModelSummaryPanel.prototype = Object.create(Autodesk.Viewing.UI.PropertyPanel.prototype);
ModelSummaryPanel.prototype.constructor = ModelSummaryPanel;
var panel = new ModelSummaryPanel(viewer, viewer.container, 'AllPropertiesPanel', 'All Properties');
panel.setVisible(true);
panel.showProperties(viewer.model.getRootId());
}
You can also take the code in the form of an extension that you can just copy-paste into a JavaScript file, add it to your project and just load it into your viewerApp.
// *******************************************
// Property Inspector Extension
// *******************************************
function PropertyInspectorExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
this.panel = null;
}
PropertyInspectorExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
PropertyInspectorExtension.prototype.constructor = PropertyInspectorExtension;
PropertyInspectorExtension.prototype.load = function () {
if (this.viewer.toolbar) {
// Toolbar is already available, create the UI
this.createUI();
} else {
// Toolbar hasn't been created yet, wait until we get notification of its creation
this.onToolbarCreatedBinded = this.onToolbarCreated.bind(this);
this.viewer.addEventListener(av.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
}
return true;
};
PropertyInspectorExtension.prototype.onToolbarCreated = function () {
this.viewer.removeEventListener(av.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
this.onToolbarCreatedBinded = null;
this.createUI();
};
PropertyInspectorExtension.prototype.createUI = function () {
var viewer = this.viewer;
var panel = this.panel;
// button to show the docking panel
var toolbarButtonShowDockingPanel = new Autodesk.Viewing.UI.Button('showPropertyInspectorPanel');
toolbarButtonShowDockingPanel.icon.classList.add("adsk-icon-properties");
toolbarButtonShowDockingPanel.container.style.color = "orange";
toolbarButtonShowDockingPanel.onClick = function (e) {
// if null, create it
if (panel == null) {
panel = new PropertyInspectorPanel(viewer, viewer.container, 'AllPropertiesPanel', 'All Properties');
panel.showProperties(viewer.model.getRootId());
}
// show/hide docking panel
panel.setVisible(!panel.isVisible());
};
toolbarButtonShowDockingPanel.addClass('propertyInspectorToolbarButton');
toolbarButtonShowDockingPanel.setToolTip('Property Inspector Panel');
// SubToolbar
this.subToolbar = new Autodesk.Viewing.UI.ControlGroup('PropertyInspectorToolbar');
this.subToolbar.addControl(toolbarButtonShowDockingPanel);
viewer.toolbar.addControl(this.subToolbar);
};
PropertyInspectorExtension.prototype.unload = function () {
this.viewer.toolbar.removeControl(this.subToolbar);
return true;
};
Autodesk.Viewing.theExtensionManager.registerExtension('PropertyInspectorExtension', PropertyInspectorExtension);
// *******************************************
// Property Inspector Extension
// *******************************************
function PropertyInspectorPanel (viewer, container, id, title, options) {
this.viewer = viewer;
this.breadcrumbsItems = [];
Autodesk.Viewing.UI.PropertyPanel.call(this, container, id, title, options);
this.showBreadcrumbs = function () {
// Create it if not there yet
if (!this.breadcrumbs) {
this.breadcrumbs = document.createElement('span');
this.title.appendChild(this.breadcrumbs);
} else {
while (this.breadcrumbs.firstChild) {
this.breadcrumbs.removeChild(this.breadcrumbs.firstChild);
}
}
// Fill it with items
this.breadcrumbs.appendChild(document.createTextNode(' ['));
this.breadcrumbsItems.forEach(dbId => {
if (this.breadcrumbs.children.length > 0) {
var text = document.createTextNode(' > ');
this.breadcrumbs.appendChild(text);
}
var item = document.createElement('a');
item.innerText = dbId;
item.style.cursor = "pointer";
item.onclick = this.onBreadcrumbClick.bind(this);
this.breadcrumbs.appendChild(item);
});
this.breadcrumbs.appendChild(document.createTextNode(']'));
}; // showBreadcrumbs
this.showProperties = function (dbId) {
this.removeAllProperties();
var that = this;
this.viewer.getProperties(dbId, props => {
props.properties.forEach(prop => {
that.addProperty(
prop.displayName + ((prop.type === 11) ? "[dbId]" : ""),
prop.displayValue,
prop.displayCategory
);
});
});
this.breadcrumbsItems.push(dbId);
this.showBreadcrumbs();
}; // showProperties
this.onBreadcrumbClick = function (event) {
var dbId = parseInt(event.currentTarget.text);
var index = this.breadcrumbsItems.indexOf(dbId)
this.breadcrumbsItems = this.breadcrumbsItems.splice(0, index);
this.showProperties(dbId);
}; // onBreadcrumbClicked
// This is overriding the default property click handler
// of Autodesk.Viewing.UI.PropertyPanel
this.onPropertyClick = function (property) {
if (!property.name.includes("[dbId]")) {
return;
}
var dbId = property.value;
this.showProperties(dbId);
}; // onPropertyClick
this.onSelectionChanged = function (event) {
var dbId = event.dbIdArray[0];
if (!dbId) {
dbId = this.viewer.model.getRootId();
}
this.breadcrumbsItems = [];
this.showProperties(dbId);
} // onSelectionChanged
viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
this.onSelectionChanged.bind(this)
);
}; // PropertyInspectorPanel
PropertyInspectorPanel.prototype = Object.create(Autodesk.Viewing.UI.PropertyPanel.prototype);
PropertyInspectorPanel.prototype.constructor = PropertyInspectorPanel;
Reference in HTML:
<script src="js/PropertyInspectorExtension.js"></script>
Reference in JS file:
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, { extensions: ['PropertyInspectorExtension']);