mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-21 23:53:51 +00:00
Initial implementation of the new Base Game Template and some starting modules.
This makes some tweaks to the engine to support this, specifically, it tweaks the hardcoded shaderpaths to defer to a pref variable, so none of the shader paths are hardcoded. Also tweaks how post effects read in texture files, removing a bizzare filepath interpretation choice, where if the file path didn't start with "/" it forcefully appended the script's file path. This made it impossible to have images not in the same dir as the script file defining the post effect. This was changed and the existing template's post effects tweaked for now to just add "./" to those few paths impacted, as well as the perf vars to support the non-hardcoded shader paths in the engine.
This commit is contained in:
parent
5c8a82180b
commit
1ed8b05169
1572 changed files with 146699 additions and 85 deletions
|
|
@ -0,0 +1,105 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 GE_ReturnToMainMenu()
|
||||
{
|
||||
loadMainMenu();
|
||||
}
|
||||
|
||||
function GE_OpenGUIFile()
|
||||
{
|
||||
%openFileName = GuiBuilder::getOpenName();
|
||||
if( %openFileName $= "" )
|
||||
return;
|
||||
|
||||
// Make sure the file is valid.
|
||||
if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso")))
|
||||
return;
|
||||
|
||||
// Allow stomping objects while exec'ing the GUI file as we want to
|
||||
// pull the file's objects even if we have another version of the GUI
|
||||
// already loaded.
|
||||
|
||||
%oldRedefineBehavior = $Con::redefineBehavior;
|
||||
$Con::redefineBehavior = "replaceExisting";
|
||||
|
||||
// Load up the level.
|
||||
exec( %openFileName );
|
||||
|
||||
$Con::redefineBehavior = %oldRedefineBehavior;
|
||||
|
||||
// The level file should have contained a scenegraph, which should now be in the instant
|
||||
// group. And, it should be the only thing in the group.
|
||||
if( !isObject( %guiContent ) )
|
||||
{
|
||||
MessageBox( getEngineName(),
|
||||
"You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown",
|
||||
"Ok", "Information" );
|
||||
GuiEditContent( Canvas.getContent() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
GuiEditContent( %guiContent );
|
||||
}
|
||||
|
||||
function GE_GUIList::onURL(%this, %url)
|
||||
{
|
||||
// Remove 'gamelink:' from front
|
||||
%gui = getSubStr(%url, 9, 1024);
|
||||
GuiEditContent(%gui);
|
||||
}
|
||||
|
||||
function EditorChooseGUI::onWake()
|
||||
{
|
||||
// Build the text list
|
||||
GE_GUIList.clear();
|
||||
|
||||
%list = "<linkcolor:0000FF><linkcolorhl:FF0000>";
|
||||
%list = GE_ScanGroupForGuis(GuiGroup, %list);
|
||||
GE_GUIList.setText(%list);
|
||||
GE_GUIList.forceReflow();
|
||||
GE_GUIList.scrollToTop();
|
||||
}
|
||||
|
||||
function GE_ScanGroupForGuis(%group, %text)
|
||||
{
|
||||
%count = %group.getCount();
|
||||
for(%i=0; %i < %count; %i++)
|
||||
{
|
||||
%obj = %group.getObject(%i);
|
||||
if(%obj.getClassName() $= "GuiCanvas")
|
||||
{
|
||||
%text = %text @ GE_ScanGroupForGuis(%obj, %text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(%obj.getName() $= "")
|
||||
%name = "(unnamed) - " @ %obj;
|
||||
else
|
||||
%name = %obj.getName() @ " - " @ %obj;
|
||||
|
||||
%text = %text @ "<a:gamelink:" @ %obj @ ">" @ %name @ "</a><br>";
|
||||
}
|
||||
}
|
||||
|
||||
return %text;
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$GUI::FileSpec = "Torque Gui Files (*.gui)|*.gui|All Files (*.*)|*.*|";
|
||||
|
||||
/// GuiBuilder::getSaveName - Open a Native File dialog and retrieve the
|
||||
/// location to save the current document.
|
||||
/// @arg defaultFileName The FileName to default in the field and to be selected when a path is opened
|
||||
function GuiBuilder::getSaveName( %defaultFileName )
|
||||
{
|
||||
%defaultPath = GuiEditor.LastPath;
|
||||
|
||||
if( %defaultFileName $= "" )
|
||||
{
|
||||
%prefix = "";
|
||||
if( isFunction( "isScriptPathExpando" ) )
|
||||
{
|
||||
// if we're editing a game, we want to default to the games dir.
|
||||
// if we're not, then we default to the tools directory or the base.
|
||||
if( isScriptPathExpando( "^game") )
|
||||
%prefix = "^game/";
|
||||
else if( isScriptPathExpando( "^tools" ) )
|
||||
%prefix = "^tools/";
|
||||
}
|
||||
|
||||
%defaultFileName = expandFilename( %prefix @ "gui/untitled.gui" );
|
||||
}
|
||||
else
|
||||
%defaultPath = filePath( %defaultFileName );
|
||||
|
||||
%dlg = new SaveFileDialog()
|
||||
{
|
||||
Filters = $GUI::FileSpec;
|
||||
DefaultPath = makeFullPath( %defaultPath );
|
||||
DefaultFile = %defaultFileName;
|
||||
ChangePath = false;
|
||||
OverwritePrompt = true;
|
||||
};
|
||||
|
||||
if( %dlg.Execute() )
|
||||
{
|
||||
GuiEditor.LastPath = filePath( %dlg.FileName );
|
||||
%filename = %dlg.FileName;
|
||||
if( fileExt( %filename ) !$= ".gui" )
|
||||
%filename = %filename @ ".gui";
|
||||
}
|
||||
else
|
||||
%filename = "";
|
||||
|
||||
%dlg.delete();
|
||||
|
||||
return %filename;
|
||||
}
|
||||
|
||||
function GuiBuilder::getOpenName( %defaultFileName )
|
||||
{
|
||||
if( %defaultFileName $= "" )
|
||||
%defaultFileName = expandFilename("^game/gui/untitled.gui");
|
||||
|
||||
%dlg = new OpenFileDialog()
|
||||
{
|
||||
Filters = $GUI::FileSpec;
|
||||
DefaultPath = GuiEditor.LastPath;
|
||||
DefaultFile = %defaultFileName;
|
||||
ChangePath = false;
|
||||
MustExist = true;
|
||||
};
|
||||
|
||||
if(%dlg.Execute())
|
||||
{
|
||||
GuiEditor.LastPath = filePath( %dlg.FileName );
|
||||
%filename = %dlg.FileName;
|
||||
%dlg.delete();
|
||||
return %filename;
|
||||
}
|
||||
|
||||
%dlg.delete();
|
||||
return "";
|
||||
}
|
||||
1189
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs
Normal file
1189
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,540 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::onAdd( %this )
|
||||
{
|
||||
// %this.setWindowTitle("Torque Gui Editor");
|
||||
|
||||
%this.onCreateMenu();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::onRemove( %this )
|
||||
{
|
||||
if( isObject( GuiEditorGui.menuGroup ) )
|
||||
GuiEditorGui.delete();
|
||||
|
||||
// cleanup
|
||||
%this.onDestroyMenu();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/// Create the Gui Editor menu bar.
|
||||
function GuiEditCanvas::onCreateMenu(%this)
|
||||
{
|
||||
if(isObject(%this.menuBar))
|
||||
return;
|
||||
|
||||
//set up %cmdctrl variable so that it matches OS standards
|
||||
if( $platform $= "macos" )
|
||||
{
|
||||
%cmdCtrl = "cmd";
|
||||
%redoShortcut = "Cmd-Shift Z";
|
||||
}
|
||||
else
|
||||
{
|
||||
%cmdCtrl = "Ctrl";
|
||||
%redoShort = "Ctrl Y";
|
||||
}
|
||||
|
||||
// Menu bar
|
||||
%this.menuBar = new MenuBar()
|
||||
{
|
||||
dynamicItemInsertPos = 3;
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
barTitle = "File";
|
||||
internalName = "FileMenu";
|
||||
|
||||
item[0] = "New Gui..." TAB %cmdCtrl SPC "N" TAB %this @ ".create();";
|
||||
item[1] = "Open..." TAB %cmdCtrl SPC "O" TAB %this @ ".open();";
|
||||
item[2] = "Save" TAB %cmdCtrl SPC "S" TAB %this @ ".save( false, true );";
|
||||
item[3] = "Save As..." TAB %cmdCtrl @ "-Shift S" TAB %this @ ".save( false );";
|
||||
item[4] = "Save Selected As..." TAB %cmdCtrl @ "-Alt S" TAB %this @ ".save( true );";
|
||||
item[5] = "-";
|
||||
item[6] = "Revert Gui" TAB "" TAB %this @ ".revert();";
|
||||
item[7] = "Add Gui From File..." TAB "" TAB %this @ ".append();";
|
||||
item[8] = "-";
|
||||
item[9] = "Open Gui File in Torsion" TAB "" TAB %this @".openInTorsion();";
|
||||
item[10] = "-";
|
||||
item[11] = "Close Editor" TAB "F10" TAB %this @ ".quit();";
|
||||
item[12] = "Quit" TAB %cmdCtrl SPC "Q" TAB "quit();";
|
||||
};
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
barTitle = "Edit";
|
||||
internalName = "EditMenu";
|
||||
|
||||
item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "GuiEditor.undo();";
|
||||
item[1] = "Redo" TAB %redoShortcut TAB "GuiEditor.redo();";
|
||||
item[2] = "-";
|
||||
item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "GuiEditor.saveSelection(); GuiEditor.deleteSelection();";
|
||||
item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "GuiEditor.saveSelection();";
|
||||
item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "GuiEditor.loadSelection();";
|
||||
item[6] = "-";
|
||||
item[7] = "Select All" TAB %cmdCtrl SPC "A" TAB "GuiEditor.selectAll();";
|
||||
item[8] = "Deselect All" TAB %cmdCtrl SPC "D" TAB "GuiEditor.clearSelection();";
|
||||
item[9] = "Select Parent(s)" TAB %cmdCtrl @ "-Alt Up" TAB "GuiEditor.selectParents();";
|
||||
item[10] = "Select Children" TAB %cmdCtrl @ "-Alt Down" TAB "GuiEditor.selectChildren();";
|
||||
item[11] = "Add Parent(s) to Selection" TAB %cmdCtrl @ "-Alt-Shift Up" TAB "GuiEditor.selectParents( true );";
|
||||
item[12] = "Add Children to Selection" TAB %cmdCtrl @ "-Alt-Shift Down" TAB "GuiEditor.selectChildren( true );";
|
||||
item[13] = "Select..." TAB "" TAB "GuiEditorSelectDlg.toggleVisibility();";
|
||||
item[14] = "-";
|
||||
item[15] = "Lock/Unlock Selection" TAB %cmdCtrl SPC "L" TAB "GuiEditor.toggleLockSelection();";
|
||||
item[16] = "Hide/Unhide Selection" TAB %cmdCtrl SPC "H" TAB "GuiEditor.toggleHideSelection();";
|
||||
item[17] = "-";
|
||||
item[18] = "Group Selection" TAB %cmdCtrl SPC "G" TAB "GuiEditor.groupSelected();";
|
||||
item[19] = "Ungroup Selection" TAB %cmdCtrl @ "-Shift G" TAB "GuiEditor.ungroupSelected();";
|
||||
item[20] = "-";
|
||||
item[21] = "Full Box Selection" TAB "" TAB "GuiEditor.toggleFullBoxSelection();";
|
||||
item[22] = "-";
|
||||
item[23] = "Grid Size" TAB %cmdCtrl SPC "," TAB "GuiEditor.showPrefsDialog();";
|
||||
};
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
barTitle = "Layout";
|
||||
internalName = "LayoutMenu";
|
||||
|
||||
item[0] = "Align Left" TAB %cmdCtrl SPC "Left" TAB "GuiEditor.Justify(0);";
|
||||
item[1] = "Center Horizontally" TAB "" TAB "GuiEditor.Justify(1);";
|
||||
item[2] = "Align Right" TAB %cmdCtrl SPC "Right" TAB "GuiEditor.Justify(2);";
|
||||
item[3] = "-";
|
||||
item[4] = "Align Top" TAB %cmdCtrl SPC "Up" TAB "GuiEditor.Justify(3);";
|
||||
item[5] = "Center Vertically" TAB "" TAB "GuiEditor.Justify(7);";
|
||||
item[6] = "Align Bottom" TAB %cmdCtrl SPC "Down" TAB "GuiEditor.Justify(4);";
|
||||
item[7] = "-";
|
||||
item[8] = "Space Vertically" TAB "" TAB "GuiEditor.Justify(5);";
|
||||
item[9] = "Space Horizontally" TAB "" TAB "GuiEditor.Justify(6);";
|
||||
item[10] = "-";
|
||||
item[11] = "Fit into Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents();";
|
||||
item[12] = "Fit Width to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( true, false );";
|
||||
item[13] = "Fit Height to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( false, true );";
|
||||
item[14] = "-";
|
||||
item[15] = "Bring to Front" TAB "" TAB "GuiEditor.BringToFront();";
|
||||
item[16] = "Send to Back" TAB "" TAB "GuiEditor.PushToBack();";
|
||||
};
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
barTitle = "Move";
|
||||
internalName = "MoveMenu";
|
||||
|
||||
item[0] = "Nudge Left" TAB "Left" TAB "GuiEditor.moveSelection( -1, 0);";
|
||||
item[1] = "Nudge Right" TAB "Right" TAB "GuiEditor.moveSelection( 1, 0);";
|
||||
item[2] = "Nudge Up" TAB "Up" TAB "GuiEditor.moveSelection( 0, -1);";
|
||||
item[3] = "Nudge Down" TAB "Down" TAB "GuiEditor.moveSelection( 0, 1 );";
|
||||
item[4] = "-";
|
||||
item[5] = "Big Nudge Left" TAB "Shift Left" TAB "GuiEditor.moveSelection( - GuiEditor.snap2gridsize, 0 );";
|
||||
item[6] = "Big Nudge Right" TAB "Shift Right" TAB "GuiEditor.moveSelection( GuiEditor.snap2gridsize, 0 );";
|
||||
item[7] = "Big Nudge Up" TAB "Shift Up" TAB "GuiEditor.moveSelection( 0, - GuiEditor.snap2gridsize );";
|
||||
item[8] = "Big Nudge Down" TAB "Shift Down" TAB "GuiEditor.moveSelection( 0, GuiEditor.snap2gridsize );";
|
||||
};
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
barTitle = "Snap";
|
||||
internalName = "SnapMenu";
|
||||
|
||||
item[0] = "Snap Edges" TAB "Alt-Shift E" TAB "GuiEditor.toggleEdgeSnap();";
|
||||
item[1] = "Snap Centers" TAB "Alt-Shift C" TAB "GuiEditor.toggleCenterSnap();";
|
||||
item[2] = "-";
|
||||
item[3] = "Snap to Guides" TAB "Alt-Shift G" TAB "GuiEditor.toggleGuideSnap();";
|
||||
item[4] = "Snap to Controls" TAB "Alt-Shift T" TAB "GuiEditor.toggleControlSnap();";
|
||||
item[5] = "Snap to Canvas" TAB "" TAB "GuiEditor.toggleCanvasSnap();";
|
||||
item[6] = "Snap to Grid" TAB "" TAB "GuiEditor.toggleGridSnap();";
|
||||
item[7] = "-";
|
||||
item[8] = "Show Guides" TAB "" TAB "GuiEditor.toggleDrawGuides();";
|
||||
item[9] = "Clear Guides" TAB "" TAB "GuiEditor.clearGuides();";
|
||||
};
|
||||
|
||||
new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
internalName = "HelpMenu";
|
||||
|
||||
barTitle = "Help";
|
||||
|
||||
item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage( GuiEditor.documentationURL );";
|
||||
item[1] = "Offline User Guid..." TAB "" TAB "gotoWebPage( GuiEditor.documentationLocal );";
|
||||
item[2] = "Offline Reference Guide..." TAB "" TAB "shellExecute( GuiEditor.documentationReference );";
|
||||
item[3] = "-";
|
||||
item[4] = "Torque 3D Public Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/73\" );";
|
||||
item[5] = "Torque 3D Private Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/63\" );";
|
||||
};
|
||||
};
|
||||
%this.menuBar.attachToCanvas( Canvas, 0 );
|
||||
}
|
||||
|
||||
$GUI_EDITOR_MENU_EDGESNAP_INDEX = 0;
|
||||
$GUI_EDITOR_MENU_CENTERSNAP_INDEX = 1;
|
||||
$GUI_EDITOR_MENU_GUIDESNAP_INDEX = 3;
|
||||
$GUI_EDITOR_MENU_CONTROLSNAP_INDEX = 4;
|
||||
$GUI_EDITOR_MENU_CANVASSNAP_INDEX = 5;
|
||||
$GUI_EDITOR_MENU_GRIDSNAP_INDEX = 6;
|
||||
$GUI_EDITOR_MENU_DRAWGUIDES_INDEX = 8;
|
||||
$GUI_EDITOR_MENU_FULLBOXSELECT_INDEX = 21;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/// Called before onSleep when the canvas content is changed
|
||||
function GuiEditCanvas::onDestroyMenu(%this)
|
||||
{
|
||||
if( !isObject( %this.menuBar ) )
|
||||
return;
|
||||
|
||||
// Destroy menus
|
||||
while( %this.menuBar.getCount() != 0 )
|
||||
%this.menuBar.getObject( 0 ).delete();
|
||||
|
||||
%this.menuBar.removeFromCanvas();
|
||||
%this.menuBar.delete();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::onWindowClose(%this)
|
||||
{
|
||||
%this.quit();
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Menu Commands.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::create( %this )
|
||||
{
|
||||
GuiEditorNewGuiDialog.init( "NewGui", "GuiControl" );
|
||||
|
||||
Canvas.pushDialog( GuiEditorNewGuiDialog );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::load( %this, %filename )
|
||||
{
|
||||
%newRedefineBehavior = "replaceExisting";
|
||||
if( isDefined( "$GuiEditor::loadRedefineBehavior" ) )
|
||||
{
|
||||
// This trick allows to choose different redefineBehaviors when loading
|
||||
// GUIs. This is useful, for example, when loading GUIs that would lead to
|
||||
// problems when loading with their correct names because script behavior
|
||||
// would immediately attach.
|
||||
//
|
||||
// This allows to also edit the GUI editor's own GUI inside itself.
|
||||
|
||||
%newRedefineBehavior = $GuiEditor::loadRedefineBehavior;
|
||||
}
|
||||
|
||||
// Allow stomping objects while exec'ing the GUI file as we want to
|
||||
// pull the file's objects even if we have another version of the GUI
|
||||
// already loaded.
|
||||
|
||||
%oldRedefineBehavior = $Con::redefineBehavior;
|
||||
$Con::redefineBehavior = %newRedefineBehavior;
|
||||
|
||||
// Load up the gui.
|
||||
exec( %fileName );
|
||||
|
||||
$Con::redefineBehavior = %oldRedefineBehavior;
|
||||
|
||||
// The GUI file should have contained a GUIControl which should now be in the instant
|
||||
// group. And, it should be the only thing in the group.
|
||||
if( !isObject( %guiContent ) )
|
||||
{
|
||||
MessageBox( getEngineName(),
|
||||
"You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown",
|
||||
"Ok", "Information" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
GuiEditor.openForEditing( %guiContent );
|
||||
|
||||
GuiEditorStatusBar.print( "Loaded '" @ %filename @ "'" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::openInTorsion( %this )
|
||||
{
|
||||
if( !GuiEditorContent.getCount() )
|
||||
return;
|
||||
|
||||
%guiObject = GuiEditorContent.getObject( 0 );
|
||||
EditorOpenDeclarationInTorsion( %guiObject );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::open( %this )
|
||||
{
|
||||
%openFileName = GuiBuilder::getOpenName();
|
||||
if( %openFileName $= "" )
|
||||
return;
|
||||
|
||||
// Make sure the file is valid.
|
||||
if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso")))
|
||||
return;
|
||||
|
||||
%this.load( %openFileName );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::save( %this, %selectedOnly, %noPrompt )
|
||||
{
|
||||
// Get the control we should save.
|
||||
|
||||
if( %selectedOnly )
|
||||
{
|
||||
%selected = GuiEditor.getSelection();
|
||||
if( !%selected.getCount() )
|
||||
return;
|
||||
else if( %selected.getCount() > 1 )
|
||||
{
|
||||
MessageBox( "Invalid selection", "Only a single control hierarchy can be saved to a file. Make sure you have selected only one control in the tree view." );
|
||||
return;
|
||||
}
|
||||
|
||||
%currentObject = %selected.getObject( 0 );
|
||||
}
|
||||
else if( GuiEditorContent.getCount() > 0 )
|
||||
%currentObject = GuiEditorContent.getObject( 0 );
|
||||
else
|
||||
return;
|
||||
|
||||
// Store the current guide set on the control.
|
||||
|
||||
GuiEditor.writeGuides( %currentObject );
|
||||
%currentObject.canSaveDynamicFields = true; // Make sure the guides get saved out.
|
||||
|
||||
// Construct a base filename.
|
||||
|
||||
if( %currentObject.getName() !$= "" )
|
||||
%name = %currentObject.getName() @ ".gui";
|
||||
else
|
||||
%name = "Untitled.gui";
|
||||
|
||||
// Construct a path.
|
||||
|
||||
if( %selectedOnly
|
||||
&& %currentObject != GuiEditorContent.getObject( 0 )
|
||||
&& %currentObject.getFileName() $= GuiEditorContent.getObject( 0 ).getFileName() )
|
||||
{
|
||||
// Selected child control that hasn't been yet saved to its own file.
|
||||
|
||||
%currentFile = GuiEditor.LastPath @ "/" @ %name;
|
||||
%currentFile = makeRelativePath( %currentFile, getMainDotCsDir() );
|
||||
}
|
||||
else
|
||||
{
|
||||
%currentFile = %currentObject.getFileName();
|
||||
if( %currentFile $= "")
|
||||
{
|
||||
// No file name set on control. Force a prompt.
|
||||
%noPrompt = false;
|
||||
|
||||
if( GuiEditor.LastPath !$= "" )
|
||||
{
|
||||
%currentFile = GuiEditor.LastPath @ "/" @ %name;
|
||||
%currentFile = makeRelativePath( %currentFile, getMainDotCsDir() );
|
||||
}
|
||||
else
|
||||
%currentFile = expandFileName( %name );
|
||||
}
|
||||
else
|
||||
%currentFile = expandFileName( %currentFile );
|
||||
}
|
||||
|
||||
// Get the filename.
|
||||
|
||||
if( !%noPrompt )
|
||||
{
|
||||
%filename = GuiBuilder::getSaveName( %currentFile );
|
||||
if( %filename $= "" )
|
||||
return;
|
||||
}
|
||||
else
|
||||
%filename = %currentFile;
|
||||
|
||||
// Save the Gui.
|
||||
|
||||
if( isWriteableFileName( %filename ) )
|
||||
{
|
||||
//
|
||||
// Extract any existent TorqueScript before writing out to disk
|
||||
//
|
||||
%fileObject = new FileObject();
|
||||
%fileObject.openForRead( %filename );
|
||||
%skipLines = true;
|
||||
%beforeObject = true;
|
||||
// %var++ does not post-increment %var, in torquescript, it pre-increments it,
|
||||
// because ++%var is illegal.
|
||||
%lines = -1;
|
||||
%beforeLines = -1;
|
||||
%skipLines = false;
|
||||
while( !%fileObject.isEOF() )
|
||||
{
|
||||
%line = %fileObject.readLine();
|
||||
if( %line $= "//--- OBJECT WRITE BEGIN ---" )
|
||||
%skipLines = true;
|
||||
else if( %line $= "//--- OBJECT WRITE END ---" )
|
||||
{
|
||||
%skipLines = false;
|
||||
%beforeObject = false;
|
||||
}
|
||||
else if( %skipLines == false )
|
||||
{
|
||||
if(%beforeObject)
|
||||
%beforeNewFileLines[ %beforeLines++ ] = %line;
|
||||
else
|
||||
%newFileLines[ %lines++ ] = %line;
|
||||
}
|
||||
}
|
||||
%fileObject.close();
|
||||
%fileObject.delete();
|
||||
|
||||
%fo = new FileObject();
|
||||
%fo.openForWrite(%filename);
|
||||
|
||||
// Write out the captured TorqueScript that was before the object before the object
|
||||
for( %i = 0; %i <= %beforeLines; %i++)
|
||||
%fo.writeLine( %beforeNewFileLines[ %i ] );
|
||||
|
||||
%fo.writeLine("//--- OBJECT WRITE BEGIN ---");
|
||||
%fo.writeObject(%currentObject, "%guiContent = ");
|
||||
%fo.writeLine("//--- OBJECT WRITE END ---");
|
||||
|
||||
// Write out captured TorqueScript below Gui object
|
||||
for( %i = 0; %i <= %lines; %i++ )
|
||||
%fo.writeLine( %newFileLines[ %i ] );
|
||||
|
||||
%fo.close();
|
||||
%fo.delete();
|
||||
|
||||
%currentObject.setFileName( makeRelativePath( %filename, getMainDotCsDir() ) );
|
||||
|
||||
GuiEditorStatusBar.print( "Saved file '" @ %currentObject.getFileName() @ "'" );
|
||||
}
|
||||
else
|
||||
MessageBox( "Error writing to file", "There was an error writing to file '" @ %currentFile @ "'. The file may be read-only.", "Ok", "Error" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::append( %this )
|
||||
{
|
||||
// Get filename.
|
||||
|
||||
%openFileName = GuiBuilder::getOpenName();
|
||||
if( %openFileName $= ""
|
||||
|| ( !isFile( %openFileName )
|
||||
&& !isFile( %openFileName @ ".dso" ) ) )
|
||||
return;
|
||||
|
||||
// Exec file.
|
||||
|
||||
%oldRedefineBehavior = $Con::redefineBehavior;
|
||||
$Con::redefineBehavior = "renameNew";
|
||||
exec( %openFileName );
|
||||
$Con::redefineBehavior = %oldRedefineBehavior;
|
||||
|
||||
// Find guiContent.
|
||||
|
||||
if( !isObject( %guiContent ) )
|
||||
{
|
||||
MessageBox( "Error loading GUI file", "The GUI content controls could not be found. This function can only be used with files saved by the GUI editor.", "Ok", "Error" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !GuiEditorContent.getCount() )
|
||||
GuiEditor.openForEditing( %guiContent );
|
||||
else
|
||||
{
|
||||
GuiEditor.getCurrentAddSet().add( %guiContent );
|
||||
GuiEditor.readGuides( %guiContent );
|
||||
GuiEditor.onAddNewCtrl( %guiContent );
|
||||
GuiEditor.onHierarchyChanged();
|
||||
}
|
||||
|
||||
GuiEditorStatusBar.print( "Appended controls from '" @ %openFileName @ "'" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::revert( %this )
|
||||
{
|
||||
if( !GuiEditorContent.getCount() )
|
||||
return;
|
||||
|
||||
%gui = GuiEditorContent.getObject( 0 );
|
||||
%filename = %gui.getFileName();
|
||||
if( %filename $= "" )
|
||||
return;
|
||||
|
||||
if( MessageBox( "Revert Gui", "Really revert the current Gui? This cannot be undone.", "OkCancel", "Question" ) == $MROk )
|
||||
%this.load( %filename );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::close( %this )
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditCanvas::quit( %this )
|
||||
{
|
||||
%this.close();
|
||||
GuiGroup.add(GuiEditorGui);
|
||||
// we must not delete a window while in its event handler, or we foul the event dispatch mechanism
|
||||
%this.schedule(10, delete);
|
||||
|
||||
Canvas.setContent(GuiEditor.lastContent);
|
||||
$InGuiEditor = false;
|
||||
|
||||
//Temp fix to disable MLAA when in GUI editor
|
||||
if( isObject(MLAAFx) && $MLAAFxGuiEditorTemp==true )
|
||||
{
|
||||
MLAAFx.isEnabled = true;
|
||||
$MLAAFxGuiEditorTemp = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Code for the drop-down that allows selecting a GUI to edit in the Gui Editor.
|
||||
|
||||
|
||||
if( !isDefined( "$GuiEditor::GuiFilterList" ) )
|
||||
{
|
||||
/// List of named controls that are filtered out from the
|
||||
/// control list dropdown.
|
||||
$GuiEditor::GuiFilterList =
|
||||
"GuiEditorGui" TAB
|
||||
"AL_ShadowVizOverlayCtrl" TAB
|
||||
"MessageBoxOKDlg" TAB
|
||||
"MessageBoxOKCancelDlg" TAB
|
||||
"MessageBoxOKCancelDetailsDlg" TAB
|
||||
"MessageBoxYesNoDlg" TAB
|
||||
"MessageBoxYesNoCancelDlg" TAB
|
||||
"MessagePopupDlg";
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorContentList::init( %this )
|
||||
{
|
||||
%this.clear();
|
||||
%this.scanGroup( GuiGroup );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorContentList::scanGroup( %this, %group )
|
||||
{
|
||||
foreach( %obj in %group )
|
||||
{
|
||||
if( %obj.isMemberOfClass( "GuiControl" ) )
|
||||
{
|
||||
if(%obj.getClassName() $= "GuiCanvas")
|
||||
{
|
||||
%this.scanGroup( %obj );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(%obj.getName() $= "")
|
||||
%name = "(unnamed) - " @ %obj;
|
||||
else
|
||||
%name = %obj.getName() @ " - " @ %obj;
|
||||
|
||||
%skip = false;
|
||||
|
||||
foreach$( %guiEntry in $GuiEditor::GuiFilterList )
|
||||
if( %obj.getName() $= %guiEntry )
|
||||
{
|
||||
%skip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !%skip )
|
||||
%this.add( %name, %obj );
|
||||
}
|
||||
}
|
||||
else if( %obj.isMemberOfClass( "SimGroup" )
|
||||
&& ( %obj.internalName !$= "EditorGuiGroup" // Don't put our editor's GUIs in the list
|
||||
|| GuiEditor.showEditorGuis ) ) // except if explicitly requested.
|
||||
{
|
||||
// Scan nested SimGroups for GuiControls.
|
||||
|
||||
%this.scanGroup( %obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorContentList::onSelect( %this, %ctrl )
|
||||
{
|
||||
GuiEditor.openForEditing( %ctrl );
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// GuiEditorGroups are recorded only for undo/redo. They are ScriptObjects
|
||||
// containing all the information about a particular GUIControl group.
|
||||
//
|
||||
// The properties of GuiEditorGroups are:
|
||||
//
|
||||
// int count - Number of controls in group.
|
||||
// object ctrl[ 0 .. count ] - Controls in group.
|
||||
// object ctrlParent[ 0 .. count ] - Original parent of each control in group (if missing, controls are moved to parent of group object in ungroup())
|
||||
// object groupObject - The GuiControl group object.
|
||||
// object groupParent - The object to which the group should be parented to.
|
||||
|
||||
|
||||
/// Return the combined global bounds of the controls contained in the GuiEditorGroup.
|
||||
function GuiEditorGroup::getGlobalBounds( %this )
|
||||
{
|
||||
%minX = 2147483647;
|
||||
%minY = 2147483647;
|
||||
%maxX = -2147483647;
|
||||
%maxY = -2147483647;
|
||||
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
{
|
||||
%ctrl = %this.ctrl[ %i ];
|
||||
|
||||
%pos = %ctrl.getGlobalPosition();
|
||||
%extent = %ctrl.getExtent();
|
||||
|
||||
// Min.
|
||||
|
||||
%posX = getWord( %pos, 0 );
|
||||
%posY = getWord( %pos, 1 );
|
||||
|
||||
if( %posX < %minX )
|
||||
%minX = %posX;
|
||||
if( %posY < %minY )
|
||||
%minY = %posY;
|
||||
|
||||
// Max.
|
||||
|
||||
%posX += getWord( %extent, 0 );
|
||||
%posY += getWord( %extent, 1 );
|
||||
|
||||
if( %posX > %maxX )
|
||||
%maxX = %posX;
|
||||
if( %posY > %maxY )
|
||||
%maxY = %posY;
|
||||
}
|
||||
|
||||
return ( %minX SPC %minY SPC ( %maxX - %minX ) SPC ( %maxY - %minY ) );
|
||||
}
|
||||
|
||||
/// Create a new GuiControl and move all the controls contained in the GuiEditorGroup into it.
|
||||
function GuiEditorGroup::group( %this )
|
||||
{
|
||||
%parent = %this.groupParent;
|
||||
|
||||
// Create group.
|
||||
|
||||
%group = new GuiControl();
|
||||
%parent.addGuiControl( %group );
|
||||
%this.groupObject = %group;
|
||||
|
||||
// Make group fit around selection.
|
||||
|
||||
%bounds = %this.getGlobalBounds();
|
||||
%parentGlobalPos = %parent.getGlobalPosition();
|
||||
|
||||
%x = getWord( %bounds, 0 ) - getWord( %parentGlobalPos, 0 );
|
||||
%y = getWord( %bounds, 1 ) - getWord( %parentGlobalPos, 1 );
|
||||
|
||||
%group.setPosition( %x, %y );
|
||||
%group.setExtent( getWord( %bounds, 2 ), getWord( %bounds, 3 ) );
|
||||
|
||||
// Reparent all objects to group.
|
||||
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
{
|
||||
%ctrl = %this.ctrl[ %i ];
|
||||
|
||||
// Save parent for undo.
|
||||
|
||||
%this.ctrlParent[ %i ] = %ctrl.parentGroup;
|
||||
|
||||
// Reparent.
|
||||
|
||||
%group.addGuiControl( %ctrl );
|
||||
|
||||
// Move into place in new parent.
|
||||
|
||||
%pos = %ctrl.getPosition();
|
||||
%ctrl.setPosition( getWord( %pos, 0 ) - %x, getWord( %pos, 1 ) - %y );
|
||||
}
|
||||
}
|
||||
|
||||
/// Move all controls out of group to either former parent or group parent.
|
||||
function GuiEditorGroup::ungroup( %this )
|
||||
{
|
||||
%defaultParent = %this.groupParent;
|
||||
%groupPos = %this.groupObject.getPosition();
|
||||
|
||||
%x = getWord( %groupPos, 0 );
|
||||
%y = getWord( %groupPos, 1 );
|
||||
|
||||
// Move each control to its former parent (or default parent when
|
||||
// there is no former parent).
|
||||
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
{
|
||||
%ctrl = %this.ctrl[ %i ];
|
||||
|
||||
%parent = %defaultParent;
|
||||
if( isObject( %this.ctrlParent[ %i ] ) )
|
||||
%parent = %this.ctrlParent[ %i ];
|
||||
|
||||
%parent.addGuiControl( %ctrl );
|
||||
|
||||
// Move into place in new parent.
|
||||
|
||||
%ctrlPos = %ctrl.getPosition();
|
||||
%ctrl.setPosition( getWord( %ctrlPos, 0 ) + %x, getWord( %ctrlPos, 1 ) + %y );
|
||||
}
|
||||
|
||||
// Delete old group object.
|
||||
|
||||
%this.groupObject.delete();
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Core for the main Gui Editor inspector that shows the properties of
|
||||
// the currently selected control.
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::update( %this, %inspectTarget )
|
||||
{
|
||||
%this.inspect( %inspectTarget );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue )
|
||||
{
|
||||
// The instant group will try to add our
|
||||
// UndoAction if we don't disable it.
|
||||
pushInstantGroup();
|
||||
|
||||
%nameOrClass = %object.getName();
|
||||
if ( %nameOrClass $= "" )
|
||||
%nameOrClass = %object.getClassname();
|
||||
|
||||
%action = new InspectorFieldUndoAction()
|
||||
{
|
||||
actionName = %nameOrClass @ "." @ %fieldName @ " Change";
|
||||
|
||||
objectId = %object.getId();
|
||||
fieldName = %fieldName;
|
||||
fieldValue = %oldValue;
|
||||
arrayIndex = %arrayIndex;
|
||||
|
||||
inspectorGui = %this;
|
||||
};
|
||||
|
||||
// Restore the instant group.
|
||||
popInstantGroup();
|
||||
|
||||
%action.addToManager( GuiEditor.getUndoManager() );
|
||||
|
||||
GuiEditor.updateUndoMenu();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex )
|
||||
{
|
||||
pushInstantGroup();
|
||||
%undoManager = GuiEditor.getUndoManager();
|
||||
|
||||
%numObjects = %this.getNumInspectObjects();
|
||||
if( %numObjects > 1 )
|
||||
%action = %undoManager.pushCompound( "Multiple Field Edit" );
|
||||
|
||||
for( %i = 0; %i < %numObjects; %i ++ )
|
||||
{
|
||||
%object = %this.getInspectObject( %i );
|
||||
|
||||
%nameOrClass = %object.getName();
|
||||
if( %nameOrClass $= "" )
|
||||
%nameOrClass = %object.getClassname();
|
||||
|
||||
%undo = new InspectorFieldUndoAction()
|
||||
{
|
||||
actionName = %nameOrClass @ "." @ %fieldName @ " Change";
|
||||
|
||||
objectId = %object.getId();
|
||||
fieldName = %fieldName;
|
||||
fieldValue = %object.getFieldValue( %fieldName, %arrayIndex );
|
||||
arrayIndex = %arrayIndex;
|
||||
|
||||
inspectorGui = %this;
|
||||
};
|
||||
|
||||
if( %numObjects > 1 )
|
||||
%undo.addToManager( %undoManager );
|
||||
else
|
||||
{
|
||||
%action = %undo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
%this.currentFieldEditAction = %action;
|
||||
popInstantGroup();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onInspectorPostFieldModification( %this )
|
||||
{
|
||||
if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) )
|
||||
{
|
||||
// Finish multiple field edit.
|
||||
GuiEditor.getUndoManager().popCompound();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue single field undo.
|
||||
%this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() );
|
||||
}
|
||||
|
||||
%this.currentFieldEditAction = "";
|
||||
GuiEditor.updateUndoMenu();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onInspectorDiscardFieldModification( %this )
|
||||
{
|
||||
%this.currentFieldEditAction.undo();
|
||||
|
||||
if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) )
|
||||
{
|
||||
// Multiple field editor. Pop and discard.
|
||||
GuiEditor.getUndoManager().popCompound( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Single field edit. Just kill undo action.
|
||||
%this.currentFieldEditAction.delete();
|
||||
}
|
||||
|
||||
%this.currentFieldEditAction = "";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc )
|
||||
{
|
||||
GuiEditorFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onBeginCompoundEdit( %this )
|
||||
{
|
||||
GuiEditor.getUndoManager().pushCompound( "Multiple Field Edits" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorInspectFields::onEndCompoundEdit( %this )
|
||||
{
|
||||
GuiEditor.getUndoManager().popCompound();
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Dialog for creating new GUIs. Allows to enter an object name and
|
||||
// select a GuiControl class to use for the toplevel object.
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorNewGuiDialog::init( %this, %guiName, %guiClass )
|
||||
{
|
||||
%this-->nameField.setValue( %guiName );
|
||||
|
||||
// Initialize the class dropdown if we haven't already.
|
||||
|
||||
%classDropdown = %this-->classDropdown;
|
||||
if( !%classDropdown.size() )
|
||||
{
|
||||
%classes = enumerateConsoleClassesByCategory( "Gui" );
|
||||
%count = getFieldCount( %classes );
|
||||
|
||||
for( %i = 0; %i < %count; %i ++ )
|
||||
{
|
||||
%className = getField( %classes, %i );
|
||||
if( GuiEditor.isFilteredClass( %className )
|
||||
|| !isMemberOfClass( %className, "GuiControl" ) )
|
||||
continue;
|
||||
|
||||
%classDropdown.add( %className, 0 );
|
||||
}
|
||||
|
||||
%classDropdown.sort();
|
||||
}
|
||||
|
||||
%classDropdown.setText( "GuiControl" );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorNewGuiDialog::onWake( %this )
|
||||
{
|
||||
// Center the dialog.
|
||||
|
||||
%root = %this.getRoot();
|
||||
%this.setPosition( %root.extent.x / 2 - %this.extent.x / 2, %root.extent.y / 2 - %this.extent.y / 2 );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorNewGuiDialog::onOK( %this )
|
||||
{
|
||||
%name = %this-->nameField.getValue();
|
||||
%class = %this-->classDropdown.getText();
|
||||
|
||||
// Make sure we don't clash with an existing object.
|
||||
// If there's an existing GUIControl with the name, ask to replace.
|
||||
// If there's an existing non-GUIControl with the name, or the name is invalid, refuse to create.
|
||||
|
||||
if( isObject( %name ) && %name.isMemberOfClass( "GuiControl" ) )
|
||||
{
|
||||
if( MessageBox( "Warning", "Replace the existing control '" @ %name @ "'?", "OkCancel", "Question" ) == $MROk )
|
||||
%name.delete();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if( Editor::validateObjectName( %name, false ) )
|
||||
{
|
||||
%this.getRoot().popDialog( %this );
|
||||
%obj = eval("return new " @ %class @ "(" @ %name @ ");");
|
||||
|
||||
// Make sure we have no association with a filename.
|
||||
%obj.setFileName( "" );
|
||||
|
||||
GuiEditContent(%obj);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorNewGuiDialog::onCancel( %this )
|
||||
{
|
||||
%this.getRoot().popDialog( %this );
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$GuiEditor::defaultGridSize = 8;
|
||||
$GuiEditor::minGridSize = 3;
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Buttons
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorPrefsDlgOkBtn::onAction(%this)
|
||||
{
|
||||
GuiEditor.snap2gridsize = GuiEditorPrefsDlgGridEdit.getValue();
|
||||
if( GuiEditor.snap2grid )
|
||||
GuiEditor.setSnapToGrid( GuiEditor.snap2gridsize );
|
||||
|
||||
Canvas.popDialog( GuiEditorPrefsDlg );
|
||||
}
|
||||
|
||||
function GuiEditorPrefsDlgCancelBtn::onAction(%this)
|
||||
{
|
||||
Canvas.popDialog( GuiEditorPrefsDlg );
|
||||
}
|
||||
|
||||
function GuiEditorPrefsDlgDefaultsBtn::onAction(%this)
|
||||
{
|
||||
GuiEditorPrefsDlgGridSlider.setValue( $GuiEditor::defaultGridSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Grid
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorPrefsDlgGridEdit::onWake(%this)
|
||||
{
|
||||
%this.setValue( GuiEditor.snap2gridsize );
|
||||
}
|
||||
|
||||
function GuiEditorPrefsDlgGridEdit::onAction( %this )
|
||||
{
|
||||
%value = %this.getValue();
|
||||
if( %value < $GuiEditor::minGridSize )
|
||||
{
|
||||
%value = $GuiEditor::minGridSize;
|
||||
%this.setValue( %value );
|
||||
}
|
||||
|
||||
GuiEditorPrefsDlgGridSlider.setValue( %value );
|
||||
}
|
||||
|
||||
function GuiEditorPrefsDlgGridSlider::onWake(%this)
|
||||
{
|
||||
%this.setValue( GuiEditor.snap2gridsize );
|
||||
}
|
||||
|
||||
function GuiEditorPrefsDlgGridSlider::onAction(%this)
|
||||
{
|
||||
%value = %this.value;
|
||||
if( %value < $GuiEditor::minGridSize )
|
||||
{
|
||||
%value = $GuiEditor::minGridSize;
|
||||
%this.setValue( %value );
|
||||
}
|
||||
|
||||
GuiEditorPrefsDlgGridEdit.setvalue( mCeil( %value ) );
|
||||
}
|
||||
|
|
@ -0,0 +1,623 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
$GUI_EDITOR_DEFAULT_PROFILE_FILENAME = "art/gui/customProfiles.cs";
|
||||
$GUI_EDITOR_DEFAULT_PROFILE_CATEGORY = "Other";
|
||||
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditor.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::createNewProfile( %this, %name, %copySource )
|
||||
{
|
||||
if( %name $= "" )
|
||||
return;
|
||||
|
||||
// Make sure the object name is unique.
|
||||
|
||||
if( isObject( %name ) )
|
||||
%name = getUniqueName( %name );
|
||||
|
||||
// Create the profile.
|
||||
|
||||
if( %copySource !$= "" )
|
||||
eval( "new GuiControlProfile( " @ %name @ " : " @ %copySource.getName() @ " );" );
|
||||
else
|
||||
eval( "new GuiControlProfile( " @ %name @ " );" );
|
||||
|
||||
// Add the item and select it.
|
||||
|
||||
%category = %this.getProfileCategory( %name );
|
||||
%group = GuiEditorProfilesTree.findChildItemByName( 0, %category );
|
||||
|
||||
%id = GuiEditorProfilesTree.insertItem( %group, %name @ " (" @ %name.getId() @ ")", %name.getId(), "" );
|
||||
|
||||
GuiEditorProfilesTree.sort( 0, true, true, false );
|
||||
GuiEditorProfilesTree.clearSelection();
|
||||
GuiEditorProfilesTree.selectItem( %id );
|
||||
|
||||
// Mark it as needing to be saved.
|
||||
|
||||
%this.setProfileDirty( %name, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::getProfileCategory( %this, %profile )
|
||||
{
|
||||
if( %this.isDefaultProfile( %name ) )
|
||||
return "Default";
|
||||
else if( %profile.category !$= "" )
|
||||
return %profile.category;
|
||||
else
|
||||
return $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::showDeleteProfileDialog( %this, %profile )
|
||||
{
|
||||
if( %profile $= "" )
|
||||
return;
|
||||
|
||||
if( %profile.isInUse() )
|
||||
{
|
||||
MessageBoxOk( "Error",
|
||||
"The profile '" @ %profile.getName() @ "' is still used by Gui controls."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBoxYesNo( "Delete Profile?",
|
||||
"Do you really want to delete '" @ %profile.getName() @ "'?",
|
||||
"GuiEditor.deleteProfile( " @ %profile @ " );"
|
||||
);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::deleteProfile( %this, %profile )
|
||||
{
|
||||
if( isObject( "GuiEditorProfilesPM" ) )
|
||||
new PersistenceManager( GuiEditorProfilesPM );
|
||||
|
||||
// Clear dirty state.
|
||||
|
||||
%this.setProfileDirty( %profile, false );
|
||||
|
||||
// Remove from tree.
|
||||
|
||||
%id = GuiEditorProfilesTree.findItemByValue( %profile.getId() );
|
||||
GuiEditorProfilesTree.removeItem( %id );
|
||||
|
||||
// Remove from file.
|
||||
|
||||
GuiEditorProfilesPM.removeObjectFromFile( %profile );
|
||||
|
||||
// Delete profile object.
|
||||
|
||||
%profile.delete();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::showSaveProfileDialog( %this, %currentFileName )
|
||||
{
|
||||
getSaveFileName( "TorqueScript Files|*.cs", %this @ ".doSaveProfile", %currentFileName );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::doSaveProfile( %this, %fileName )
|
||||
{
|
||||
%path = makeRelativePath( %fileName, getMainDotCsDir() );
|
||||
|
||||
GuiEditorProfileFileName.setText( %path );
|
||||
%this.saveProfile( GuiEditorProfilesTree.getSelectedProfile(), %path );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::saveProfile( %this, %profile, %fileName )
|
||||
{
|
||||
if( !isObject( "GuiEditorProfilesPM" ) )
|
||||
new PersistenceManager( GuiEditorProfilesPM );
|
||||
|
||||
if( !GuiEditorProfilesPM.isDirty( %profile )
|
||||
&& ( %fileName $= "" || %fileName $= %profile.getFileName() ) )
|
||||
return;
|
||||
|
||||
// Update the filename, if requested.
|
||||
|
||||
if( %fileName !$= "" )
|
||||
{
|
||||
%profile.setFileName( %fileName );
|
||||
GuiEditorProfilesPM.setDirty( %profile, %fileName );
|
||||
}
|
||||
|
||||
// Save the object.
|
||||
|
||||
GuiEditorProfilesPM.saveDirtyObject( %profile );
|
||||
|
||||
// Clear its dirty state.
|
||||
|
||||
%this.setProfileDirty( %profile, false, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::revertProfile( %this, %profile )
|
||||
{
|
||||
// Revert changes.
|
||||
|
||||
GuiEditorProfileChangeManager.revertEdits( %profile );
|
||||
|
||||
// Clear its dirty state.
|
||||
|
||||
%this.setProfileDirty( %profile, false );
|
||||
|
||||
// Refresh inspector.
|
||||
|
||||
if( GuiEditorProfileInspector.getInspectObject() == %profile )
|
||||
GuiEditorProfileInspector.refresh();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::isProfileDirty( %this, %profile )
|
||||
{
|
||||
if( !isObject( "GuiEditorProfilesPM" ) )
|
||||
return false;
|
||||
|
||||
return GuiEditorProfilesPM.isDirty( %profile );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::setProfileDirty( %this, %profile, %value, %noCheck )
|
||||
{
|
||||
if( !isObject( "GuiEditorProfilesPM" ) )
|
||||
new PersistenceManager( GuiEditorProfilesPM );
|
||||
|
||||
if( %value )
|
||||
{
|
||||
if( !GuiEditorProfilesPM.isDirty( %profile ) || %noCheck )
|
||||
{
|
||||
// If the profile hasn't yet been associated with a file,
|
||||
// put it in the default file.
|
||||
|
||||
if( %profile.getFileName() $= "" )
|
||||
%profile.setFileName( $GUI_EDITOR_DEFAULT_PROFILE_FILENAME );
|
||||
|
||||
// Add the profile to the dirty set.
|
||||
|
||||
GuiEditorProfilesPM.setDirty( %profile );
|
||||
|
||||
// Show the item as dirty in the tree.
|
||||
|
||||
%id = GuiEditorProfilesTree.findItemByValue( %profile.getId() );
|
||||
GuiEditorProfilesTree.editItem( %id, GuiEditorProfilesTree.getItemText( %id ) SPC "*", %profile.getId() );
|
||||
|
||||
// Count the number of unsaved profiles. If this is
|
||||
// the first one, indicate in the window title that
|
||||
// we have unsaved profiles.
|
||||
|
||||
%this.increaseNumDirtyProfiles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( GuiEditorProfilesPM.isDirty( %profile ) || %noCheck )
|
||||
{
|
||||
// Remove from dirty list.
|
||||
|
||||
GuiEditorProfilesPM.removeDirty( %profile );
|
||||
|
||||
// Clear the dirty marker in the tree.
|
||||
|
||||
%id = GuiEditorProfilesTree.findItemByValue( %profile.getId() );
|
||||
%text = GuiEditorProfilesTree.getItemText( %id );
|
||||
GuiEditorProfilesTree.editItem( %id, getSubStr( %text, 0, strlen( %text ) - 2 ), %profile.getId() );
|
||||
|
||||
// Count saved profiles. If this was the last unsaved profile,
|
||||
// remove the unsaved changes indicator from the window title.
|
||||
|
||||
%this.decreaseNumDirtyProfiles();
|
||||
|
||||
// Remove saved edits from the change manager.
|
||||
|
||||
GuiEditorProfileChangeManager.clearEdits( %profile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/// Return true if the given profile name is the default profile for a
|
||||
/// GuiControl class or if it's the GuiDefaultProfile.
|
||||
function GuiEditor::isDefaultProfile( %this, %name )
|
||||
{
|
||||
if( %name $= "GuiDefaultProfile" )
|
||||
return true;
|
||||
|
||||
if( !endsWith( %name, "Profile" ) )
|
||||
return false;
|
||||
|
||||
%className = getSubStr( %name, 0, strlen( %name ) - 7 ) @ "Ctrl";
|
||||
if( !isClass( %className ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::increaseNumDirtyProfiles( %this )
|
||||
{
|
||||
%this.numDirtyProfiles ++;
|
||||
if( %this.numDirtyProfiles == 1 )
|
||||
{
|
||||
%tab = GuiEditorTabBook-->profilesPage;
|
||||
%tab.setText( %tab.text @ " *" );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditor::decreaseNumDirtyProfiles( %this )
|
||||
{
|
||||
%this.numDirtyProfiles --;
|
||||
if( !%this.numDirtyProfiles )
|
||||
{
|
||||
%tab = GuiEditorTabBook-->profilesPage;
|
||||
%title = %tab.text;
|
||||
%title = getSubstr( %title, 0, strlen( %title ) - 2 );
|
||||
|
||||
%tab.setText( %title );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditorProfilesTree.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::init( %this )
|
||||
{
|
||||
%this.clear();
|
||||
|
||||
%defaultGroup = %this.insertItem( 0, "Default", -1 );
|
||||
%otherGroup = %this.insertItem( 0, $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY, -1 );
|
||||
|
||||
foreach( %obj in GuiDataGroup )
|
||||
{
|
||||
if( !%obj.isMemberOfClass( "GuiControlProfile" ) )
|
||||
continue;
|
||||
|
||||
// If it's an Editor profile, skip if showing them is not enabled.
|
||||
|
||||
if( %obj.category $= "Editor" && !GuiEditor.showEditorProfiles )
|
||||
continue;
|
||||
|
||||
// Create a visible name.
|
||||
|
||||
%name = %obj.getName();
|
||||
if( %name $= "" )
|
||||
%name = "<Unnamed>";
|
||||
%text = %name @ " (" @ %obj.getId() @ ")";
|
||||
|
||||
// Find which group to put the control in.
|
||||
|
||||
%isDefaultProfile = GuiEditor.isDefaultProfile( %name );
|
||||
if( %isDefaultProfile )
|
||||
%group = %defaultGroup;
|
||||
else if( %obj.category !$= "" )
|
||||
{
|
||||
%group = %this.findChildItemByName( 0, %obj.category );
|
||||
if( !%group )
|
||||
%group = %this.insertItem( 0, %obj.category );
|
||||
}
|
||||
else
|
||||
%group = %otherGroup;
|
||||
|
||||
// Insert the item.
|
||||
|
||||
%this.insertItem( %group, %text, %obj.getId(), "" );
|
||||
}
|
||||
|
||||
%this.sort( 0, true, true, false );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::onSelect( %this, %id )
|
||||
{
|
||||
%obj = %this.getItemValue( %id );
|
||||
if( %obj == -1 )
|
||||
return;
|
||||
|
||||
GuiEditorProfileInspector.inspect( %obj );
|
||||
|
||||
%fileName = %obj.getFileName();
|
||||
if( %fileName $= "" )
|
||||
%fileName = $GUI_EDITOR_DEFAULT_PROFILE_FILENAME;
|
||||
|
||||
GuiEditorProfileFileName.setText( %fileName );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::onUnselect( %this, %id )
|
||||
{
|
||||
GuiEditorProfileInspector.inspect( 0 );
|
||||
GuiEditorProfileFileName.setText( "" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::onProfileRenamed( %this, %profile, %newName )
|
||||
{
|
||||
%item = %this.findItemByValue( %profile.getId() );
|
||||
if( %item == -1 )
|
||||
return;
|
||||
|
||||
%newText = %newName @ " (" @ %profile.getId() @ ")";
|
||||
if( GuiEditor.isProfileDirty( %profile ) )
|
||||
%newText = %newText @ " *";
|
||||
|
||||
%this.editItem( %item, %newText, %profile.getId() );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::getSelectedProfile( %this )
|
||||
{
|
||||
return %this.getItemValue( %this.getSelectedItem() );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfilesTree::setSelectedProfile( %this, %profile )
|
||||
{
|
||||
%id = %this.findItemByValue( %profile.getId() );
|
||||
%this.selectItem( %id );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditorProfileInspector.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc )
|
||||
{
|
||||
GuiEditorProfileFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onFieldAdded( %this, %object, %fieldName )
|
||||
{
|
||||
GuiEditor.setProfileDirty( %object, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onFieldRemoved( %this, %object, %fieldName )
|
||||
{
|
||||
GuiEditor.setProfileDirty( %object, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onFieldRenamed( %this, %object, %oldFieldName, %newFieldName )
|
||||
{
|
||||
GuiEditor.setProfileDirty( %object, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue )
|
||||
{
|
||||
GuiEditor.setProfileDirty( %object, true );
|
||||
|
||||
// If it's the name field, make sure to sync up the treeview.
|
||||
|
||||
if( %fieldName $= "name" )
|
||||
GuiEditorProfilesTree.onProfileRenamed( %object, %newValue );
|
||||
|
||||
// Add change record.
|
||||
|
||||
GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue );
|
||||
|
||||
// Add undo.
|
||||
|
||||
pushInstantGroup();
|
||||
|
||||
%nameOrClass = %object.getName();
|
||||
if ( %nameOrClass $= "" )
|
||||
%nameOrClass = %object.getClassname();
|
||||
|
||||
%action = new InspectorFieldUndoAction()
|
||||
{
|
||||
actionName = %nameOrClass @ "." @ %fieldName @ " Change";
|
||||
|
||||
objectId = %object.getId();
|
||||
fieldName = %fieldName;
|
||||
fieldValue = %oldValue;
|
||||
arrayIndex = %arrayIndex;
|
||||
|
||||
inspectorGui = %this;
|
||||
};
|
||||
|
||||
popInstantGroup();
|
||||
%action.addToManager( GuiEditor.getUndoManager() );
|
||||
GuiEditor.updateUndoMenu();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex )
|
||||
{
|
||||
pushInstantGroup();
|
||||
%undoManager = GuiEditor.getUndoManager();
|
||||
|
||||
%object = %this.getInspectObject();
|
||||
|
||||
%nameOrClass = %object.getName();
|
||||
if( %nameOrClass $= "" )
|
||||
%nameOrClass = %object.getClassname();
|
||||
|
||||
%action = new InspectorFieldUndoAction()
|
||||
{
|
||||
actionName = %nameOrClass @ "." @ %fieldName @ " Change";
|
||||
|
||||
objectId = %object.getId();
|
||||
fieldName = %fieldName;
|
||||
fieldValue = %object.getFieldValue( %fieldName, %arrayIndex );
|
||||
arrayIndex = %arrayIndex;
|
||||
|
||||
inspectorGui = %this;
|
||||
};
|
||||
|
||||
%this.currentFieldEditAction = %action;
|
||||
popInstantGroup();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onInspectorPostFieldModification( %this )
|
||||
{
|
||||
%action = %this.currentFieldEditAction;
|
||||
%object = %action.objectId;
|
||||
%fieldName = %action.fieldName;
|
||||
%arrayIndex = %action.arrayIndex;
|
||||
%oldValue = %action.fieldValue;
|
||||
%newValue = %object.getFieldValue( %fieldName, %arrayIndex );
|
||||
|
||||
// If it's the name field, make sure to sync up the treeview.
|
||||
|
||||
if( %action.fieldName $= "name" )
|
||||
GuiEditorProfilesTree.onProfileRenamed( %object, %newValue );
|
||||
|
||||
// Add change record.
|
||||
|
||||
GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue );
|
||||
|
||||
%this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() );
|
||||
%this.currentFieldEditAction = "";
|
||||
|
||||
GuiEditor.updateUndoMenu();
|
||||
GuiEditor.setProfileDirty( %object, true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileInspector::onInspectorDiscardFieldModification( %this )
|
||||
{
|
||||
%this.currentFieldEditAction.undo();
|
||||
%this.currentFieldEditAction.delete();
|
||||
%this.currentFieldEditAction = "";
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditorProfileChangeManager.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileChangeManager::registerEdit( %this, %profile, %fieldName, %arrayIndex, %oldValue )
|
||||
{
|
||||
// Early-out if we already have a registered edit on the same field.
|
||||
|
||||
foreach( %obj in %this )
|
||||
{
|
||||
if( %obj.profile != %profile )
|
||||
continue;
|
||||
|
||||
if( %obj.fieldName $= %fieldName
|
||||
&& %obj.arrayIndex $= %arrayIndex )
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new change record.
|
||||
|
||||
new ScriptObject()
|
||||
{
|
||||
parentGroup = %this;
|
||||
profile = %profile;
|
||||
fieldName = %fieldName;
|
||||
arrayIndex = %arrayIndex;
|
||||
oldValue = %oldValue;
|
||||
};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileChangeManager::clearEdits( %this, %profile )
|
||||
{
|
||||
for( %i = 0; %i < %this.getCount(); %i ++ )
|
||||
{
|
||||
%obj = %this.getObject( %i );
|
||||
if( %obj.profile != %profile )
|
||||
continue;
|
||||
|
||||
%obj.delete();
|
||||
%i --;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileChangeManager::revertEdits( %this, %profile )
|
||||
{
|
||||
for( %i = 0; %i < %this.getCount(); %i ++ )
|
||||
{
|
||||
%obj = %this.getObject( %i );
|
||||
if( %obj.profile != %profile )
|
||||
continue;
|
||||
|
||||
%profile.setFieldValue( %obj.fieldName, %obj.oldValue, %obj.arrayIndex );
|
||||
|
||||
%obj.delete();
|
||||
%i --;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorProfileChangeManager::getEdits( %this, %profile )
|
||||
{
|
||||
%set = new SimSet();
|
||||
|
||||
foreach( %obj in %this )
|
||||
if( %obj.profile == %profile )
|
||||
%set.add( %obj );
|
||||
|
||||
return %set;
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 GuiEditorSelectDlg::toggleVisibility( %this )
|
||||
{
|
||||
if( %this.isVisible() )
|
||||
%this.setVisible( false );
|
||||
else
|
||||
%this.setVisible( true );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorSelectDlg::getRootGroup( %this )
|
||||
{
|
||||
return GuiEditor.getContentControl();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorSelectDlg::includeClass( %this, %className )
|
||||
{
|
||||
return ( isMemberOfClass( %className, "GuiControl" )
|
||||
&& !GuiEditor.isFilteredClass( %className ) );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorSelectDlg::selectObject( %this, %object, %val )
|
||||
{
|
||||
if( %val )
|
||||
GuiEditor.addSelection( %object );
|
||||
else
|
||||
GuiEditor.removeSelection( %object );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorSelectDlg::clearSelection( %this )
|
||||
{
|
||||
GuiEditor.clearSelection();
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Events.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorSelectDlg::onVisible( %this, %visible )
|
||||
{
|
||||
if( !%visible )
|
||||
return;
|
||||
|
||||
if( !%this.isInitialized )
|
||||
{
|
||||
%this.init();
|
||||
%this.isInitialized = true;
|
||||
}
|
||||
|
||||
// Re-initialize the group list on each wake.
|
||||
|
||||
%this.initGroupList();
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Code for the status bar in the Gui Editor.
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorStatusBar::getMouseModeHelp( %this )
|
||||
{
|
||||
%isMac = ( $platform $= "macos" );
|
||||
if( %isMac )
|
||||
%cmdCtrl = "CMD";
|
||||
else
|
||||
%cmdCtrl = "CTRL";
|
||||
|
||||
%mouseMode = GuiEditor.getMouseMode();
|
||||
switch$( %mouseMode )
|
||||
{
|
||||
case "Selecting":
|
||||
return "";
|
||||
|
||||
case "DragSelecting":
|
||||
return %cmdCtrl @ " to add to selection; ALT to exclude parents; CTRL+ALT to exclude children";
|
||||
|
||||
case "MovingSelection":
|
||||
return "";
|
||||
|
||||
case "SizingSelection":
|
||||
return "CTRL to activate snapping; ALT to move instead of resize";
|
||||
|
||||
case "DragGuide":
|
||||
return "Drag into ruler to delete; drop to place";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorStatusBar::print( %this, %message )
|
||||
{
|
||||
%this.setText( %message );
|
||||
|
||||
%sequenceNum = %this.sequenceNum + 1;
|
||||
%this.sequenceNum = %sequenceNum;
|
||||
|
||||
%this.schedule( 4 * 1000, "clearMessage", %sequenceNum );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorStatusBar::clearMessage( %this, %sequenceNum )
|
||||
{
|
||||
// If we had no newer message in the meantime, clear
|
||||
// out the current text.
|
||||
|
||||
if( %this.sequenceNum == %sequenceNum )
|
||||
%this.setText( %this.getMouseModeHelp() );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorStatusBar::onWake( %this )
|
||||
{
|
||||
%this.setText( %this.getMouseModeHelp() );
|
||||
}
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Code for the toolbox tab of the Gui Editor sidebar.
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::initialize( %this )
|
||||
{
|
||||
// Set up contents.
|
||||
|
||||
%viewType = %this.currentViewType;
|
||||
if( %viewType $= "" )
|
||||
%viewType = "Categorized";
|
||||
|
||||
%this.currentViewType = "";
|
||||
%this.setViewType( %viewType );
|
||||
|
||||
%this.isInitialized = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::getViewType( %this )
|
||||
{
|
||||
return %this.currentViewType;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::setViewType( %this, %viewType )
|
||||
{
|
||||
if( %this.currentViewType $= %viewType
|
||||
|| !%this.isMethod( "setViewType" @ %viewType ) )
|
||||
return;
|
||||
|
||||
%this.clear();
|
||||
eval( %this @ ".setViewType" @ %viewType @ "();" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::setViewTypeAlphabetical( %this )
|
||||
{
|
||||
%controls = enumerateConsoleClassesByCategory( "Gui" );
|
||||
%classes = new ArrayObject();
|
||||
|
||||
// Collect relevant classes.
|
||||
|
||||
foreach$( %className in %controls )
|
||||
{
|
||||
if( GuiEditor.isFilteredClass( %className )
|
||||
|| !isMemberOfClass( %className, "GuiControl" ) )
|
||||
continue;
|
||||
|
||||
%classes.push_back( %className );
|
||||
}
|
||||
|
||||
// Sort classes alphabetically.
|
||||
|
||||
%classes.sortk( true );
|
||||
|
||||
// Add toolbox buttons.
|
||||
|
||||
%numClasses = %classes.count();
|
||||
for( %i = 0; %i < %numClasses; %i ++ )
|
||||
{
|
||||
%className = %classes.getKey( %i );
|
||||
%ctrl = new GuiIconButtonCtrl()
|
||||
{
|
||||
profile = "ToolsGuiIconButtonSmallProfile";
|
||||
extent = "128 18";
|
||||
text = %className;
|
||||
iconBitmap = EditorIconRegistry::findIconByClassName( %className );
|
||||
buttonMargin = "2 2";
|
||||
iconLocation = "left";
|
||||
textLocation = "left";
|
||||
textMargin = "24";
|
||||
AutoSize = true;
|
||||
|
||||
command = "GuiEditor.createControl( " @ %className @ " );";
|
||||
useMouseEvents = true;
|
||||
className = "GuiEditorToolboxButton";
|
||||
tooltip = %className NL "\n" @ getDescriptionOfClass( %className );
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
};
|
||||
|
||||
%this.add( %ctrl );
|
||||
}
|
||||
|
||||
%classes.delete();
|
||||
%this.currentViewType = "Alphabetical";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::setViewTypeCategorized( %this )
|
||||
{
|
||||
// Create rollouts for each class category we have and
|
||||
// record the classes in each category in a temporary array
|
||||
// on the rollout so we can later sort the class names before
|
||||
// creating the actual controls in the toolbox.
|
||||
|
||||
%controls = enumerateConsoleClassesByCategory( "Gui" );
|
||||
foreach$( %className in %controls )
|
||||
{
|
||||
if( GuiEditor.isFilteredClass( %className )
|
||||
|| !isMemberOfClass( %className, "GuiControl" ) )
|
||||
continue;
|
||||
|
||||
// Get the class's next category under Gui.
|
||||
|
||||
%category = getWord( getCategoryOfClass( %className ), 1 );
|
||||
if( %category $= "" )
|
||||
continue;
|
||||
|
||||
// Find or create the rollout for the category.
|
||||
|
||||
%rollout = %this.getOrCreateRolloutForCategory( %category );
|
||||
|
||||
// Insert the item.
|
||||
|
||||
if( !%rollout.classes )
|
||||
%rollout.classes = new ArrayObject();
|
||||
|
||||
%rollout.classes.push_back( %className );
|
||||
}
|
||||
|
||||
// Go through the rollouts, sort the class names, and
|
||||
// create the toolbox controls.
|
||||
|
||||
foreach( %rollout in %this )
|
||||
{
|
||||
if( !%rollout.isMemberOfClass( "GuiRolloutCtrl" ) )
|
||||
continue;
|
||||
|
||||
// Get the array with the class names and sort it.
|
||||
// Sort in descending order to counter reversal of order
|
||||
// when we later add the controls to the stack.
|
||||
|
||||
%classes = %rollout.classes;
|
||||
%classes.sortk( true );
|
||||
|
||||
// Add a control for each of the classes to the
|
||||
// rollout's stack control.
|
||||
|
||||
%stack = %rollout-->array;
|
||||
%numClasses = %classes.count();
|
||||
for( %n = 0; %n < %numClasses; %n ++ )
|
||||
{
|
||||
%className = %classes.getKey( %n );
|
||||
%ctrl = new GuiIconButtonCtrl()
|
||||
{
|
||||
profile = "ToolsGuiIconButtonSmallProfile";
|
||||
extent = "128 18";
|
||||
text = %className;
|
||||
iconBitmap = EditorIconRegistry::findIconByClassName( %className );
|
||||
buttonMargin = "2 2";
|
||||
iconLocation = "left";
|
||||
textLocation = "left";
|
||||
textMargin = "24";
|
||||
AutoSize = true;
|
||||
|
||||
command = "GuiEditor.createControl( " @ %className @ " );";
|
||||
useMouseEvents = true;
|
||||
className = "GuiEditorToolboxButton";
|
||||
tooltip = %className NL "\n" @ getDescriptionOfClass( %className );
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
};
|
||||
|
||||
%stack.add( %ctrl );
|
||||
}
|
||||
|
||||
// Delete the temporary array.
|
||||
|
||||
%rollout.classes = "";
|
||||
%classes.delete();
|
||||
}
|
||||
|
||||
%this.currentViewType = "Categorized";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::getOrCreateRolloutForCategory( %this, %category )
|
||||
{
|
||||
// Try to find an existing rollout.
|
||||
|
||||
%ctrl = %this.getRolloutForCategory( %category );
|
||||
if( %ctrl != 0 )
|
||||
return %ctrl;
|
||||
|
||||
// None there. Create a new one.
|
||||
|
||||
%ctrl = new GuiRolloutCtrl() {
|
||||
Margin = "0 0 0 0";
|
||||
DefaultHeight = "40";
|
||||
Expanded = "1";
|
||||
ClickCollapse = "1";
|
||||
HideHeader = "0";
|
||||
isContainer = "1";
|
||||
Profile = "GuiRolloutProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "0 0";
|
||||
Extent = "421 114";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
autoCollapseSiblings = true;
|
||||
caption = %category;
|
||||
class = "GuiEditorToolboxRolloutCtrl";
|
||||
|
||||
new GuiDynamicCtrlArrayControl() {
|
||||
isContainer = "1";
|
||||
Profile = "ToolsGuiDefaultProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "0 0";
|
||||
Extent = "421 64";
|
||||
MinExtent = "64 64";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
padding = "6 2 4 0";
|
||||
colSpacing = "1";
|
||||
rowSpacing = "9";
|
||||
dynamicSize = true;
|
||||
autoCellSize = true;
|
||||
internalName = "array";
|
||||
};
|
||||
};
|
||||
|
||||
%this.add( %ctrl );
|
||||
%ctrl.collapse();
|
||||
|
||||
// Sort the rollouts by their caption.
|
||||
|
||||
%this.sort( "_GuiEditorToolboxSortRollouts" );
|
||||
|
||||
return %ctrl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::getRolloutForCategory( %this, %category )
|
||||
{
|
||||
foreach( %obj in %this )
|
||||
{
|
||||
if( !%obj.isMemberOfClass( "GuiRolloutCtrl" ) )
|
||||
continue;
|
||||
|
||||
if( stricmp( %obj.caption, %category ) == 0 )
|
||||
return %obj;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolbox::startGuiControlDrag( %this, %class )
|
||||
{
|
||||
// Create a new control of the given class.
|
||||
|
||||
%payload = eval( "return new " @ %class @ "();" );
|
||||
if( !isObject( %payload ) )
|
||||
return;
|
||||
|
||||
// this offset puts the cursor in the middle of the dragged object.
|
||||
%xOffset = getWord( %payload.extent, 0 ) / 2;
|
||||
%yOffset = getWord( %payload.extent, 1 ) / 2;
|
||||
|
||||
// position where the drag will start, to prevent visible jumping.
|
||||
%cursorpos = Canvas.getCursorPos();
|
||||
%xPos = getWord( %cursorpos, 0 ) - %xOffset;
|
||||
%yPos = getWord( %cursorpos, 1 ) - %yOffset;
|
||||
|
||||
// Create drag&drop control.
|
||||
|
||||
%dragCtrl = new GuiDragAndDropControl()
|
||||
{
|
||||
canSaveDynamicFields = "0";
|
||||
Profile = "ToolsGuiSolidDefaultProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
Position = %xPos SPC %yPos;
|
||||
extent = %payload.extent;
|
||||
MinExtent = "32 32";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
hovertime = "1000";
|
||||
deleteOnMouseUp = true;
|
||||
class = "GuiDragAndDropControlType_GuiControl";
|
||||
};
|
||||
|
||||
%dragCtrl.add( %payload );
|
||||
Canvas.getContent().add( %dragCtrl );
|
||||
|
||||
// Start drag.
|
||||
|
||||
%dragCtrl.startDragging( %xOffset, %yOffset );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditorToolboxRolloutCtrl.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolboxRolloutCtrl::onHeaderRightClick( %this )
|
||||
{
|
||||
if( !isObject( GuiEditorToolboxRolloutCtrlMenu ) )
|
||||
new PopupMenu( GuiEditorToolboxRolloutCtrlMenu )
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
isPopup = true;
|
||||
|
||||
item[ 0 ] = "Expand All" TAB "" TAB %this @ ".expandAll();";
|
||||
item[ 1 ] = "Collapse All" TAB "" TAB %this @ ".collapseAll();";
|
||||
};
|
||||
|
||||
GuiEditorToolboxRolloutCtrlMenu.showPopup( %this.getRoot() );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolboxRolloutCtrl::expandAll( %this )
|
||||
{
|
||||
foreach( %ctrl in %this.parentGroup )
|
||||
{
|
||||
if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) )
|
||||
%ctrl.instantExpand();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolboxRolloutCtrl::collapseAll( %this )
|
||||
{
|
||||
foreach( %ctrl in %this.parentGroup )
|
||||
{
|
||||
if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) )
|
||||
%ctrl.instantCollapse();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// GuiEditorToolboxButton.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorToolboxButton::onMouseDragged( %this )
|
||||
{
|
||||
GuiEditorToolbox.startGuiControlDrag( %this.text );
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Misc.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/// Utility function to sort rollouts by their caption.
|
||||
function _GuiEditorToolboxSortRollouts( %a, %b )
|
||||
{
|
||||
return strinatcmp( %a.caption, %b.caption );
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Code for the main Gui Editor tree view that shows the hierarchy of the
|
||||
// current GUI being edited.
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::init(%this)
|
||||
{
|
||||
if( !isObject( %this.contextMenu ) )
|
||||
%this.contextMenu = new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
isPopup = true;
|
||||
|
||||
item[ 0 ] = "Rename" TAB "" TAB "GuiEditorTreeView.showItemRenameCtrl( GuiEditorTreeView.findItemByObjectId( %this.object ) );";
|
||||
item[ 1 ] = "Delete" TAB "" TAB "GuiEditor.deleteControl( %this.object );";
|
||||
item[ 2 ] = "-";
|
||||
item[ 3 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); GuiEditorTreeView.update();";
|
||||
item[ 4 ] = "Hidden" TAB "" TAB "%this.object.setVisible( !%this.object.isVisible() ); GuiEditorTreeView.update();";
|
||||
item[ 5 ] = "-";
|
||||
item[ 6 ] = "Add New Controls Here" TAB "" TAB "GuiEditor.setCurrentAddSet( %this.object );";
|
||||
item[ 7 ] = "Add Child Controls to Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, false );";
|
||||
item[ 8 ] = "Remove Child Controls from Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, true );";
|
||||
|
||||
object = -1;
|
||||
};
|
||||
|
||||
if( !isObject( %this.contextMenuMultiSel ) )
|
||||
%this.contextMenuMultiSel = new PopupMenu()
|
||||
{
|
||||
superClass = "MenuBuilder";
|
||||
isPopup = true;
|
||||
|
||||
item[ 0 ] = "Delete" TAB "" TAB "GuiEditor.deleteSelection();";
|
||||
};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::update( %this )
|
||||
{
|
||||
%obj = GuiEditorContent.getObject( 0 );
|
||||
|
||||
if( !isObject( %obj ) )
|
||||
GuiEditorTreeView.clear();
|
||||
else
|
||||
{
|
||||
// Open inspector tree.
|
||||
|
||||
GuiEditorTreeView.open( %obj );
|
||||
|
||||
// Sync selection with GuiEditor.
|
||||
|
||||
GuiEditorTreeView.clearSelection();
|
||||
|
||||
%selection = GuiEditor.getSelection();
|
||||
%count = %selection.getCount();
|
||||
|
||||
for( %i = 0; %i < %count; %i ++ )
|
||||
GuiEditorTreeView.addSelection( %selection.getObject( %i ) );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================================
|
||||
// Event Handlers.
|
||||
//=============================================================================================
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/// Defines the icons to be used in the tree view control.
|
||||
/// Provide the paths to each icon minus the file extension.
|
||||
/// Seperate them with ':'.
|
||||
/// The order of the icons must correspond to the bit array defined
|
||||
/// in the GuiTreeViewCtrl.h.
|
||||
function GuiEditorTreeView::onDefineIcons(%this)
|
||||
{
|
||||
%icons = ":" @ // Default1
|
||||
":" @ // SimGroup1
|
||||
":" @ // SimGroup2
|
||||
":" @ // SimGroup3
|
||||
":" @ // SimGroup4
|
||||
"tools/gui/images/treeview/hidden:" @
|
||||
"tools/worldEditor/images/lockedHandle";
|
||||
|
||||
GuiEditorTreeView.buildIconTable( %icons );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onRightMouseDown( %this, %item, %pts, %obj )
|
||||
{
|
||||
if( %this.getSelectedItemsCount() > 1 )
|
||||
{
|
||||
%popup = %this.contextMenuMultiSel;
|
||||
%popup.showPopup( Canvas );
|
||||
}
|
||||
else if( %obj )
|
||||
{
|
||||
%popup = %this.contextMenu;
|
||||
|
||||
%popup.checkItem( 3, %obj.locked );
|
||||
%popup.checkItem( 4, !%obj.isVisible() );
|
||||
|
||||
%popup.enableItem( 6, %obj.isContainer );
|
||||
%popup.enableItem( 7, %obj.getCount() > 0 );
|
||||
%popup.enableItem( 8, %obj.getCount() > 0 );
|
||||
|
||||
%popup.object = %obj;
|
||||
%popup.showPopup( Canvas );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onAddSelection(%this,%ctrl)
|
||||
{
|
||||
GuiEditor.dontSyncTreeViewSelection = true;
|
||||
GuiEditor.addSelection( %ctrl );
|
||||
GuiEditor.dontSyncTreeViewSelection = false;
|
||||
GuiEditor.setFirstResponder();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onRemoveSelection( %this, %ctrl )
|
||||
{
|
||||
GuiEditor.dontSyncTreeViewSelection = true;
|
||||
GuiEditor.removeSelection( %ctrl );
|
||||
GuiEditor.dontSyncTreeViewSelection = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onDeleteSelection(%this)
|
||||
{
|
||||
GuiEditor.clearSelection();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onSelect( %this, %obj )
|
||||
{
|
||||
if( isObject( %obj ) )
|
||||
{
|
||||
GuiEditor.dontSyncTreeViewSelection = true;
|
||||
GuiEditor.select( %obj );
|
||||
GuiEditor.dontSyncTreeViewSelection = false;
|
||||
GuiEditorInspectFields.update( %obj );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::isValidDragTarget( %this, %id, %obj )
|
||||
{
|
||||
return ( %obj.isContainer || %obj.getCount() > 0 );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onBeginReparenting( %this )
|
||||
{
|
||||
if( isObject( %this.reparentUndoAction ) )
|
||||
%this.reparentUndoAction.delete();
|
||||
|
||||
%action = UndoActionReparentObjects::create( %this );
|
||||
|
||||
%this.reparentUndoAction = %action;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onReparent( %this, %obj, %oldParent, %newParent )
|
||||
{
|
||||
%this.reparentUndoAction.add( %obj, %oldParent, %newParent );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
function GuiEditorTreeView::onEndReparenting( %this )
|
||||
{
|
||||
%action = %this.reparentUndoAction;
|
||||
%this.reparentUndoAction = "";
|
||||
|
||||
if( %action.numObjects > 0 )
|
||||
{
|
||||
if( %action.numObjects == 1 )
|
||||
%action.actionName = "Reparent Control";
|
||||
else
|
||||
%action.actionName = "Reparent Controls";
|
||||
|
||||
%action.addToManager( GuiEditor.getUndoManager() );
|
||||
|
||||
GuiEditor.updateUndoMenu();
|
||||
}
|
||||
else
|
||||
%action.delete();
|
||||
}
|
||||
|
|
@ -0,0 +1,598 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 GuiEditorUndoManager::onAddUndo( %this )
|
||||
{
|
||||
GuiEditor.updateUndoMenu();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Undo adding an object
|
||||
function UndoActionAddObject::create( %set, %trash, %treeView )
|
||||
{
|
||||
%act = UndoActionAddDelete::create( UndoActionAddObject, %set, %trash, %treeView );
|
||||
%act.actionName = "Add Objects";
|
||||
return %act;
|
||||
}
|
||||
|
||||
function UndoActionAddObject::undo(%this)
|
||||
{
|
||||
%this.trashObjects();
|
||||
}
|
||||
|
||||
function UndoActionAddObject::redo(%this)
|
||||
{
|
||||
%this.restoreObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Undo Deleting an object
|
||||
function UndoActionDeleteObject::create( %set, %trash, %treeView )
|
||||
{
|
||||
%act = UndoActionAddDelete::create( UndoActionDeleteObject, %set, %trash, %treeView, true );
|
||||
%act.designatedDeleter = true;
|
||||
%act.actionName = "Delete Objects";
|
||||
return %act;
|
||||
}
|
||||
|
||||
function UndoActionDeleteObject::undo( %this )
|
||||
{
|
||||
%this.restoreObjects();
|
||||
}
|
||||
|
||||
function UndoActionDeleteObject::redo( %this )
|
||||
{
|
||||
%this.trashObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Behavior common to Add and Delete UndoActions
|
||||
function UndoActionAddDelete::create( %class, %set, %trash, %treeView, %clearNames )
|
||||
{
|
||||
// record objects
|
||||
// record parents
|
||||
// record trash
|
||||
// return new subclass %class of UndoActionAddDelete
|
||||
|
||||
// The instant group will try to add our
|
||||
// UndoAction if we don't disable it.
|
||||
pushInstantGroup();
|
||||
|
||||
%act = new UndoScriptAction() { class = %class; superclass = UndoActionAddDelete; };
|
||||
|
||||
// Restore the instant group.
|
||||
popInstantGroup();
|
||||
|
||||
for(%i = 0; %i < %set.getCount(); %i++)
|
||||
{
|
||||
%obj = %set.getObject(%i);
|
||||
|
||||
%act.object[ %i ] = %obj.getId();
|
||||
%act.parent[ %i ] = %obj.getParent();
|
||||
%act.objectName[ %i ] = %obj.name;
|
||||
|
||||
// Clear object name so we don't get name clashes with the trash.
|
||||
|
||||
if( %clearNames )
|
||||
%obj.name = "";
|
||||
}
|
||||
|
||||
%act.objCount = %set.getCount();
|
||||
%act.trash = %trash;
|
||||
%act.tree = %treeView;
|
||||
|
||||
return %act;
|
||||
}
|
||||
|
||||
function UndoActionAddDelete::trashObjects(%this)
|
||||
{
|
||||
// Move objects to trash.
|
||||
|
||||
for( %i = 0; %i < %this.objCount; %i ++ )
|
||||
{
|
||||
%object = %this.object[ %i ];
|
||||
|
||||
%this.trash.add( %object );
|
||||
%object.name = "";
|
||||
}
|
||||
|
||||
// Note that we're responsible for deleting those objects we've moved to the trash.
|
||||
|
||||
%this.designatedDeleter = true;
|
||||
|
||||
// Update the tree view.
|
||||
|
||||
if( isObject( %this.tree ) )
|
||||
%this.tree.update();
|
||||
}
|
||||
|
||||
function UndoActionAddDelete::restoreObjects(%this)
|
||||
{
|
||||
// Move objects to saved parent and restore names.
|
||||
|
||||
for( %i = 0; %i < %this.objCount; %i ++ )
|
||||
{
|
||||
%object = %this.object[ %i ];
|
||||
%object.name = %this.objectName[ %i ];
|
||||
%this.parent[ %i ].add( %object );
|
||||
}
|
||||
|
||||
// Note that we no longer own the objects, and should not delete them when we're deleted.
|
||||
|
||||
%this.designatedDeleter = false;
|
||||
|
||||
// Update the tree view.
|
||||
|
||||
if( isObject( %this.tree ) )
|
||||
%this.tree.update();
|
||||
}
|
||||
|
||||
function UndoActionAddObject::onRemove(%this)
|
||||
{
|
||||
// if this undoAction owns objects in the trash, delete them.
|
||||
if( !%this.designatedDeleter)
|
||||
return;
|
||||
|
||||
for( %i = 0; %i < %this.objCount; %i ++)
|
||||
%this.object[ %i ].delete();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Undo grouping/ungrouping of controls.
|
||||
|
||||
function GuiEditorGroupUngroupAction::groupControls( %this )
|
||||
{
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
%this.group[ %i ].group();
|
||||
|
||||
GuiEditorTreeView.update();
|
||||
}
|
||||
|
||||
function GuiEditorGroupUngroupAction::ungroupControls( %this )
|
||||
{
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
%this.group[ %i ].ungroup();
|
||||
|
||||
GuiEditorTreeView.update();
|
||||
}
|
||||
|
||||
function GuiEditorGroupUngroupAction::onRemove( %this )
|
||||
{
|
||||
for( %i = 0; %i < %this.count; %i ++ )
|
||||
if( isObject( %this.group[ %i ] ) )
|
||||
%this.group[ %i ].delete();
|
||||
}
|
||||
|
||||
function GuiEditorGroupAction::create( %set, %root )
|
||||
{
|
||||
// Create action object.
|
||||
|
||||
pushInstantGroup();
|
||||
%action = new UndoScriptAction()
|
||||
{
|
||||
actionName = "Group";
|
||||
className = GuiEditorGroupAction;
|
||||
superClass = GuiEditorGroupUngroupAction;
|
||||
count = 1;
|
||||
group[ 0 ] = new ScriptObject()
|
||||
{
|
||||
className = GuiEditorGroup;
|
||||
count = %set.getCount();
|
||||
groupParent = GuiEditor.getCurrentAddSet();
|
||||
};
|
||||
};
|
||||
popInstantGroup();
|
||||
|
||||
// Add objects from set to group.
|
||||
|
||||
%group = %action.group[ 0 ];
|
||||
%num = %set.getCount();
|
||||
for( %i = 0; %i < %num; %i ++ )
|
||||
{
|
||||
%ctrl = %set.getObject( %i );
|
||||
if( %ctrl != %root )
|
||||
%group.ctrl[ %i ] = %ctrl;
|
||||
}
|
||||
|
||||
return %action;
|
||||
}
|
||||
|
||||
function GuiEditorGroupAction::undo( %this )
|
||||
{
|
||||
%this.ungroupControls();
|
||||
}
|
||||
|
||||
function GuiEditorGroupAction::redo( %this )
|
||||
{
|
||||
%this.groupControls();
|
||||
}
|
||||
|
||||
function GuiEditorUngroupAction::create( %set, %root )
|
||||
{
|
||||
// Create action object.
|
||||
|
||||
pushInstantGroup();
|
||||
%action = new UndoScriptAction()
|
||||
{
|
||||
actionName = "Ungroup";
|
||||
className = GuiEditorUngroupAction;
|
||||
superClass = GuiEditorGroupUngroupAction;
|
||||
};
|
||||
|
||||
// Add groups from set to action.
|
||||
|
||||
%groupCount = 0;
|
||||
%numInSet = %set.getCount();
|
||||
for( %i = 0; %i < %numInSet; %i ++ )
|
||||
{
|
||||
%obj = %set.getObject( %i );
|
||||
if( %obj.getClassName() $= "GuiControl" && %obj != %root )
|
||||
{
|
||||
// Create group object.
|
||||
|
||||
%group = new ScriptObject()
|
||||
{
|
||||
className = GuiEditorGroup;
|
||||
count = %obj.getCount();
|
||||
groupParent = %obj.parentGroup;
|
||||
groupObject = %obj;
|
||||
};
|
||||
%action.group[ %groupCount ] = %group;
|
||||
%groupCount ++;
|
||||
|
||||
// Add controls.
|
||||
|
||||
%numControls = %obj.getCount();
|
||||
for( %j = 0; %j < %numControls; %j ++ )
|
||||
%group.ctrl[ %j ] = %obj.getObject( %j );
|
||||
}
|
||||
}
|
||||
|
||||
popInstantGroup();
|
||||
|
||||
%action.count = %groupCount;
|
||||
return %action;
|
||||
}
|
||||
|
||||
function GuiEditorUngroupAction::undo( %this )
|
||||
{
|
||||
%this.groupControls();
|
||||
}
|
||||
|
||||
function GuiEditorUngroupAction::redo( %this )
|
||||
{
|
||||
%this.ungroupControls();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Undo Any State Change.
|
||||
function GenericUndoAction::create()
|
||||
{
|
||||
// The instant group will try to add our
|
||||
// UndoAction if we don't disable it.
|
||||
pushInstantGroup();
|
||||
|
||||
%act = new UndoScriptAction() { class = GenericUndoAction; };
|
||||
%act.actionName = "Edit Objects";
|
||||
|
||||
// Restore the instant group.
|
||||
popInstantGroup();
|
||||
|
||||
return %act;
|
||||
}
|
||||
|
||||
function GenericUndoAction::watch(%this, %object)
|
||||
{
|
||||
// make sure we're working with the object id, because it cannot change.
|
||||
%object = %object.getId();
|
||||
|
||||
%fieldCount = %object.getFieldCount();
|
||||
%dynFieldCount = %object.getDynamicFieldCount();
|
||||
|
||||
// inspect all the fields on the object, including dyanamic ones.
|
||||
// record field names and values.
|
||||
for(%i = 0; %i < %fieldCount; %i++)
|
||||
{
|
||||
%field = %object.getField(%i);
|
||||
%this.fieldNames[%object] = %this.fieldNames[%object] SPC %field;
|
||||
%this.fieldValues[%object, %field] = %object.getFieldValue(%field);
|
||||
}
|
||||
for(%i = 0; %i < %dynFieldCount; %i++)
|
||||
{
|
||||
%field = %object.getDynamicField(%i);
|
||||
%this.fieldNames[%object] = %this.fieldNames[%object] SPC %field;
|
||||
%this.fieldValues[%object, %field] = %object.getFieldValue(%field);
|
||||
}
|
||||
// clean spurious spaces from the field name list
|
||||
%this.fieldNames[%object] = trim(%this.fieldNames[%object]);
|
||||
// record that we know this object
|
||||
%this.objectIds[%object] = 1;
|
||||
%this.objectIdList = %this.objectIdList SPC %object;
|
||||
}
|
||||
|
||||
function GenericUndoAction::learn(%this, %object)
|
||||
{
|
||||
// make sure we're working with the object id, because it cannot change.
|
||||
%object = %object.getId();
|
||||
|
||||
%fieldCount = %object.getFieldCount();
|
||||
%dynFieldCount = %object.getDynamicFieldCount();
|
||||
|
||||
// inspect all the fields on the object, including dyanamic ones.
|
||||
// record field names and values.
|
||||
for(%i = 0; %i < %fieldCount; %i++)
|
||||
{
|
||||
%field = %object.getField(%i);
|
||||
%this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field;
|
||||
%this.newFieldValues[%object, %field] = %object.getFieldValue(%field);
|
||||
}
|
||||
for(%i = 0; %i < %dynFieldCount; %i++)
|
||||
{
|
||||
%field = %object.getDynamicField(%i);
|
||||
%this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field;
|
||||
%this.newFieldValues[%object, %field] = %object.getFieldValue(%field);
|
||||
}
|
||||
// trim
|
||||
%this.newFieldNames[%object] = trim(%this.newFieldNames[%object]);
|
||||
|
||||
// look for differences
|
||||
//----------------------------------------------------------------------
|
||||
%diffs = false;
|
||||
%newFieldNames = %this.newFieldNames[%object];
|
||||
%oldFieldNames = %this.fieldNames[%object];
|
||||
%numNewFields = getWordCount(%newFieldNames);
|
||||
%numOldFields = getWordCount(%oldFieldNames);
|
||||
// compare the old field list to the new field list.
|
||||
// if a field is on the old list that isn't on the new list,
|
||||
// add it to the newNullFields list.
|
||||
for(%i = 0; %i < %numOldFields; %i++)
|
||||
{
|
||||
%field = getWord(%oldFieldNames, %i);
|
||||
%newVal = %this.newFieldValues[%object, %field];
|
||||
%oldVal = %this.fieldValues[%object, %field];
|
||||
if(%newVal !$= %oldVal)
|
||||
{
|
||||
%diffs = true;
|
||||
if(%newVal $= "")
|
||||
{
|
||||
%newNullFields = %newNullFields SPC %field;
|
||||
}
|
||||
}
|
||||
}
|
||||
// scan the new field list
|
||||
// add missing fields to the oldNullFields list
|
||||
for(%i = 0; %i < %numNewFields; %i++)
|
||||
{
|
||||
%field = getWord(%newFieldNames, %i);
|
||||
%newVal = %this.newFieldValues[%object, %field];
|
||||
%oldVal = %this.fieldValues[%object, %field];
|
||||
if(%newVal !$= %oldVal)
|
||||
{
|
||||
%diffs = true;
|
||||
if(%oldVal $= "")
|
||||
{
|
||||
%oldNullFields = %oldNullFields SPC %field;
|
||||
}
|
||||
}
|
||||
}
|
||||
%this.newNullFields[%object] = trim(%newNullFields);
|
||||
%this.oldNullFields[%object] = trim(%oldNullFields);
|
||||
|
||||
return %diffs;
|
||||
}
|
||||
|
||||
function GenericUndoAction::watchSet(%this, %set)
|
||||
{
|
||||
// scan the set
|
||||
// this.watch each object.
|
||||
%setcount = %set.getCount();
|
||||
%i = 0;
|
||||
for(; %i < %setcount; %i++)
|
||||
{
|
||||
%object = %set.getObject(%i);
|
||||
%this.watch(%object);
|
||||
}
|
||||
}
|
||||
|
||||
function GenericUndoAction::learnSet(%this, %set)
|
||||
{
|
||||
// scan the set
|
||||
// this.learn any objects that we have a this.objectIds[] entry for.
|
||||
%diffs = false;
|
||||
for(%i = 0; %i < %set.getCount(); %i++)
|
||||
{
|
||||
%object = %set.getObject(%i).getId();
|
||||
if(%this.objectIds[%object] != 1)
|
||||
continue;
|
||||
|
||||
if(%this.learn(%object))
|
||||
%diffs = true;
|
||||
}
|
||||
|
||||
return %diffs;
|
||||
}
|
||||
|
||||
function GenericUndoAction::undo(%this)
|
||||
{
|
||||
// set the objects to the old values
|
||||
// scan through our objects
|
||||
%objectList = %this.objectIdList;
|
||||
for(%i = 0; %i < getWordCount(%objectList); %i++)
|
||||
{
|
||||
%object = getWord(%objectList, %i);
|
||||
// scan through the old extant fields
|
||||
%fieldNames = %this.fieldNames[%object];
|
||||
for(%j = 0; %j < getWordCount(%fieldNames); %j++)
|
||||
{
|
||||
%field = getWord(%fieldNames, %j);
|
||||
%object.setFieldValue(%field, %this.fieldValues[%object, %field]);
|
||||
}
|
||||
// null out the fields in the null list
|
||||
%fieldNames = %this.oldNullFields[%object];
|
||||
for(%j = 0; %j < getWordCount(%fieldNames); %j++)
|
||||
{
|
||||
%field = getWord(%fieldNames, %j);
|
||||
%object.setFieldValue(%field, "");
|
||||
}
|
||||
}
|
||||
|
||||
// update the tree view
|
||||
if(isObject(%this.tree))
|
||||
%this.tree.update();
|
||||
}
|
||||
|
||||
function GenericUndoAction::redo(%this)
|
||||
{
|
||||
// set the objects to the new values
|
||||
// set the objects to the new values
|
||||
// scan through our objects
|
||||
%objectList = %this.objectIdList;
|
||||
for(%i = 0; %i < getWordCount(%objectList); %i++)
|
||||
{
|
||||
%object = getWord(%objectList, %i);
|
||||
// scan through the new extant fields
|
||||
%fieldNames = %this.newFieldNames[%object];
|
||||
for(%j = 0; %j < getWordCount(%fieldNames); %j++)
|
||||
{
|
||||
%field = getWord(%fieldNames, %j);
|
||||
%object.setFieldValue(%field, %this.newFieldValues[%object, %field]);
|
||||
}
|
||||
// null out the fields in the null list
|
||||
%fieldNames = %this.newNullFields[%object];
|
||||
for(%j = 0; %j < getWordCount(%fieldNames); %j++)
|
||||
{
|
||||
%field = getWord(%fieldNames, %j);
|
||||
%object.setFieldValue(%field, "");
|
||||
}
|
||||
}
|
||||
|
||||
// update the tree view
|
||||
if(isObject(%this.tree))
|
||||
%this.tree.update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Gui Editor Undo hooks from code
|
||||
function GuiEditor::onPreEdit(%this, %selection)
|
||||
{
|
||||
if ( isObject(%this.pendingGenericUndoAction) )
|
||||
{
|
||||
error("Error: attempting to create two generic undo actions at once in the same editor!");
|
||||
return;
|
||||
}
|
||||
|
||||
//echo("pre edit");
|
||||
%act = GenericUndoAction::create();
|
||||
%act.watchSet(%selection);
|
||||
%act.tree = GuiEditorTreeView;
|
||||
|
||||
%this.pendingGenericUndoAction = %act;
|
||||
|
||||
%this.updateUndoMenu();
|
||||
}
|
||||
|
||||
function GuiEditor::onPostEdit(%this, %selection)
|
||||
{
|
||||
if(!isObject(%this.pendingGenericUndoAction))
|
||||
error("Error: attempting to complete a GenericUndoAction that hasn't been started!");
|
||||
|
||||
%act = %this.pendingGenericUndoAction;
|
||||
%this.pendingGenericUndoAction = "";
|
||||
|
||||
%diffs = %act.learnSet(%selection);
|
||||
if(%diffs)
|
||||
{
|
||||
//echo("adding generic undoaction to undo manager");
|
||||
//%act.dump();
|
||||
%act.addToManager(%this.getUndoManager());
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo("deleting empty generic undoaction");
|
||||
%act.delete();
|
||||
}
|
||||
|
||||
%this.updateUndoMenu();
|
||||
}
|
||||
|
||||
function GuiEditor::onPreSelectionNudged(%this, %selection)
|
||||
{
|
||||
%this.onPreEdit(%selection);
|
||||
%this.pendingGenericUndoAction.actionName = "Nudge";
|
||||
}
|
||||
|
||||
function GuiEditor::onPostSelectionNudged(%this, %selection)
|
||||
{
|
||||
%this.onPostEdit(%selection);
|
||||
}
|
||||
|
||||
function GuiEditor::onAddNewCtrl(%this, %ctrl)
|
||||
{
|
||||
%set = new SimSet();
|
||||
%set.add(%ctrl);
|
||||
%act = UndoActionAddObject::create(%set, %this.getTrash(), GuiEditorTreeView);
|
||||
%set.delete();
|
||||
%act.addToManager(%this.getUndoManager());
|
||||
%this.updateUndoMenu();
|
||||
//GuiEditorInspectFields.update(0);
|
||||
}
|
||||
|
||||
function GuiEditor::onAddNewCtrlSet(%this, %selection)
|
||||
{
|
||||
%act = UndoActionAddObject::create(%selection, %this.getTrash(), GuiEditorTreeView);
|
||||
%act.addToManager(%this.getUndoManager());
|
||||
%this.updateUndoMenu();
|
||||
}
|
||||
|
||||
function GuiEditor::onTrashSelection(%this, %selection)
|
||||
{
|
||||
%act = UndoActionDeleteObject::create(%selection, %this.getTrash(), GuiEditorTreeView);
|
||||
%act.addToManager(%this.getUndoManager());
|
||||
%this.updateUndoMenu();
|
||||
}
|
||||
|
||||
function GuiEditor::onControlInspectPreApply(%this, %object)
|
||||
{
|
||||
%set = new SimSet();
|
||||
%set.add(%object);
|
||||
%this.onPreEdit(%set);
|
||||
%this.pendingGenericUndoAction.actionName = "Change Properties";
|
||||
%set.delete();
|
||||
}
|
||||
|
||||
function GuiEditor::onControlInspectPostApply(%this, %object)
|
||||
{
|
||||
%set = new SimSet();
|
||||
%set.add(%object);
|
||||
%this.onPostEdit(%set);
|
||||
%set.delete();
|
||||
GuiEditorTreeView.update();
|
||||
}
|
||||
|
||||
function GuiEditor::onFitIntoParents( %this )
|
||||
{
|
||||
%selected = %this.getSelection();
|
||||
//TODO
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue