| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- using System;
- using System.Collections.Generic;
- using BansheeEngine;
- namespace BansheeEditor
- {
- /** @addtogroup Inspectors
- * @{
- */
- /// <summary>
- /// Renders an inspector for the <see cref="GUISkin"/> resource.
- /// </summary>
- [CustomInspector(typeof(GUISkin))]
- internal class GUISkinInspector : Inspector
- {
- private GUIDictionaryField<string, GUIElementStyle, GUIElementStyleEntry> valuesField;
- private Dictionary<string, GUIElementStyle> styles = new Dictionary<string, GUIElementStyle>();
- /// <inheritdoc/>
- protected internal override void Initialize()
- {
- LoadResource();
- BuildGUI();
- }
- /// <inheritdoc/>
- protected internal override InspectableState Refresh()
- {
- valuesField.Refresh();
- return InspectableState.NotModified;
- }
- /// <summary>
- /// Recreates all the GUI elements used by this inspector.
- /// </summary>
- private void BuildGUI()
- {
- Layout.Clear();
- styles.Clear();
- GUISkin guiSkin = InspectedObject as GUISkin;
- if (guiSkin == null)
- return;
- string[] styleNames = guiSkin.StyleNames;
- foreach (var styleName in styleNames)
- styles[styleName] = guiSkin.GetStyle(styleName);
- valuesField = GUIDictionaryField<string, GUIElementStyle, GUIElementStyleEntry>.Create
- (new LocEdString("Styles"), styles, Layout);
- valuesField.IsExpanded = Persistent.GetBool("valuesField_Expanded");
- valuesField.OnExpand += x => Persistent.SetBool("valuesField_Expanded", x);
- valuesField.OnChanged += x =>
- {
- if (x != null)
- {
- foreach (var KVP in x)
- {
- if (guiSkin.HasStyle(KVP.Key))
- {
- GUIElementStyle oldValue = guiSkin.GetStyle(KVP.Key);
- if (oldValue != KVP.Value)
- guiSkin.SetStyle(KVP.Key, KVP.Value);
- }
- else
- guiSkin.SetStyle(KVP.Key, KVP.Value);
- }
- string[] oldStyleNames = guiSkin.StyleNames;
- foreach (var styleName in oldStyleNames)
- {
- if (!x.ContainsKey(styleName))
- guiSkin.RemoveStyle(styleName);
- }
- styles = x;
- }
- else
- {
- foreach (var KVP in styles)
- guiSkin.RemoveStyle(KVP.Key);
- styles.Clear();
- }
- EditorApplication.SetDirty(guiSkin);
- };
- valuesField.OnValueChanged += x =>
- {
- guiSkin.SetStyle(x, styles[x]);
- EditorApplication.SetDirty(guiSkin);
- };
- valuesField.OnValueRemoved += x =>
- {
- guiSkin.RemoveStyle(x);
- EditorApplication.SetDirty(guiSkin);
- };
- Layout.AddSpace(10);
- }
- /// <summary>
- /// Row element used for displaying GUI for GUI element style dictionary elements.
- /// </summary>
- private class GUIElementStyleEntry : GUIDictionaryFieldRow
- {
- private GUITextField keyField;
- private GUIElementStyleGUI valueField;
- /// <inheritdoc/>
- protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
- {
- GUILayoutX titleLayout = layout.AddLayoutX();
- keyField = new GUITextField(new LocEdString("Name"));
- titleLayout.AddElement(keyField);
- keyField.OnChanged += SetKey;
- return titleLayout;
- }
- /// <inheritdoc/>
- protected override void CreateValueGUI(GUILayoutY layout)
- {
- if(valueField == null)
- valueField = new GUIElementStyleGUI();
- valueField.BuildGUI(layout, Depth);
- }
- /// <inheritdoc/>
- protected override void OnEditModeChanged(bool editMode)
- {
- keyField.Disabled = !editMode;
- }
- /// <inheritdoc/>
- internal protected override InspectableState Refresh()
- {
- keyField.Value = GetKey<string>();
- return valueField.Refresh(GetValue<GUIElementStyle>());
- }
- }
- /// <summary>
- /// Creates GUI elements for editing/displaying <see cref="GUIElementStyle"/>
- /// </summary>
- private class GUIElementStyleGUI
- {
- private const int IndentAmount = 5;
- private GUIResourceField fontField;
- private GUIIntField fontSizeField;
- private GUIEnumField horzAlignField;
- private GUIEnumField vertAlignField;
- private GUIEnumField imagePositionField;
- private GUIToggleField wordWrapField;
- private GUIElementStateStyleGUI normalGUI;
- private GUIElementStateStyleGUI hoverGUI;
- private GUIElementStateStyleGUI activeGUI;
- private GUIElementStateStyleGUI focusedGUI;
- private GUIElementStateStyleGUI normalOnGUI;
- private GUIElementStateStyleGUI hoverOnGUI;
- private GUIElementStateStyleGUI activeOnGUI;
- private GUIElementStateStyleGUI focusedOnGUI;
- private RectOffsetGUI borderGUI;
- private RectOffsetGUI marginsGUI;
- private RectOffsetGUI contentOffsetGUI;
- private GUIToggleField fixedWidthField;
- private GUIIntField widthField;
- private GUIIntField minWidthField;
- private GUIIntField maxWidthField;
- private GUIToggleField fixedHeightField;
- private GUIIntField heightField;
- private GUIIntField minHeightField;
- private GUIIntField maxHeightField;
- private GUIElementStyle style;
- private bool isExpanded;
- private InspectableState modifiedState;
- /// <summary>
- /// Creates a new GUI element style GUI.
- /// </summary>
- public GUIElementStyleGUI()
- {
- normalGUI = new GUIElementStateStyleGUI();
- hoverGUI = new GUIElementStateStyleGUI();
- activeGUI = new GUIElementStateStyleGUI();
- focusedGUI = new GUIElementStateStyleGUI();
- normalOnGUI = new GUIElementStateStyleGUI();
- hoverOnGUI = new GUIElementStateStyleGUI();
- activeOnGUI = new GUIElementStateStyleGUI();
- focusedOnGUI = new GUIElementStateStyleGUI();
- }
- /// <summary>
- /// Builds GUI for the specified GUI element style.
- /// </summary>
- /// <param name="layout">Layout to append the GUI elements to.</param>
- /// <param name="depth">Determines the depth at which the element is rendered.</param>
- public void BuildGUI(GUILayout layout, int depth)
- {
- short backgroundDepth = (short)(Inspector.START_BACKGROUND_DEPTH - depth - 1);
- string bgPanelStyle = depth % 2 == 0
- ? EditorStylesInternal.InspectorContentBgAlternate
- : EditorStylesInternal.InspectorContentBg;
- GUIToggle foldout = new GUIToggle(new LocEdString("Style"), EditorStyles.Foldout);
- foldout.AcceptsKeyFocus = false;
- GUITexture inspectorContentBg = new GUITexture(null, bgPanelStyle);
- layout.AddElement(foldout);
- GUIPanel panel = layout.AddPanel();
- GUIPanel backgroundPanel = panel.AddPanel(backgroundDepth);
-
- backgroundPanel.AddElement(inspectorContentBg);
- GUILayoutX guiIndentLayoutX = panel.AddLayoutX();
- guiIndentLayoutX.AddSpace(IndentAmount);
- GUILayoutY guiIndentLayoutY = guiIndentLayoutX.AddLayoutY();
- guiIndentLayoutY.AddSpace(IndentAmount);
- GUILayoutY contentLayout = guiIndentLayoutY.AddLayoutY();
- guiIndentLayoutY.AddSpace(IndentAmount);
- guiIndentLayoutX.AddSpace(IndentAmount);
- fontField = new GUIResourceField(typeof (Font), new LocEdString("Font"));
- fontSizeField = new GUIIntField(new LocEdString("Font size"));
- horzAlignField = new GUIEnumField(typeof (TextHorzAlign), new LocEdString("Horizontal alignment"));
- vertAlignField = new GUIEnumField(typeof(TextVertAlign), new LocEdString("Vertical alignment"));
- imagePositionField = new GUIEnumField(typeof(GUIImagePosition), new LocEdString("Image position"));
- wordWrapField = new GUIToggleField(new LocEdString("Word wrap"));
- contentLayout.AddElement(fontField);
- contentLayout.AddElement(fontSizeField);
- contentLayout.AddElement(horzAlignField);
- contentLayout.AddElement(vertAlignField);
- contentLayout.AddElement(imagePositionField);
- contentLayout.AddElement(wordWrapField);
- normalGUI.BuildGUI(new LocEdString("Normal"), contentLayout);
- hoverGUI.BuildGUI(new LocEdString("Hover"), contentLayout);
- activeGUI.BuildGUI(new LocEdString("Active"), contentLayout);
- focusedGUI.BuildGUI(new LocEdString("Focused"), contentLayout);
- normalOnGUI.BuildGUI(new LocEdString("NormalOn"), contentLayout);
- hoverOnGUI.BuildGUI(new LocEdString("HoverOn"), contentLayout);
- activeOnGUI.BuildGUI(new LocEdString("ActiveOn"), contentLayout);
- focusedOnGUI.BuildGUI(new LocEdString("FocusedOn"), contentLayout);
- borderGUI = new RectOffsetGUI(new LocEdString("Border"), contentLayout);
- marginsGUI = new RectOffsetGUI(new LocEdString("Margins"), contentLayout);
- contentOffsetGUI = new RectOffsetGUI(new LocEdString("Content offset"), contentLayout);
- fixedWidthField = new GUIToggleField(new LocEdString("Fixed width"));
- widthField = new GUIIntField(new LocEdString("Width"));
- minWidthField = new GUIIntField(new LocEdString("Min. width"));
- maxWidthField = new GUIIntField(new LocEdString("Max. width"));
- fixedHeightField = new GUIToggleField(new LocEdString("Fixed height"));
- heightField = new GUIIntField(new LocEdString("Height"));
- minHeightField = new GUIIntField(new LocEdString("Min. height"));
- maxHeightField = new GUIIntField(new LocEdString("Max. height"));
- contentLayout.AddElement(fixedWidthField);
- contentLayout.AddElement(widthField);
- contentLayout.AddElement(minWidthField);
- contentLayout.AddElement(maxWidthField);
- contentLayout.AddElement(fixedHeightField);
- contentLayout.AddElement(heightField);
- contentLayout.AddElement(minHeightField);
- contentLayout.AddElement(maxHeightField);
- foldout.OnToggled += x =>
- {
- panel.Active = x;
- isExpanded = x;
- };
- fontField.OnChanged += x =>
- {
- Font font = Resources.Load<Font>(x);
- GetStyle().Font = font;
- MarkAsModified();
- ConfirmModify();
- };
- fontSizeField.OnChanged += x => { GetStyle().FontSize = x; MarkAsModified(); };
- fontSizeField.OnFocusLost += ConfirmModify;
- fontSizeField.OnConfirmed += ConfirmModify;
- horzAlignField.OnSelectionChanged += x =>
- {
- GetStyle().TextHorzAlign = (TextHorzAlign)x;
- MarkAsModified();
- ConfirmModify();
- };
- vertAlignField.OnSelectionChanged += x =>
- {
- GetStyle().TextVertAlign = (TextVertAlign)x;
- MarkAsModified();
- ConfirmModify();
- };
- imagePositionField.OnSelectionChanged += x =>
- {
- GetStyle().ImagePosition = (GUIImagePosition)x;
- MarkAsModified();
- ConfirmModify();
- };
- wordWrapField.OnChanged += x => { GetStyle().WordWrap = x; MarkAsModified(); ConfirmModify(); };
- normalGUI.OnChanged += x => { GetStyle().Normal = x; MarkAsModified(); ConfirmModify(); };
- hoverGUI.OnChanged += x => { GetStyle().Hover = x; MarkAsModified(); ConfirmModify(); };
- activeGUI.OnChanged += x => { GetStyle().Active = x; MarkAsModified(); ConfirmModify(); };
- focusedGUI.OnChanged += x => { GetStyle().Focused = x; MarkAsModified(); ConfirmModify(); };
- normalOnGUI.OnChanged += x => { GetStyle().NormalOn = x; MarkAsModified(); ConfirmModify(); };
- hoverOnGUI.OnChanged += x => { GetStyle().HoverOn = x; MarkAsModified(); ConfirmModify(); };
- activeOnGUI.OnChanged += x => { GetStyle().ActiveOn = x; MarkAsModified(); ConfirmModify(); };
- focusedOnGUI.OnChanged += x => { GetStyle().FocusedOn = x; MarkAsModified(); ConfirmModify(); };
- borderGUI.OnChanged += x => { GetStyle().Border = x; MarkAsModified(); };
- marginsGUI.OnChanged += x => { GetStyle().Margins = x; MarkAsModified(); };
- contentOffsetGUI.OnChanged += x => { GetStyle().ContentOffset = x; MarkAsModified(); };
- borderGUI.OnConfirmed += ConfirmModify;
- marginsGUI.OnConfirmed += ConfirmModify;
- contentOffsetGUI.OnConfirmed += ConfirmModify;
- fixedWidthField.OnChanged += x => { GetStyle().FixedWidth = x; MarkAsModified(); ConfirmModify(); };
- widthField.OnChanged += x => GetStyle().Width = x;
- widthField.OnFocusLost += ConfirmModify;
- widthField.OnConfirmed += ConfirmModify;
- minWidthField.OnChanged += x => GetStyle().MinWidth = x;
- minWidthField.OnFocusLost += ConfirmModify;
- minWidthField.OnConfirmed += ConfirmModify;
- maxWidthField.OnChanged += x => GetStyle().MaxWidth = x;
- maxWidthField.OnFocusLost += ConfirmModify;
- maxWidthField.OnConfirmed += ConfirmModify;
- fixedHeightField.OnChanged += x => { GetStyle().FixedHeight = x; MarkAsModified(); ConfirmModify(); };
- heightField.OnChanged += x => GetStyle().Height = x;
- heightField.OnFocusLost += ConfirmModify;
- heightField.OnConfirmed += ConfirmModify;
- minHeightField.OnChanged += x => GetStyle().MinHeight = x;
- minHeightField.OnFocusLost += ConfirmModify;
- minHeightField.OnConfirmed += ConfirmModify;
- maxHeightField.OnChanged += x => GetStyle().MaxHeight = x;
- maxHeightField.OnFocusLost += ConfirmModify;
- maxHeightField.OnConfirmed += ConfirmModify;
- foldout.Value = isExpanded;
- panel.Active = isExpanded;
- }
- /// <summary>
- /// Updates all GUI elements from the style if style changes.
- /// </summary>
- /// <param name="style">Style to display in the GUI.</param>
- /// <returns>State representing was anything modified between two last calls to <see cref="Refresh"/>.</returns>
- public InspectableState Refresh(GUIElementStyle style)
- {
- this.style = style;
- InspectableState oldModifiedState = modifiedState;
- if (modifiedState.HasFlag(InspectableState.Modified))
- modifiedState = InspectableState.NotModified;
- if (style == null)
- return oldModifiedState;
- fontField.Value = style.Font;
- fontSizeField.Value = style.FontSize;
- horzAlignField.Value = (ulong)style.TextHorzAlign;
- vertAlignField.Value = (ulong)style.TextVertAlign;
- imagePositionField.Value = (ulong)style.ImagePosition;
- wordWrapField.Value = style.WordWrap;
- normalGUI.Refresh(style.Normal);
- hoverGUI.Refresh(style.Hover);
- activeGUI.Refresh(style.Active);
- focusedGUI.Refresh(style.Focused);
- normalOnGUI.Refresh(style.NormalOn);
- hoverOnGUI.Refresh(style.HoverOn);
- activeOnGUI.Refresh(style.ActiveOn);
- focusedOnGUI.Refresh(style.FocusedOn);
- borderGUI.Refresh(style.Border);
- marginsGUI.Refresh(style.Margins);
- contentOffsetGUI.Refresh(style.ContentOffset);
- fixedWidthField.Value = style.FixedWidth;
- widthField.Value = style.Width;
- minWidthField.Value = style.MinWidth;
- maxWidthField.Value = style.MaxWidth;
- fixedHeightField.Value = style.FixedHeight;
- heightField.Value = style.Height;
- minHeightField.Value = style.MinHeight;
- maxHeightField.Value = style.MaxHeight;
- widthField.Active = style.FixedWidth;
- minWidthField.Active = !style.FixedWidth;
- maxWidthField.Active = !style.FixedWidth;
- heightField.Active = style.FixedHeight;
- minHeightField.Active = !style.FixedHeight;
- maxHeightField.Active = !style.FixedHeight;
- return oldModifiedState;
- }
- /// <summary>
- /// Returns the style displayed in the GUI.
- /// </summary>
- /// <returns>Style displayed in the GUI.</returns>
- private GUIElementStyle GetStyle()
- {
- return style;
- }
- /// <summary>
- /// Marks the contents of the style as modified.
- /// </summary>
- private void MarkAsModified()
- {
- modifiedState |= InspectableState.ModifyInProgress;
- }
- /// <summary>
- /// Confirms any queued modifications, signaling parent element.
- /// </summary>
- private void ConfirmModify()
- {
- if (modifiedState.HasFlag(InspectableState.ModifyInProgress))
- modifiedState |= InspectableState.Modified;
- }
- /// <summary>
- /// Creates GUI elements for editing/displaying <see cref="GUIElementStateStyle"/>
- /// </summary>
- private class GUIElementStateStyleGUI
- {
- private GUIElementStateStyle state;
- private GUIToggle foldout;
- private GUIResourceField textureField;
- private GUIColorField textColorField;
- private bool isExpanded;
- /// <summary>
- /// Triggered when some value in the style state changes.
- /// </summary>
- public Action<GUIElementStateStyle> OnChanged;
- /// <summary>
- /// Creates a new GUI element state style GUI.
- /// </summary>
- public GUIElementStateStyleGUI()
- { }
- /// <summary>
- /// Builds the GUI for the specified state style.
- /// </summary>
- /// <param name="title">Text to display on the title bar.</param>
- /// <param name="layout">Layout to append the GUI elements to.</param>
- public void BuildGUI(LocString title, GUILayout layout)
- {
- foldout = new GUIToggle(title, EditorStyles.Foldout);
- textureField = new GUIResourceField(typeof(SpriteTexture), new LocEdString("Texture"));
- textColorField = new GUIColorField(new LocEdString("Text color"));
- foldout.AcceptsKeyFocus = false;
- foldout.OnToggled += x =>
- {
- textureField.Active = x;
- textColorField.Active = x;
- isExpanded = x;
- };
- textureField.OnChanged += x =>
- {
- SpriteTexture texture = Resources.Load<SpriteTexture>(x);
- state.Texture = texture;
- if (OnChanged != null)
- OnChanged(state);
- };
- textColorField.OnChanged += x =>
- {
- state.TextColor = x;
- if (OnChanged != null)
- OnChanged(state);
- };
- layout.AddElement(foldout);
- layout.AddElement(textureField);
- layout.AddElement(textColorField);
- foldout.Value = isExpanded;
- textureField.Active = isExpanded;
- textColorField.Active = isExpanded;
- }
- /// <summary>
- /// Updates all GUI elements from the current state values.
- /// </summary>
- /// <param name="state">State object to display in the GUI.</param>
- public void Refresh(GUIElementStateStyle state)
- {
- this.state = state;
- textureField.Value = state.Texture;
- textColorField.Value = state.TextColor;
- }
- }
- /// <summary>
- /// Creates GUI elements for editing/displaying <see cref="RectOffset"/>
- /// </summary>
- private class RectOffsetGUI
- {
- private RectOffset offset;
- private GUIIntField offsetLeftField;
- private GUIIntField offsetRightField;
- private GUIIntField offsetTopField;
- private GUIIntField offsetBottomField;
- /// <summary>
- /// Triggered when some value in the offset rectangle changes.
- /// </summary>
- public Action<RectOffset> OnChanged;
- /// <summary>
- /// Triggered when the user confirms input.
- /// </summary>
- public Action OnConfirmed;
- /// <summary>
- /// Creates a new rectangle offset GUI.
- /// </summary>
- /// <param name="title">Text to display on the title bar.</param>
- /// <param name="layout">Layout to append the GUI elements to.</param>
- public RectOffsetGUI(LocString title, GUILayout layout)
- {
- GUILayoutX rectLayout = layout.AddLayoutX();
- rectLayout.AddElement(new GUILabel(title, GUIOption.FixedWidth(100)));
- GUILayoutY rectContentLayout = rectLayout.AddLayoutY();
- GUILayoutX rectTopRow = rectContentLayout.AddLayoutX();
- GUILayoutX rectBotRow = rectContentLayout.AddLayoutX();
- offsetLeftField = new GUIIntField(new LocEdString("Left"), 40);
- offsetRightField = new GUIIntField(new LocEdString("Right"), 40);
- offsetTopField = new GUIIntField(new LocEdString("Top"), 40);
- offsetBottomField = new GUIIntField(new LocEdString("Bottom"), 40);
- rectTopRow.AddElement(offsetLeftField);
- rectTopRow.AddElement(offsetRightField);
- rectBotRow.AddElement(offsetTopField);
- rectBotRow.AddElement(offsetBottomField);
- offsetLeftField.OnChanged += x =>
- {
- offset.left = x;
- if(OnChanged != null)
- OnChanged(offset);
- };
- offsetRightField.OnChanged += x =>
- {
- offset.right = x;
- if (OnChanged != null)
- OnChanged(offset);
- };
- offsetTopField.OnChanged += x =>
- {
- offset.top = x;
- if (OnChanged != null)
- OnChanged(offset);
- };
- offsetBottomField.OnChanged += x =>
- {
- offset.bottom = x;
- if (OnChanged != null)
- OnChanged(offset);
- };
- Action DoOnConfirmed = () =>
- {
- if (OnConfirmed != null)
- OnConfirmed();
- };
- offsetLeftField.OnConfirmed += DoOnConfirmed;
- offsetLeftField.OnFocusLost += DoOnConfirmed;
- offsetRightField.OnConfirmed += DoOnConfirmed;
- offsetRightField.OnFocusLost += DoOnConfirmed;
- offsetTopField.OnConfirmed += DoOnConfirmed;
- offsetTopField.OnFocusLost += DoOnConfirmed;
- offsetBottomField.OnConfirmed += DoOnConfirmed;
- offsetBottomField.OnFocusLost += DoOnConfirmed;
- }
- /// <summary>
- /// Updates all GUI elements from the offset.
- /// </summary>
- /// <param name="offset">Offset to update the GUI to.</param>
- public void Refresh(RectOffset offset)
- {
- this.offset = offset;
- offsetLeftField.Value = offset.left;
- offsetRightField.Value = offset.right;
- offsetTopField.Value = offset.top;
- offsetBottomField.Value = offset.bottom;
- }
- }
- }
- }
- /** @} */
- }
|