//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- function DecalEditorGui::onWake(%this) { %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; if(EditorSettings.value( "WorldEditor/forceSidebarToSide" ) == 1) { // Let's dock the side panel to the right side %this.docked = false; %this.resizing = true; %this.dockSidePanel(); } else { // Let's release the side panel so it can be moved %this.docked = true; %this.resizing = false; %this.releaseSidePanel(); } } function DecalEditorGui::maxSize(%this, %window) { // Resize the windows to the max height // and force these to the right side if set if(EditorSettings.value( "WorldEditor/forceSidebarToSide" ) == 1 && %this.resizing == true) { // prevent onResize after a resize %this.resizing = false; %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; %offset = -1; // tweak the vertical offset so that it aligns neatly %top = EditorGuiToolbar.extent.y + %offset; %bottom = %top + 59; %maxHeight = Canvas.extent.y - %top - %bottom; // --- Fixed window (top) ------------------------------------------------ // put it back if it moved %fixedWindow.position.x = Canvas.extent.x - %fixedWindow.extent.x; %fixedWindow.position.y = %top; // don't go beyond the canvas if(%fixedWindow.extent.y > %maxHeight) %fixedWindow.extent.y = %maxHeight - %fluidWindow.extent.y; %position = %fixedWindow.position.x SPC %fixedWindow.position.y; %extent = %window.extent.x SPC %fixedWindow.extent.y; %fixedWindow.resize(%position.x, %position.y, %extent.x, %extent.y); // --- Fluid window (bottom) --------------------------------------------- // position is relative to the top window %position = %fixedWindow.position.x SPC %fixedWindow.extent.y + %top; %extent = %window.extent.x SPC Canvas.extent.y - %fixedWindow.extent.y - %bottom; %fluidWindow.resize(%position.x, %position.y, %extent.x, %extent.y); // --- AssetBrowser window ---------------------------------------------- if(isObject(AssetBrowserWindow)) { // Only resize the AssetBrowser if it's docked if(AssetBrowserWindow.docked == true) { // The width is relative to the sidepanel %browserWidth = Canvas.extent.x - %extent.x; %browserHeight = AssetBrowserWindow.extent.y; %browserPosY = Canvas.extent.y - AssetBrowserWindow.extent.y - 33; AssetBrowserWindow.resize(0, %browserPosY, %browserWidth, %browserHeight); } } // --- Windowed Console -------------------------------------------------- if(isObject(windowConsoleControl)) { // Only resize the AssetBrowser if it's docked if(windowConsoleControl.docked == true) { // The width is relative to the sidepanel %consoleWidth = Canvas.extent.x - %extent.x; %consoleHeight = windowConsoleControl.extent.y; %consolePosY = Canvas.extent.y - windowConsoleControl.extent.y - 33; windowConsoleControl.resize(0, %consolePosY, %consoleWidth, %consoleHeight); } } } } function DecalEditorWindow::onMouseDragged(%this) { %parent = DecalEditorGui; if(%parent.panelHidden == true) { %parent.showSidePanel(); } if(%parent.resizing == false && %parent.docked == true) { %parent.resizing = true; %parent.maxSize(%this); } } function DecalPreviewWindow::onMouseDragged(%this) { %parent = DecalEditorGui; if(%parent.panelHidden == true) { %parent.showSidePanel(); } if(%parent.resizing == false && %parent.docked == true) { %parent.resizing = true; %parent.maxSize(%this); } } function DecalEditorGui::onResize(%this, %newPosition, %newExtent) { // Window to focus on (mostly the fluid window) %window = DecalPreviewWindow; if(%window.panelHidden == true) { %window.showSidePanel(); } if(%this.resizing == false && %this.docked == true) { // Only resize once %this.resizing = true; %this.maxSize(%window); } } function DecalEditorGui::dockSidePanel() { %parent = DecalEditorGui; %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; if(%parent.docked == true) return; // Move and resize the window(s) %parent.resizing = true; %parent.maxSize(%fluidWindow); %parent.docked = true; %fluidWindow.onMouseDragged(); // Lock the windows in place %fixedWindow.canCollapse = "0"; %fixedWindow.canMove = "0"; %fluidWindow.canCollapse = "0"; %fluidWindow.canMove = "0"; DecalEditorGui_UnDockBtn.Visible = "1"; DecalEditorGui_DockBtn.Visible = "0"; DecalEditorGui_showBtn.Visible = "0"; DecalEditorGui_hideBtn.Visible = "1"; } function DecalEditorGui::releaseSidePanel() { %parent = DecalEditorGui; %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; if(%parent.docked == false) return; // Unlock the windows so that be moved %fixedWindow.canCollapse = "1"; %fixedWindow.canMove = "1"; %fluidWindow.canCollapse = "1"; %fluidWindow.canMove = "1"; DecalEditorGui_UnDockBtn.Visible = "0"; DecalEditorGui_DockBtn.Visible = "1"; DecalEditorGui_showBtn.Visible = "0"; DecalEditorGui_hideBtn.Visible = "0"; // Let's do a small resize so it's visually clear we're undocking %position = %fixedWindow.position.x - 6 SPC %fixedWindow.position.y + 6; %extent = %fixedWindow.extent.x SPC %fixedWindow.extent.y; %fixedWindow.resize(%position.x, %position.y, %extent.x, %extent.y); %position = %fluidWindow.position.x - 6 SPC %fluidWindow.position.y + 6; %extent = %fluidWindow.extent.x SPC %fluidWindow.extent.y - 12; %fluidWindow.resize(%position.x, %position.y, %extent.x, %extent.y); %parent.docked = false; %parent.resizing = false; } function DecalEditorGui::hideSidePanel() { %parent = DecalEditorGui; %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; DecalEditorGui_showBtn.Visible = "1"; DecalEditorGui_hideBtn.Visible = "0"; // hide the content of the panels %fixedWindow.titleText = %fixedWindow.text; %fluidWindow.titleText = %fluidWindow.text; %fixedWindow.text = ""; DecalEditorTabBook.Visible = "0"; %fluidWindow.text = ""; DecalEditorTemplateProperties.Visible = "0"; DecalEditorLibraryProperties.Visible = "0"; // Let's do a resize so that the panel is collapsed to the side %position = Canvas.extent.x - 24 SPC %fixedWindow.position.y; %extent = %fixedWindow.extent.x SPC %fixedWindow.extent.y; %fixedWindow.resize(%position.x, %position.y, %extent.x, %extent.y); %position = Canvas.extent.x - 24 SPC %fluidWindow.position.y; %extent = %fluidWindow.extent.x SPC %fluidWindow.extent.y; %fluidWindow.resize(%position.x, %position.y, %extent.x, %extent.y); %parent.panelHidden = true; } function DecalEditorGui::showSidePanel() { %parent = DecalEditorGui; %fixedWindow = DecalEditorWindow; %fluidWindow = DecalPreviewWindow; DecalEditorGui_showBtn.Visible = "0"; DecalEditorGui_hideBtn.Visible = "1"; // show the content of the panels %fixedWindow.text = %fixedWindow.titleText; DecalEditorTabBook.Visible = "1"; %fluidWindow.text = %fluidWindow.titleText; DecalEditorTemplateProperties.Visible = "1"; DecalEditorLibraryProperties.Visible = "1"; %parent.resizing = true; %parent.maxSize(%fluidWindow); %parent.panelHidden = false; } //----------------------------------------------------------------------------- function DecalEditorGui::onSelectInstance( %this, %decalId, %lookupName ) { if( DecalEditorGui.selDecalInstanceId == %decalId ) return; // Lets remember the new Id DecalEditorGui.selDecalInstanceId = %decalId; DecalEditorTreeView.clearSelection(); %name = %decalId SPC %lookupName; %item = DecalEditorTreeView.findItemByName( %name ); DecalEditorTreeView.selectItem( %item ); DecalEditorGui.syncNodeDetails(); } function DecalEditorGui::onCreateInstance( %this, %decalId, %lookupName ) { // Lets remember the new Id DecalEditorGui.selDecalInstanceId = %decalId; // Add the new instance to the node tree DecalEditorTreeView.addNodeTree( %decalId, %lookupName ); DecalEditorTreeView.clearSelection(); %name = %decalId SPC %lookupName; %item = DecalEditorTreeView.findItemByName( %name ); DecalEditorTreeView.selectItem( %item ); DecalEditorGui.syncNodeDetails(); } function DecalEditorGui::onDeleteInstance( %this, %decalId, %lookupName ) { if( %decalId == DecalEditorGui.selDecalInstanceId ) DecalEditorGui.selDecalInstanceId = -1; %id = DecalEditorTreeView.findItemByName( %decalId SPC %lookupName ); DecalEditorTreeView.removeItem(%id); } function DecalEditorGui::editNodeDetails( %this ) { %decalId = DecalEditorGui.selDecalInstanceId; if( %decalId == -1 ) return; %nodeDetails = DecalEditorDetailContainer-->nodePosition.getText(); %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeTangent.getText(); %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeSize.getText(); if( getWordCount(%nodeDetails) == 7 ) DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, false ); } // Stores the information when the gizmo is first used function DecalEditorGui::prepGizmoTransform( %this, %decalId, %nodeDetails ) { DecalEditorGui.gizmoDetails = %nodeDetails; } // Activated in onMouseUp while gizmo is dirty function DecalEditorGui::completeGizmoTransform( %this, %decalId, %nodeDetails ) { DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, true ); } function DecalEditorGui::onSleep( %this ) { } function DecalEditorGui::syncNodeDetails( %this ) { %decalId = DecalEditorGui.selDecalInstanceId; if( %decalId == -1 ) return; %lookupName = DecalEditorGui.getDecalLookupName( %decalId ); DecalEditorGui.updateInstancePreview( %lookupName.materialAsset ); DecalEditorDetailContainer-->instanceId.setText(%decalId @ " " @ %lookupName); %transformData = DecalEditorGui.getDecalTransform(%decalId); DecalEditorDetailContainer-->nodePosition.setText(getWords(%transformData, 0, 2)); DecalEditorDetailContainer-->nodeTangent.setText(getWords(%transformData, 3, 5)); DecalEditorDetailContainer-->nodeSize.setText(getWord(%transformData, 6)); } function DecalEditorGui::paletteSync( %this, %mode ) { %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; eval(%evalShortcut); } function DecalDataList::onSelect( %this, %id, %text ) { %obj = %this.getItemObject( %id ); DecalEditorGui.currentDecalData = %obj; %itemNum = DecalDataList.getSelectedItem(); if ( %itemNum == -1 ) return; %data = DecalDataList.getItemObject( %itemNum ); // Update the materialEditorList $Tools::materialEditorList = %data.getId(); //Canvas.pushDialog( DecalEditDlg ); DecalInspector.inspect( %data ); DecalEditorGui.updateDecalPreview( %data.materialAsset ); } function RetargetDecalButton::onClick( %this ) { %id = DecalDataList.getSelectedItem(); %datablock = DecalDataList.getItemText(%id ); if( !isObject(%datablock) ) { toolsMessageBoxOK("Error", "A valid Decal Template must be selected."); return; } // This is the first place IODropdown is used. The # in the function passed replaced with the output // of the preset menu. IODropdown("Retarget Decal Instances", "Retarget DecalInstances from " @ %datablock.getName() @ " over to....", "decalDataSet", "DecalEditorGui.retargetDecalDatablock(" @ %datablock.getName() @ ", #);", ""); DecalEditorGui.rebuildInstanceTree(); } function NewDecalButton::onClick( %this ) { AssetBrowser_SelectModule.showDialog("DecalEditorGui.pickedNewDecalTargetModule"); AssetBrowser_SelectModuleWindow.selectWindow(); } function DecalEditorGui::pickedNewDecalTargetModule(%this, %module) { %moduleDef = ModuleDatabase.findModule(%module); $decalDataFile = %moduleDef.ModulePath @ "/scripts/managedData/managedDecalData." @ $TorqueScriptFileExtension; if(!isDirectory(filePath($decalDataFile))) { AssetBrowser.dirHandler.createFolder(filePath($decalDataFile)); } %name = getUniqueName( "NewDecalData" ); %str = "datablock DecalData( " @ %name @ " ) { Material = \"WarningMaterial\"; };"; eval( %str ); DecalPMan.setDirty( %name, $decalDataFile ); if ( strchr(LibraryTabControl.text, "*") $= "" ) LibraryTabControl.text = LibraryTabControl.text @ "*"; DecalDataList.doMirror(); %id = DecalDataList.findItemText( %name ); DecalDataList.setSelected( %id, true ); Canvas.pushDialog( DecalEditDlg ); DecalInspector.inspect( %name ); } function DeleteDecalButton::onClick( %this ) { if( DecalEditorTabBook.getSelectedPage() == 0 ) // library { %id = DecalDataList.getSelectedItem(); %datablock = DecalDataList.getItemText(%id ); toolsMessageBoxYesNoCancel("Delete Decal Datablock?", "Are you sure you want to delete

" @ %datablock @ "

Datablock deletion won't take affect until the engine is quit.", "DecalEditorGui.deleteSelectedDecalDatablock();", "", "" ); } else // instances { DecalEditorGui.deleteSelectedDecal(); } } // Intended for gui use. The undo/redo functionality for deletion of datablocks // will enable itself automatically after using this function. function DecalEditorGui::deleteSelectedDecalDatablock() { %id = DecalDataList.getSelectedItem(); %datablock = DecalDataList.getItemText(%id ); DecalEditorGui.deleteDecalDatablock( %datablock ); if( %datablock.getFilename() !$= "" ) { DecalPMan.removeDirty( %datablock ); DecalPMan.removeObjectFromFile( %datablock ); } DecalDataList.addFilteredItem( %datablock ); } function DecalEditorTabBook::onTabSelected( %this, %text, %idx ) { if( %idx == 0) { DecalPreviewWindow.text = ":: Decal Editor - Template Properties"; DecalEditorLibraryProperties.setVisible(true); DecalEditorTemplateProperties.setVisible(false); RetargetDecalButton.setVisible( true ); SaveDecalsButton.setVisible( true ); NewDecalButton.setVisible( true ); DeleteDecalButton.tabSelected = %idx; } else { DecalPreviewWindow.text = ":: Decal Editor - Instance Properties"; RetargetDecalButton.setVisible( false ); NewDecalButton.setVisible( false ); SaveDecalsButton.setVisible( false ); DeleteDecalButton.tabSelected = %idx; DecalEditorLibraryProperties.setVisible(false); DecalEditorTemplateProperties.setVisible(true); } } function DecalEditorTreeView::onDefineIcons() { %icons = "tools/gui/images/treeview/default:" @ "tools/classIcons/decal:" @ "tools/classIcons/decalNode:"; DecalEditorTreeView.buildIconTable( %icons ); } function DecalEditorTreeView::onSelect(%this, %id) { %instanceTag = getWord( DecalEditorTreeView.getItemText(%id), 1 ); if( !isObject( %instanceTag ) ) return; if( %instanceTag.getClassName() !$= "DecalData" ) return; // Grab the id from the tree view %decalId = getWord( DecalEditorTreeView.getItemText(%id), 0 ); if( DecalEditorGui.selDecalInstanceId == %decalId ) return; // Set the curent decalinstances id DecalEditorGui.selDecalInstanceId = %decalId; DecalEditorGui.selectDecal(%decalId); DecalEditorGui.syncNodeDetails(%id); } // Creating per node in the instance tree function DecalEditorTreeView::addNodeTree(%this, %nodeName, %parentName) { // If my template isnt there...put it there if ( %this.findItemByName(%parentName) == 0 ) { %rootId = %this.findItemByName(""); %this.insertItem( %rootId, %parentName, 0, "", 1, 1); } %nodeName = %nodeName SPC %parentName; %parentId = %this.findItemByName(%parentName); %id = %this.insertItem(%parentId, %nodeName, 0, "", 2); } function DecalInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) { if( %fieldName $= "Material" || %fieldName $= "MaterialAsset") DecalEditorGui.updateDecalPreview( %newValue ); // Same work to do as for the regular WorldEditor Inspector. Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); if (%oldValue != %newValue || %oldValue !$= %newValue) %this.setDirty(%object); } function DecalInspector::setDirty( %this, %object ) { DecalPMan.setDirty( %object ); if ( strchr(LibraryTabControl.text, "*") $= "" ) LibraryTabControl.text = LibraryTabControl.text @ "*"; } function DecalInspector::removeDirty() { if ( strchr(LibraryTabControl.text, "*") !$= "" ) LibraryTabControl.text = stripChars(LibraryTabControl.text, "*"); } function DecalEditorGui::updateDecalPreview( %this, %material ) { %previewImage = ""; if( isObject( %material ) ) { %previewImage = %material.getDiffuseMap(0); } else { if(AssetDatabase.isDeclaredAsset(%material)) { %previewImage = %material; } } DecalPreviewWindow-->decalPreview.setBitmap( getAssetPreviewImage(%previewImage) ); } function DecalEditorGui::updateInstancePreview( %this, %material ) { %previewImage = ""; if( isObject( %material ) ) { %previewImage = %material.getDiffuseMap(0); } else { if(AssetDatabase.isDeclaredAsset(%material)) { %previewImage = %material; } } DecalPreviewWindow-->instancePreview.setBitmap( getAssetPreviewImage(%previewImage) ); } function DecalEditorGui::rebuildInstanceTree( %this ) { // Initialize the instance tree when the tab is selected DecalEditorTreeView.removeItem(0); %rootId = DecalEditorTreeView.insertItem(0, "", 0, ""); %count = DecalEditorGui.getDecalCount(); for (%i = 0; %i < %count; %i++) { %name = DecalEditorGui.getDecalLookupName(%i); if( %name $= "invalid" ) continue; DecalEditorTreeView.addNodeTree(%i, %name); } }