EditorActions.as 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. class EditAction
  2. {
  3. void Undo()
  4. {
  5. }
  6. void Redo()
  7. {
  8. }
  9. }
  10. class EditActionGroup
  11. {
  12. Array<EditAction@> actions;
  13. }
  14. class CreateDrawableMaskAction : EditAction
  15. {
  16. uint nodeID;
  17. uint drawableID;
  18. int oldMask;
  19. int redoMask;
  20. int typeMask;
  21. void Define(Drawable@ drawable, int editMaskType)
  22. {
  23. drawableID = drawable.id;
  24. nodeID = drawable.node.id;
  25. switch (editMaskType)
  26. {
  27. case EDIT_VIEW_MASK:
  28. oldMask = drawable.viewMask;
  29. break;
  30. case EDIT_LIGHT_MASK:
  31. oldMask = drawable.lightMask;
  32. break;
  33. case EDIT_SHADOW_MASK:
  34. oldMask = drawable.shadowMask;
  35. break;
  36. case EDIT_ZONE_MASK:
  37. oldMask = drawable.zoneMask;
  38. break;
  39. }
  40. typeMask = editMaskType;
  41. redoMask = oldMask;
  42. }
  43. void Undo()
  44. {
  45. Node@ node = editorScene.GetNode(nodeID);
  46. Drawable@ drawable = editorScene.GetComponent(drawableID);
  47. if (node !is null && drawable !is null)
  48. {
  49. switch (typeMask)
  50. {
  51. case EDIT_VIEW_MASK:
  52. redoMask = drawable.viewMask;
  53. drawable.viewMask = oldMask;
  54. break;
  55. case EDIT_LIGHT_MASK:
  56. redoMask = drawable.lightMask;
  57. drawable.lightMask = oldMask;
  58. break;
  59. case EDIT_SHADOW_MASK:
  60. redoMask = drawable.shadowMask;
  61. drawable.shadowMask = oldMask;
  62. break;
  63. case EDIT_ZONE_MASK:
  64. redoMask = drawable.zoneMask;
  65. drawable.zoneMask = oldMask;
  66. break;
  67. }
  68. }
  69. }
  70. void Redo()
  71. {
  72. Node@ node = editorScene.GetNode(nodeID);
  73. Drawable@ drawable = editorScene.GetComponent(drawableID);
  74. if (node !is null && drawable !is null)
  75. {
  76. switch (typeMask)
  77. {
  78. case EDIT_VIEW_MASK:
  79. oldMask = drawable.viewMask;
  80. drawable.viewMask = redoMask;
  81. break;
  82. case EDIT_LIGHT_MASK:
  83. oldMask = drawable.lightMask;
  84. drawable.lightMask = redoMask;
  85. break;
  86. case EDIT_SHADOW_MASK:
  87. oldMask = drawable.shadowMask;
  88. drawable.shadowMask = redoMask;
  89. break;
  90. case EDIT_ZONE_MASK:
  91. oldMask = drawable.zoneMask;
  92. drawable.zoneMask = redoMask;
  93. break;
  94. }
  95. }
  96. }
  97. }
  98. class CreateNodeAction : EditAction
  99. {
  100. uint nodeID;
  101. uint parentID;
  102. XMLFile@ nodeData;
  103. void Define(Node@ node)
  104. {
  105. nodeID = node.id;
  106. parentID = node.parent.id;
  107. nodeData = XMLFile();
  108. XMLElement rootElem = nodeData.CreateRoot("node");
  109. node.SaveXML(rootElem);
  110. }
  111. void Undo()
  112. {
  113. Node@ parent = editorScene.GetNode(parentID);
  114. Node@ node = editorScene.GetNode(nodeID);
  115. if (parent !is null && node !is null)
  116. {
  117. parent.RemoveChild(node);
  118. hierarchyList.ClearSelection();
  119. }
  120. }
  121. void Redo()
  122. {
  123. Node@ parent = editorScene.GetNode(parentID);
  124. if (parent !is null)
  125. {
  126. Node@ node = parent.CreateChild("", nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL, nodeID);
  127. node.LoadXML(nodeData.root);
  128. FocusNode(node);
  129. }
  130. }
  131. }
  132. class DeleteNodeAction : EditAction
  133. {
  134. uint nodeID;
  135. uint parentID;
  136. XMLFile@ nodeData;
  137. void Define(Node@ node)
  138. {
  139. nodeID = node.id;
  140. parentID = node.parent.id;
  141. nodeData = XMLFile();
  142. XMLElement rootElem = nodeData.CreateRoot("node");
  143. node.SaveXML(rootElem);
  144. rootElem.SetUInt("listItemIndex", GetListIndex(node));
  145. }
  146. void Undo()
  147. {
  148. Node@ parent = editorScene.GetNode(parentID);
  149. if (parent !is null)
  150. {
  151. // Handle update manually so that the node can be reinserted back into its previous list index
  152. suppressSceneChanges = true;
  153. Node@ node = parent.CreateChild("", nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL, nodeID);
  154. if (node.LoadXML(nodeData.root))
  155. {
  156. uint listItemIndex = nodeData.root.GetUInt("listItemIndex");
  157. UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
  158. UpdateHierarchyItem(listItemIndex, node, parentItem);
  159. FocusNode(node);
  160. }
  161. suppressSceneChanges = false;
  162. }
  163. }
  164. void Redo()
  165. {
  166. Node@ parent = editorScene.GetNode(parentID);
  167. Node@ node = editorScene.GetNode(nodeID);
  168. if (parent !is null && node !is null)
  169. {
  170. parent.RemoveChild(node);
  171. hierarchyList.ClearSelection();
  172. }
  173. }
  174. }
  175. class ReparentNodeAction : EditAction
  176. {
  177. uint nodeID;
  178. uint oldParentID;
  179. uint newParentID;
  180. Array<uint> nodeList; // 2 uints get inserted per node (node, node.parent)
  181. bool multiple;
  182. void Define(Node@ node, Node@ newParent)
  183. {
  184. multiple = false;
  185. nodeID = node.id;
  186. oldParentID = node.parent.id;
  187. newParentID = newParent.id;
  188. }
  189. void Define(Array<Node@> nodes, Node@ newParent)
  190. {
  191. multiple = true;
  192. newParentID = newParent.id;
  193. for(uint i = 0; i < nodes.length; ++i)
  194. {
  195. Node@ node = nodes[i];
  196. nodeList.Push(node.id);
  197. nodeList.Push(node.parent.id);
  198. }
  199. }
  200. void Undo()
  201. {
  202. if (multiple)
  203. {
  204. for (uint i = 0; i < nodeList.length; i+=2)
  205. {
  206. uint nodeID_ = nodeList[i];
  207. uint oldParentID_ = nodeList[i+1];
  208. Node@ parent = editorScene.GetNode(oldParentID_);
  209. Node@ node = editorScene.GetNode(nodeID_);
  210. if (parent !is null && node !is null)
  211. node.parent = parent;
  212. }
  213. }
  214. else
  215. {
  216. Node@ parent = editorScene.GetNode(oldParentID);
  217. Node@ node = editorScene.GetNode(nodeID);
  218. if (parent !is null && node !is null)
  219. node.parent = parent;
  220. }
  221. }
  222. void Redo()
  223. {
  224. if (multiple)
  225. {
  226. Node@ parent = editorScene.GetNode(newParentID);
  227. if (parent is null)
  228. return;
  229. for (uint i = 0; i < nodeList.length; i+=2)
  230. {
  231. uint nodeID_ = nodeList[i];
  232. Node@ node = editorScene.GetNode(nodeID_);
  233. if (node !is null)
  234. node.parent = parent;
  235. }
  236. }
  237. else
  238. {
  239. Node@ parent = editorScene.GetNode(newParentID);
  240. Node@ node = editorScene.GetNode(nodeID);
  241. if (parent !is null && node !is null)
  242. node.parent = parent;
  243. }
  244. }
  245. }
  246. class CreateComponentAction : EditAction
  247. {
  248. uint nodeID;
  249. uint componentID;
  250. XMLFile@ componentData;
  251. void Define(Component@ component)
  252. {
  253. componentID = component.id;
  254. nodeID = component.node.id;
  255. componentData = XMLFile();
  256. XMLElement rootElem = componentData.CreateRoot("component");
  257. component.SaveXML(rootElem);
  258. }
  259. void Undo()
  260. {
  261. Node@ node = editorScene.GetNode(nodeID);
  262. Component@ component = editorScene.GetComponent(componentID);
  263. if (node !is null && component !is null)
  264. {
  265. node.RemoveComponent(component);
  266. hierarchyList.ClearSelection();
  267. }
  268. }
  269. void Redo()
  270. {
  271. Node@ node = editorScene.GetNode(nodeID);
  272. if (node !is null)
  273. {
  274. Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), componentID < FIRST_LOCAL_ID ?
  275. REPLICATED : LOCAL, componentID);
  276. component.LoadXML(componentData.root);
  277. component.ApplyAttributes();
  278. FocusComponent(component);
  279. }
  280. }
  281. }
  282. class DeleteComponentAction : EditAction
  283. {
  284. uint nodeID;
  285. uint componentID;
  286. XMLFile@ componentData;
  287. void Define(Component@ component)
  288. {
  289. componentID = component.id;
  290. nodeID = component.node.id;
  291. componentData = XMLFile();
  292. XMLElement rootElem = componentData.CreateRoot("component");
  293. component.SaveXML(rootElem);
  294. rootElem.SetUInt("listItemIndex", GetComponentListIndex(component));
  295. }
  296. void Undo()
  297. {
  298. Node@ node = editorScene.GetNode(nodeID);
  299. if (node !is null)
  300. {
  301. // Handle update manually so that the component can be reinserted back into its previous list index
  302. suppressSceneChanges = true;
  303. Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), componentID < FIRST_LOCAL_ID ?
  304. REPLICATED : LOCAL, componentID);
  305. if (component.LoadXML(componentData.root))
  306. {
  307. component.ApplyAttributes();
  308. uint listItemIndex = componentData.root.GetUInt("listItemIndex");
  309. UIElement@ parentItem = hierarchyList.items[GetListIndex(node)];
  310. UpdateHierarchyItem(listItemIndex, component, parentItem);
  311. FocusComponent(component);
  312. }
  313. suppressSceneChanges = false;
  314. }
  315. }
  316. void Redo()
  317. {
  318. Node@ node = editorScene.GetNode(nodeID);
  319. Component@ component = editorScene.GetComponent(componentID);
  320. if (node !is null && component !is null)
  321. {
  322. node.RemoveComponent(component);
  323. hierarchyList.ClearSelection();
  324. }
  325. }
  326. }
  327. class EditAttributeAction : EditAction
  328. {
  329. int targetType;
  330. uint targetID;
  331. uint attrIndex;
  332. Variant undoValue;
  333. Variant redoValue;
  334. void Define(Serializable@ target, uint index, const Variant&in oldValue)
  335. {
  336. attrIndex = index;
  337. undoValue = oldValue;
  338. redoValue = target.attributes[index];
  339. targetType = GetType(target);
  340. targetID = GetID(target, targetType);
  341. }
  342. Serializable@ GetTarget()
  343. {
  344. switch (targetType)
  345. {
  346. case ITEM_NODE:
  347. return editorScene.GetNode(targetID);
  348. case ITEM_COMPONENT:
  349. return editorScene.GetComponent(targetID);
  350. case ITEM_UI_ELEMENT:
  351. return GetUIElementByID(targetID);
  352. }
  353. return null;
  354. }
  355. void Undo()
  356. {
  357. Serializable@ target = GetTarget();
  358. if (target !is null)
  359. {
  360. target.attributes[attrIndex] = undoValue;
  361. target.ApplyAttributes();
  362. // Can't know if need a full update, so assume true
  363. attributesFullDirty = true;
  364. // Apply side effects
  365. PostEditAttribute(target, attrIndex);
  366. if (targetType == ITEM_UI_ELEMENT)
  367. SetUIElementModified(target);
  368. else
  369. SetSceneModified();
  370. EditScriptAttributes(target, attrIndex);
  371. }
  372. }
  373. void Redo()
  374. {
  375. Serializable@ target = GetTarget();
  376. if (target !is null)
  377. {
  378. target.attributes[attrIndex] = redoValue;
  379. target.ApplyAttributes();
  380. // Can't know if need a full update, so assume true
  381. attributesFullDirty = true;
  382. // Apply side effects
  383. PostEditAttribute(target, attrIndex);
  384. if (targetType == ITEM_UI_ELEMENT)
  385. SetUIElementModified(target);
  386. else
  387. SetSceneModified();
  388. EditScriptAttributes(target, attrIndex);
  389. }
  390. }
  391. }
  392. class ResetAttributesAction : EditAction
  393. {
  394. int targetType;
  395. uint targetID;
  396. Array<Variant> undoValues;
  397. VariantMap internalVars; // UIElement specific
  398. void Define(Serializable@ target)
  399. {
  400. for (uint i = 0; i < target.numAttributes; ++i)
  401. undoValues.Push(target.attributes[i]);
  402. targetType = GetType(target);
  403. targetID = GetID(target, targetType);
  404. if (targetType == ITEM_UI_ELEMENT)
  405. {
  406. // Special handling for UIElement to preserve the internal variables containing the element's generated ID among others
  407. UIElement@ element = target;
  408. Array<StringHash> keys = element.vars.keys;
  409. for (uint i = 0; i < keys.length; ++i)
  410. {
  411. // If variable name is empty (or unregistered) then it is an internal variable and should be preserved
  412. String name = GetVarName(keys[i]);
  413. if (name.empty)
  414. internalVars[keys[i]] = element.vars[keys[i]];
  415. }
  416. }
  417. }
  418. Serializable@ GetTarget()
  419. {
  420. switch (targetType)
  421. {
  422. case ITEM_NODE:
  423. return editorScene.GetNode(targetID);
  424. case ITEM_COMPONENT:
  425. return editorScene.GetComponent(targetID);
  426. case ITEM_UI_ELEMENT:
  427. return GetUIElementByID(targetID);
  428. }
  429. return null;
  430. }
  431. void SetInternalVars(UIElement@ element)
  432. {
  433. // Revert back internal variables
  434. Array<StringHash> keys = internalVars.keys;
  435. for (uint i = 0; i < keys.length; ++i)
  436. element.vars[keys[i]] = internalVars[keys[i]];
  437. if (element.vars.Contains(FILENAME_VAR))
  438. CenterDialog(element);
  439. }
  440. void Undo()
  441. {
  442. ui.cursor.shape = CS_BUSY;
  443. Serializable@ target = GetTarget();
  444. if (target !is null)
  445. {
  446. for (uint i = 0; i < target.numAttributes; ++i)
  447. {
  448. AttributeInfo info = target.attributeInfos[i];
  449. if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
  450. continue;
  451. target.attributes[i] = undoValues[i];
  452. }
  453. target.ApplyAttributes();
  454. // Apply side effects
  455. for (uint i = 0; i < target.numAttributes; ++i)
  456. PostEditAttribute(target, i);
  457. if (targetType == ITEM_UI_ELEMENT)
  458. SetUIElementModified(target);
  459. else
  460. SetSceneModified();
  461. attributesFullDirty = true;
  462. }
  463. }
  464. void Redo()
  465. {
  466. ui.cursor.shape = CS_BUSY;
  467. Serializable@ target = GetTarget();
  468. if (target !is null)
  469. {
  470. for (uint i = 0; i < target.numAttributes; ++i)
  471. {
  472. AttributeInfo info = target.attributeInfos[i];
  473. if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
  474. continue;
  475. target.attributes[i] = target.attributeDefaults[i];
  476. }
  477. if (targetType == ITEM_UI_ELEMENT)
  478. SetInternalVars(target);
  479. target.ApplyAttributes();
  480. // Apply side effects
  481. for (uint i = 0; i < target.numAttributes; ++i)
  482. PostEditAttribute(target, i);
  483. if (targetType == ITEM_UI_ELEMENT)
  484. SetUIElementModified(target);
  485. else
  486. SetSceneModified();
  487. attributesFullDirty = true;
  488. }
  489. }
  490. }
  491. class ToggleNodeEnabledAction : EditAction
  492. {
  493. uint nodeID;
  494. bool undoValue;
  495. void Define(Node@ node, bool oldEnabled)
  496. {
  497. nodeID = node.id;
  498. undoValue = oldEnabled;
  499. }
  500. void Undo()
  501. {
  502. Node@ node = editorScene.GetNode(nodeID);
  503. if (node !is null)
  504. node.SetEnabledRecursive(undoValue);
  505. }
  506. void Redo()
  507. {
  508. Node@ node = editorScene.GetNode(nodeID);
  509. if (node !is null)
  510. node.SetEnabledRecursive(!undoValue);
  511. }
  512. }
  513. class Transform
  514. {
  515. Vector3 position;
  516. Quaternion rotation;
  517. Vector3 scale;
  518. void Define(Node@ node)
  519. {
  520. position = node.position;
  521. rotation = node.rotation;
  522. scale = node.scale;
  523. }
  524. void Apply(Node@ node)
  525. {
  526. node.SetTransform(position, rotation, scale);
  527. }
  528. }
  529. class EditNodeTransformAction : EditAction
  530. {
  531. uint nodeID;
  532. Transform undoTransform;
  533. Transform redoTransform;
  534. void Define(Node@ node, const Transform&in oldTransform)
  535. {
  536. nodeID = node.id;
  537. undoTransform = oldTransform;
  538. redoTransform.Define(node);
  539. }
  540. void Undo()
  541. {
  542. Node@ node = editorScene.GetNode(nodeID);
  543. if (node !is null)
  544. {
  545. undoTransform.Apply(node);
  546. UpdateNodeAttributes();
  547. }
  548. }
  549. void Redo()
  550. {
  551. Node@ node = editorScene.GetNode(nodeID);
  552. if (node !is null)
  553. {
  554. redoTransform.Apply(node);
  555. UpdateNodeAttributes();
  556. }
  557. }
  558. }
  559. class CreateUIElementAction : EditAction
  560. {
  561. Variant elementID;
  562. Variant parentID;
  563. XMLFile@ elementData;
  564. XMLFile@ styleFile;
  565. void Define(UIElement@ element)
  566. {
  567. elementID = GetUIElementID(element);
  568. parentID = GetUIElementID(element.parent);
  569. elementData = XMLFile();
  570. XMLElement rootElem = elementData.CreateRoot("element");
  571. element.SaveXML(rootElem);
  572. styleFile = element.defaultStyle;
  573. }
  574. void Undo()
  575. {
  576. UIElement@ parent = GetUIElementByID(parentID);
  577. UIElement@ element = GetUIElementByID(elementID);
  578. if (parent !is null && element !is null)
  579. {
  580. parent.RemoveChild(element);
  581. hierarchyList.ClearSelection();
  582. SetUIElementModified(parent);
  583. }
  584. }
  585. void Redo()
  586. {
  587. UIElement@ parent = GetUIElementByID(parentID);
  588. if (parent !is null)
  589. {
  590. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  591. suppressUIElementChanges = true;
  592. if (parent.LoadChildXML(elementData.root, styleFile))
  593. {
  594. UIElement@ element = parent.children[parent.numChildren - 1];
  595. UpdateHierarchyItem(element);
  596. FocusUIElement(element);
  597. SetUIElementModified(parent);
  598. }
  599. suppressUIElementChanges = false;
  600. }
  601. }
  602. }
  603. class DeleteUIElementAction : EditAction
  604. {
  605. Variant elementID;
  606. Variant parentID;
  607. XMLFile@ elementData;
  608. XMLFile@ styleFile;
  609. void Define(UIElement@ element)
  610. {
  611. elementID = GetUIElementID(element);
  612. parentID = GetUIElementID(element.parent);
  613. elementData = XMLFile();
  614. XMLElement rootElem = elementData.CreateRoot("element");
  615. element.SaveXML(rootElem);
  616. rootElem.SetUInt("index", element.parent.FindChild(element));
  617. rootElem.SetUInt("listItemIndex", GetListIndex(element));
  618. styleFile = element.defaultStyle;
  619. }
  620. void Undo()
  621. {
  622. UIElement@ parent = GetUIElementByID(parentID);
  623. if (parent !is null)
  624. {
  625. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  626. suppressUIElementChanges = true;
  627. if (parent.LoadChildXML(elementData.root, styleFile))
  628. {
  629. XMLElement rootElem = elementData.root;
  630. uint index = rootElem.GetUInt("index");
  631. uint listItemIndex = rootElem.GetUInt("listItemIndex");
  632. UIElement@ element = parent.children[index];
  633. UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
  634. UpdateHierarchyItem(listItemIndex, element, parentItem);
  635. FocusUIElement(element);
  636. SetUIElementModified(parent);
  637. }
  638. suppressUIElementChanges = false;
  639. }
  640. }
  641. void Redo()
  642. {
  643. UIElement@ parent = GetUIElementByID(parentID);
  644. UIElement@ element = GetUIElementByID(elementID);
  645. if (parent !is null && element !is null)
  646. {
  647. parent.RemoveChild(element);
  648. hierarchyList.ClearSelection();
  649. SetUIElementModified(parent);
  650. }
  651. }
  652. }
  653. class ReparentUIElementAction : EditAction
  654. {
  655. Variant elementID;
  656. Variant oldParentID;
  657. uint oldChildIndex;
  658. Variant newParentID;
  659. void Define(UIElement@ element, UIElement@ newParent)
  660. {
  661. elementID = GetUIElementID(element);
  662. oldParentID = GetUIElementID(element.parent);
  663. oldChildIndex = element.parent.FindChild(element);
  664. newParentID = GetUIElementID(newParent);
  665. }
  666. void Undo()
  667. {
  668. UIElement@ parent = GetUIElementByID(oldParentID);
  669. UIElement@ element = GetUIElementByID(elementID);
  670. if (parent !is null && element !is null)
  671. {
  672. element.SetParent(parent, oldChildIndex);
  673. SetUIElementModified(parent);
  674. }
  675. }
  676. void Redo()
  677. {
  678. UIElement@ parent = GetUIElementByID(newParentID);
  679. UIElement@ element = GetUIElementByID(elementID);
  680. if (parent !is null && element !is null)
  681. {
  682. element.parent = parent;
  683. SetUIElementModified(parent);
  684. }
  685. }
  686. }
  687. class ApplyUIElementStyleAction : EditAction
  688. {
  689. Variant elementID;
  690. Variant parentID;
  691. XMLFile@ elementData;
  692. XMLFile@ styleFile;
  693. String elementOldStyle;
  694. String elementNewStyle;
  695. void Define(UIElement@ element, const String&in newStyle)
  696. {
  697. elementID = GetUIElementID(element);
  698. parentID = GetUIElementID(element.parent);
  699. elementData = XMLFile();
  700. XMLElement rootElem = elementData.CreateRoot("element");
  701. element.SaveXML(rootElem);
  702. rootElem.SetUInt("index", element.parent.FindChild(element));
  703. rootElem.SetUInt("listItemIndex", GetListIndex(element));
  704. styleFile = element.defaultStyle;
  705. elementOldStyle = element.style;
  706. elementNewStyle = newStyle;
  707. }
  708. void ApplyStyle(const String&in style)
  709. {
  710. UIElement@ parent = GetUIElementByID(parentID);
  711. UIElement@ element = GetUIElementByID(elementID);
  712. if (parent !is null && element !is null)
  713. {
  714. // Apply the style in the XML data
  715. elementData.root.SetAttribute("style", style);
  716. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  717. suppressUIElementChanges = true;
  718. parent.RemoveChild(element);
  719. if (parent.LoadChildXML(elementData.root, styleFile))
  720. {
  721. XMLElement rootElem = elementData.root;
  722. uint index = rootElem.GetUInt("index");
  723. uint listItemIndex = rootElem.GetUInt("listItemIndex");
  724. UIElement@ element = parent.children[index];
  725. UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
  726. UpdateHierarchyItem(listItemIndex, element, parentItem);
  727. SetUIElementModified(element);
  728. hierarchyUpdateSelections.Push(listItemIndex);
  729. }
  730. suppressUIElementChanges = false;
  731. }
  732. }
  733. void Undo()
  734. {
  735. ApplyStyle(elementOldStyle);
  736. }
  737. void Redo()
  738. {
  739. ApplyStyle(elementNewStyle);
  740. }
  741. }
  742. class EditMaterialAction : EditAction
  743. {
  744. XMLFile@ oldState;
  745. XMLFile@ newState;
  746. WeakHandle material;
  747. void Define(Material@ material_, XMLFile@ oldState_)
  748. {
  749. material = material_;
  750. oldState = oldState_;
  751. newState = XMLFile();
  752. XMLElement materialElem = newState.CreateRoot("material");
  753. material_.Save(materialElem);
  754. }
  755. void Undo()
  756. {
  757. Material@ mat = material.Get();
  758. if (mat !is null)
  759. {
  760. mat.Load(oldState.root);
  761. RefreshMaterialEditor();
  762. }
  763. }
  764. void Redo()
  765. {
  766. Material@ mat = material.Get();
  767. if (mat !is null)
  768. {
  769. mat.Load(newState.root);
  770. RefreshMaterialEditor();
  771. }
  772. }
  773. }
  774. class EditParticleEffectAction : EditAction
  775. {
  776. XMLFile@ oldState;
  777. XMLFile@ newState;
  778. WeakHandle particleEffect;
  779. ParticleEmitter@ particleEmitter;
  780. void Define(ParticleEmitter@ particleEmitter_, ParticleEffect@ particleEffect_, XMLFile@ oldState_)
  781. {
  782. particleEmitter = particleEmitter_;
  783. particleEffect = particleEffect_;
  784. oldState = oldState_;
  785. newState = XMLFile();
  786. XMLElement particleElem = newState.CreateRoot("particleeffect");
  787. particleEffect_.Save(particleElem);
  788. }
  789. void Undo()
  790. {
  791. ParticleEffect@ effect = particleEffect.Get();
  792. if (effect !is null)
  793. {
  794. effect.Load(oldState.root);
  795. particleEmitter.ApplyEffect();
  796. RefreshParticleEffectEditor();
  797. }
  798. }
  799. void Redo()
  800. {
  801. ParticleEffect@ effect = particleEffect.Get();
  802. if (effect !is null)
  803. {
  804. effect.Load(newState.root);
  805. particleEmitter.ApplyEffect();
  806. RefreshParticleEffectEditor();
  807. }
  808. }
  809. }
  810. class AssignMaterialAction : EditAction
  811. {
  812. WeakHandle model;
  813. Array<String> oldMaterials;
  814. String newMaterialName;
  815. void Define(StaticModel@ model_, Array<String> oldMaterials_, Material@ newMaterial_)
  816. {
  817. model = model_;
  818. oldMaterials = oldMaterials_;
  819. newMaterialName = newMaterial_.name;
  820. }
  821. void Undo()
  822. {
  823. StaticModel@ staticModel = model.Get();
  824. if (staticModel is null)
  825. return;
  826. for(uint i=0; i<oldMaterials.length; ++i)
  827. {
  828. Material@ material = cache.GetResource("Material", oldMaterials[i]);
  829. staticModel.materials[i] = material;
  830. }
  831. }
  832. void Redo()
  833. {
  834. StaticModel@ staticModel = model.Get();
  835. if (staticModel is null)
  836. return;
  837. Material@ material = cache.GetResource("Material", newMaterialName);
  838. staticModel.material = material;
  839. }
  840. }
  841. class AssignModelAction : EditAction
  842. {
  843. WeakHandle staticModel;
  844. String oldModel;
  845. String newModel;
  846. void Define(StaticModel@ staticModel_, Model@ oldModel_, Model@ newModel_)
  847. {
  848. staticModel = staticModel_;
  849. oldModel = oldModel_.name;
  850. newModel = newModel_.name;
  851. }
  852. void Undo()
  853. {
  854. StaticModel@ staticModel_ = staticModel.Get();
  855. if (staticModel_ is null)
  856. return;
  857. Model@ model = cache.GetResource("Model", oldModel);
  858. if (model is null)
  859. return;
  860. staticModel_.model = model;
  861. }
  862. void Redo()
  863. {
  864. StaticModel@ staticModel_ = staticModel.Get();
  865. if (staticModel_ is null)
  866. return;
  867. Model@ model = cache.GetResource("Model", newModel);
  868. if (model is null)
  869. return;
  870. staticModel_.model = model;
  871. }
  872. }