using System; using System.Collections.Generic; using System.Reflection; using Robust.Client.Graphics; using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.ViewVariables.Editors; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; namespace Robust.Client.ViewVariables { /// /// Controls the behavior of a VV window. /// internal abstract class ViewVariablesInstance { public readonly IViewVariablesManagerInternal ViewVariablesManager; protected readonly IResourceCache _resourceCache; protected ViewVariablesInstance(IViewVariablesManagerInternal vvm, IResourceCache resCache) { ViewVariablesManager = vvm; _resourceCache = resCache; } /// /// Initializes this instance to work on a local object. /// /// The window to initialize by adding GUI components. /// The object that is being VV'd public abstract void Initialize(SS14Window window, object obj); /// /// Initializes this instance to work on a remote object. /// This is called when the view variables manager has already made a session to the remote object. /// /// The window to initialize by adding GUI components. /// The data blob sent by the server for this remote object. /// The session connecting to the remote object. public virtual void Initialize(SS14Window window, ViewVariablesBlobMetadata blob, ViewVariablesRemoteSession session) { throw new NotSupportedException(); } /// /// Invoked to "clean up" the instance, such as closing remote sessions. /// public virtual void Close() { } protected internal static IEnumerable LocalPropertyList(object obj, IViewVariablesManagerInternal vvm, IResourceCache resCache) { var styleOther = false; var type = obj.GetType(); var members = new List<(MemberInfo, VVAccess, object value, Action onValueChanged, Type)>(); foreach (var fieldInfo in type.GetAllFields()) { var attr = fieldInfo.GetCustomAttribute(); if (attr == null) { continue; } members.Add((fieldInfo, attr.Access, fieldInfo.GetValue(obj), v => fieldInfo.SetValue(obj, v), fieldInfo.FieldType)); } foreach (var propertyInfo in type.GetAllProperties()) { var attr = propertyInfo.GetCustomAttribute(); if (attr == null) { continue; } if (!propertyInfo.IsBasePropertyDefinition()) { continue; } members.Add((propertyInfo, attr.Access, propertyInfo.GetValue(obj), v => propertyInfo.GetSetMethod(true).Invoke(obj, new[] {v}), propertyInfo.PropertyType)); } members.Sort((a, b) => string.Compare(a.Item1.Name, b.Item1.Name, StringComparison.Ordinal)); foreach (var (memberInfo, access, value, onValueChanged, memberType) in members) { var data = new ViewVariablesBlobMembers.MemberData { Editable = access == VVAccess.ReadWrite, Name = memberInfo.Name, Type = memberType.AssemblyQualifiedName, TypePretty = memberType.ToString(), Value = value }; var propertyEdit = new ViewVariablesPropertyControl(vvm, resCache); propertyEdit.SetStyle(styleOther = !styleOther); var editor = propertyEdit.SetProperty(data); editor.OnValueChanged += onValueChanged; // TODO: should this maybe not be hardcoded? if (editor is ViewVariablesPropertyEditorReference refEditor) { refEditor.OnPressed += () => vvm.OpenVV(data.Value); } yield return propertyEdit; } } protected static Control MakeTopBar(string top, string bottom) { if (top == bottom) { return new Label {Text = top, ClipText = true}; } //var smallFont = // new VectorFont(IoCManager.Resolve().GetResource("/Fonts/CALIBRI.TTF"), // 10); // Custom ToString() implementation. var headBox = new VBoxContainer {SeparationOverride = 0}; headBox.AddChild(new Label {Text = top, ClipText = true}); headBox.AddChild(new Label { Text = bottom, // FontOverride = smallFont, FontColorOverride = Color.DarkGray, ClipText = true }); return headBox; } } }