GUISkinInspector.cs 26 KB

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