Urho3D/bin/Data/Scripts/Editor/EditorActions.as
2020-10-28 19:18:41 +08:00

1153 lines
32 KiB
ActionScript

class EditAction
{
void Undo()
{
}
void Redo()
{
}
}
class EditActionGroup
{
Array<EditAction@> actions;
}
class CreateDrawableMaskAction : EditAction
{
uint nodeID;
uint drawableID;
int oldMask;
int redoMask;
int typeMask;
void Define(Drawable@ drawable, int editMaskType)
{
drawableID = drawable.id;
nodeID = drawable.node.id;
switch (editMaskType)
{
case EDIT_VIEW_MASK:
oldMask = drawable.viewMask;
break;
case EDIT_LIGHT_MASK:
oldMask = drawable.lightMask;
break;
case EDIT_SHADOW_MASK:
oldMask = drawable.shadowMask;
break;
case EDIT_ZONE_MASK:
oldMask = drawable.zoneMask;
break;
}
typeMask = editMaskType;
redoMask = oldMask;
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
Drawable@ drawable = editorScene.GetComponent(drawableID);
if (node !is null && drawable !is null)
{
switch (typeMask)
{
case EDIT_VIEW_MASK:
redoMask = drawable.viewMask;
drawable.viewMask = oldMask;
break;
case EDIT_LIGHT_MASK:
redoMask = drawable.lightMask;
drawable.lightMask = oldMask;
break;
case EDIT_SHADOW_MASK:
redoMask = drawable.shadowMask;
drawable.shadowMask = oldMask;
break;
case EDIT_ZONE_MASK:
redoMask = drawable.zoneMask;
drawable.zoneMask = oldMask;
break;
}
}
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
Drawable@ drawable = editorScene.GetComponent(drawableID);
if (node !is null && drawable !is null)
{
switch (typeMask)
{
case EDIT_VIEW_MASK:
oldMask = drawable.viewMask;
drawable.viewMask = redoMask;
break;
case EDIT_LIGHT_MASK:
oldMask = drawable.lightMask;
drawable.lightMask = redoMask;
break;
case EDIT_SHADOW_MASK:
oldMask = drawable.shadowMask;
drawable.shadowMask = redoMask;
break;
case EDIT_ZONE_MASK:
oldMask = drawable.zoneMask;
drawable.zoneMask = redoMask;
break;
}
}
}
}
class CreateNodeAction : EditAction
{
uint nodeID;
uint parentID;
XMLFile@ nodeData;
void Define(Node@ node)
{
nodeID = node.id;
parentID = node.parent.id;
nodeData = XMLFile();
XMLElement rootElem = nodeData.CreateRoot("node");
node.SaveXML(rootElem);
}
void Undo()
{
Node@ parent = editorScene.GetNode(parentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
{
parent.RemoveChild(node);
hierarchyList.ClearSelection();
}
}
void Redo()
{
Node@ parent = editorScene.GetNode(parentID);
if (parent !is null)
{
Node@ node = parent.CreateChild("", Scene::IsReplicatedID(nodeID) ? REPLICATED : LOCAL, nodeID);
node.LoadXML(nodeData.root);
FocusNode(node);
}
}
}
class DeleteNodeAction : EditAction
{
uint nodeID;
uint parentID;
XMLFile@ nodeData;
void Define(Node@ node)
{
nodeID = node.id;
parentID = node.parent.id;
nodeData = XMLFile();
XMLElement rootElem = nodeData.CreateRoot("node");
node.SaveXML(rootElem);
rootElem.SetUInt("listItemIndex", GetListIndex(node));
}
void Undo()
{
Node@ parent = editorScene.GetNode(parentID);
if (parent !is null)
{
// Handle update manually so that the node can be reinserted back into its previous list index
suppressSceneChanges = true;
Node@ node = parent.CreateChild("", Scene::IsReplicatedID(nodeID) ? REPLICATED : LOCAL, nodeID);
if (node.LoadXML(nodeData.root))
{
uint listItemIndex = nodeData.root.GetUInt("listItemIndex");
UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
UpdateHierarchyItem(listItemIndex, node, parentItem);
FocusNode(node);
}
suppressSceneChanges = false;
}
}
void Redo()
{
Node@ parent = editorScene.GetNode(parentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
{
parent.RemoveChild(node);
hierarchyList.ClearSelection();
}
}
}
class ReparentNodeAction : EditAction
{
uint nodeID;
uint oldParentID;
uint newParentID;
Array<uint> nodeList; // 2 uints get inserted per node (node, node.parent)
bool multiple;
void Define(Node@ node, Node@ newParent)
{
multiple = false;
nodeID = node.id;
oldParentID = node.parent.id;
newParentID = newParent.id;
}
void Define(Array<Node@> nodes, Node@ newParent)
{
multiple = true;
newParentID = newParent.id;
for(uint i = 0; i < nodes.length; ++i)
{
Node@ node = nodes[i];
nodeList.Push(node.id);
nodeList.Push(node.parent.id);
}
}
void Undo()
{
if (multiple)
{
for (uint i = 0; i < nodeList.length; i+=2)
{
uint nodeID_ = nodeList[i];
uint oldParentID_ = nodeList[i+1];
Node@ parent = editorScene.GetNode(oldParentID_);
Node@ node = editorScene.GetNode(nodeID_);
if (parent !is null && node !is null)
node.parent = parent;
}
}
else
{
Node@ parent = editorScene.GetNode(oldParentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
node.parent = parent;
}
}
void Redo()
{
if (multiple)
{
Node@ parent = editorScene.GetNode(newParentID);
if (parent is null)
return;
for (uint i = 0; i < nodeList.length; i+=2)
{
uint nodeID_ = nodeList[i];
Node@ node = editorScene.GetNode(nodeID_);
if (node !is null)
node.parent = parent;
}
}
else
{
Node@ parent = editorScene.GetNode(newParentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
node.parent = parent;
}
}
}
class ReorderNodeAction : EditAction
{
uint nodeID;
uint parentID;
uint oldChildIndex;
uint newChildIndex;
void Define(Node@ node, uint newIndex)
{
nodeID = node.id;
parentID = node.parent.id;
oldChildIndex = SceneFindChildIndex(node.parent, node);
newChildIndex = newIndex;
}
void Undo()
{
Node@ parent = editorScene.GetNode(parentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
PerformReorder(parent, node, oldChildIndex);
}
void Redo()
{
Node@ parent = editorScene.GetNode(parentID);
Node@ node = editorScene.GetNode(nodeID);
if (parent !is null && node !is null)
PerformReorder(parent, node, newChildIndex);
}
}
class ReorderComponentAction : EditAction
{
uint componentID;
uint nodeID;
uint oldComponentIndex;
uint newComponentIndex;
void Define(Component@ component, uint newIndex)
{
componentID = component.id;
nodeID = component.node.id;
oldComponentIndex = SceneFindComponentIndex(component.node, component);
newComponentIndex = newIndex;
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
Component@ component = editorScene.GetComponent(componentID);
if (node !is null && component !is null)
PerformReorder(node, component, oldComponentIndex);
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
Component@ component = editorScene.GetComponent(componentID);
if (node !is null && component !is null)
PerformReorder(node, component, newComponentIndex);
}
}
class CreateComponentAction : EditAction
{
uint nodeID;
uint componentID;
XMLFile@ componentData;
void Define(Component@ component)
{
componentID = component.id;
nodeID = component.node.id;
componentData = XMLFile();
XMLElement rootElem = componentData.CreateRoot("component");
component.SaveXML(rootElem);
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
Component@ component = editorScene.GetComponent(componentID);
if (node !is null && component !is null)
{
node.RemoveComponent(component);
hierarchyList.ClearSelection();
}
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
{
Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), Scene::IsReplicatedID(componentID) ?
REPLICATED : LOCAL, componentID);
component.LoadXML(componentData.root);
component.ApplyAttributes();
FocusComponent(component);
}
}
}
class DeleteComponentAction : EditAction
{
uint nodeID;
uint componentID;
XMLFile@ componentData;
void Define(Component@ component)
{
componentID = component.id;
nodeID = component.node.id;
componentData = XMLFile();
XMLElement rootElem = componentData.CreateRoot("component");
component.SaveXML(rootElem);
rootElem.SetUInt("listItemIndex", GetComponentListIndex(component));
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
{
// Handle update manually so that the component can be reinserted back into its previous list index
suppressSceneChanges = true;
Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), Scene::IsReplicatedID(componentID) ?
REPLICATED : LOCAL, componentID);
if (component.LoadXML(componentData.root))
{
component.ApplyAttributes();
uint listItemIndex = componentData.root.GetUInt("listItemIndex");
UIElement@ parentItem = hierarchyList.items[GetListIndex(node)];
UpdateHierarchyItem(listItemIndex, component, parentItem);
FocusComponent(component);
}
suppressSceneChanges = false;
}
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
Component@ component = editorScene.GetComponent(componentID);
if (node !is null && component !is null)
{
node.RemoveComponent(component);
hierarchyList.ClearSelection();
}
}
}
class EditAttributeAction : EditAction
{
int targetType;
uint targetID;
uint attrIndex;
Variant undoValue;
Variant redoValue;
void Define(Serializable@ target, uint index, const Variant&in oldValue)
{
attrIndex = index;
undoValue = oldValue;
redoValue = target.attributes[index];
targetType = GetType(target);
targetID = GetID(target, targetType);
}
Serializable@ GetTarget()
{
switch (targetType)
{
case ITEM_NODE:
return editorScene.GetNode(targetID);
case ITEM_COMPONENT:
return editorScene.GetComponent(targetID);
case ITEM_UI_ELEMENT:
return GetUIElementByID(targetID);
}
return null;
}
void Undo()
{
Serializable@ target = GetTarget();
if (target !is null)
{
target.attributes[attrIndex] = undoValue;
target.ApplyAttributes();
// Can't know if need a full update, so assume true
attributesFullDirty = true;
// Apply side effects
PostEditAttribute(target, attrIndex);
if (targetType == ITEM_UI_ELEMENT)
SetUIElementModified(target);
else
SetSceneModified();
}
}
void Redo()
{
Serializable@ target = GetTarget();
if (target !is null)
{
target.attributes[attrIndex] = redoValue;
target.ApplyAttributes();
// Can't know if need a full update, so assume true
attributesFullDirty = true;
// Apply side effects
PostEditAttribute(target, attrIndex);
if (targetType == ITEM_UI_ELEMENT)
SetUIElementModified(target);
else
SetSceneModified();
}
}
}
class ResetAttributesAction : EditAction
{
int targetType;
uint targetID;
Array<Variant> undoValues;
VariantMap internalVars; // UIElement specific
void Define(Serializable@ target)
{
for (uint i = 0; i < target.numAttributes; ++i)
undoValues.Push(target.attributes[i]);
targetType = GetType(target);
targetID = GetID(target, targetType);
if (targetType == ITEM_UI_ELEMENT)
{
// Special handling for UIElement to preserve the internal variables containing the element's generated ID among others
UIElement@ element = target;
Array<StringHash> keys = element.vars.keys;
for (uint i = 0; i < keys.length; ++i)
{
// If variable name is empty (or unregistered) then it is an internal variable and should be preserved
String name = GetVarName(keys[i]);
if (name.empty)
internalVars[keys[i]] = element.vars[keys[i]];
}
}
}
Serializable@ GetTarget()
{
switch (targetType)
{
case ITEM_NODE:
return editorScene.GetNode(targetID);
case ITEM_COMPONENT:
return editorScene.GetComponent(targetID);
case ITEM_UI_ELEMENT:
return GetUIElementByID(targetID);
}
return null;
}
void SetInternalVars(UIElement@ element)
{
// Revert back internal variables
Array<StringHash> keys = internalVars.keys;
for (uint i = 0; i < keys.length; ++i)
element.vars[keys[i]] = internalVars[keys[i]];
if (element.vars.Contains(FILENAME_VAR))
CenterDialog(element);
}
void Undo()
{
ui.cursor.shape = CS_BUSY;
Serializable@ target = GetTarget();
if (target !is null)
{
for (uint i = 0; i < target.numAttributes; ++i)
{
AttributeInfo info = target.attributeInfos[i];
if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
continue;
target.attributes[i] = undoValues[i];
}
target.ApplyAttributes();
// Apply side effects
for (uint i = 0; i < target.numAttributes; ++i)
PostEditAttribute(target, i);
if (targetType == ITEM_UI_ELEMENT)
SetUIElementModified(target);
else
SetSceneModified();
attributesFullDirty = true;
}
}
void Redo()
{
ui.cursor.shape = CS_BUSY;
Serializable@ target = GetTarget();
if (target !is null)
{
for (uint i = 0; i < target.numAttributes; ++i)
{
AttributeInfo info = target.attributeInfos[i];
if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
continue;
target.attributes[i] = target.attributeDefaults[i];
}
if (targetType == ITEM_UI_ELEMENT)
SetInternalVars(target);
target.ApplyAttributes();
// Apply side effects
for (uint i = 0; i < target.numAttributes; ++i)
PostEditAttribute(target, i);
if (targetType == ITEM_UI_ELEMENT)
SetUIElementModified(target);
else
SetSceneModified();
attributesFullDirty = true;
}
}
}
class ToggleNodeEnabledAction : EditAction
{
uint nodeID;
bool undoValue;
void Define(Node@ node, bool oldEnabled)
{
nodeID = node.id;
undoValue = oldEnabled;
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
node.SetEnabledRecursive(undoValue);
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
node.SetEnabledRecursive(!undoValue);
}
}
class Transform
{
Vector3 position;
Quaternion rotation;
Vector3 scale;
void Define(Node@ node)
{
position = node.position;
rotation = node.rotation;
scale = node.scale;
}
void Apply(Node@ node)
{
node.SetTransform(position, rotation, scale);
}
}
class EditNodeTransformAction : EditAction
{
uint nodeID;
Transform undoTransform;
Transform redoTransform;
void Define(Node@ node, const Transform&in oldTransform)
{
nodeID = node.id;
undoTransform = oldTransform;
redoTransform.Define(node);
}
void Undo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
{
undoTransform.Apply(node);
UpdateNodeAttributes();
}
}
void Redo()
{
Node@ node = editorScene.GetNode(nodeID);
if (node !is null)
{
redoTransform.Apply(node);
UpdateNodeAttributes();
}
}
}
class CreateUIElementAction : EditAction
{
Variant elementID;
Variant parentID;
XMLFile@ elementData;
XMLFile@ styleFile;
void Define(UIElement@ element)
{
elementID = GetUIElementID(element);
parentID = GetUIElementID(element.parent);
elementData = XMLFile();
XMLElement rootElem = elementData.CreateRoot("element");
element.SaveXML(rootElem);
styleFile = element.defaultStyle;
}
void Undo()
{
UIElement@ parent = GetUIElementByID(parentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
{
parent.RemoveChild(element);
hierarchyList.ClearSelection();
SetUIElementModified(parent);
}
}
void Redo()
{
UIElement@ parent = GetUIElementByID(parentID);
if (parent !is null)
{
// Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
suppressUIElementChanges = true;
if (parent.LoadChildXML(elementData.root, styleFile) !is null)
{
UIElement@ element = parent.children[parent.numChildren - 1];
UpdateHierarchyItem(element);
FocusUIElement(element);
SetUIElementModified(parent);
}
suppressUIElementChanges = false;
}
}
}
class DeleteUIElementAction : EditAction
{
Variant elementID;
Variant parentID;
XMLFile@ elementData;
XMLFile@ styleFile;
void Define(UIElement@ element)
{
elementID = GetUIElementID(element);
parentID = GetUIElementID(element.parent);
elementData = XMLFile();
XMLElement rootElem = elementData.CreateRoot("element");
element.SaveXML(rootElem);
rootElem.SetUInt("index", element.parent.FindChild(element));
rootElem.SetUInt("listItemIndex", GetListIndex(element));
styleFile = element.defaultStyle;
}
void Undo()
{
UIElement@ parent = GetUIElementByID(parentID);
if (parent !is null)
{
// Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
suppressUIElementChanges = true;
if (parent.LoadChildXML(elementData.root, styleFile) !is null)
{
XMLElement rootElem = elementData.root;
uint index = rootElem.GetUInt("index");
uint listItemIndex = rootElem.GetUInt("listItemIndex");
UIElement@ element = parent.children[index];
UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
UpdateHierarchyItem(listItemIndex, element, parentItem);
FocusUIElement(element);
SetUIElementModified(parent);
}
suppressUIElementChanges = false;
}
}
void Redo()
{
UIElement@ parent = GetUIElementByID(parentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
{
parent.RemoveChild(element);
hierarchyList.ClearSelection();
SetUIElementModified(parent);
}
}
}
class ReparentUIElementAction : EditAction
{
Variant elementID;
Variant oldParentID;
uint oldChildIndex;
Variant newParentID;
void Define(UIElement@ element, UIElement@ newParent)
{
elementID = GetUIElementID(element);
oldParentID = GetUIElementID(element.parent);
oldChildIndex = element.parent.FindChild(element);
newParentID = GetUIElementID(newParent);
}
void Undo()
{
UIElement@ parent = GetUIElementByID(oldParentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
{
element.SetParent(parent, oldChildIndex);
SetUIElementModified(parent);
}
}
void Redo()
{
UIElement@ parent = GetUIElementByID(newParentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
{
element.parent = parent;
SetUIElementModified(parent);
}
}
}
class ReorderUIElementAction : EditAction
{
Variant elementID;
Variant parentID;
uint oldChildIndex;
uint newChildIndex;
void Define(UIElement@ element, uint newIndex)
{
elementID = GetUIElementID(element);
parentID = GetUIElementID(element.parent);
oldChildIndex = element.parent.FindChild(element);
newChildIndex = newIndex;
}
void Undo()
{
UIElement@ parent = GetUIElementByID(parentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
PerformReorder(parent, element, oldChildIndex);
}
void Redo()
{
UIElement@ parent = GetUIElementByID(parentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
PerformReorder(parent, element, newChildIndex);
}
}
class ApplyUIElementStyleAction : EditAction
{
Variant elementID;
Variant parentID;
XMLFile@ elementData;
XMLFile@ styleFile;
String elementOldStyle;
String elementNewStyle;
void Define(UIElement@ element, const String&in newStyle)
{
elementID = GetUIElementID(element);
parentID = GetUIElementID(element.parent);
elementData = XMLFile();
XMLElement rootElem = elementData.CreateRoot("element");
element.SaveXML(rootElem);
rootElem.SetUInt("index", element.parent.FindChild(element));
rootElem.SetUInt("listItemIndex", GetListIndex(element));
styleFile = element.defaultStyle;
elementOldStyle = element.style;
elementNewStyle = newStyle;
}
void ApplyStyle(const String&in style)
{
UIElement@ parent = GetUIElementByID(parentID);
UIElement@ element = GetUIElementByID(elementID);
if (parent !is null && element !is null)
{
// Apply the style in the XML data
elementData.root.SetAttribute("style", style);
// Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
suppressUIElementChanges = true;
parent.RemoveChild(element);
if (parent.LoadChildXML(elementData.root, styleFile) !is null)
{
XMLElement rootElem = elementData.root;
uint index = rootElem.GetUInt("index");
uint listItemIndex = rootElem.GetUInt("listItemIndex");
UIElement@ elem = parent.children[index];
UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
UpdateHierarchyItem(listItemIndex, elem, parentItem);
SetUIElementModified(elem);
hierarchyUpdateSelections.Push(listItemIndex);
}
suppressUIElementChanges = false;
}
}
void Undo()
{
ApplyStyle(elementOldStyle);
}
void Redo()
{
ApplyStyle(elementNewStyle);
}
}
class EditMaterialAction : EditAction
{
XMLFile@ oldState;
XMLFile@ newState;
WeakHandle material;
void Define(Material@ material_, XMLFile@ oldState_)
{
material = material_;
oldState = oldState_;
newState = XMLFile();
XMLElement materialElem = newState.CreateRoot("material");
material_.Save(materialElem);
}
void Undo()
{
Material@ mat = material.Get();
if (mat !is null)
{
mat.Load(oldState.root);
RefreshMaterialEditor();
}
}
void Redo()
{
Material@ mat = material.Get();
if (mat !is null)
{
mat.Load(newState.root);
RefreshMaterialEditor();
}
}
}
class EditParticleEffectAction : EditAction
{
XMLFile@ oldState;
XMLFile@ newState;
WeakHandle particleEffect;
ParticleEmitter@ particleEmitter;
void Define(ParticleEmitter@ particleEmitter_, ParticleEffect@ particleEffect_, XMLFile@ oldState_)
{
particleEmitter = particleEmitter_;
particleEffect = particleEffect_;
oldState = oldState_;
newState = XMLFile();
XMLElement particleElem = newState.CreateRoot("particleeffect");
particleEffect_.Save(particleElem);
}
void Undo()
{
ParticleEffect@ effect = particleEffect.Get();
if (effect !is null)
{
effect.Load(oldState.root);
particleEmitter.ApplyEffect();
RefreshParticleEffectEditor();
}
}
void Redo()
{
ParticleEffect@ effect = particleEffect.Get();
if (effect !is null)
{
effect.Load(newState.root);
particleEmitter.ApplyEffect();
RefreshParticleEffectEditor();
}
}
}
class AssignMaterialAction : EditAction
{
WeakHandle model;
Array<String> oldMaterials;
String newMaterialName;
void Define(StaticModel@ model_, Array<String> oldMaterials_, Material@ newMaterial_)
{
model = model_;
oldMaterials = oldMaterials_;
newMaterialName = newMaterial_.name;
}
void Undo()
{
StaticModel@ staticModel = model.Get();
if (staticModel is null)
return;
for(uint i=0; i<oldMaterials.length; ++i)
{
Material@ material = cache.GetResource("Material", oldMaterials[i]);
staticModel.materials[i] = material;
}
}
void Redo()
{
StaticModel@ staticModel = model.Get();
if (staticModel is null)
return;
Material@ material = cache.GetResource("Material", newMaterialName);
staticModel.material = material;
}
}
class AssignModelAction : EditAction
{
WeakHandle staticModel;
String oldModel;
String newModel;
void Define(StaticModel@ staticModel_, Model@ oldModel_, Model@ newModel_)
{
staticModel = staticModel_;
oldModel = (oldModel_ !is null) ? oldModel_.name : "";
newModel = (newModel_ !is null) ? newModel_.name : "";
}
void Undo()
{
StaticModel@ staticModel_ = staticModel.Get();
if (staticModel_ is null)
return;
Model@ model = cache.GetResource("Model", oldModel);
if (model is null)
return;
staticModel_.model = model;
}
void Redo()
{
StaticModel@ staticModel_ = staticModel.Get();
if (staticModel_ is null)
return;
Model@ model = cache.GetResource("Model", newModel);
if (model is null)
return;
staticModel_.model = model;
}
}
class ModifyTerrainAction : EditAction
{
WeakHandle terrain;
IntVector2 offset;
VectorBuffer compressedOldBuffer;
VectorBuffer compressedNewBuffer;
void Define(Terrain@ terrain_, IntVector2 offset_, Image@ oldImage_, Image@ newImage_)
{
terrain = terrain_;
offset = offset_;
VectorBuffer uncompressedOldBuffer;
VectorBuffer uncompressedNewBuffer;
oldImage_.Save(uncompressedOldBuffer);
newImage_.Save(uncompressedNewBuffer);
compressedOldBuffer = CompressVectorBuffer(uncompressedOldBuffer);
compressedNewBuffer = CompressVectorBuffer(uncompressedNewBuffer);
}
void Undo()
{
Terrain@ terrain_ = terrain.Get();
if (terrain_ is null)
return;
VectorBuffer uncompressedOldBuffer = DecompressVectorBuffer(compressedOldBuffer);
Image oldImage;
oldImage.Load(uncompressedOldBuffer);
for (int y = 0; y < oldImage.height; ++y)
{
for (int x = 0; x < oldImage.width; ++x)
{
terrain_.heightMap.SetPixel(offset.x + x, offset.y + y, oldImage.GetPixel(x, y));
}
}
terrain_.ApplyHeightMap();
}
void Redo()
{
Terrain@ terrain_ = terrain.Get();
if (terrain_ is null)
return;
VectorBuffer uncompressedNewBuffer = DecompressVectorBuffer(compressedNewBuffer);
Image newImage;
newImage.Load(uncompressedNewBuffer);
for (int y = 0; y < newImage.height; ++y)
{
for (int x = 0; x < newImage.width; ++x)
{
terrain_.heightMap.SetPixel(offset.x + x, offset.y + y, newImage.GetPixel(x, y));
}
}
terrain_.ApplyHeightMap();
}
}