28 Feb 2018
Extension Skeleton: Toolbar & Docking Panel
Creating an extension is the recomended approach to add custom code to Viewer. And in most cases we want some UI for it: buttons & panels. This skeleton code shows how to create an extension with that.
Docking Panel
First let's create a Docking Panel using the Autodesk.Viewing.UI.DockingPanel UI. Note the main container hosts the panel and the child div is where we should place the content. The CSS class used here allow themes on Viewer 4+.
// *******************************************
// My Awesome (Docking) Panel
// *******************************************
function MyAwesomePanel(viewer, container, id, title, options) {
this.viewer = viewer;
Autodesk.Viewing.UI.DockingPanel.call(this, container, id, title, options);
// the style of the docking panel
// use this built-in style to support Themes on Viewer 4+
this.container.classList.add('docking-panel-container-solid-color-a');
this.container.style.top = "10px";
this.container.style.left = "10px";
this.container.style.width = "auto";
this.container.style.height = "auto";
this.container.style.resize = "auto";
// this is where we should place the content of our panel
var div = document.createElement('div');
div.style.margin = '20px';
div.innerText = "My content here";
this.container.appendChild(div);
// and may also append child elements...
}
MyAwesomePanel.prototype = Object.create(Autodesk.Viewing.UI.DockingPanel.prototype);
MyAwesomePanel.prototype.constructor = MyAwesomePanel;
Extension
We actually have many samples with Extensions, here the main difference is to merge a Toolbar button with it. There are 2 tutorials on this subject: extensions and toolbar. The following code is just putting them togheter, and using the docking panel defined above. The button CSS should be defined on your .css file.
// *******************************************
// My Awesome Extension
// *******************************************
function MyAwesomeExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
this.panel = null;
}
MyAwesomeExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
MyAwesomeExtension.prototype.constructor = MyAwesomeExtension;
MyAwesomeExtension.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;
};
MyAwesomeExtension.prototype.onToolbarCreated = function () {
this.viewer.removeEventListener(av.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
this.onToolbarCreatedBinded = null;
this.createUI();
};
MyAwesomeExtension.prototype.createUI = function () {
var viewer = this.viewer;
var panel = this.panel;
// button to show the docking panel
var toolbarButtonShowDockingPanel = new Autodesk.Viewing.UI.Button('showMyAwesomePanel');
toolbarButtonShowDockingPanel.onClick = function (e) {
// if null, create it
if (panel == null) {
panel = new MyAwesomePanel(viewer, viewer.container,
'awesomeExtensionPanel', 'My Awesome Extension');
}
// show/hide docking panel
panel.setVisible(!panel.isVisible());
};
// myAwesomeToolbarButton CSS class should be defined on your .css file
// you may include icons, below is a sample class:
/*
.myAwesomeToolbarButton {
background-image: url(/img/myAwesomeIcon.png);
background-size: 24px;
background-repeat: no-repeat;
background-position: center;
}*/
toolbarButtonShowDockingPanel.addClass('myAwesomeToolbarButton');
toolbarButtonShowDockingPanel.setToolTip('My Awesome extension');
// SubToolbar
this.subToolbar = new Autodesk.Viewing.UI.ControlGroup('MyAwesomeAppToolbar');
this.subToolbar.addControl(toolbarButtonShowDockingPanel);
viewer.toolbar.addControl(this.subToolbar);
};
MyAwesomeExtension.prototype.unload = function () {
this.viewer.toolbar.removeControl(this.subToolbar);
return true;
};
Autodesk.Viewing.theExtensionManager.registerExtension('MyAwesomeExtension', MyAwesomeExtension);
Loading the extension
To use the extension you need to include the JavaScript file:
<script src="your_folder/MyExtensionFileName.js"></script>
Then there are different ways to load an extension, here are the 2 most used. The following assumes you are using a code based on Basic Application tutorial.
1. On Viewer initialize
That's the most used, during registerViewer call, add a list of extensions you want to load.
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, { extensions: ['MyAwesomeExtension'] });
2. On Document Load event
In this case you need to pass options (or custom parameters to the extension), which is not possible during registerViewer call. Or just need to wait until the document is loaded as your extension needs to access the document data.
function onItemLoadSuccess(viewer, item) {
viewer.loadExtension('MyAwesomeExtension', { param1: 'value1' });
}
As a reference, here is an example of on viewer initialize and an example of on document load.