GUISkinInspector.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Collections.Generic;
  5. using BansheeEngine;
  6. namespace BansheeEditor
  7. {
  8. /** @addtogroup Inspectors
  9. * @{
  10. */
  11. /// <summary>
  12. /// Renders an inspector for the <see cref="GUISkin"/> resource.
  13. /// </summary>
  14. [CustomInspector(typeof(GUISkin))]
  15. internal class GUISkinInspector : Inspector
  16. {
  17. private GUIDictionaryField<string, GUIElementStyle, GUIElementStyleEntry> valuesField;
  18. private Dictionary<string, GUIElementStyle> styles = new Dictionary<string, GUIElementStyle>();
  19. /// <inheritdoc/>
  20. protected internal override void Initialize()
  21. {
  22. BuildGUI();
  23. }
  24. /// <inheritdoc/>
  25. protected internal override InspectableState Refresh()
  26. {
  27. valuesField.Refresh();
  28. return InspectableState.NotModified;
  29. }
  30. /// <summary>
  31. /// Recreates all the GUI elements used by this inspector.
  32. /// </summary>
  33. private void BuildGUI()
  34. {
  35. Layout.Clear();
  36. styles.Clear();
  37. GUISkin guiSkin = InspectedObject as GUISkin;
  38. if (guiSkin == null)
  39. return;
  40. string[] styleNames = guiSkin.StyleNames;
  41. foreach (var styleName in styleNames)
  42. styles[styleName] = guiSkin.GetStyle(styleName);
  43. valuesField = GUIDictionaryField<string, GUIElementStyle, GUIElementStyleEntry>.Create
  44. (new LocEdString("Styles"), styles, Layout);
  45. valuesField.IsExpanded = Persistent.GetBool("valuesField_Expanded");
  46. valuesField.OnExpand += x => Persistent.SetBool("valuesField_Expanded", x);
  47. valuesField.OnChanged += x =>
  48. {
  49. if (x != null)
  50. {
  51. foreach (var KVP in x)
  52. {
  53. if (guiSkin.HasStyle(KVP.Key))
  54. {
  55. GUIElementStyle oldValue = guiSkin.GetStyle(KVP.Key);
  56. if (oldValue != KVP.Value)
  57. guiSkin.SetStyle(KVP.Key, KVP.Value);
  58. }
  59. else
  60. guiSkin.SetStyle(KVP.Key, KVP.Value);
  61. }
  62. string[] oldStyleNames = guiSkin.StyleNames;
  63. foreach (var styleName in oldStyleNames)
  64. {
  65. if (!x.ContainsKey(styleName))
  66. guiSkin.RemoveStyle(styleName);
  67. }
  68. styles = x;
  69. }
  70. else
  71. {
  72. foreach (var KVP in styles)
  73. guiSkin.RemoveStyle(KVP.Key);
  74. styles.Clear();
  75. }
  76. EditorApplication.SetDirty(guiSkin);
  77. };
  78. valuesField.OnValueChanged += x =>
  79. {
  80. guiSkin.SetStyle(x, styles[x]);
  81. EditorApplication.SetDirty(guiSkin);
  82. };
  83. valuesField.OnValueRemoved += x =>
  84. {
  85. guiSkin.RemoveStyle(x);
  86. EditorApplication.SetDirty(guiSkin);
  87. };
  88. Layout.AddSpace(10);
  89. }
  90. /// <summary>
  91. /// Row element used for displaying GUI for GUI element style dictionary elements.
  92. /// </summary>
  93. private class GUIElementStyleEntry : GUIDictionaryFieldRow
  94. {
  95. private GUITextField keyField;
  96. private GUIElementStyleGUI valueField;
  97. /// <inheritdoc/>
  98. protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
  99. {
  100. GUILayoutX titleLayout = layout.AddLayoutX();
  101. keyField = new GUITextField(new LocEdString("Name"));
  102. titleLayout.AddElement(keyField);
  103. keyField.OnChanged += SetKey;
  104. return titleLayout;
  105. }
  106. /// <inheritdoc/>
  107. protected override void CreateValueGUI(GUILayoutY layout)
  108. {
  109. if(valueField == null)
  110. valueField = new GUIElementStyleGUI();
  111. valueField.BuildGUI(layout, Depth);
  112. }
  113. /// <inheritdoc/>
  114. protected override void OnEditModeChanged(bool editMode)
  115. {
  116. keyField.Disabled = !editMode;
  117. }
  118. /// <inheritdoc/>
  119. internal protected override InspectableState Refresh()
  120. {
  121. keyField.Value = GetKey<string>();
  122. return valueField.Refresh(GetValue<GUIElementStyle>());
  123. }
  124. }
  125. /// <summary>
  126. /// Creates GUI elements for editing/displaying <see cref="GUIElementStyle"/>
  127. /// </summary>
  128. private class GUIElementStyleGUI
  129. {
  130. private const int IndentAmount = 5;
  131. private GUIResourceField fontField;
  132. private GUIIntField fontSizeField;
  133. private GUIEnumField horzAlignField;
  134. private GUIEnumField vertAlignField;
  135. private GUIEnumField imagePositionField;
  136. private GUIToggleField wordWrapField;
  137. private GUIElementStateStyleGUI normalGUI;
  138. private GUIElementStateStyleGUI hoverGUI;
  139. private GUIElementStateStyleGUI activeGUI;
  140. private GUIElementStateStyleGUI focusedGUI;
  141. private GUIElementStateStyleGUI normalOnGUI;
  142. private GUIElementStateStyleGUI hoverOnGUI;
  143. private GUIElementStateStyleGUI activeOnGUI;
  144. private GUIElementStateStyleGUI focusedOnGUI;
  145. private RectOffsetGUI borderGUI;
  146. private RectOffsetGUI marginsGUI;
  147. private RectOffsetGUI contentOffsetGUI;
  148. private GUIToggleField fixedWidthField;
  149. private GUIIntField widthField;
  150. private GUIIntField minWidthField;
  151. private GUIIntField maxWidthField;
  152. private GUIToggleField fixedHeightField;
  153. private GUIIntField heightField;
  154. private GUIIntField minHeightField;
  155. private GUIIntField maxHeightField;
  156. private GUIElementStyle style;
  157. private bool isExpanded;
  158. private InspectableState modifiedState;
  159. /// <summary>
  160. /// Creates a new GUI element style GUI.
  161. /// </summary>
  162. public GUIElementStyleGUI()
  163. {
  164. normalGUI = new GUIElementStateStyleGUI();
  165. hoverGUI = new GUIElementStateStyleGUI();
  166. activeGUI = new GUIElementStateStyleGUI();
  167. focusedGUI = new GUIElementStateStyleGUI();
  168. normalOnGUI = new GUIElementStateStyleGUI();
  169. hoverOnGUI = new GUIElementStateStyleGUI();
  170. activeOnGUI = new GUIElementStateStyleGUI();
  171. focusedOnGUI = new GUIElementStateStyleGUI();
  172. }
  173. /// <summary>
  174. /// Builds GUI for the specified GUI element style.
  175. /// </summary>
  176. /// <param name="layout">Layout to append the GUI elements to.</param>
  177. /// <param name="depth">Determines the depth at which the element is rendered.</param>
  178. public void BuildGUI(GUILayout layout, int depth)
  179. {
  180. short backgroundDepth = (short)(Inspector.START_BACKGROUND_DEPTH - depth - 1);
  181. string bgPanelStyle = depth % 2 == 0
  182. ? EditorStylesInternal.InspectorContentBgAlternate
  183. : EditorStylesInternal.InspectorContentBg;
  184. GUIToggle foldout = new GUIToggle(new LocEdString("Style"), EditorStyles.Foldout);
  185. GUITexture inspectorContentBg = new GUITexture(null, bgPanelStyle);
  186. layout.AddElement(foldout);
  187. GUIPanel panel = layout.AddPanel();
  188. GUIPanel backgroundPanel = panel.AddPanel(backgroundDepth);
  189. backgroundPanel.AddElement(inspectorContentBg);
  190. GUILayoutX guiIndentLayoutX = panel.AddLayoutX();
  191. guiIndentLayoutX.AddSpace(IndentAmount);
  192. GUILayoutY guiIndentLayoutY = guiIndentLayoutX.AddLayoutY();
  193. guiIndentLayoutY.AddSpace(IndentAmount);
  194. GUILayoutY contentLayout = guiIndentLayoutY.AddLayoutY();
  195. guiIndentLayoutY.AddSpace(IndentAmount);
  196. guiIndentLayoutX.AddSpace(IndentAmount);
  197. fontField = new GUIResourceField(typeof (Font), new LocEdString("Font"));
  198. fontSizeField = new GUIIntField(new LocEdString("Font size"));
  199. horzAlignField = new GUIEnumField(typeof (TextHorzAlign), new LocEdString("Horizontal alignment"));
  200. vertAlignField = new GUIEnumField(typeof(TextVertAlign), new LocEdString("Vertical alignment"));
  201. imagePositionField = new GUIEnumField(typeof(GUIImagePosition), new LocEdString("Image position"));
  202. wordWrapField = new GUIToggleField(new LocEdString("Word wrap"));
  203. contentLayout.AddElement(fontField);
  204. contentLayout.AddElement(fontSizeField);
  205. contentLayout.AddElement(horzAlignField);
  206. contentLayout.AddElement(vertAlignField);
  207. contentLayout.AddElement(imagePositionField);
  208. contentLayout.AddElement(wordWrapField);
  209. normalGUI.BuildGUI(new LocEdString("Normal"), contentLayout);
  210. hoverGUI.BuildGUI(new LocEdString("Hover"), contentLayout);
  211. activeGUI.BuildGUI(new LocEdString("Active"), contentLayout);
  212. focusedGUI.BuildGUI(new LocEdString("Focused"), contentLayout);
  213. normalOnGUI.BuildGUI(new LocEdString("NormalOn"), contentLayout);
  214. hoverOnGUI.BuildGUI(new LocEdString("HoverOn"), contentLayout);
  215. activeOnGUI.BuildGUI(new LocEdString("ActiveOn"), contentLayout);
  216. focusedOnGUI.BuildGUI(new LocEdString("FocusedOn"), contentLayout);
  217. borderGUI = new RectOffsetGUI(new LocEdString("Border"), contentLayout);
  218. marginsGUI = new RectOffsetGUI(new LocEdString("Margins"), contentLayout);
  219. contentOffsetGUI = new RectOffsetGUI(new LocEdString("Content offset"), contentLayout);
  220. fixedWidthField = new GUIToggleField(new LocEdString("Fixed width"));
  221. widthField = new GUIIntField(new LocEdString("Width"));
  222. minWidthField = new GUIIntField(new LocEdString("Min. width"));
  223. maxWidthField = new GUIIntField(new LocEdString("Max. width"));
  224. fixedHeightField = new GUIToggleField(new LocEdString("Fixed height"));
  225. heightField = new GUIIntField(new LocEdString("Height"));
  226. minHeightField = new GUIIntField(new LocEdString("Min. height"));
  227. maxHeightField = new GUIIntField(new LocEdString("Max. height"));
  228. contentLayout.AddElement(fixedWidthField);
  229. contentLayout.AddElement(widthField);
  230. contentLayout.AddElement(minWidthField);
  231. contentLayout.AddElement(maxWidthField);
  232. contentLayout.AddElement(fixedHeightField);
  233. contentLayout.AddElement(heightField);
  234. contentLayout.AddElement(minHeightField);
  235. contentLayout.AddElement(maxHeightField);
  236. foldout.OnToggled += x =>
  237. {
  238. panel.Active = x;
  239. isExpanded = x;
  240. };
  241. fontField.OnChanged += x =>
  242. {
  243. Font font = Resources.Load<Font>(x);
  244. GetStyle().Font = font;
  245. MarkAsModified();
  246. ConfirmModify();
  247. };
  248. fontSizeField.OnChanged += x => { GetStyle().FontSize = x; MarkAsModified(); };
  249. fontSizeField.OnFocusLost += ConfirmModify;
  250. fontSizeField.OnConfirmed += ConfirmModify;
  251. horzAlignField.OnSelectionChanged += x =>
  252. {
  253. GetStyle().TextHorzAlign = (TextHorzAlign)x;
  254. MarkAsModified();
  255. ConfirmModify();
  256. };
  257. vertAlignField.OnSelectionChanged += x =>
  258. {
  259. GetStyle().TextVertAlign = (TextVertAlign)x;
  260. MarkAsModified();
  261. ConfirmModify();
  262. };
  263. imagePositionField.OnSelectionChanged += x =>
  264. {
  265. GetStyle().ImagePosition = (GUIImagePosition)x;
  266. MarkAsModified();
  267. ConfirmModify();
  268. };
  269. wordWrapField.OnChanged += x => { GetStyle().WordWrap = x; MarkAsModified(); ConfirmModify(); };
  270. normalGUI.OnChanged += x => { GetStyle().Normal = x; MarkAsModified(); ConfirmModify(); };
  271. hoverGUI.OnChanged += x => { GetStyle().Hover = x; MarkAsModified(); ConfirmModify(); };
  272. activeGUI.OnChanged += x => { GetStyle().Active = x; MarkAsModified(); ConfirmModify(); };
  273. focusedGUI.OnChanged += x => { GetStyle().Focused = x; MarkAsModified(); ConfirmModify(); };
  274. normalOnGUI.OnChanged += x => { GetStyle().NormalOn = x; MarkAsModified(); ConfirmModify(); };
  275. hoverOnGUI.OnChanged += x => { GetStyle().HoverOn = x; MarkAsModified(); ConfirmModify(); };
  276. activeOnGUI.OnChanged += x => { GetStyle().ActiveOn = x; MarkAsModified(); ConfirmModify(); };
  277. focusedOnGUI.OnChanged += x => { GetStyle().FocusedOn = x; MarkAsModified(); ConfirmModify(); };
  278. borderGUI.OnChanged += x => { GetStyle().Border = x; MarkAsModified(); };
  279. marginsGUI.OnChanged += x => { GetStyle().Margins = x; MarkAsModified(); };
  280. contentOffsetGUI.OnChanged += x => { GetStyle().ContentOffset = x; MarkAsModified(); };
  281. borderGUI.OnConfirmed += ConfirmModify;
  282. marginsGUI.OnConfirmed += ConfirmModify;
  283. contentOffsetGUI.OnConfirmed += ConfirmModify;
  284. fixedWidthField.OnChanged += x => { GetStyle().FixedWidth = x; MarkAsModified(); ConfirmModify(); };
  285. widthField.OnChanged += x => GetStyle().Width = x;
  286. widthField.OnFocusLost += ConfirmModify;
  287. widthField.OnConfirmed += ConfirmModify;
  288. minWidthField.OnChanged += x => GetStyle().MinWidth = x;
  289. minWidthField.OnFocusLost += ConfirmModify;
  290. minWidthField.OnConfirmed += ConfirmModify;
  291. maxWidthField.OnChanged += x => GetStyle().MaxWidth = x;
  292. maxWidthField.OnFocusLost += ConfirmModify;
  293. maxWidthField.OnConfirmed += ConfirmModify;
  294. fixedHeightField.OnChanged += x => { GetStyle().FixedHeight = x; MarkAsModified(); ConfirmModify(); };
  295. heightField.OnChanged += x => GetStyle().Height = x;
  296. heightField.OnFocusLost += ConfirmModify;
  297. heightField.OnConfirmed += ConfirmModify;
  298. minHeightField.OnChanged += x => GetStyle().MinHeight = x;
  299. minHeightField.OnFocusLost += ConfirmModify;
  300. minHeightField.OnConfirmed += ConfirmModify;
  301. maxHeightField.OnChanged += x => GetStyle().MaxHeight = x;
  302. maxHeightField.OnFocusLost += ConfirmModify;
  303. maxHeightField.OnConfirmed += ConfirmModify;
  304. foldout.Value = isExpanded;
  305. panel.Active = isExpanded;
  306. }
  307. /// <summary>
  308. /// Updates all GUI elements from the style if style changes.
  309. /// </summary>
  310. /// <param name="style">Style to display in the GUI.</param>
  311. /// <returns>State representing was anything modified between two last calls to <see cref="Refresh"/>.</returns>
  312. public InspectableState Refresh(GUIElementStyle style)
  313. {
  314. this.style = style;
  315. InspectableState oldModifiedState = modifiedState;
  316. if (modifiedState.HasFlag(InspectableState.Modified))
  317. modifiedState = InspectableState.NotModified;
  318. if (style == null)
  319. return oldModifiedState;
  320. fontField.Value = style.Font;
  321. fontSizeField.Value = style.FontSize;
  322. horzAlignField.Value = (ulong)style.TextHorzAlign;
  323. vertAlignField.Value = (ulong)style.TextVertAlign;
  324. imagePositionField.Value = (ulong)style.ImagePosition;
  325. wordWrapField.Value = style.WordWrap;
  326. normalGUI.Refresh(style.Normal);
  327. hoverGUI.Refresh(style.Hover);
  328. activeGUI.Refresh(style.Active);
  329. focusedGUI.Refresh(style.Focused);
  330. normalOnGUI.Refresh(style.NormalOn);
  331. hoverOnGUI.Refresh(style.HoverOn);
  332. activeOnGUI.Refresh(style.ActiveOn);
  333. focusedOnGUI.Refresh(style.FocusedOn);
  334. borderGUI.Refresh(style.Border);
  335. marginsGUI.Refresh(style.Margins);
  336. contentOffsetGUI.Refresh(style.ContentOffset);
  337. fixedWidthField.Value = style.FixedWidth;
  338. widthField.Value = style.Width;
  339. minWidthField.Value = style.MinWidth;
  340. maxWidthField.Value = style.MaxWidth;
  341. fixedHeightField.Value = style.FixedHeight;
  342. heightField.Value = style.Height;
  343. minHeightField.Value = style.MinHeight;
  344. maxHeightField.Value = style.MaxHeight;
  345. widthField.Active = style.FixedWidth;
  346. minWidthField.Active = !style.FixedWidth;
  347. maxWidthField.Active = !style.FixedWidth;
  348. heightField.Active = style.FixedHeight;
  349. minHeightField.Active = !style.FixedHeight;
  350. maxHeightField.Active = !style.FixedHeight;
  351. return oldModifiedState;
  352. }
  353. /// <summary>
  354. /// Returns the style displayed in the GUI.
  355. /// </summary>
  356. /// <returns>Style displayed in the GUI.</returns>
  357. private GUIElementStyle GetStyle()
  358. {
  359. return style;
  360. }
  361. /// <summary>
  362. /// Marks the contents of the style as modified.
  363. /// </summary>
  364. private void MarkAsModified()
  365. {
  366. modifiedState |= InspectableState.ModifyInProgress;
  367. }
  368. /// <summary>
  369. /// Confirms any queued modifications, signaling parent element.
  370. /// </summary>
  371. private void ConfirmModify()
  372. {
  373. if (modifiedState.HasFlag(InspectableState.ModifyInProgress))
  374. modifiedState |= InspectableState.Modified;
  375. }
  376. /// <summary>
  377. /// Creates GUI elements for editing/displaying <see cref="GUIElementStateStyle"/>
  378. /// </summary>
  379. private class GUIElementStateStyleGUI
  380. {
  381. private GUIElementStateStyle state;
  382. private GUIToggle foldout;
  383. private GUIResourceField textureField;
  384. private GUIColorField textColorField;
  385. private bool isExpanded;
  386. /// <summary>
  387. /// Triggered when some value in the style state changes.
  388. /// </summary>
  389. public Action<GUIElementStateStyle> OnChanged;
  390. /// <summary>
  391. /// Creates a new GUI element state style GUI.
  392. /// </summary>
  393. public GUIElementStateStyleGUI()
  394. { }
  395. /// <summary>
  396. /// Builds the GUI for the specified state style.
  397. /// </summary>
  398. /// <param name="title">Text to display on the title bar.</param>
  399. /// <param name="layout">Layout to append the GUI elements to.</param>
  400. public void BuildGUI(LocString title, GUILayout layout)
  401. {
  402. foldout = new GUIToggle(title, EditorStyles.Foldout);
  403. textureField = new GUIResourceField(typeof(SpriteTexture), new LocEdString("Texture"));
  404. textColorField = new GUIColorField(new LocEdString("Text color"));
  405. foldout.OnToggled += x =>
  406. {
  407. textureField.Active = x;
  408. textColorField.Active = x;
  409. isExpanded = x;
  410. };
  411. textureField.OnChanged += x =>
  412. {
  413. SpriteTexture texture = Resources.Load<SpriteTexture>(x);
  414. state.Texture = texture;
  415. if (OnChanged != null)
  416. OnChanged(state);
  417. };
  418. textColorField.OnChanged += x =>
  419. {
  420. state.TextColor = x;
  421. if (OnChanged != null)
  422. OnChanged(state);
  423. };
  424. layout.AddElement(foldout);
  425. layout.AddElement(textureField);
  426. layout.AddElement(textColorField);
  427. foldout.Value = isExpanded;
  428. textureField.Active = isExpanded;
  429. textColorField.Active = isExpanded;
  430. }
  431. /// <summary>
  432. /// Updates all GUI elements from the current state values.
  433. /// </summary>
  434. /// <param name="state">State object to display in the GUI.</param>
  435. public void Refresh(GUIElementStateStyle state)
  436. {
  437. this.state = state;
  438. textureField.Value = state.Texture;
  439. textColorField.Value = state.TextColor;
  440. }
  441. }
  442. /// <summary>
  443. /// Creates GUI elements for editing/displaying <see cref="RectOffset"/>
  444. /// </summary>
  445. private class RectOffsetGUI
  446. {
  447. private RectOffset offset;
  448. private GUIIntField offsetLeftField;
  449. private GUIIntField offsetRightField;
  450. private GUIIntField offsetTopField;
  451. private GUIIntField offsetBottomField;
  452. /// <summary>
  453. /// Triggered when some value in the offset rectangle changes.
  454. /// </summary>
  455. public Action<RectOffset> OnChanged;
  456. /// <summary>
  457. /// Triggered when the user confirms input.
  458. /// </summary>
  459. public Action OnConfirmed;
  460. /// <summary>
  461. /// Creates a new rectangle offset GUI.
  462. /// </summary>
  463. /// <param name="title">Text to display on the title bar.</param>
  464. /// <param name="layout">Layout to append the GUI elements to.</param>
  465. public RectOffsetGUI(LocString title, GUILayout layout)
  466. {
  467. GUILayoutX rectLayout = layout.AddLayoutX();
  468. rectLayout.AddElement(new GUILabel(title, GUIOption.FixedWidth(100)));
  469. GUILayoutY rectContentLayout = rectLayout.AddLayoutY();
  470. GUILayoutX rectTopRow = rectContentLayout.AddLayoutX();
  471. GUILayoutX rectBotRow = rectContentLayout.AddLayoutX();
  472. offsetLeftField = new GUIIntField(new LocEdString("Left"), 40);
  473. offsetRightField = new GUIIntField(new LocEdString("Right"), 40);
  474. offsetTopField = new GUIIntField(new LocEdString("Top"), 40);
  475. offsetBottomField = new GUIIntField(new LocEdString("Bottom"), 40);
  476. rectTopRow.AddElement(offsetLeftField);
  477. rectTopRow.AddElement(offsetRightField);
  478. rectBotRow.AddElement(offsetTopField);
  479. rectBotRow.AddElement(offsetBottomField);
  480. offsetLeftField.OnChanged += x =>
  481. {
  482. offset.left = x;
  483. if(OnChanged != null)
  484. OnChanged(offset);
  485. };
  486. offsetRightField.OnChanged += x =>
  487. {
  488. offset.right = x;
  489. if (OnChanged != null)
  490. OnChanged(offset);
  491. };
  492. offsetTopField.OnChanged += x =>
  493. {
  494. offset.top = x;
  495. if (OnChanged != null)
  496. OnChanged(offset);
  497. };
  498. offsetBottomField.OnChanged += x =>
  499. {
  500. offset.bottom = x;
  501. if (OnChanged != null)
  502. OnChanged(offset);
  503. };
  504. Action DoOnConfirmed = () =>
  505. {
  506. if (OnConfirmed != null)
  507. OnConfirmed();
  508. };
  509. offsetLeftField.OnConfirmed += DoOnConfirmed;
  510. offsetLeftField.OnFocusLost += DoOnConfirmed;
  511. offsetRightField.OnConfirmed += DoOnConfirmed;
  512. offsetRightField.OnFocusLost += DoOnConfirmed;
  513. offsetTopField.OnConfirmed += DoOnConfirmed;
  514. offsetTopField.OnFocusLost += DoOnConfirmed;
  515. offsetBottomField.OnConfirmed += DoOnConfirmed;
  516. offsetBottomField.OnFocusLost += DoOnConfirmed;
  517. }
  518. /// <summary>
  519. /// Updates all GUI elements from the offset.
  520. /// </summary>
  521. /// <param name="offset">Offset to update the GUI to.</param>
  522. public void Refresh(RectOffset offset)
  523. {
  524. this.offset = offset;
  525. offsetLeftField.Value = offset.left;
  526. offsetRightField.Value = offset.right;
  527. offsetTopField.Value = offset.top;
  528. offsetBottomField.Value = offset.bottom;
  529. }
  530. }
  531. }
  532. }
  533. /** @} */
  534. }