GUISkinInspector.cs 21 KB

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