Use panel set for sidebar.
This commit is contained in:
parent
557768afe6
commit
01b09e08d0
@ -87,9 +87,7 @@
|
|||||||
"website/o3dv/js/navigatoritems.js",
|
"website/o3dv/js/navigatoritems.js",
|
||||||
"website/o3dv/js/navigatorpanels.js",
|
"website/o3dv/js/navigatorpanels.js",
|
||||||
"website/o3dv/js/navigator.js",
|
"website/o3dv/js/navigator.js",
|
||||||
"website/o3dv/js/sidebarpanel.js",
|
"website/o3dv/js/sidebarpanels.js",
|
||||||
"website/o3dv/js/detailssidebarpanel.js",
|
|
||||||
"website/o3dv/js/settingssidebarpanel.js",
|
|
||||||
"website/o3dv/js/sidebar.js",
|
"website/o3dv/js/sidebar.js",
|
||||||
"website/o3dv/js/hashhandler.js",
|
"website/o3dv/js/hashhandler.js",
|
||||||
"website/o3dv/js/loader.js",
|
"website/o3dv/js/loader.js",
|
||||||
|
|||||||
@ -110,9 +110,7 @@
|
|||||||
<script type="text/javascript" src="o3dv/js/navigatoritems.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigatoritems.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/navigatorpanels.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigatorpanels.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/navigator.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigator.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/sidebarpanel.js"></script>
|
<script type="text/javascript" src="o3dv/js/sidebarpanels.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/detailssidebarpanel.js"></script>
|
|
||||||
<script type="text/javascript" src="o3dv/js/settingssidebarpanel.js"></script>
|
|
||||||
<script type="text/javascript" src="o3dv/js/sidebar.js"></script>
|
<script type="text/javascript" src="o3dv/js/sidebar.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/hashhandler.js"></script>
|
<script type="text/javascript" src="o3dv/js/hashhandler.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/loader.js"></script>
|
<script type="text/javascript" src="o3dv/js/loader.js"></script>
|
||||||
|
|||||||
@ -110,9 +110,7 @@
|
|||||||
<script type="text/javascript" src="o3dv/js/navigatoritems.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigatoritems.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/navigatorpanels.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigatorpanels.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/navigator.js"></script>
|
<script type="text/javascript" src="o3dv/js/navigator.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/sidebarpanel.js"></script>
|
<script type="text/javascript" src="o3dv/js/sidebarpanels.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/detailssidebarpanel.js"></script>
|
|
||||||
<script type="text/javascript" src="o3dv/js/settingssidebarpanel.js"></script>
|
|
||||||
<script type="text/javascript" src="o3dv/js/sidebar.js"></script>
|
<script type="text/javascript" src="o3dv/js/sidebar.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/hashhandler.js"></script>
|
<script type="text/javascript" src="o3dv/js/hashhandler.js"></script>
|
||||||
<script type="text/javascript" src="o3dv/js/loader.js"></script>
|
<script type="text/javascript" src="o3dv/js/loader.js"></script>
|
||||||
@ -168,13 +166,13 @@
|
|||||||
<div class="toolbar" id="toolbar"></div>
|
<div class="toolbar" id="toolbar"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main" id="main">
|
<div class="main" id="main">
|
||||||
<div class="main_navigator only_full_width" id="main_navigator">
|
<div class="main_navigator ov_panel_set_container only_full_width" id="main_navigator">
|
||||||
</div>
|
</div>
|
||||||
<div class="main_navigator_splitter only_full_width" id="main_navigator_splitter">
|
<div class="main_navigator_splitter only_full_width" id="main_navigator_splitter">
|
||||||
</div>
|
</div>
|
||||||
<div class="main_viewer" id="main_viewer">
|
<div class="main_viewer" id="main_viewer">
|
||||||
</div>
|
</div>
|
||||||
<div class="main_sidebar only_full_width" id="main_sidebar">
|
<div class="main_sidebar ov_panel_set_right_container only_full_width" id="main_sidebar">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="intro ov_thin_scrollbar" id="intro">
|
<div class="intro ov_thin_scrollbar" id="intro">
|
||||||
|
|||||||
@ -1,21 +1,33 @@
|
|||||||
div.ov_panel_set_menu
|
div.ov_panel_set_container div.ov_panel_set_menu
|
||||||
{
|
{
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.ov_panel_set_right_container div.ov_panel_set_menu
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
div.ov_panel_set_menu div.ov_panel_set_menu_button
|
div.ov_panel_set_menu div.ov_panel_set_menu_button
|
||||||
{
|
{
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.ov_panel_set_content
|
div.ov_panel_set_container div.ov_panel_set_content
|
||||||
{
|
{
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
border-left: 1px solid var(--ov_border_color);
|
border-left: 1px solid var(--ov_border_color);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.ov_panel_set_right_container div.ov_panel_set_content
|
||||||
|
{
|
||||||
|
padding-right: 10px;
|
||||||
|
border-right: 1px solid var(--ov_border_color);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
@media (hover)
|
@media (hover)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -125,14 +125,14 @@ div.main_viewer
|
|||||||
div.main_sidebar
|
div.main_sidebar
|
||||||
{
|
{
|
||||||
width: 300px;
|
width: 300px;
|
||||||
margin: 10px 10px 10px 0px;
|
margin: 10px 0px 10px 10px;
|
||||||
overflow: none;
|
overflow: none;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.main_viewer canvas
|
div.main_viewer canvas
|
||||||
{
|
{
|
||||||
margin: 10px 10px 10px 0px;
|
margin: 10px 0px 10px 0px;
|
||||||
border: 1px solid var(--ov_border_color);
|
border: 1px solid var(--ov_border_color);
|
||||||
outline: none;
|
outline: none;
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@ -1,159 +0,0 @@
|
|||||||
OV.DetailsSidebarPanel = class extends OV.SidebarPanel
|
|
||||||
{
|
|
||||||
constructor (parentDiv)
|
|
||||||
{
|
|
||||||
super (parentDiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetTitle ()
|
|
||||||
{
|
|
||||||
return 'Details';
|
|
||||||
}
|
|
||||||
|
|
||||||
AddObject3DProperties (object3D)
|
|
||||||
{
|
|
||||||
this.Clear ();
|
|
||||||
let table = $('<div>').addClass ('ov_property_table').appendTo (this.contentDiv);
|
|
||||||
let boundingBox = OV.GetBoundingBox (object3D);
|
|
||||||
let size = OV.SubCoord3D (boundingBox.max, boundingBox.min);
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertex Count', object3D.VertexCount ()));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangle Count', object3D.TriangleCount ()));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size X', size.x));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Y', size.y));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z));
|
|
||||||
this.AddCalculatedProperty (table, 'Volume', () => {
|
|
||||||
const volume = OV.CalculateVolume (object3D);
|
|
||||||
if (volume === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new OV.Property (OV.PropertyType.Number, null, volume);
|
|
||||||
});
|
|
||||||
this.AddCalculatedProperty (table, 'Surface Area', () => {
|
|
||||||
const volume = OV.CalculateSurfaceArea (object3D);
|
|
||||||
if (volume === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new OV.Property (OV.PropertyType.Number, null, volume);
|
|
||||||
});
|
|
||||||
if (object3D.PropertyGroupCount () > 0) {
|
|
||||||
let customTable = $('<div>').addClass ('ov_property_table ov_property_table_custom').appendTo (this.contentDiv);
|
|
||||||
for (let i = 0; i < object3D.PropertyGroupCount (); i++) {
|
|
||||||
const propertyGroup = object3D.GetPropertyGroup (i);
|
|
||||||
this.AddPropertyGroup (customTable, propertyGroup);
|
|
||||||
for (let j = 0; j < propertyGroup.PropertyCount (); j++) {
|
|
||||||
const property = propertyGroup.GetProperty (j);
|
|
||||||
this.AddPropertyInGroup (customTable, property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.Resize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
AddMaterialProperties (material)
|
|
||||||
{
|
|
||||||
function AddTextureMap (obj, table, name, map)
|
|
||||||
{
|
|
||||||
if (map === null || map.name === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let fileName = OV.GetFileName (map.name);
|
|
||||||
obj.AddProperty (table, new OV.Property (OV.PropertyType.Text, name, fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Clear ();
|
|
||||||
let table = $('<div>').addClass ('ov_property_table').appendTo (this.contentDiv);
|
|
||||||
let typeString = null;
|
|
||||||
if (material.type === OV.MaterialType.Phong) {
|
|
||||||
typeString = 'Phong';
|
|
||||||
} else if (material.type === OV.MaterialType.Physical) {
|
|
||||||
typeString = 'Physical';
|
|
||||||
}
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Source', material.isDefault ? 'Default' : 'Model'));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Type', typeString));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Color', material.color));
|
|
||||||
if (material.type === OV.MaterialType.Physical) {
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Metalness', material.metalness));
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Roughness', material.roughness));
|
|
||||||
}
|
|
||||||
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Opacity', material.opacity));
|
|
||||||
AddTextureMap (this, table, 'Diffuse Map', material.diffuseMap);
|
|
||||||
AddTextureMap (this, table, 'Specular Map', material.specularMap);
|
|
||||||
AddTextureMap (this, table, 'Bump Map', material.bumpMap);
|
|
||||||
AddTextureMap (this, table, 'Normal Map', material.normalMap);
|
|
||||||
AddTextureMap (this, table, 'Emissive Map', material.emissiveMap);
|
|
||||||
AddTextureMap (this, table, 'Metallic Map', material.metalnessMap);
|
|
||||||
this.Resize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
AddPropertyGroup (table, propertyGroup)
|
|
||||||
{
|
|
||||||
let row = $('<div>').addClass ('ov_property_table_row group').appendTo (table);
|
|
||||||
row.html (propertyGroup.name).attr ('title', propertyGroup.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddProperty (table, property)
|
|
||||||
{
|
|
||||||
let row = $('<div>').addClass ('ov_property_table_row').appendTo (table);
|
|
||||||
let nameColum = $('<div>').addClass ('ov_property_table_cell ov_property_table_name').appendTo (row);
|
|
||||||
let valueColumn = $('<div>').addClass ('ov_property_table_cell ov_property_table_value').appendTo (row);
|
|
||||||
nameColum.html (property.name + ':').attr ('title', property.name);
|
|
||||||
this.DisplayPropertyValue (property, valueColumn);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddPropertyInGroup (table, property)
|
|
||||||
{
|
|
||||||
let row = this.AddProperty (table, property);
|
|
||||||
row.addClass ('ingroup');
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCalculatedProperty (table, name, calculateValue)
|
|
||||||
{
|
|
||||||
let row = $('<div>').addClass ('ov_property_table_row').appendTo (table);
|
|
||||||
let nameColum = $('<div>').addClass ('ov_property_table_cell ov_property_table_name').appendTo (row);
|
|
||||||
let valueColumn = $('<div>').addClass ('ov_property_table_cell ov_property_table_value').appendTo (row);
|
|
||||||
nameColum.html (name + ':').attr ('title', name);
|
|
||||||
|
|
||||||
let calculateButton = $('<div>').addClass ('ov_property_table_button').html ('Calculate...').appendTo (valueColumn);
|
|
||||||
calculateButton.click (() => {
|
|
||||||
valueColumn.empty ();
|
|
||||||
valueColumn.html ('Please wait...');
|
|
||||||
OV.RunTaskAsync (() => {
|
|
||||||
let propertyValue = calculateValue ();
|
|
||||||
if (propertyValue === null) {
|
|
||||||
valueColumn.html ('-');
|
|
||||||
} else {
|
|
||||||
this.DisplayPropertyValue (propertyValue, valueColumn);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayPropertyValue (property, targetDiv)
|
|
||||||
{
|
|
||||||
targetDiv.empty ();
|
|
||||||
let valueText = null;
|
|
||||||
if (property.type === OV.PropertyType.Text) {
|
|
||||||
valueText = property.value;
|
|
||||||
} else if (property.type === OV.PropertyType.Integer) {
|
|
||||||
valueText = property.value.toLocaleString ();
|
|
||||||
} else if (property.type === OV.PropertyType.Number) {
|
|
||||||
valueText = property.value.toLocaleString (undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2
|
|
||||||
});
|
|
||||||
} else if (property.type === OV.PropertyType.Boolean) {
|
|
||||||
valueText = property.value ? 'True' : 'False';
|
|
||||||
} else if (property.type === OV.PropertyType.Percent) {
|
|
||||||
valueText = parseInt (property.value * 100, 10).toString () + '%';
|
|
||||||
} else if (property.type === OV.PropertyType.Color) {
|
|
||||||
let hexString = '#' + OV.ColorToHexString (property.value);
|
|
||||||
let colorCircle = OV.CreateInlineColorCircle (property.value);
|
|
||||||
colorCircle.appendTo (targetDiv);
|
|
||||||
$('<span>').html (hexString).appendTo (targetDiv);
|
|
||||||
}
|
|
||||||
if (valueText !== null) {
|
|
||||||
targetDiv.html (valueText).attr ('title', valueText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -149,11 +149,13 @@ OV.NavigatorPanel = class extends OV.Panel
|
|||||||
this.titleDiv = $('<div>').addClass ('ov_navigator_tree_title').appendTo (this.panelDiv);
|
this.titleDiv = $('<div>').addClass ('ov_navigator_tree_title').appendTo (this.panelDiv);
|
||||||
this.treeDiv = $('<div>').addClass ('ov_navigator_tree_panel').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv);
|
this.treeDiv = $('<div>').addClass ('ov_navigator_tree_panel').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv);
|
||||||
this.treeView = new OV.TreeView (this.treeDiv);
|
this.treeView = new OV.TreeView (this.treeDiv);
|
||||||
|
|
||||||
|
let panelName = this.GetName ();
|
||||||
|
this.titleDiv.html (panelName).attr ('title', panelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Clear ()
|
Clear ()
|
||||||
{
|
{
|
||||||
this.titleDiv.empty ();
|
|
||||||
this.treeView.Clear ();
|
this.treeView.Clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,8 +171,7 @@ OV.NavigatorPanel = class extends OV.Panel
|
|||||||
|
|
||||||
Fill (importResult)
|
Fill (importResult)
|
||||||
{
|
{
|
||||||
let panelName = this.GetName ();
|
|
||||||
this.titleDiv.html (panelName).attr ('title', panelName);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,6 +182,11 @@ OV.NavigatorFilesPanel = class extends OV.NavigatorPanel
|
|||||||
super (parentDiv);
|
super (parentDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return 'Files';
|
||||||
|
}
|
||||||
|
|
||||||
GetIcon ()
|
GetIcon ()
|
||||||
{
|
{
|
||||||
return 'files';
|
return 'files';
|
||||||
@ -198,11 +204,6 @@ OV.NavigatorFilesPanel = class extends OV.NavigatorPanel
|
|||||||
super.Clear ();
|
super.Clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetName ()
|
|
||||||
{
|
|
||||||
return 'Files';
|
|
||||||
}
|
|
||||||
|
|
||||||
Fill (importResult)
|
Fill (importResult)
|
||||||
{
|
{
|
||||||
super.Fill (importResult);
|
super.Fill (importResult);
|
||||||
@ -248,6 +249,11 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel
|
|||||||
this.meshesButton = new OV.NavigatorMeshesPopupButton (this.popupDiv);
|
this.meshesButton = new OV.NavigatorMeshesPopupButton (this.popupDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return 'Materials';
|
||||||
|
}
|
||||||
|
|
||||||
GetIcon ()
|
GetIcon ()
|
||||||
{
|
{
|
||||||
return 'materials';
|
return 'materials';
|
||||||
@ -268,11 +274,6 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel
|
|||||||
this.materialIndexToItem = new Map ();
|
this.materialIndexToItem = new Map ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetName ()
|
|
||||||
{
|
|
||||||
return 'Materials';
|
|
||||||
}
|
|
||||||
|
|
||||||
Init (callbacks)
|
Init (callbacks)
|
||||||
{
|
{
|
||||||
super.Init (callbacks);
|
super.Init (callbacks);
|
||||||
@ -333,6 +334,11 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel
|
|||||||
this.materialsButton = new OV.NavigatorMaterialsPopupButton (this.popupDiv);
|
this.materialsButton = new OV.NavigatorMaterialsPopupButton (this.popupDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return 'Meshes';
|
||||||
|
}
|
||||||
|
|
||||||
GetIcon ()
|
GetIcon ()
|
||||||
{
|
{
|
||||||
return 'meshes';
|
return 'meshes';
|
||||||
@ -370,11 +376,6 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GetName ()
|
|
||||||
{
|
|
||||||
return 'Meshes';
|
|
||||||
}
|
|
||||||
|
|
||||||
Fill (importResult)
|
Fill (importResult)
|
||||||
{
|
{
|
||||||
super.Fill (importResult);
|
super.Fill (importResult);
|
||||||
@ -542,40 +543,4 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePopupButton ()
|
|
||||||
{
|
|
||||||
// if (this.selection === null) {
|
|
||||||
// let usedMaterials = this.callbacks.getMaterialsForModel ();
|
|
||||||
// this.popupButton.FillWithModelInfo (usedMaterials, {
|
|
||||||
// onMaterialSelect : (materialIndex) => {
|
|
||||||
// this.SetSelection (new OV.Selection (OV.SelectionType.Material, materialIndex));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// this.callbacks.onModelSelected ();
|
|
||||||
// } else {
|
|
||||||
// if (this.selection.type === OV.SelectionType.Material) {
|
|
||||||
// let usedByMeshes = this.callbacks.getMeshesForMaterial (this.selection.materialIndex);
|
|
||||||
// this.popupButton.FillWithMaterialInfo (usedByMeshes, {
|
|
||||||
// onMeshHover : (meshInstanceId) => {
|
|
||||||
// this.tempSelectedMeshId = meshInstanceId;
|
|
||||||
// this.callbacks.updateMeshesSelection ();
|
|
||||||
// },
|
|
||||||
// onMeshSelect : (meshInstanceId) => {
|
|
||||||
// this.SetSelection (new OV.Selection (OV.SelectionType.Mesh, meshInstanceId));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// this.callbacks.onMaterialSelected (this.selection.materialIndex);
|
|
||||||
// } else if (this.selection.type === OV.SelectionType.Mesh) {
|
|
||||||
// let usedMaterials = this.callbacks.getMaterialsForMesh (this.selection.meshInstanceId);
|
|
||||||
// this.popupButton.FillWithModelInfo (usedMaterials, {
|
|
||||||
// onMaterialSelect : (materialIndex) => {
|
|
||||||
// this.SetSelection (new OV.Selection (OV.SelectionType.Material, materialIndex));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// this.callbacks.onMeshSelected (this.selection.meshInstanceId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// this.Resize ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,167 +0,0 @@
|
|||||||
OV.SettingsSidebarPanel = class extends OV.SidebarPanel
|
|
||||||
{
|
|
||||||
constructor (parentDiv)
|
|
||||||
{
|
|
||||||
super (parentDiv);
|
|
||||||
this.backgroundColorInput = null;
|
|
||||||
this.defaultColorInput = null;
|
|
||||||
this.defaultColorWarning = null;
|
|
||||||
this.themeInput = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetTitle ()
|
|
||||||
{
|
|
||||||
return 'Settings';
|
|
||||||
}
|
|
||||||
|
|
||||||
HidePopups ()
|
|
||||||
{
|
|
||||||
this.backgroundColorInput.pickr.hide ();
|
|
||||||
this.defaultColorInput.pickr.hide ();
|
|
||||||
}
|
|
||||||
|
|
||||||
InitSettings (settings, defaultSettings, callbacks)
|
|
||||||
{
|
|
||||||
this.backgroundColorInput = this.AddColorParameter (
|
|
||||||
'Background Color',
|
|
||||||
'Background color affects only the visualization of the model.',
|
|
||||||
null,
|
|
||||||
['#ffffff', '#e3e3e3', '#c9c9c9', '#898989', '#5f5f5f', '#494949', '#383838', '#0f0f0f'],
|
|
||||||
settings.backgroundColor,
|
|
||||||
callbacks.onBackgroundColorChange
|
|
||||||
);
|
|
||||||
this.defaultColorInput = this.AddColorParameter (
|
|
||||||
'Default Color',
|
|
||||||
'Default color appears when the model doesn\'t contain materials.',
|
|
||||||
'This setting has no effect on the currently loaded file.',
|
|
||||||
['#ffffff', '#e3e3e3', '#cc3333', '#fac832', '#4caf50', '#3393bd', '#9b27b0', '#fda4b8'],
|
|
||||||
settings.defaultColor,
|
|
||||||
callbacks.onDefaultColorChange
|
|
||||||
);
|
|
||||||
this.themeInput = this.AddThemeParameter (settings.themeId, callbacks.onThemeChange);
|
|
||||||
this.AddResetToDefaultsButton (defaultSettings, callbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSettings (settings)
|
|
||||||
{
|
|
||||||
this.backgroundColorInput.pickr.setColor ('#' + OV.ColorToHexString (settings.backgroundColor));
|
|
||||||
this.defaultColorInput.pickr.setColor ('#' + OV.ColorToHexString (settings.defaultColor));
|
|
||||||
}
|
|
||||||
|
|
||||||
Update (model)
|
|
||||||
{
|
|
||||||
let hasDefaultMaterial = OV.HasDefaultMaterial (model);
|
|
||||||
if (!hasDefaultMaterial) {
|
|
||||||
this.defaultColorInput.warning.show ();
|
|
||||||
} else {
|
|
||||||
this.defaultColorInput.warning.hide ();
|
|
||||||
}
|
|
||||||
this.Resize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
AddColorParameter (title, description, warningText, predefinedColors, defaultValue, onChange)
|
|
||||||
{
|
|
||||||
let contentDiv = $('<div>').addClass ('ov_sidebar_settings_content').appendTo (this.contentDiv);
|
|
||||||
let titleDiv = $('<div>').addClass ('ov_sidebar_subtitle').appendTo (contentDiv);
|
|
||||||
let colorInput = $('<div>').addClass ('color-picker').appendTo (titleDiv);
|
|
||||||
$('<span>').html (title).appendTo (titleDiv);
|
|
||||||
const pickr = Pickr.create ({
|
|
||||||
el : colorInput.get (0),
|
|
||||||
theme : 'monolith',
|
|
||||||
position : 'left-start',
|
|
||||||
swatches : predefinedColors,
|
|
||||||
comparison : false,
|
|
||||||
default : '#' + OV.ColorToHexString (defaultValue),
|
|
||||||
components : {
|
|
||||||
preview : false,
|
|
||||||
opacity : false,
|
|
||||||
hue : true,
|
|
||||||
interaction: {
|
|
||||||
hex : false,
|
|
||||||
rgba : false,
|
|
||||||
hsla : false,
|
|
||||||
hsva : false,
|
|
||||||
cmyk : false,
|
|
||||||
input : true,
|
|
||||||
clear : false,
|
|
||||||
save : false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pickr.on ('change', (color, source, instance) => {
|
|
||||||
let rgbaColor = color.toRGBA ();
|
|
||||||
let ovColor = new OV.Color (
|
|
||||||
parseInt (rgbaColor[0], 10),
|
|
||||||
parseInt (rgbaColor[1], 10),
|
|
||||||
parseInt (rgbaColor[2], 10)
|
|
||||||
);
|
|
||||||
onChange (ovColor);
|
|
||||||
});
|
|
||||||
$('<div>').addClass ('ov_sidebar_settings_padded').html (description).appendTo (contentDiv);
|
|
||||||
let warningDiv = null;
|
|
||||||
if (warningText !== null) {
|
|
||||||
warningDiv = $('<div>').addClass ('ov_sidebar_settings_padded').appendTo (contentDiv);
|
|
||||||
OV.AddSvgIcon (warningDiv, 'warning', 'left_inline light');
|
|
||||||
$('<div>').addClass ('ov_sidebar_settings_warning').html (warningText).appendTo (warningDiv);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
pickr : pickr,
|
|
||||||
warning : warningDiv
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
AddThemeParameter (defaultValue, onChange)
|
|
||||||
{
|
|
||||||
function AddRadioButton (contentDiv, themeId, themeName, onChange)
|
|
||||||
{
|
|
||||||
let row = $('<div>').addClass ('ov_sidebar_settings_row').appendTo (contentDiv);
|
|
||||||
let label = $('<label>').attr ('for', themeId.toString ()).appendTo (row);
|
|
||||||
let radio = $('<input>').addClass ('ov_radio_button').attr ('type', 'radio').attr ('id', themeId.toString ()).attr ('name', 'theme').appendTo (label);
|
|
||||||
$('<span>').html (themeName).appendTo (label);
|
|
||||||
radio.change (() => {
|
|
||||||
onChange (themeId);
|
|
||||||
});
|
|
||||||
return radio;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Select (radioButtons, defaultValue)
|
|
||||||
{
|
|
||||||
for (let i = 0; i < radioButtons.length; i++) {
|
|
||||||
let radioButton = radioButtons[i];
|
|
||||||
radioButton.prop ('checked', radioButton.attr ('id') === defaultValue.toString ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let contentDiv = $('<div>').addClass ('ov_sidebar_settings_content').appendTo (this.contentDiv);
|
|
||||||
let titleDiv = $('<div>').addClass ('ov_sidebar_subtitle').appendTo (contentDiv);
|
|
||||||
OV.AddSvgIcon (titleDiv, 'theme', 'ov_sidebar_subtitle_icon');
|
|
||||||
$('<div>').html ('Appearance').appendTo (titleDiv);
|
|
||||||
let buttonsDiv = $('<div>').addClass ('ov_sidebar_settings_padded').appendTo (contentDiv);
|
|
||||||
let result = {
|
|
||||||
buttons : [],
|
|
||||||
select: (value) => {
|
|
||||||
Select (result.buttons, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
result.buttons.push (AddRadioButton (buttonsDiv, OV.Theme.Light, 'Light', onChange));
|
|
||||||
result.buttons.push (AddRadioButton (buttonsDiv, OV.Theme.Dark, 'Dark', onChange));
|
|
||||||
Select (result.buttons, defaultValue);
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AddResetToDefaultsButton (defaultSettings, callbacks)
|
|
||||||
{
|
|
||||||
let resetToDefaultsButton = $('<div>').addClass ('ov_button').addClass ('outline').addClass ('ov_sidebar_button').html ('Reset to Default').appendTo (this.contentDiv);
|
|
||||||
resetToDefaultsButton.click (() => {
|
|
||||||
this.backgroundColorInput.pickr.setColor ('#' + OV.ColorToHexString (defaultSettings.backgroundColor));
|
|
||||||
callbacks.onBackgroundColorChange (defaultSettings.backgroundColor);
|
|
||||||
this.defaultColorInput.pickr.setColor ('#' + OV.ColorToHexString (defaultSettings.defaultColor));
|
|
||||||
callbacks.onDefaultColorChange (defaultSettings.defaultColor);
|
|
||||||
if (this.themeInput !== null) {
|
|
||||||
this.themeInput.select (defaultSettings.themeId);
|
|
||||||
callbacks.onThemeChange (defaultSettings.themeId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,73 +1,86 @@
|
|||||||
OV.Sidebar = class
|
OV.Sidebar = class
|
||||||
{
|
{
|
||||||
constructor (parentDiv)
|
constructor (mainDiv)
|
||||||
{
|
{
|
||||||
this.parentDiv = parentDiv;
|
this.mainDiv = mainDiv;
|
||||||
this.visible = true;
|
this.panelSet = new OV.PanelSet (mainDiv);
|
||||||
this.titleDiv = null;
|
|
||||||
this.contentDiv = null;
|
this.detailsPanel = new OV.DetailsSidebarPanel (this.panelSet.GetContentDiv ());
|
||||||
this.panels = [];
|
this.settingsPanel = new OV.SettingsSidebarPanel (this.panelSet.GetContentDiv ());
|
||||||
|
|
||||||
|
this.panelSet.AddPanel (this.detailsPanel);
|
||||||
|
this.panelSet.AddPanel (this.settingsPanel);
|
||||||
|
this.panelSet.ShowPanel (this.detailsPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddPanel (panel)
|
Init (settings, callbacks)
|
||||||
{
|
{
|
||||||
this.panels.push (panel);
|
this.callbacks = callbacks;
|
||||||
return this.panels.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPanel (id)
|
this.panelSet.Init ({
|
||||||
{
|
onResize : () => {
|
||||||
return this.panels[id];
|
if (this.panelSet.IsPanelsVisible ()) {
|
||||||
}
|
//this.splitterDiv.show ();
|
||||||
|
|
||||||
Show (panelId)
|
|
||||||
{
|
|
||||||
if (panelId !== null) {
|
|
||||||
this.visible = true;
|
|
||||||
this.parentDiv.show ();
|
|
||||||
for (let id = 0; id < this.panels.length; id++) {
|
|
||||||
let panel = this.panels[id];
|
|
||||||
if (id === panelId) {
|
|
||||||
panel.Show (true);
|
|
||||||
} else {
|
} else {
|
||||||
panel.Show (false);
|
//this.splitterDiv.hide ();
|
||||||
|
}
|
||||||
|
this.callbacks.onResize ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let defaultSettings = new OV.Settings ();
|
||||||
|
this.settingsPanel.InitSettings (
|
||||||
|
settings,
|
||||||
|
defaultSettings,
|
||||||
|
{
|
||||||
|
onBackgroundColorChange : (newVal) => {
|
||||||
|
this.callbacks.onBackgroundColorChange (newVal);
|
||||||
|
},
|
||||||
|
onDefaultColorChange : (newVal) => {
|
||||||
|
this.callbacks.onDefaultColorChange (newVal);
|
||||||
|
},
|
||||||
|
onThemeChange : (newVal) => {
|
||||||
|
this.callbacks.onThemeChange (newVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
);
|
||||||
this.visible = false;
|
|
||||||
this.parentDiv.hide ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IsVisible ()
|
Update (model)
|
||||||
{
|
{
|
||||||
return this.visible;
|
this.settingsPanel.Update (model);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetVisiblePanelId ()
|
Resize (height)
|
||||||
{
|
{
|
||||||
if (!this.visible) {
|
this.mainDiv.outerHeight (height, true);
|
||||||
return null;
|
//this.splitterDiv.outerHeight (height, true);
|
||||||
}
|
this.panelSet.Resize ();
|
||||||
for (let id = 0; id < this.panels.length; id++) {
|
|
||||||
if (this.panels[id].IsVisible ()) {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HidePopups ()
|
GetWidth ()
|
||||||
{
|
{
|
||||||
for (let id = 0; id < this.panels.length; id++) {
|
let sidebarWidth = parseInt (this.mainDiv.outerWidth (true), 10);
|
||||||
this.panels[id].HidePopups ();
|
// let splitterWidth = 0;
|
||||||
}
|
// if (this.panelSet.IsPanelsVisible ()) {
|
||||||
|
// splitterWidth = parseInt (this.splitterDiv.outerWidth (true), 10);
|
||||||
|
// }
|
||||||
|
//return sidebarWidth + splitterWidth;
|
||||||
|
return sidebarWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resize ()
|
Clear ()
|
||||||
{
|
{
|
||||||
for (let id = 0; id < this.panels.length; id++) {
|
this.panelSet.Clear ();
|
||||||
this.panels[id].Resize ();
|
}
|
||||||
}
|
|
||||||
|
AddObject3DProperties (object3D)
|
||||||
|
{
|
||||||
|
this.detailsPanel.AddObject3DProperties (object3D);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddMaterialProperties (material)
|
||||||
|
{
|
||||||
|
this.detailsPanel.AddMaterialProperties (material);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
OV.SidebarPanel = class
|
|
||||||
{
|
|
||||||
constructor (parentDiv)
|
|
||||||
{
|
|
||||||
this.parentDiv = parentDiv;
|
|
||||||
this.panelDiv = $('<div>').appendTo (this.parentDiv).hide ();
|
|
||||||
this.titleDiv = null;
|
|
||||||
this.contentDiv = null;
|
|
||||||
this.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Init (callbacks)
|
|
||||||
{
|
|
||||||
this.titleDiv = $('<div>').addClass ('ov_sidebar_title').appendTo (this.panelDiv);
|
|
||||||
this.contentDiv = $('<div>').addClass ('ov_sidebar_content').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv);
|
|
||||||
$('<div>').addClass ('ov_sidebar_title_text').html (this.GetTitle ()).appendTo (this.titleDiv);
|
|
||||||
let titleImg = OV.AddSvgIcon (this.titleDiv, 'close', 'ov_sidebar_title_img');
|
|
||||||
titleImg.click (() => {
|
|
||||||
callbacks.onClose ();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
GetTitle ()
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
Show (show)
|
|
||||||
{
|
|
||||||
this.visible = show;
|
|
||||||
if (this.visible) {
|
|
||||||
this.panelDiv.show ();
|
|
||||||
} else {
|
|
||||||
this.panelDiv.hide ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IsVisible ()
|
|
||||||
{
|
|
||||||
return this.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resize ()
|
|
||||||
{
|
|
||||||
let titleHeight = this.titleDiv.outerHeight (true);
|
|
||||||
let height = this.parentDiv.height ();
|
|
||||||
this.contentDiv.outerHeight (height - titleHeight, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Clear ()
|
|
||||||
{
|
|
||||||
this.contentDiv.empty ();
|
|
||||||
}
|
|
||||||
|
|
||||||
HidePopups ()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
364
website/o3dv/js/sidebarpanels.js
Normal file
364
website/o3dv/js/sidebarpanels.js
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
|
||||||
|
OV.SidebarPanel = class extends OV.Panel
|
||||||
|
{
|
||||||
|
constructor (parentDiv)
|
||||||
|
{
|
||||||
|
super (parentDiv);
|
||||||
|
this.callbacks = null;
|
||||||
|
|
||||||
|
this.titleDiv = $('<div>').addClass ('ov_sidebar_title').appendTo (this.panelDiv);
|
||||||
|
this.contentDiv = $('<div>').addClass ('ov_sidebar_content').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv);
|
||||||
|
$('<div>').addClass ('ov_sidebar_title_text').html (this.GetName ()).appendTo (this.titleDiv);
|
||||||
|
|
||||||
|
let panelName = this.GetName ();
|
||||||
|
this.titleDiv.html (panelName).attr ('title', panelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear ()
|
||||||
|
{
|
||||||
|
this.contentDiv.empty ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Init (callbacks)
|
||||||
|
{
|
||||||
|
this.callbacks = callbacks;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OV.DetailsSidebarPanel = class extends OV.SidebarPanel
|
||||||
|
{
|
||||||
|
constructor (parentDiv)
|
||||||
|
{
|
||||||
|
super (parentDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return 'Details';
|
||||||
|
}
|
||||||
|
|
||||||
|
GetIcon ()
|
||||||
|
{
|
||||||
|
return 'details';
|
||||||
|
}
|
||||||
|
|
||||||
|
AddObject3DProperties (object3D)
|
||||||
|
{
|
||||||
|
this.Clear ();
|
||||||
|
let table = $('<div>').addClass ('ov_property_table').appendTo (this.contentDiv);
|
||||||
|
let boundingBox = OV.GetBoundingBox (object3D);
|
||||||
|
let size = OV.SubCoord3D (boundingBox.max, boundingBox.min);
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertex Count', object3D.VertexCount ()));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangle Count', object3D.TriangleCount ()));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size X', size.x));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Y', size.y));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z));
|
||||||
|
this.AddCalculatedProperty (table, 'Volume', () => {
|
||||||
|
const volume = OV.CalculateVolume (object3D);
|
||||||
|
if (volume === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new OV.Property (OV.PropertyType.Number, null, volume);
|
||||||
|
});
|
||||||
|
this.AddCalculatedProperty (table, 'Surface Area', () => {
|
||||||
|
const volume = OV.CalculateSurfaceArea (object3D);
|
||||||
|
if (volume === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new OV.Property (OV.PropertyType.Number, null, volume);
|
||||||
|
});
|
||||||
|
if (object3D.PropertyGroupCount () > 0) {
|
||||||
|
let customTable = $('<div>').addClass ('ov_property_table ov_property_table_custom').appendTo (this.contentDiv);
|
||||||
|
for (let i = 0; i < object3D.PropertyGroupCount (); i++) {
|
||||||
|
const propertyGroup = object3D.GetPropertyGroup (i);
|
||||||
|
this.AddPropertyGroup (customTable, propertyGroup);
|
||||||
|
for (let j = 0; j < propertyGroup.PropertyCount (); j++) {
|
||||||
|
const property = propertyGroup.GetProperty (j);
|
||||||
|
this.AddPropertyInGroup (customTable, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Resize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddMaterialProperties (material)
|
||||||
|
{
|
||||||
|
function AddTextureMap (obj, table, name, map)
|
||||||
|
{
|
||||||
|
if (map === null || map.name === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let fileName = OV.GetFileName (map.name);
|
||||||
|
obj.AddProperty (table, new OV.Property (OV.PropertyType.Text, name, fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Clear ();
|
||||||
|
let table = $('<div>').addClass ('ov_property_table').appendTo (this.contentDiv);
|
||||||
|
let typeString = null;
|
||||||
|
if (material.type === OV.MaterialType.Phong) {
|
||||||
|
typeString = 'Phong';
|
||||||
|
} else if (material.type === OV.MaterialType.Physical) {
|
||||||
|
typeString = 'Physical';
|
||||||
|
}
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Source', material.isDefault ? 'Default' : 'Model'));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Type', typeString));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Color', material.color));
|
||||||
|
if (material.type === OV.MaterialType.Physical) {
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Metalness', material.metalness));
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Roughness', material.roughness));
|
||||||
|
}
|
||||||
|
this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Opacity', material.opacity));
|
||||||
|
AddTextureMap (this, table, 'Diffuse Map', material.diffuseMap);
|
||||||
|
AddTextureMap (this, table, 'Specular Map', material.specularMap);
|
||||||
|
AddTextureMap (this, table, 'Bump Map', material.bumpMap);
|
||||||
|
AddTextureMap (this, table, 'Normal Map', material.normalMap);
|
||||||
|
AddTextureMap (this, table, 'Emissive Map', material.emissiveMap);
|
||||||
|
AddTextureMap (this, table, 'Metallic Map', material.metalnessMap);
|
||||||
|
this.Resize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPropertyGroup (table, propertyGroup)
|
||||||
|
{
|
||||||
|
let row = $('<div>').addClass ('ov_property_table_row group').appendTo (table);
|
||||||
|
row.html (propertyGroup.name).attr ('title', propertyGroup.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddProperty (table, property)
|
||||||
|
{
|
||||||
|
let row = $('<div>').addClass ('ov_property_table_row').appendTo (table);
|
||||||
|
let nameColum = $('<div>').addClass ('ov_property_table_cell ov_property_table_name').appendTo (row);
|
||||||
|
let valueColumn = $('<div>').addClass ('ov_property_table_cell ov_property_table_value').appendTo (row);
|
||||||
|
nameColum.html (property.name + ':').attr ('title', property.name);
|
||||||
|
this.DisplayPropertyValue (property, valueColumn);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPropertyInGroup (table, property)
|
||||||
|
{
|
||||||
|
let row = this.AddProperty (table, property);
|
||||||
|
row.addClass ('ingroup');
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCalculatedProperty (table, name, calculateValue)
|
||||||
|
{
|
||||||
|
let row = $('<div>').addClass ('ov_property_table_row').appendTo (table);
|
||||||
|
let nameColum = $('<div>').addClass ('ov_property_table_cell ov_property_table_name').appendTo (row);
|
||||||
|
let valueColumn = $('<div>').addClass ('ov_property_table_cell ov_property_table_value').appendTo (row);
|
||||||
|
nameColum.html (name + ':').attr ('title', name);
|
||||||
|
|
||||||
|
let calculateButton = $('<div>').addClass ('ov_property_table_button').html ('Calculate...').appendTo (valueColumn);
|
||||||
|
calculateButton.click (() => {
|
||||||
|
valueColumn.empty ();
|
||||||
|
valueColumn.html ('Please wait...');
|
||||||
|
OV.RunTaskAsync (() => {
|
||||||
|
let propertyValue = calculateValue ();
|
||||||
|
if (propertyValue === null) {
|
||||||
|
valueColumn.html ('-');
|
||||||
|
} else {
|
||||||
|
this.DisplayPropertyValue (propertyValue, valueColumn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayPropertyValue (property, targetDiv)
|
||||||
|
{
|
||||||
|
targetDiv.empty ();
|
||||||
|
let valueText = null;
|
||||||
|
if (property.type === OV.PropertyType.Text) {
|
||||||
|
valueText = property.value;
|
||||||
|
} else if (property.type === OV.PropertyType.Integer) {
|
||||||
|
valueText = property.value.toLocaleString ();
|
||||||
|
} else if (property.type === OV.PropertyType.Number) {
|
||||||
|
valueText = property.value.toLocaleString (undefined, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
});
|
||||||
|
} else if (property.type === OV.PropertyType.Boolean) {
|
||||||
|
valueText = property.value ? 'True' : 'False';
|
||||||
|
} else if (property.type === OV.PropertyType.Percent) {
|
||||||
|
valueText = parseInt (property.value * 100, 10).toString () + '%';
|
||||||
|
} else if (property.type === OV.PropertyType.Color) {
|
||||||
|
let hexString = '#' + OV.ColorToHexString (property.value);
|
||||||
|
let colorCircle = OV.CreateInlineColorCircle (property.value);
|
||||||
|
colorCircle.appendTo (targetDiv);
|
||||||
|
$('<span>').html (hexString).appendTo (targetDiv);
|
||||||
|
}
|
||||||
|
if (valueText !== null) {
|
||||||
|
targetDiv.html (valueText).attr ('title', valueText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OV.SettingsSidebarPanel = class extends OV.SidebarPanel
|
||||||
|
{
|
||||||
|
constructor (parentDiv)
|
||||||
|
{
|
||||||
|
super (parentDiv);
|
||||||
|
this.backgroundColorInput = null;
|
||||||
|
this.defaultColorInput = null;
|
||||||
|
this.defaultColorWarning = null;
|
||||||
|
this.themeInput = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetName ()
|
||||||
|
{
|
||||||
|
return 'Settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
GetIcon ()
|
||||||
|
{
|
||||||
|
return 'settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear ()
|
||||||
|
{
|
||||||
|
this.backgroundColorInput.pickr.hide ();
|
||||||
|
this.defaultColorInput.pickr.hide ();
|
||||||
|
}
|
||||||
|
|
||||||
|
InitSettings (settings, defaultSettings, callbacks)
|
||||||
|
{
|
||||||
|
this.Init (callbacks);
|
||||||
|
this.backgroundColorInput = this.AddColorParameter (
|
||||||
|
'Background Color',
|
||||||
|
'Background color affects only the visualization of the model.',
|
||||||
|
null,
|
||||||
|
['#ffffff', '#e3e3e3', '#c9c9c9', '#898989', '#5f5f5f', '#494949', '#383838', '#0f0f0f'],
|
||||||
|
settings.backgroundColor,
|
||||||
|
this.callbacks.onBackgroundColorChange
|
||||||
|
);
|
||||||
|
this.defaultColorInput = this.AddColorParameter (
|
||||||
|
'Default Color',
|
||||||
|
'Default color appears when the model doesn\'t contain materials.',
|
||||||
|
'This setting has no effect on the currently loaded file.',
|
||||||
|
['#ffffff', '#e3e3e3', '#cc3333', '#fac832', '#4caf50', '#3393bd', '#9b27b0', '#fda4b8'],
|
||||||
|
settings.defaultColor,
|
||||||
|
this.callbacks.onDefaultColorChange
|
||||||
|
);
|
||||||
|
this.themeInput = this.AddThemeParameter (settings.themeId);
|
||||||
|
this.AddResetToDefaultsButton (defaultSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
Update (model)
|
||||||
|
{
|
||||||
|
let hasDefaultMaterial = OV.HasDefaultMaterial (model);
|
||||||
|
if (!hasDefaultMaterial) {
|
||||||
|
this.defaultColorInput.warning.show ();
|
||||||
|
} else {
|
||||||
|
this.defaultColorInput.warning.hide ();
|
||||||
|
}
|
||||||
|
this.Resize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddColorParameter (title, description, warningText, predefinedColors, defaultValue, onChange)
|
||||||
|
{
|
||||||
|
let contentDiv = $('<div>').addClass ('ov_sidebar_settings_content').appendTo (this.contentDiv);
|
||||||
|
let titleDiv = $('<div>').addClass ('ov_sidebar_subtitle').appendTo (contentDiv);
|
||||||
|
let colorInput = $('<div>').addClass ('color-picker').appendTo (titleDiv);
|
||||||
|
$('<span>').html (title).appendTo (titleDiv);
|
||||||
|
const pickr = Pickr.create ({
|
||||||
|
el : colorInput.get (0),
|
||||||
|
theme : 'monolith',
|
||||||
|
position : 'left-start',
|
||||||
|
swatches : predefinedColors,
|
||||||
|
comparison : false,
|
||||||
|
default : '#' + OV.ColorToHexString (defaultValue),
|
||||||
|
components : {
|
||||||
|
preview : false,
|
||||||
|
opacity : false,
|
||||||
|
hue : true,
|
||||||
|
interaction: {
|
||||||
|
hex : false,
|
||||||
|
rgba : false,
|
||||||
|
hsla : false,
|
||||||
|
hsva : false,
|
||||||
|
cmyk : false,
|
||||||
|
input : true,
|
||||||
|
clear : false,
|
||||||
|
save : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pickr.on ('change', (color, source, instance) => {
|
||||||
|
let rgbaColor = color.toRGBA ();
|
||||||
|
let ovColor = new OV.Color (
|
||||||
|
parseInt (rgbaColor[0], 10),
|
||||||
|
parseInt (rgbaColor[1], 10),
|
||||||
|
parseInt (rgbaColor[2], 10)
|
||||||
|
);
|
||||||
|
onChange (ovColor);
|
||||||
|
});
|
||||||
|
$('<div>').addClass ('ov_sidebar_settings_padded').html (description).appendTo (contentDiv);
|
||||||
|
let warningDiv = null;
|
||||||
|
if (warningText !== null) {
|
||||||
|
warningDiv = $('<div>').addClass ('ov_sidebar_settings_padded').appendTo (contentDiv);
|
||||||
|
OV.AddSvgIcon (warningDiv, 'warning', 'left_inline light');
|
||||||
|
$('<div>').addClass ('ov_sidebar_settings_warning').html (warningText).appendTo (warningDiv);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
pickr : pickr,
|
||||||
|
warning : warningDiv
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
AddThemeParameter (defaultValue)
|
||||||
|
{
|
||||||
|
function AddRadioButton (contentDiv, themeId, themeName, onChange)
|
||||||
|
{
|
||||||
|
let row = $('<div>').addClass ('ov_sidebar_settings_row').appendTo (contentDiv);
|
||||||
|
let label = $('<label>').attr ('for', themeId.toString ()).appendTo (row);
|
||||||
|
let radio = $('<input>').addClass ('ov_radio_button').attr ('type', 'radio').attr ('id', themeId.toString ()).attr ('name', 'theme').appendTo (label);
|
||||||
|
$('<span>').html (themeName).appendTo (label);
|
||||||
|
radio.change (() => {
|
||||||
|
onChange (themeId);
|
||||||
|
});
|
||||||
|
return radio;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Select (radioButtons, defaultValue)
|
||||||
|
{
|
||||||
|
for (let i = 0; i < radioButtons.length; i++) {
|
||||||
|
let radioButton = radioButtons[i];
|
||||||
|
radioButton.prop ('checked', radioButton.attr ('id') === defaultValue.toString ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentDiv = $('<div>').addClass ('ov_sidebar_settings_content').appendTo (this.contentDiv);
|
||||||
|
let titleDiv = $('<div>').addClass ('ov_sidebar_subtitle').appendTo (contentDiv);
|
||||||
|
OV.AddSvgIcon (titleDiv, 'theme', 'ov_sidebar_subtitle_icon');
|
||||||
|
$('<div>').html ('Appearance').appendTo (titleDiv);
|
||||||
|
let buttonsDiv = $('<div>').addClass ('ov_sidebar_settings_padded').appendTo (contentDiv);
|
||||||
|
let result = {
|
||||||
|
buttons : [],
|
||||||
|
select: (value) => {
|
||||||
|
Select (result.buttons, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result.buttons.push (AddRadioButton (buttonsDiv, OV.Theme.Light, 'Light', this.callbacks.onThemeChange));
|
||||||
|
result.buttons.push (AddRadioButton (buttonsDiv, OV.Theme.Dark, 'Dark', this.callbacks.onThemeChange));
|
||||||
|
Select (result.buttons, defaultValue);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AddResetToDefaultsButton (defaultSettings)
|
||||||
|
{
|
||||||
|
let resetToDefaultsButton = $('<div>').addClass ('ov_button').addClass ('outline').addClass ('ov_sidebar_button').html ('Reset to Default').appendTo (this.contentDiv);
|
||||||
|
resetToDefaultsButton.click (() => {
|
||||||
|
this.backgroundColorInput.pickr.setColor ('#' + OV.ColorToHexString (defaultSettings.backgroundColor));
|
||||||
|
this.callbacks.onBackgroundColorChange (defaultSettings.backgroundColor);
|
||||||
|
this.defaultColorInput.pickr.setColor ('#' + OV.ColorToHexString (defaultSettings.defaultColor));
|
||||||
|
this.callbacks.onDefaultColorChange (defaultSettings.defaultColor);
|
||||||
|
if (this.themeInput !== null) {
|
||||||
|
this.themeInput.select (defaultSettings.themeId);
|
||||||
|
this.callbacks.onThemeChange (defaultSettings.themeId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -14,15 +14,13 @@ OV.Website = class
|
|||||||
this.hashHandler = new OV.HashHandler ();
|
this.hashHandler = new OV.HashHandler ();
|
||||||
this.cookieHandler = new OV.CookieHandler ();
|
this.cookieHandler = new OV.CookieHandler ();
|
||||||
this.toolbar = new OV.Toolbar (this.parameters.toolbarDiv);
|
this.toolbar = new OV.Toolbar (this.parameters.toolbarDiv);
|
||||||
this.sidebar = new OV.Sidebar (this.parameters.sidebarDiv);
|
|
||||||
this.navigator = new OV.Navigator (this.parameters.navigatorDiv, this.parameters.navigatorSplitterDiv);
|
this.navigator = new OV.Navigator (this.parameters.navigatorDiv, this.parameters.navigatorSplitterDiv);
|
||||||
|
this.sidebar = new OV.Sidebar (this.parameters.sidebarDiv);
|
||||||
this.eventHandler = new OV.EventHandler (this.parameters.eventHandler);
|
this.eventHandler = new OV.EventHandler (this.parameters.eventHandler);
|
||||||
this.settings = new OV.Settings ();
|
this.settings = new OV.Settings ();
|
||||||
this.modelLoader = new OV.ThreeModelLoader ();
|
this.modelLoader = new OV.ThreeModelLoader ();
|
||||||
this.themeHandler = new OV.ThemeHandler ();
|
this.themeHandler = new OV.ThemeHandler ();
|
||||||
this.highlightColor = new THREE.Color (0x8ec9f0);
|
this.highlightColor = new THREE.Color (0x8ec9f0);
|
||||||
this.detailsPanel = null;
|
|
||||||
this.settingsPanel = null;
|
|
||||||
this.model = null;
|
this.model = null;
|
||||||
this.dialog = null;
|
this.dialog = null;
|
||||||
}
|
}
|
||||||
@ -63,9 +61,7 @@ OV.Website = class
|
|||||||
let safetyMargin = 0;
|
let safetyMargin = 0;
|
||||||
if (!OV.IsSmallWidth ()) {
|
if (!OV.IsSmallWidth ()) {
|
||||||
navigatorWidth = this.navigator.GetWidth ();
|
navigatorWidth = this.navigator.GetWidth ();
|
||||||
if (this.sidebar.IsVisible ()) {
|
sidebarWidth = this.sidebar.GetWidth ();
|
||||||
sidebarWidth = parseInt (this.parameters.sidebarDiv.outerWidth (true), 10);
|
|
||||||
}
|
|
||||||
safetyMargin = 1;
|
safetyMargin = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +72,7 @@ OV.Website = class
|
|||||||
this.parameters.introDiv.outerHeight (contentHeight, true);
|
this.parameters.introDiv.outerHeight (contentHeight, true);
|
||||||
|
|
||||||
this.navigator.Resize (contentHeight);
|
this.navigator.Resize (contentHeight);
|
||||||
this.sidebar.Resize ();
|
this.sidebar.Resize (contentHeight);
|
||||||
this.viewer.Resize (contentWidth, contentHeight);
|
this.viewer.Resize (contentWidth, contentHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +112,7 @@ OV.Website = class
|
|||||||
this.model = null;
|
this.model = null;
|
||||||
this.viewer.Clear ();
|
this.viewer.Clear ();
|
||||||
this.navigator.Clear ();
|
this.navigator.Clear ();
|
||||||
|
this.sidebar.Clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
HidePopups ()
|
HidePopups ()
|
||||||
@ -124,7 +121,6 @@ OV.Website = class
|
|||||||
this.dialog.Hide ();
|
this.dialog.Hide ();
|
||||||
this.dialog = null;
|
this.dialog = null;
|
||||||
}
|
}
|
||||||
this.sidebar.HidePopups ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnModelFinished (importResult, threeObject)
|
OnModelFinished (importResult, threeObject)
|
||||||
@ -133,7 +129,7 @@ OV.Website = class
|
|||||||
this.viewer.SetMainObject (threeObject);
|
this.viewer.SetMainObject (threeObject);
|
||||||
this.viewer.SetUpVector (importResult.upVector, false);
|
this.viewer.SetUpVector (importResult.upVector, false);
|
||||||
this.navigator.FillTree (importResult);
|
this.navigator.FillTree (importResult);
|
||||||
this.settingsPanel.Update (this.model);
|
this.sidebar.Update (this.model);
|
||||||
this.FitModelToWindow (true);
|
this.FitModelToWindow (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,9 +324,6 @@ OV.Website = class
|
|||||||
OV.ReplaceDefaultMaterialColor (this.model, this.settings.defaultColor);
|
OV.ReplaceDefaultMaterialColor (this.model, this.settings.defaultColor);
|
||||||
this.modelLoader.ReplaceDefaultMaterialColor (this.settings.defaultColor);
|
this.modelLoader.ReplaceDefaultMaterialColor (this.settings.defaultColor);
|
||||||
}
|
}
|
||||||
if (this.settingsPanel !== null) {
|
|
||||||
this.settingsPanel.UpdateSettings (this.settings);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,85 +508,11 @@ OV.Website = class
|
|||||||
|
|
||||||
InitSidebar ()
|
InitSidebar ()
|
||||||
{
|
{
|
||||||
function AddSidebarButton (toolbar, eventHandler, sidebarPanel, onClick)
|
this.sidebar.Init (this.settings,
|
||||||
{
|
|
||||||
let button = toolbar.AddImageButton (sidebarPanel.image, sidebarPanel.title, () => {
|
|
||||||
eventHandler.HandleEvent ('sidebar_clicked', { item : sidebarPanel.image });
|
|
||||||
onClick ();
|
|
||||||
});
|
|
||||||
button.AddClass ('only_full_width only_on_model right');
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
function UpdateSidebarButtons (sidebar, sidebarPanels)
|
|
||||||
{
|
|
||||||
const visiblePanelId = sidebar.GetVisiblePanelId ();
|
|
||||||
for (let i = 0; i < sidebarPanels.length; i++) {
|
|
||||||
let sidebarPanel = sidebarPanels[i];
|
|
||||||
if (sidebarPanel.panelId === visiblePanelId) {
|
|
||||||
sidebarPanel.button.AddImageClass ('selected');
|
|
||||||
} else {
|
|
||||||
sidebarPanel.button.RemoveImageClass ('selected');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ShowSidebar (sidebar, cookieHandler, sidebarPanels, panelId)
|
|
||||||
{
|
|
||||||
sidebar.Show (panelId);
|
|
||||||
UpdateSidebarButtons (sidebar, sidebarPanels);
|
|
||||||
cookieHandler.SetBoolVal ('ov_show_sidebar', sidebar.IsVisible ());
|
|
||||||
}
|
|
||||||
|
|
||||||
function ToggleSidebar (sidebar, cookieHandler, sidebarPanels, panelId)
|
|
||||||
{
|
|
||||||
if (sidebar.GetVisiblePanelId () !== panelId) {
|
|
||||||
ShowSidebar (sidebar, cookieHandler, sidebarPanels, panelId);
|
|
||||||
} else {
|
|
||||||
ShowSidebar (sidebar, cookieHandler, sidebarPanels, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.detailsPanel = new OV.DetailsSidebarPanel (this.parameters.sidebarDiv);
|
|
||||||
this.settingsPanel = new OV.SettingsSidebarPanel (this.parameters.sidebarDiv);
|
|
||||||
|
|
||||||
let sidebarPanels = [
|
|
||||||
{
|
{
|
||||||
panelId : null,
|
onResize : () => {
|
||||||
panel : this.detailsPanel,
|
|
||||||
image : 'details',
|
|
||||||
title : 'Details panel',
|
|
||||||
button : null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
panelId : null,
|
|
||||||
panel : this.settingsPanel,
|
|
||||||
image : 'settings',
|
|
||||||
title : 'Settings panel',
|
|
||||||
button : null
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
for (let id = 0; id < sidebarPanels.length; id++) {
|
|
||||||
let sidebarPanel = sidebarPanels[id];
|
|
||||||
sidebarPanel.panelId = this.sidebar.AddPanel (sidebarPanel.panel);
|
|
||||||
sidebarPanel.button = AddSidebarButton (this.toolbar, this.eventHandler, sidebarPanel, () => {
|
|
||||||
ToggleSidebar (this.sidebar, this.cookieHandler, sidebarPanels, sidebarPanel.panelId);
|
|
||||||
this.Resize ();
|
|
||||||
});
|
|
||||||
sidebarPanel.panel.Init ({
|
|
||||||
onClose : () => {
|
|
||||||
ShowSidebar (this.sidebar, this.cookieHandler, sidebarPanels, null);
|
|
||||||
this.Resize ();
|
this.Resize ();
|
||||||
}
|
},
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let defaultSettings = new OV.Settings ();
|
|
||||||
this.settingsPanel.InitSettings (
|
|
||||||
this.settings,
|
|
||||||
defaultSettings,
|
|
||||||
{
|
|
||||||
onBackgroundColorChange : (newVal) => {
|
onBackgroundColorChange : (newVal) => {
|
||||||
this.settings.backgroundColor = newVal;
|
this.settings.backgroundColor = newVal;
|
||||||
this.settings.SaveToCookies (this.cookieHandler);
|
this.settings.SaveToCookies (this.cookieHandler);
|
||||||
@ -613,9 +532,6 @@ OV.Website = class
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let show = this.cookieHandler.GetBoolVal ('ov_show_sidebar', true);
|
|
||||||
ShowSidebar (this.sidebar, this.cookieHandler, sidebarPanels, show ? sidebarPanels[0].panelId : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InitNavigator ()
|
InitNavigator ()
|
||||||
@ -699,14 +615,14 @@ OV.Website = class
|
|||||||
return GetMaterialsForMesh (this.viewer, this.model, meshInstanceId);
|
return GetMaterialsForMesh (this.viewer, this.model, meshInstanceId);
|
||||||
},
|
},
|
||||||
onModelSelected : () => {
|
onModelSelected : () => {
|
||||||
this.detailsPanel.AddObject3DProperties (this.model);
|
this.sidebar.AddObject3DProperties (this.model);
|
||||||
},
|
},
|
||||||
onMeshSelected : (meshInstanceId) => {
|
onMeshSelected : (meshInstanceId) => {
|
||||||
let meshInstance = this.model.GetMeshInstance (meshInstanceId);
|
let meshInstance = this.model.GetMeshInstance (meshInstanceId);
|
||||||
this.detailsPanel.AddObject3DProperties (meshInstance);
|
this.sidebar.AddObject3DProperties (meshInstance);
|
||||||
},
|
},
|
||||||
onMaterialSelected : (materialIndex) => {
|
onMaterialSelected : (materialIndex) => {
|
||||||
this.detailsPanel.AddMaterialProperties (this.model.GetMaterial (materialIndex));
|
this.sidebar.AddMaterialProperties (this.model.GetMaterial (materialIndex));
|
||||||
},
|
},
|
||||||
onResize : () => {
|
onResize : () => {
|
||||||
this.Resize ();
|
this.Resize ();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user