EditorActions.as 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  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("", Scene::IsReplicatedID(nodeID) ? 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("", Scene::IsReplicatedID(nodeID) ? 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 ReorderNodeAction : EditAction
  247. {
  248. uint nodeID;
  249. uint parentID;
  250. uint oldChildIndex;
  251. uint newChildIndex;
  252. void Define(Node@ node, uint newIndex)
  253. {
  254. nodeID = node.id;
  255. parentID = node.parent.id;
  256. oldChildIndex = SceneFindChildIndex(node.parent, node);
  257. newChildIndex = newIndex;
  258. }
  259. void Undo()
  260. {
  261. Node@ parent = editorScene.GetNode(parentID);
  262. Node@ node = editorScene.GetNode(nodeID);
  263. if (parent !is null && node !is null)
  264. PerformReorder(parent, node, oldChildIndex);
  265. }
  266. void Redo()
  267. {
  268. Node@ parent = editorScene.GetNode(parentID);
  269. Node@ node = editorScene.GetNode(nodeID);
  270. if (parent !is null && node !is null)
  271. PerformReorder(parent, node, newChildIndex);
  272. }
  273. }
  274. class ReorderComponentAction : EditAction
  275. {
  276. uint componentID;
  277. uint nodeID;
  278. uint oldComponentIndex;
  279. uint newComponentIndex;
  280. void Define(Component@ component, uint newIndex)
  281. {
  282. componentID = component.id;
  283. nodeID = component.node.id;
  284. oldComponentIndex = SceneFindComponentIndex(component.node, component);
  285. newComponentIndex = newIndex;
  286. }
  287. void Undo()
  288. {
  289. Node@ node = editorScene.GetNode(nodeID);
  290. Component@ component = editorScene.GetComponent(componentID);
  291. if (node !is null && component !is null)
  292. PerformReorder(node, component, oldComponentIndex);
  293. }
  294. void Redo()
  295. {
  296. Node@ node = editorScene.GetNode(nodeID);
  297. Component@ component = editorScene.GetComponent(componentID);
  298. if (node !is null && component !is null)
  299. PerformReorder(node, component, newComponentIndex);
  300. }
  301. }
  302. class CreateComponentAction : EditAction
  303. {
  304. uint nodeID;
  305. uint componentID;
  306. XMLFile@ componentData;
  307. void Define(Component@ component)
  308. {
  309. componentID = component.id;
  310. nodeID = component.node.id;
  311. componentData = XMLFile();
  312. XMLElement rootElem = componentData.CreateRoot("component");
  313. component.SaveXML(rootElem);
  314. }
  315. void Undo()
  316. {
  317. Node@ node = editorScene.GetNode(nodeID);
  318. Component@ component = editorScene.GetComponent(componentID);
  319. if (node !is null && component !is null)
  320. {
  321. node.RemoveComponent(component);
  322. hierarchyList.ClearSelection();
  323. }
  324. }
  325. void Redo()
  326. {
  327. Node@ node = editorScene.GetNode(nodeID);
  328. if (node !is null)
  329. {
  330. Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), Scene::IsReplicatedID(componentID) ?
  331. REPLICATED : LOCAL, componentID);
  332. component.LoadXML(componentData.root);
  333. component.ApplyAttributes();
  334. FocusComponent(component);
  335. }
  336. }
  337. }
  338. class DeleteComponentAction : EditAction
  339. {
  340. uint nodeID;
  341. uint componentID;
  342. XMLFile@ componentData;
  343. void Define(Component@ component)
  344. {
  345. componentID = component.id;
  346. nodeID = component.node.id;
  347. componentData = XMLFile();
  348. XMLElement rootElem = componentData.CreateRoot("component");
  349. component.SaveXML(rootElem);
  350. rootElem.SetUInt("listItemIndex", GetComponentListIndex(component));
  351. }
  352. void Undo()
  353. {
  354. Node@ node = editorScene.GetNode(nodeID);
  355. if (node !is null)
  356. {
  357. // Handle update manually so that the component can be reinserted back into its previous list index
  358. suppressSceneChanges = true;
  359. Component@ component = node.CreateComponent(componentData.root.GetAttribute("type"), Scene::IsReplicatedID(componentID) ?
  360. REPLICATED : LOCAL, componentID);
  361. if (component.LoadXML(componentData.root))
  362. {
  363. component.ApplyAttributes();
  364. uint listItemIndex = componentData.root.GetUInt("listItemIndex");
  365. UIElement@ parentItem = hierarchyList.items[GetListIndex(node)];
  366. UpdateHierarchyItem(listItemIndex, component, parentItem);
  367. FocusComponent(component);
  368. }
  369. suppressSceneChanges = false;
  370. }
  371. }
  372. void Redo()
  373. {
  374. Node@ node = editorScene.GetNode(nodeID);
  375. Component@ component = editorScene.GetComponent(componentID);
  376. if (node !is null && component !is null)
  377. {
  378. node.RemoveComponent(component);
  379. hierarchyList.ClearSelection();
  380. }
  381. }
  382. }
  383. class EditAttributeAction : EditAction
  384. {
  385. int targetType;
  386. uint targetID;
  387. uint attrIndex;
  388. Variant undoValue;
  389. Variant redoValue;
  390. void Define(Serializable@ target, uint index, const Variant&in oldValue)
  391. {
  392. attrIndex = index;
  393. undoValue = oldValue;
  394. redoValue = target.attributes[index];
  395. targetType = GetType(target);
  396. targetID = GetID(target, targetType);
  397. }
  398. Serializable@ GetTarget()
  399. {
  400. switch (targetType)
  401. {
  402. case ITEM_NODE:
  403. return editorScene.GetNode(targetID);
  404. case ITEM_COMPONENT:
  405. return editorScene.GetComponent(targetID);
  406. case ITEM_UI_ELEMENT:
  407. return GetUIElementByID(targetID);
  408. }
  409. return null;
  410. }
  411. void Undo()
  412. {
  413. Serializable@ target = GetTarget();
  414. if (target !is null)
  415. {
  416. target.attributes[attrIndex] = undoValue;
  417. target.ApplyAttributes();
  418. // Can't know if need a full update, so assume true
  419. attributesFullDirty = true;
  420. // Apply side effects
  421. PostEditAttribute(target, attrIndex);
  422. if (targetType == ITEM_UI_ELEMENT)
  423. SetUIElementModified(target);
  424. else
  425. SetSceneModified();
  426. }
  427. }
  428. void Redo()
  429. {
  430. Serializable@ target = GetTarget();
  431. if (target !is null)
  432. {
  433. target.attributes[attrIndex] = redoValue;
  434. target.ApplyAttributes();
  435. // Can't know if need a full update, so assume true
  436. attributesFullDirty = true;
  437. // Apply side effects
  438. PostEditAttribute(target, attrIndex);
  439. if (targetType == ITEM_UI_ELEMENT)
  440. SetUIElementModified(target);
  441. else
  442. SetSceneModified();
  443. }
  444. }
  445. }
  446. class ResetAttributesAction : EditAction
  447. {
  448. int targetType;
  449. uint targetID;
  450. Array<Variant> undoValues;
  451. VariantMap internalVars; // UIElement specific
  452. void Define(Serializable@ target)
  453. {
  454. for (uint i = 0; i < target.numAttributes; ++i)
  455. undoValues.Push(target.attributes[i]);
  456. targetType = GetType(target);
  457. targetID = GetID(target, targetType);
  458. if (targetType == ITEM_UI_ELEMENT)
  459. {
  460. // Special handling for UIElement to preserve the internal variables containing the element's generated ID among others
  461. UIElement@ element = target;
  462. Array<StringHash> keys = element.vars.keys;
  463. for (uint i = 0; i < keys.length; ++i)
  464. {
  465. // If variable name is empty (or unregistered) then it is an internal variable and should be preserved
  466. String name = GetVarName(keys[i]);
  467. if (name.empty)
  468. internalVars[keys[i]] = element.vars[keys[i]];
  469. }
  470. }
  471. }
  472. Serializable@ GetTarget()
  473. {
  474. switch (targetType)
  475. {
  476. case ITEM_NODE:
  477. return editorScene.GetNode(targetID);
  478. case ITEM_COMPONENT:
  479. return editorScene.GetComponent(targetID);
  480. case ITEM_UI_ELEMENT:
  481. return GetUIElementByID(targetID);
  482. }
  483. return null;
  484. }
  485. void SetInternalVars(UIElement@ element)
  486. {
  487. // Revert back internal variables
  488. Array<StringHash> keys = internalVars.keys;
  489. for (uint i = 0; i < keys.length; ++i)
  490. element.vars[keys[i]] = internalVars[keys[i]];
  491. if (element.vars.Contains(FILENAME_VAR))
  492. CenterDialog(element);
  493. }
  494. void Undo()
  495. {
  496. ui.cursor.shape = CS_BUSY;
  497. Serializable@ target = GetTarget();
  498. if (target !is null)
  499. {
  500. for (uint i = 0; i < target.numAttributes; ++i)
  501. {
  502. AttributeInfo info = target.attributeInfos[i];
  503. if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
  504. continue;
  505. target.attributes[i] = undoValues[i];
  506. }
  507. target.ApplyAttributes();
  508. // Apply side effects
  509. for (uint i = 0; i < target.numAttributes; ++i)
  510. PostEditAttribute(target, i);
  511. if (targetType == ITEM_UI_ELEMENT)
  512. SetUIElementModified(target);
  513. else
  514. SetSceneModified();
  515. attributesFullDirty = true;
  516. }
  517. }
  518. void Redo()
  519. {
  520. ui.cursor.shape = CS_BUSY;
  521. Serializable@ target = GetTarget();
  522. if (target !is null)
  523. {
  524. for (uint i = 0; i < target.numAttributes; ++i)
  525. {
  526. AttributeInfo info = target.attributeInfos[i];
  527. if (info.mode & AM_NOEDIT != 0 || info.mode & AM_NODEID != 0 || info.mode & AM_COMPONENTID != 0)
  528. continue;
  529. target.attributes[i] = target.attributeDefaults[i];
  530. }
  531. if (targetType == ITEM_UI_ELEMENT)
  532. SetInternalVars(target);
  533. target.ApplyAttributes();
  534. // Apply side effects
  535. for (uint i = 0; i < target.numAttributes; ++i)
  536. PostEditAttribute(target, i);
  537. if (targetType == ITEM_UI_ELEMENT)
  538. SetUIElementModified(target);
  539. else
  540. SetSceneModified();
  541. attributesFullDirty = true;
  542. }
  543. }
  544. }
  545. class ToggleNodeEnabledAction : EditAction
  546. {
  547. uint nodeID;
  548. bool undoValue;
  549. void Define(Node@ node, bool oldEnabled)
  550. {
  551. nodeID = node.id;
  552. undoValue = oldEnabled;
  553. }
  554. void Undo()
  555. {
  556. Node@ node = editorScene.GetNode(nodeID);
  557. if (node !is null)
  558. node.SetEnabledRecursive(undoValue);
  559. }
  560. void Redo()
  561. {
  562. Node@ node = editorScene.GetNode(nodeID);
  563. if (node !is null)
  564. node.SetEnabledRecursive(!undoValue);
  565. }
  566. }
  567. class Transform
  568. {
  569. Vector3 position;
  570. Quaternion rotation;
  571. Vector3 scale;
  572. void Define(Node@ node)
  573. {
  574. position = node.position;
  575. rotation = node.rotation;
  576. scale = node.scale;
  577. }
  578. void Apply(Node@ node)
  579. {
  580. node.SetTransform(position, rotation, scale);
  581. }
  582. }
  583. class EditNodeTransformAction : EditAction
  584. {
  585. uint nodeID;
  586. Transform undoTransform;
  587. Transform redoTransform;
  588. void Define(Node@ node, const Transform&in oldTransform)
  589. {
  590. nodeID = node.id;
  591. undoTransform = oldTransform;
  592. redoTransform.Define(node);
  593. }
  594. void Undo()
  595. {
  596. Node@ node = editorScene.GetNode(nodeID);
  597. if (node !is null)
  598. {
  599. undoTransform.Apply(node);
  600. UpdateNodeAttributes();
  601. }
  602. }
  603. void Redo()
  604. {
  605. Node@ node = editorScene.GetNode(nodeID);
  606. if (node !is null)
  607. {
  608. redoTransform.Apply(node);
  609. UpdateNodeAttributes();
  610. }
  611. }
  612. }
  613. class CreateUIElementAction : EditAction
  614. {
  615. Variant elementID;
  616. Variant parentID;
  617. XMLFile@ elementData;
  618. XMLFile@ styleFile;
  619. void Define(UIElement@ element)
  620. {
  621. elementID = GetUIElementID(element);
  622. parentID = GetUIElementID(element.parent);
  623. elementData = XMLFile();
  624. XMLElement rootElem = elementData.CreateRoot("element");
  625. element.SaveXML(rootElem);
  626. styleFile = element.defaultStyle;
  627. }
  628. void Undo()
  629. {
  630. UIElement@ parent = GetUIElementByID(parentID);
  631. UIElement@ element = GetUIElementByID(elementID);
  632. if (parent !is null && element !is null)
  633. {
  634. parent.RemoveChild(element);
  635. hierarchyList.ClearSelection();
  636. SetUIElementModified(parent);
  637. }
  638. }
  639. void Redo()
  640. {
  641. UIElement@ parent = GetUIElementByID(parentID);
  642. if (parent !is null)
  643. {
  644. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  645. suppressUIElementChanges = true;
  646. if (parent.LoadChildXML(elementData.root, styleFile) !is null)
  647. {
  648. UIElement@ element = parent.children[parent.numChildren - 1];
  649. UpdateHierarchyItem(element);
  650. FocusUIElement(element);
  651. SetUIElementModified(parent);
  652. }
  653. suppressUIElementChanges = false;
  654. }
  655. }
  656. }
  657. class DeleteUIElementAction : EditAction
  658. {
  659. Variant elementID;
  660. Variant parentID;
  661. XMLFile@ elementData;
  662. XMLFile@ styleFile;
  663. void Define(UIElement@ element)
  664. {
  665. elementID = GetUIElementID(element);
  666. parentID = GetUIElementID(element.parent);
  667. elementData = XMLFile();
  668. XMLElement rootElem = elementData.CreateRoot("element");
  669. element.SaveXML(rootElem);
  670. rootElem.SetUInt("index", element.parent.FindChild(element));
  671. rootElem.SetUInt("listItemIndex", GetListIndex(element));
  672. styleFile = element.defaultStyle;
  673. }
  674. void Undo()
  675. {
  676. UIElement@ parent = GetUIElementByID(parentID);
  677. if (parent !is null)
  678. {
  679. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  680. suppressUIElementChanges = true;
  681. if (parent.LoadChildXML(elementData.root, styleFile) !is null)
  682. {
  683. XMLElement rootElem = elementData.root;
  684. uint index = rootElem.GetUInt("index");
  685. uint listItemIndex = rootElem.GetUInt("listItemIndex");
  686. UIElement@ element = parent.children[index];
  687. UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
  688. UpdateHierarchyItem(listItemIndex, element, parentItem);
  689. FocusUIElement(element);
  690. SetUIElementModified(parent);
  691. }
  692. suppressUIElementChanges = false;
  693. }
  694. }
  695. void Redo()
  696. {
  697. UIElement@ parent = GetUIElementByID(parentID);
  698. UIElement@ element = GetUIElementByID(elementID);
  699. if (parent !is null && element !is null)
  700. {
  701. parent.RemoveChild(element);
  702. hierarchyList.ClearSelection();
  703. SetUIElementModified(parent);
  704. }
  705. }
  706. }
  707. class ReparentUIElementAction : EditAction
  708. {
  709. Variant elementID;
  710. Variant oldParentID;
  711. uint oldChildIndex;
  712. Variant newParentID;
  713. void Define(UIElement@ element, UIElement@ newParent)
  714. {
  715. elementID = GetUIElementID(element);
  716. oldParentID = GetUIElementID(element.parent);
  717. oldChildIndex = element.parent.FindChild(element);
  718. newParentID = GetUIElementID(newParent);
  719. }
  720. void Undo()
  721. {
  722. UIElement@ parent = GetUIElementByID(oldParentID);
  723. UIElement@ element = GetUIElementByID(elementID);
  724. if (parent !is null && element !is null)
  725. {
  726. element.SetParent(parent, oldChildIndex);
  727. SetUIElementModified(parent);
  728. }
  729. }
  730. void Redo()
  731. {
  732. UIElement@ parent = GetUIElementByID(newParentID);
  733. UIElement@ element = GetUIElementByID(elementID);
  734. if (parent !is null && element !is null)
  735. {
  736. element.parent = parent;
  737. SetUIElementModified(parent);
  738. }
  739. }
  740. }
  741. class ReorderUIElementAction : EditAction
  742. {
  743. Variant elementID;
  744. Variant parentID;
  745. uint oldChildIndex;
  746. uint newChildIndex;
  747. void Define(UIElement@ element, uint newIndex)
  748. {
  749. elementID = GetUIElementID(element);
  750. parentID = GetUIElementID(element.parent);
  751. oldChildIndex = element.parent.FindChild(element);
  752. newChildIndex = newIndex;
  753. }
  754. void Undo()
  755. {
  756. UIElement@ parent = GetUIElementByID(parentID);
  757. UIElement@ element = GetUIElementByID(elementID);
  758. if (parent !is null && element !is null)
  759. PerformReorder(parent, element, oldChildIndex);
  760. }
  761. void Redo()
  762. {
  763. UIElement@ parent = GetUIElementByID(parentID);
  764. UIElement@ element = GetUIElementByID(elementID);
  765. if (parent !is null && element !is null)
  766. PerformReorder(parent, element, newChildIndex);
  767. }
  768. }
  769. class ApplyUIElementStyleAction : EditAction
  770. {
  771. Variant elementID;
  772. Variant parentID;
  773. XMLFile@ elementData;
  774. XMLFile@ styleFile;
  775. String elementOldStyle;
  776. String elementNewStyle;
  777. void Define(UIElement@ element, const String&in newStyle)
  778. {
  779. elementID = GetUIElementID(element);
  780. parentID = GetUIElementID(element.parent);
  781. elementData = XMLFile();
  782. XMLElement rootElem = elementData.CreateRoot("element");
  783. element.SaveXML(rootElem);
  784. rootElem.SetUInt("index", element.parent.FindChild(element));
  785. rootElem.SetUInt("listItemIndex", GetListIndex(element));
  786. styleFile = element.defaultStyle;
  787. elementOldStyle = element.style;
  788. elementNewStyle = newStyle;
  789. }
  790. void ApplyStyle(const String&in style)
  791. {
  792. UIElement@ parent = GetUIElementByID(parentID);
  793. UIElement@ element = GetUIElementByID(elementID);
  794. if (parent !is null && element !is null)
  795. {
  796. // Apply the style in the XML data
  797. elementData.root.SetAttribute("style", style);
  798. // Have to update manually because the element ID var is not set yet when the E_ELEMENTADDED event is sent
  799. suppressUIElementChanges = true;
  800. parent.RemoveChild(element);
  801. if (parent.LoadChildXML(elementData.root, styleFile) !is null)
  802. {
  803. XMLElement rootElem = elementData.root;
  804. uint index = rootElem.GetUInt("index");
  805. uint listItemIndex = rootElem.GetUInt("listItemIndex");
  806. UIElement@ elem = parent.children[index];
  807. UIElement@ parentItem = hierarchyList.items[GetListIndex(parent)];
  808. UpdateHierarchyItem(listItemIndex, elem, parentItem);
  809. SetUIElementModified(elem);
  810. hierarchyUpdateSelections.Push(listItemIndex);
  811. }
  812. suppressUIElementChanges = false;
  813. }
  814. }
  815. void Undo()
  816. {
  817. ApplyStyle(elementOldStyle);
  818. }
  819. void Redo()
  820. {
  821. ApplyStyle(elementNewStyle);
  822. }
  823. }
  824. class EditMaterialAction : EditAction
  825. {
  826. XMLFile@ oldState;
  827. XMLFile@ newState;
  828. WeakHandle material;
  829. void Define(Material@ material_, XMLFile@ oldState_)
  830. {
  831. material = material_;
  832. oldState = oldState_;
  833. newState = XMLFile();
  834. XMLElement materialElem = newState.CreateRoot("material");
  835. material_.Save(materialElem);
  836. }
  837. void Undo()
  838. {
  839. Material@ mat = material.Get();
  840. if (mat !is null)
  841. {
  842. mat.Load(oldState.root);
  843. RefreshMaterialEditor();
  844. }
  845. }
  846. void Redo()
  847. {
  848. Material@ mat = material.Get();
  849. if (mat !is null)
  850. {
  851. mat.Load(newState.root);
  852. RefreshMaterialEditor();
  853. }
  854. }
  855. }
  856. class EditParticleEffectAction : EditAction
  857. {
  858. XMLFile@ oldState;
  859. XMLFile@ newState;
  860. WeakHandle particleEffect;
  861. ParticleEmitter@ particleEmitter;
  862. void Define(ParticleEmitter@ particleEmitter_, ParticleEffect@ particleEffect_, XMLFile@ oldState_)
  863. {
  864. particleEmitter = particleEmitter_;
  865. particleEffect = particleEffect_;
  866. oldState = oldState_;
  867. newState = XMLFile();
  868. XMLElement particleElem = newState.CreateRoot("particleeffect");
  869. particleEffect_.Save(particleElem);
  870. }
  871. void Undo()
  872. {
  873. ParticleEffect@ effect = particleEffect.Get();
  874. if (effect !is null)
  875. {
  876. effect.Load(oldState.root);
  877. particleEmitter.ApplyEffect();
  878. RefreshParticleEffectEditor();
  879. }
  880. }
  881. void Redo()
  882. {
  883. ParticleEffect@ effect = particleEffect.Get();
  884. if (effect !is null)
  885. {
  886. effect.Load(newState.root);
  887. particleEmitter.ApplyEffect();
  888. RefreshParticleEffectEditor();
  889. }
  890. }
  891. }
  892. class AssignMaterialAction : EditAction
  893. {
  894. WeakHandle model;
  895. Array<String> oldMaterials;
  896. String newMaterialName;
  897. void Define(StaticModel@ model_, Array<String> oldMaterials_, Material@ newMaterial_)
  898. {
  899. model = model_;
  900. oldMaterials = oldMaterials_;
  901. newMaterialName = newMaterial_.name;
  902. }
  903. void Undo()
  904. {
  905. StaticModel@ staticModel = model.Get();
  906. if (staticModel is null)
  907. return;
  908. for(uint i=0; i<oldMaterials.length; ++i)
  909. {
  910. Material@ material = cache.GetResource("Material", oldMaterials[i]);
  911. staticModel.materials[i] = material;
  912. }
  913. }
  914. void Redo()
  915. {
  916. StaticModel@ staticModel = model.Get();
  917. if (staticModel is null)
  918. return;
  919. Material@ material = cache.GetResource("Material", newMaterialName);
  920. staticModel.material = material;
  921. }
  922. }
  923. class AssignModelAction : EditAction
  924. {
  925. WeakHandle staticModel;
  926. String oldModel;
  927. String newModel;
  928. void Define(StaticModel@ staticModel_, Model@ oldModel_, Model@ newModel_)
  929. {
  930. staticModel = staticModel_;
  931. oldModel = (oldModel_ !is null) ? oldModel_.name : "";
  932. newModel = (newModel_ !is null) ? newModel_.name : "";
  933. }
  934. void Undo()
  935. {
  936. StaticModel@ staticModel_ = staticModel.Get();
  937. if (staticModel_ is null)
  938. return;
  939. Model@ model = cache.GetResource("Model", oldModel);
  940. if (model is null)
  941. return;
  942. staticModel_.model = model;
  943. }
  944. void Redo()
  945. {
  946. StaticModel@ staticModel_ = staticModel.Get();
  947. if (staticModel_ is null)
  948. return;
  949. Model@ model = cache.GetResource("Model", newModel);
  950. if (model is null)
  951. return;
  952. staticModel_.model = model;
  953. }
  954. }
  955. class ModifyTerrainAction : EditAction
  956. {
  957. WeakHandle terrain;
  958. IntVector2 offset;
  959. VectorBuffer compressedOldBuffer;
  960. VectorBuffer compressedNewBuffer;
  961. void Define(Terrain@ terrain_, IntVector2 offset_, Image@ oldImage_, Image@ newImage_)
  962. {
  963. terrain = terrain_;
  964. offset = offset_;
  965. VectorBuffer uncompressedOldBuffer;
  966. VectorBuffer uncompressedNewBuffer;
  967. oldImage_.Save(uncompressedOldBuffer);
  968. newImage_.Save(uncompressedNewBuffer);
  969. compressedOldBuffer = CompressVectorBuffer(uncompressedOldBuffer);
  970. compressedNewBuffer = CompressVectorBuffer(uncompressedNewBuffer);
  971. }
  972. void Undo()
  973. {
  974. Terrain@ terrain_ = terrain.Get();
  975. if (terrain_ is null)
  976. return;
  977. VectorBuffer uncompressedOldBuffer = DecompressVectorBuffer(compressedOldBuffer);
  978. Image oldImage;
  979. oldImage.Load(uncompressedOldBuffer);
  980. for (int y = 0; y < oldImage.height; ++y)
  981. {
  982. for (int x = 0; x < oldImage.width; ++x)
  983. {
  984. terrain_.heightMap.SetPixel(offset.x + x, offset.y + y, oldImage.GetPixel(x, y));
  985. }
  986. }
  987. terrain_.ApplyHeightMap();
  988. }
  989. void Redo()
  990. {
  991. Terrain@ terrain_ = terrain.Get();
  992. if (terrain_ is null)
  993. return;
  994. VectorBuffer uncompressedNewBuffer = DecompressVectorBuffer(compressedNewBuffer);
  995. Image newImage;
  996. newImage.Load(uncompressedNewBuffer);
  997. for (int y = 0; y < newImage.height; ++y)
  998. {
  999. for (int x = 0; x < newImage.width; ++x)
  1000. {
  1001. terrain_.heightMap.SetPixel(offset.x + x, offset.y + y, newImage.GetPixel(x, y));
  1002. }
  1003. }
  1004. terrain_.ApplyHeightMap();
  1005. }
  1006. }