diff --git a/Docs/Example-Metadata-Class.md b/Docs/Example-Metadata-Class.md new file mode 100644 index 0000000..a502166 --- /dev/null +++ b/Docs/Example-Metadata-Class.md @@ -0,0 +1,60 @@ +Here is an example template for decorating a mocked ingame block. + +```cs +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using IngameScript.Mockups.Base; +using Sandbox.ModAPI.Interfaces; +using SpaceEngineers.Game.ModAPI.Ingame; + +namespace IngameScript.Mockups.Blocks +{ +#if !MOCKUP_DEBUG + [System.Diagnostics.DebuggerNonUserCode] +#endif +// Decorate the class with a DisplayName attribute to have it visible in the block picker. + [DisplayName("Air Vent")] + public partial class MockAirVent : MockFunctionalBlock, IMyAirVent + { +// Decorate a property with a DisplayName attribute to have it visible in the block details screen. +// Add Range and ReadOnly attributes when appropriate to control how the property is rendered. + [DisplayName("Oxygen Level"), Range(0, 1)] + public virtual float OxygenLevel { get; set; } = 0; + + [DisplayName("Can Pressurize")] + public virtual bool CanPressurize { get; set; } = true; + + [DisplayName("Is Depressurizing"), ReadOnly(true)] + public virtual bool IsDepressurizing => Enabled && (Status == VentStatus.Depressurizing || Status == VentStatus.Depressurized); + + [DisplayName("De-pressurize")] + public virtual bool Depressurize { get; set; } = false; + + [DisplayName("Status")] + public virtual VentStatus Status { get; set; } + + public virtual bool PressurizationEnabled { get; } = true; + + protected override IEnumerable CreateTerminalProperties() + { + return base.CreateTerminalProperties().Concat(new[] + { + new MockTerminalProperty("Depressurize", b => b.Depressurize, (b, v) => b.Depressurize = v) + }); + } + +// Decorate methods with a DisplayName attribute to add them to the list of actions in the block details screen. + [DisplayName("Get Oxygen Level")] + public virtual float GetOxygenLevel() => OxygenLevel; + + public virtual bool IsPressurized() => PressurizationEnabled && (Status == VentStatus.Pressurized || Status == VentStatus.Pressurizing); + } +} +``` + +Additional things to consider: +* Space Engineers only supports C# 6.0, do not use any language features from higher versions (the TestScript will help confirm this). +* Do not create `private` properties unless they are only required for your specific implementation, these classes should be easily extendable. diff --git a/Docs/Getting-Started-Contribute.md b/Docs/Getting-Started-Contribute.md index 395a973..6f4e3c7 100644 --- a/Docs/Getting-Started-Contribute.md +++ b/Docs/Getting-Started-Contribute.md @@ -51,13 +51,20 @@ Once you've made a change you wish to share, you will need to [create a pull req ## Rules and Etiquette: MDK-UI +* To implement editable property support to a Mocked block, the block type must be decorated with the `DisplayNameAttribute`. + * Editable properties must also be decorated with the `DisplayNameAttribute`. + * Properties which are locked between two values must be decorated with the `RangeAttribute`. + * Properties which are not editable must be decorated with the `ReadOnlyAttribute`. +* To implement methods which are executable via the interface should be decorate with a `DisplayNameAttribute`. + * Methods which accept arguments are not yet supported. + * Methods which return a value are output to a MessageBox. * MDK-UI specific code must be part of the MDK-UI project, and not implemented within MDK-Mockups - * The MDK-Mockups Shared Project must remain usable by MDK-SE projects without the use of the MDK-UI project. * Mockups should be implemented by creating a new _partial_ component and implementing the new functionality. - * Mockup classes which support custom UI interaction must be decorated with the `IMockupDataTemplateProvider` interface. * Mockup classes which support realtime runtime updates (such as doors and lights) must implement the `IMockupRuntimeProvider` interface. * If a mockup's existing implementation must be changed to facilty UI interaction (for example by replacing an already mocked method), the mockup class should be marked with the `[MockOverridden]` attribute and a sub-class created. + +* Example metadata implementation. [MockAirVentMetadata.cs](Example-Metadata-Class.md) ### None Version-Controlled Configuration diff --git a/MDK-UI/App.xaml.cs b/MDK-UI/App.xaml.cs index 955c5d7..0be4f7f 100644 --- a/MDK-UI/App.xaml.cs +++ b/MDK-UI/App.xaml.cs @@ -1,14 +1,9 @@ using System; -using System.Collections.Generic; -using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Windows; -using Malware.MDKUtilities; -using Microsoft.Win32; -using Sandbox.ModAPI; namespace MDK_UI { diff --git a/MDK-UI/Dialogs/AddBlockDialogBox.xaml b/MDK-UI/Dialogs/AddBlockDialogBox.xaml index cb4740c..faa949c 100644 --- a/MDK-UI/Dialogs/AddBlockDialogBox.xaml +++ b/MDK-UI/Dialogs/AddBlockDialogBox.xaml @@ -4,12 +4,16 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MDK_UI" + xmlns:tc="clr-namespace:MDK_UI.TemplateConverters" mc:Ignorable="d" Title="Add New Block" Width="300" WindowStyle="ToolWindow" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" SizeToContent="Height" DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}" FocusManager.FocusedElement="{Binding ElementName=BlockName}"> + + + @@ -30,7 +34,7 @@ - + diff --git a/MDK-UI/Dialogs/AddBlockDialogBox.xaml.cs b/MDK-UI/Dialogs/AddBlockDialogBox.xaml.cs index d9bfeb5..b88966b 100644 --- a/MDK-UI/Dialogs/AddBlockDialogBox.xaml.cs +++ b/MDK-UI/Dialogs/AddBlockDialogBox.xaml.cs @@ -1,19 +1,10 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; -using IngameScript.Mockups.Base; using MDK_UI.MockupExtensions; +using Sandbox.ModAPI.Ingame; namespace MDK_UI { @@ -22,21 +13,23 @@ namespace MDK_UI /// public partial class AddBlockDialogBox : Window { - private static Type BaseType { get; } = typeof(IMockupDataTemplateProvider); + private static Type BaseType { get; } = typeof(IMyTerminalBlock); + private static Type SelectorType { get; } = typeof(DisplayNameAttribute); private static Type OverriddenType { get; } = typeof(MockOverriddenAttribute); public delegate void BlockSubmittedEventHandler(object sender, string title, Type type); public event BlockSubmittedEventHandler OnSubmit; - public IEnumerable AvailableTypes { get; } + public IEnumerable AvailableTypes { get; } public AddBlockDialogBox() { AvailableTypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && BaseType.IsAssignableFrom(t))) + .Where(t => t.CustomAttributes.Any(a => a.AttributeType == SelectorType)) .Where(t => !t.CustomAttributes.Any(a => a.AttributeType == OverriddenType)) .Select(t => Activator.CreateInstance(t)) - .OfType() + .OfType() .ToList(); InitializeComponent(); diff --git a/MDK-UI/Dialogs/AddGroupDialogBox.xaml.cs b/MDK-UI/Dialogs/AddGroupDialogBox.xaml.cs index b7ffe4a..61af608 100644 --- a/MDK-UI/Dialogs/AddGroupDialogBox.xaml.cs +++ b/MDK-UI/Dialogs/AddGroupDialogBox.xaml.cs @@ -1,16 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using System.Windows; namespace MDK_UI { diff --git a/MDK-UI/Extensions/ReflectionBindingExtensions.cs b/MDK-UI/Extensions/ReflectionBindingExtensions.cs new file mode 100644 index 0000000..c2ce338 --- /dev/null +++ b/MDK-UI/Extensions/ReflectionBindingExtensions.cs @@ -0,0 +1,197 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Reflection; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using MDK_UI.TemplateConverters; +using Xceed.Wpf.Toolkit; +using MessageBox = System.Windows.MessageBox; + +namespace MDK_UI.Extensions +{ + static class ReflectionBindingExtensions + { + public static UIElement ToUiElement(this PropertyInfo prop, object target, PropertyInfo parent = null) + { + switch (prop.GetDataType()) + { + case DataType.MultilineText: + var textArea = new TextBox() + { + Height = 200, + VerticalScrollBarVisibility = ScrollBarVisibility.Auto, + AcceptsReturn = true, + IsReadOnly = prop.IsReadOnly() + }; + + textArea.SetBinding(TextBox.TextProperty, prop.GetBinding(target)); + return textArea; + default: + var type = parent?.PropertyType ?? prop.PropertyType; + + if (type == typeof(bool)) + { + var checkBox = new CheckBox + { + IsEnabled = !prop.IsReadOnly(), + VerticalAlignment = VerticalAlignment.Center + }; + + checkBox.SetBinding(ToggleButton.IsCheckedProperty, prop.GetBinding(target)); + return checkBox; + } + else if (type == typeof(int) || type == typeof(float)) + { + if (prop.HasAttribute()) + { + var values = prop.GetCustomAttribute(); + var range = new Slider + { + Minimum = (double)values.Minimum, + Maximum = (double)values.Maximum, + IsEnabled = !prop.IsReadOnly(), + VerticalAlignment = VerticalAlignment.Center + }; + + if (type == typeof(int)) + { + range.TickFrequency = 1; + } + else + { + range.TickFrequency = 0.01; + } + + range.SetBinding(RangeBase.ValueProperty, prop.GetBinding(target)); + return range; + } + else + { + var range = new SingleUpDown + { + IsReadOnly = !prop.IsReadOnly(), + VerticalAlignment = VerticalAlignment.Center + }; + + if (type == typeof(int)) + { + range.Increment = 1; + } + else + { + range.Increment = 0.01f; + } + + range.SetBinding(SingleUpDown.ValueProperty, prop.GetBinding(target)); + return range; + } + } + else if (type == typeof(VRageMath.Color)) + { + var colorPicker = new ColorPicker + { + VerticalAlignment = VerticalAlignment.Center + }; + + var binder = prop.GetBinding(target); + binder.Converter = new ColorConverter(); + + colorPicker.SetBinding(ColorPicker.SelectedColorProperty, binder); + return colorPicker; + } + else if (type == typeof(string)) + { + var textBox = new TextBox + { + AcceptsReturn = false, + IsReadOnly = prop.IsReadOnly() + }; + + textBox.SetBinding(TextBox.TextProperty, prop.GetBinding(target)); + + return textBox; + } + else if (type.IsEnum) + { + var comboBox = new ComboBox + { + IsReadOnly = prop.IsReadOnly(), + IsEnabled = !prop.IsReadOnly() + }; + + foreach (var value in Enum.GetValues(type)) + { + comboBox.Items.Add(value); + } + + var binding = prop.GetBinding(target); + //binding.Converter = new DisplayNameConverter(); + + comboBox.SetBinding(Selector.SelectedItemProperty, binding); + return comboBox; + } + else + { + return new TextBlock() + { + Text = $"Unsupported property type {type.Name}." + }; + } + } + } + + public static UIElement ToUIElement(this MethodInfo method, object target, MethodInfo parent = null) + { + var name = method.GetCustomAttribute().DisplayName; + var element = new Button + { + Content = name + }; + + method = parent ?? method; + if (method.GetParameters().Any()) + { + element.Click += UnsupportedMethod; + } + else + { + element.Click += (sender, args) => + { + var result = method.Invoke(target, new object[] { }); + + if (method.ReturnType != typeof(void)) + element.InvokeMessageBox($"{name} returned:\n{result}", "Action Result", MessageBoxButton.OK, MessageBoxImage.Information); + }; + } + + return element; + } + + private static void InvokeMessageBox(this UIElement element, string message, string caption, MessageBoxButton button, MessageBoxImage icon) + { + element.Dispatcher.Invoke(() => MessageBox.Show(message, caption, button, icon)); + } + + private static RoutedEventHandler UnsupportedMethod { get; } = (sender, args) => + { + (sender as UIElement).InvokeMessageBox("Executing actions with parameters is not yet supported.", "Not Supported", MessageBoxButton.OK, MessageBoxImage.Exclamation); + }; + + private static bool IsReadOnly(this PropertyInfo prop) + => !prop.CanWrite || (prop.GetCustomAttribute()?.IsReadOnly ?? false); + + private static DataType GetDataType(this PropertyInfo prop) + => prop.GetCustomAttribute()?.DataType ?? DataType.Text; + + private static Binding GetBinding(this PropertyInfo prop, object target) + => new Binding(prop.Name) + { + Mode = prop.IsReadOnly() ? BindingMode.OneWay : BindingMode.Default, + Source = target + }; + } +} diff --git a/MDK-UI/MDK-UI.csproj b/MDK-UI/MDK-UI.csproj index 3e812f0..ec166f4 100644 --- a/MDK-UI/MDK-UI.csproj +++ b/MDK-UI/MDK-UI.csproj @@ -37,6 +37,7 @@ + @@ -72,9 +73,8 @@ MSBuild:Compile Designer - + - AddBlockDialogBox.xaml @@ -86,26 +86,15 @@ - - - - + Designer MSBuild:Compile - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - MSBuild:Compile Designer @@ -122,22 +111,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - Designer MSBuild:Compile diff --git a/MDK-UI/MainWindow.xaml b/MDK-UI/MainWindow.xaml index b964217..829d25b 100644 --- a/MDK-UI/MainWindow.xaml +++ b/MDK-UI/MainWindow.xaml @@ -111,7 +111,7 @@ + Text="{Binding TickRate, Mode=OneWay, StringFormat={}{0:P2}}" VerticalContentAlignment="Center" /> - - + + + + + + diff --git a/MDK-UI/MainWindow.xaml.cs b/MDK-UI/MainWindow.xaml.cs index 85e70d5..4e1b6c6 100644 --- a/MDK-UI/MainWindow.xaml.cs +++ b/MDK-UI/MainWindow.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.IO; using System.Linq; @@ -13,13 +14,17 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; using IngameScript.Mockups; using IngameScript.Mockups.Base; using IngameScript.Mockups.Blocks; +using MDK_UI.Extensions; using MDK_UI.MockupExtensions; +using MDK_UI.TemplateConverters; using Microsoft.Win32; using Sandbox.ModAPI.Ingame; using VRage.Game; +using GridProp = System.Windows.Controls.Grid; namespace MDK_UI { @@ -528,8 +533,111 @@ private void LbGridComponents_SelectionChanged(object sender, SelectionChangedEv { BlockGroups.Add(group); } + + var labelConverter = new DisplayNameConverter(); + var props = gComponentProperties; + + props.DataContext = SelectedBlock; + props.Children.Clear(); + props.RowDefinitions.Clear(); + + props.RowDefinitions.Add(AutoRow()); + + var title = new TextBlock + { + FontWeight = FontWeight.FromOpenTypeWeight(100) + }; + + title.SetValue(GridProp.ColumnSpanProperty, 2); + title.SetValue(GridProp.RowProperty, 0); + title.SetBinding(TextBlock.TextProperty, new Binding() + { + Converter = labelConverter, + Source = SelectedBlock + }); + + props.Children.Add(title); + + var properties = SelectedBlock.GetType().GetProperties(); + var methods = SelectedBlock.GetType().GetMethods(); + var displayProps = properties.Where(p => p.HasAttribute()).ToList(); + var displayMethods = methods.Where(m => m.HasAttribute()).ToList(); + + if (SelectedBlock.GetType().HasAttribute()) + { + var metadata = SelectedBlock.GetType().GetCustomAttributes(true).OfType().Select(t => t.MetadataClassType); + var metaProps = metadata.SelectMany(t => t.GetProperties().Where(p => p.HasAttribute())); + + foreach (var metaprop in metaProps) + { + if (!displayProps.Any(p => p.Name == metaprop.Name)) + displayProps.Add(metaprop); + } + + var metaMethods = metadata.SelectMany(t => t.GetMethods().Where(p => p.HasAttribute())); + + foreach (var metamethod in metaMethods) + { + if (!displayMethods.Any(m => m.Name == metamethod.Name)) + displayMethods.Add(metamethod); + } + } + + var rowNum = 1; + + foreach (var prop in displayProps.OrderBy(p => p.GetCustomAttribute().DisplayName)) + { + props.RowDefinitions.Add(AutoRow()); + + var label = new Label(); + var binding = label.SetBinding(ContentProperty, new Binding() + { + ConverterParameter = prop.Name, + Converter = labelConverter, + Source = SelectedBlock + }); + label.SetValue(GridProp.RowProperty, rowNum); + label.SetValue(GridProp.ColumnProperty, 0); + + props.Children.Add(label); + + var control = prop.ToUiElement(SelectedBlock, properties.FirstOrDefault(p => p.Name == prop.Name)); + + control.SetValue(GridProp.RowProperty, rowNum); + control.SetValue(GridProp.ColumnProperty, 1); + props.Children.Add(control); + + rowNum++; + } + + if (displayMethods.Any()) + { + props.RowDefinitions.Add(AutoRow()); + + var label = new Label() + { + Content = "Actions" + }; + label.SetValue(GridProp.RowProperty, rowNum); + label.SetValue(GridProp.ColumnProperty, 0); + + props.Children.Add(label); + + var actions = new StackPanel(); + actions.SetValue(GridProp.RowProperty, rowNum); + actions.SetValue(GridProp.ColumnProperty, 1); + + props.Children.Add(actions); + + foreach (var method in displayMethods.OrderBy(p => p.GetCustomAttribute().DisplayName)) + { + actions.Children.Add(method.ToUIElement(SelectedBlock, methods.FirstOrDefault(m => m.Name == method.Name))); + } + } } + private RowDefinition AutoRow() => new RowDefinition() { Height = GridLength.Auto }; + private void BtAddBlockToGroup_Click(object sender, RoutedEventArgs e) { if (SelectedBlock == null) diff --git a/MDK-UI/MockupExtensions/CommandProxy.cs b/MDK-UI/MockupExtensions/CommandProxy.cs deleted file mode 100644 index 7e64bd8..0000000 --- a/MDK-UI/MockupExtensions/CommandProxy.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Windows.Input; - -namespace IngameScript.Mockups.Blocks -{ - public class CommandProxy : ICommand - { - private Action Proxy { get; } - private Func CanExecuteTest { get; } = () => true; - - public CommandProxy(Action proxy, Func canExecute = null) - { - Proxy = proxy; - if (canExecute != null) - { - CanExecuteTest = canExecute; - } - } - - public event EventHandler CanExecuteChanged; - - public bool CanExecute(object parameter) => CanExecuteTest(); - public void Execute(object parameter) => Proxy(); - - public void OnExecuteChange() => CanExecuteChanged?.Invoke(this, new EventArgs()); - } -} diff --git a/MDK-UI/MockupExtensions/IMockupDataTemplateProvider.cs b/MDK-UI/MockupExtensions/IMockupDataTemplateProvider.cs deleted file mode 100644 index 9999c03..0000000 --- a/MDK-UI/MockupExtensions/IMockupDataTemplateProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Windows; - -namespace MDK_UI.MockupExtensions -{ - public interface IMockupDataTemplateProvider - { - string TemplateDisplayName { get; } - string DataTemplateName { get; } - } -} diff --git a/MDK-UI/MockupExtensions/MockAirVent.cs b/MDK-UI/MockupExtensions/MockAirVent.cs deleted file mode 100644 index 3ffd8c5..0000000 --- a/MDK-UI/MockupExtensions/MockAirVent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using IngameScript.Mockups.Base; -using Sandbox.ModAPI.Interfaces; -using SpaceEngineers.Game.ModAPI.Ingame; - -namespace IngameScript.Mockups.Blocks -{ - public partial class MockAirVent - { - public override string DataTemplateName => "AirVent"; - public override string TemplateDisplayName => "Air Vent"; - } -} diff --git a/MDK-UI/MockupExtensions/MockDoorRuntime.cs b/MDK-UI/MockupExtensions/MockDoorRuntime.cs index 64d25e3..6cac519 100644 --- a/MDK-UI/MockupExtensions/MockDoorRuntime.cs +++ b/MDK-UI/MockupExtensions/MockDoorRuntime.cs @@ -4,15 +4,13 @@ namespace IngameScript.Mockups.Blocks { + [DisplayName("Sliding Door")] public class MockRuntimeDoor: MockDoor, IMockupRuntimeProvider { const float OpenRate = 0.1666f; public event PropertyChangedEventHandler PropertyChanged; - public override string DataTemplateName => "Door"; - public override string TemplateDisplayName => "Sliding Door"; - public int ProcessPriority => 1; public override string CustomName @@ -65,17 +63,7 @@ public override void CloseDoor() if (Status != DoorStatus.Closed) Status = DoorStatus.Closing; } - - public CommandProxy OpenCommand { get; } - public CommandProxy CloseCommand { get; } - - public MockRuntimeDoor() - :base() - { - OpenCommand = new CommandProxy(OpenDoor); - CloseCommand = new CommandProxy(CloseDoor); - } - + public void ProcessGameTick(IMyGridTerminalSystem gridTerminalSystem, int tick) { switch (Status) diff --git a/MDK-UI/MockupExtensions/MockInteriorLight.cs b/MDK-UI/MockupExtensions/MockInteriorLight.cs index df50afb..d80abc2 100644 --- a/MDK-UI/MockupExtensions/MockInteriorLight.cs +++ b/MDK-UI/MockupExtensions/MockInteriorLight.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using IngameScript.Mockups.Base; -using MDK_UI.MockupExtensions; -using Sandbox.ModAPI.Interfaces; -using SpaceEngineers.Game.ModAPI.Ingame; -using VRageMath; +using MDK_UI.MockupExtensions; namespace IngameScript.Mockups.Blocks { diff --git a/MDK-UI/MockupExtensions/MockInteriorLightRuntime.cs b/MDK-UI/MockupExtensions/MockInteriorLightRuntime.cs index 44d9e36..8d6db75 100644 --- a/MDK-UI/MockupExtensions/MockInteriorLightRuntime.cs +++ b/MDK-UI/MockupExtensions/MockInteriorLightRuntime.cs @@ -6,11 +6,9 @@ namespace IngameScript.Mockups.Blocks { + [DisplayName("Interior Light")] public class MockInteriorLightRuntime: MockInteriorLight, IMockupRuntimeProvider { - public override string DataTemplateName => "LightingBlock"; - public override string TemplateDisplayName => "Interior Light"; - public int ProcessPriority => 1; private int CurrentTick = 0; diff --git a/MDK-UI/MockupExtensions/MockTerminalBlock.cs b/MDK-UI/MockupExtensions/MockTerminalBlock.cs deleted file mode 100644 index b77434f..0000000 --- a/MDK-UI/MockupExtensions/MockTerminalBlock.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Windows; -using MDK_UI.MockupExtensions; - -namespace IngameScript.Mockups.Base -{ - public partial class MockTerminalBlock: IMockupDataTemplateProvider - { - public virtual string DataTemplateName { get; } = "UnsupportedBlock"; - public virtual string TemplateDisplayName => GetType().Name.Substring(4); - } -} diff --git a/MDK-UI/MockupExtensions/MockTextPanel.cs b/MDK-UI/MockupExtensions/MockTextPanel.cs index e415c91..8d4c7ab 100644 --- a/MDK-UI/MockupExtensions/MockTextPanel.cs +++ b/MDK-UI/MockupExtensions/MockTextPanel.cs @@ -1,20 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using IngameScript.Mockups.Base; -using Sandbox.Common.ObjectBuilders; -using Sandbox.ModAPI.Ingame; -using Sandbox.ModAPI.Interfaces; -using VRage.Game.GUI.TextPanel; -using VRageMath; +using System.ComponentModel; namespace IngameScript.Mockups.Blocks { - public partial class MockTextPanel - { - public override string DataTemplateName => "TextSurface"; - public override string TemplateDisplayName => "Text Panel"; - } + public partial class MockTextPanel { } } diff --git a/MDK-UI/MockupExtensions/RuntimeConstants.cs b/MDK-UI/MockupExtensions/RuntimeConstants.cs index 94b8c41..aad1098 100644 --- a/MDK-UI/MockupExtensions/RuntimeConstants.cs +++ b/MDK-UI/MockupExtensions/RuntimeConstants.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MDK_UI.MockupExtensions +namespace MDK_UI.MockupExtensions { static class RuntimeConstants { diff --git a/MDK-UI/MockupExtensions/UiMockedRun.cs b/MDK-UI/MockupExtensions/UiMockedRun.cs index 6133408..8f60ef8 100644 --- a/MDK-UI/MockupExtensions/UiMockedRun.cs +++ b/MDK-UI/MockupExtensions/UiMockedRun.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using IngameScript.Mockups; using Sandbox.ModAPI.Ingame; diff --git a/MDK-UI/Resources/DisplayTemplates/AirVent.xaml b/MDK-UI/Resources/DisplayTemplates/AirVent.xaml deleted file mode 100644 index d94f438..0000000 --- a/MDK-UI/Resources/DisplayTemplates/AirVent.xaml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - Air Vent - - - - - - - - - - - - \ No newline at end of file diff --git a/MDK-UI/Resources/DisplayTemplates/Common.xaml b/MDK-UI/Resources/DisplayTemplates/Common.xaml deleted file mode 100644 index 7aa632a..0000000 --- a/MDK-UI/Resources/DisplayTemplates/Common.xaml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - No Block Selected - Select a block from the menu to the left. - - - - - - - - - - - - - - - - - - - - - Basic - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This block is not supported, only basic properties can be edited. - - - \ No newline at end of file diff --git a/MDK-UI/Resources/DisplayTemplates/DisplayTemplates.xaml b/MDK-UI/Resources/DisplayTemplates/DisplayTemplates.xaml deleted file mode 100644 index eefe8c3..0000000 --- a/MDK-UI/Resources/DisplayTemplates/DisplayTemplates.xaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/MDK-UI/Resources/DisplayTemplates/Door.xaml b/MDK-UI/Resources/DisplayTemplates/Door.xaml deleted file mode 100644 index 399fdb6..0000000 --- a/MDK-UI/Resources/DisplayTemplates/Door.xaml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Door - - - - - - - - - - - - \ No newline at end of file diff --git a/MDK-UI/Resources/DisplayTemplates/LightingBlock.xaml b/MDK-UI/Resources/DisplayTemplates/LightingBlock.xaml deleted file mode 100644 index 37c9b26..0000000 --- a/MDK-UI/Resources/DisplayTemplates/LightingBlock.xaml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - Lighting Block - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MDK-UI/Resources/DisplayTemplates/TextSurface.xaml b/MDK-UI/Resources/DisplayTemplates/TextSurface.xaml deleted file mode 100644 index a0b58a6..0000000 --- a/MDK-UI/Resources/DisplayTemplates/TextSurface.xaml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - Text Surface - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MDK-UI/Resources/MainWindow.xaml b/MDK-UI/Resources/MainWindow.xaml index 5893104..ec2a5f1 100644 --- a/MDK-UI/Resources/MainWindow.xaml +++ b/MDK-UI/Resources/MainWindow.xaml @@ -3,12 +3,7 @@ xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:SEIngame="clr-namespace:SpaceEngineers.Game.ModAPI.Ingame;assembly=SpaceEngineers.Game" xmlns:VRageGame="clr-namespace:VRage.Game;assembly=VRage.Game" - xmlns:ts="clr-namespace:MDK_UI.TemplateSelectors" - xmlns:tc="clr-namespace:MDK_UI.TemplateConverters"> - - - - + xmlns:tc="clr-namespace:MDK_UI.TemplateConverters"> @@ -22,7 +17,5 @@ - - - + \ No newline at end of file diff --git a/MDK-UI/TemplateConverters/DisplayNameConverter.cs b/MDK-UI/TemplateConverters/DisplayNameConverter.cs new file mode 100644 index 0000000..e074bf3 --- /dev/null +++ b/MDK-UI/TemplateConverters/DisplayNameConverter.cs @@ -0,0 +1,50 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Reflection; +using System.Windows.Data; + +namespace MDK_UI.TemplateConverters +{ + public sealed class DisplayNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value == null) + return Binding.DoNothing; + + var type = value.GetType(); + var meta = type.GetCustomAttribute(); + + var propertyName = parameter as string; + if (string.IsNullOrEmpty(propertyName)) + { + var attribute = type.GetCustomAttribute(); + if (attribute == null) + return new ArgumentOutOfRangeException(nameof(parameter), parameter, $"Class \"{type.Name}\" has no associated DisplayName attribute.").ToString(); + + return attribute.DisplayName; + } + else + { + var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + return new ArgumentOutOfRangeException(nameof(parameter), parameter, $"Property \"{propertyName}\" not found in type \"{type.Name}\".").ToString(); + + var attribute = property.GetCustomAttribute() ?? meta?.MetadataClassType?.GetProperty(propertyName)?.GetCustomAttribute(); + + if (attribute == null) + { + return new ArgumentOutOfRangeException(nameof(parameter), parameter, $"Property \"{propertyName}\" of type \"{type.Name}\" has no associated DisplayName attribute.").ToString(); + } + + return attribute.DisplayName; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/MDK-UI/TemplateSelectors/MyTerminalBlockCommon.cs b/MDK-UI/TemplateSelectors/MyTerminalBlockCommon.cs deleted file mode 100644 index d2e1e60..0000000 --- a/MDK-UI/TemplateSelectors/MyTerminalBlockCommon.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace MDK_UI.TemplateSelectors -{ - public class MyTerminalBlockCommon: DataTemplateSelector - { - public override DataTemplate SelectTemplate(object item, DependencyObject container) - { - if (container is FrameworkElement element) - { - if (item == null) - return GetTemplate(element, "NoBlockSelected"); - - return GetTemplate(element, "BlockProperties"); - } - - return null; - } - - private DataTemplate GetTemplate(FrameworkElement element, string template) - => element.FindResource("dt" + template) as DataTemplate; - } -} diff --git a/MDK-UI/TemplateSelectors/MyTerminalBlockDetail.cs b/MDK-UI/TemplateSelectors/MyTerminalBlockDetail.cs deleted file mode 100644 index 178f7e3..0000000 --- a/MDK-UI/TemplateSelectors/MyTerminalBlockDetail.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using MDK_UI.MockupExtensions; - -namespace MDK_UI.TemplateSelectors -{ - public class MyTerminalBlockDetail: DataTemplateSelector - { - public override DataTemplate SelectTemplate(object item, DependencyObject container) - { - if (container is FrameworkElement element - && item is IMockupDataTemplateProvider provider) - { - return GetTemplate(element, provider.DataTemplateName); - } - - return null; - } - - private DataTemplate GetTemplate(FrameworkElement element, string template) - => element.FindResource("dt" + template) as DataTemplate; - } -} diff --git a/Mockups/Base/MockFunctionalBlock.debug.cs b/Mockups/Base/MockFunctionalBlock.debug.cs index 61560a2..b6a8a79 100644 --- a/Mockups/Base/MockFunctionalBlock.debug.cs +++ b/Mockups/Base/MockFunctionalBlock.debug.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using Sandbox.ModAPI.Ingame; using Sandbox.ModAPI.Interfaces; @@ -9,8 +10,9 @@ namespace IngameScript.Mockups.Base #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif - public abstract class MockFunctionalBlock : MockTerminalBlock, IMyFunctionalBlock + public abstract partial class MockFunctionalBlock : MockTerminalBlock, IMyFunctionalBlock { + [DisplayName("Enabled")] public virtual bool Enabled { get; set; } = true; protected override IEnumerable CreateTerminalProperties() diff --git a/Mockups/Base/MockTerminalBlock.debug.cs b/Mockups/Base/MockTerminalBlock.debug.cs index 13aff4d..9de8830 100644 --- a/Mockups/Base/MockTerminalBlock.debug.cs +++ b/Mockups/Base/MockTerminalBlock.debug.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Sandbox.ModAPI.Ingame; @@ -12,6 +14,7 @@ namespace IngameScript.Mockups.Base #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Unsupported Block")] public abstract partial class MockTerminalBlock : MockCubeBlock, IMyTerminalBlock { public Dictionary Relationships { get; } @@ -30,6 +33,7 @@ protected ReadOnlyCollection Properties } } + [DisplayName("Custom Name")] public virtual string CustomName { // Ugh... >_< @@ -60,14 +64,19 @@ public virtual string CustomNameWithFaction public virtual string CustomInfo { get; set; } = ""; + [DisplayName("Custom Data"), DataType(DataType.MultilineText)] public virtual string CustomData { get; set; } = ""; + [DisplayName("Show On HUD")] public virtual bool ShowOnHUD { get; set; } = true; + [DisplayName("Show In Terminal")] public virtual bool ShowInTerminal { get; set; } = true; + [DisplayName("Show In Toolbar Config")] public virtual bool ShowInToolbarConfig { get; set; } = true; + [DisplayName("Show In Inventory")] public virtual bool ShowInInventory { get; set; } = true; protected virtual IEnumerable CreateTerminalProperties() diff --git a/Mockups/Blocks/MockAirVent.debug.cs b/Mockups/Blocks/MockAirVent.debug.cs index a5b0a40..7e8a924 100644 --- a/Mockups/Blocks/MockAirVent.debug.cs +++ b/Mockups/Blocks/MockAirVent.debug.cs @@ -1,5 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using IngameScript.Mockups.Base; @@ -11,16 +12,22 @@ namespace IngameScript.Mockups.Blocks #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Air Vent")] public partial class MockAirVent : MockFunctionalBlock, IMyAirVent { + [DisplayName("Oxygen Level"), Range(0d, 1d)] public virtual float OxygenLevel { get; set; } = 0; + [DisplayName("Can Pressurize")] public virtual bool CanPressurize { get; set; } = true; + [DisplayName("Is Depressurizing"), ReadOnly(true)] public virtual bool IsDepressurizing => Enabled && (Status == VentStatus.Depressurizing || Status == VentStatus.Depressurized); + [DisplayName("De-pressurize")] public virtual bool Depressurize { get; set; } = false; + [DisplayName("Status")] public virtual VentStatus Status { get; set; } public virtual bool PressurizationEnabled { get; } = true; @@ -33,6 +40,7 @@ protected override IEnumerable CreateTerminalProperties() }); } + [DisplayName("Get Oxygen Level")] public virtual float GetOxygenLevel() => OxygenLevel; public virtual bool IsPressurized() => PressurizationEnabled && (Status == VentStatus.Pressurized || Status == VentStatus.Pressurizing); diff --git a/Mockups/Blocks/MockDoor.debug.cs b/Mockups/Blocks/MockDoor.debug.cs index c38e682..66d9d69 100644 --- a/Mockups/Blocks/MockDoor.debug.cs +++ b/Mockups/Blocks/MockDoor.debug.cs @@ -2,6 +2,8 @@ using Sandbox.ModAPI.Ingame; using Sandbox.ModAPI.Interfaces; using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; @@ -10,12 +12,15 @@ namespace IngameScript.Mockups.Blocks #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Sliding Door")] public partial class MockDoor : MockFunctionalBlock, IMyDoor { public virtual bool Open => OpenRatio != 0; + [DisplayName("Status"), ReadOnly(true)] public virtual DoorStatus Status { get; set; } = DoorStatus.Closed; + [DisplayName("Open Ratio"), Range(0d, 1d)] public virtual float OpenRatio { get; set; } = 0; protected override IEnumerable CreateTerminalProperties() @@ -36,6 +41,7 @@ protected override IEnumerable CreateTerminalProperties() }); } + [DisplayName("Close")] public virtual void CloseDoor() { if (Enabled && IsFunctional) @@ -45,6 +51,7 @@ public virtual void CloseDoor() } } + [DisplayName("Open")] public virtual void OpenDoor() { if (Enabled && IsFunctional) @@ -54,6 +61,7 @@ public virtual void OpenDoor() } } + [DisplayName("Toggle")] public virtual void ToggleDoor() { switch (Status) diff --git a/Mockups/Blocks/MockInteriorLight.debug.cs b/Mockups/Blocks/MockInteriorLight.debug.cs index 4eb1742..7cb802d 100644 --- a/Mockups/Blocks/MockInteriorLight.debug.cs +++ b/Mockups/Blocks/MockInteriorLight.debug.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using IngameScript.Mockups.Base; using Sandbox.ModAPI.Interfaces; @@ -11,23 +12,30 @@ namespace IngameScript.Mockups.Blocks #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Interior Light")] public partial class MockInteriorLight : MockFunctionalBlock, IMyInteriorLight { protected float _offset; - public virtual float Radius { get; set; } = 2; - [Obsolete("Use " + nameof(Radius))] - public virtual float ReflectorRadius => Radius; + [DisplayName("Radius")] + public virtual float Radius { get; set; } = 2; + [DisplayName("Intensity")] public virtual float Intensity { get; set; } = 1; + + [DisplayName("Falloff")] public virtual float Falloff { get; set; } = 1; - public virtual float BlinkIntervalSeconds { get; set; } = 0; - [Obsolete("Use " + nameof(BlinkLength) + " instead.")] - public virtual float BlinkLenght => BlinkLength; + [DisplayName("Blink Interval Seconds")] + public virtual float BlinkIntervalSeconds { get; set; } = 0; + [DisplayName("Blink Length")] public virtual float BlinkLength { get; set; } = 0; + + [DisplayName("Blink Offset")] public virtual float BlinkOffset { get; set; } = 0; + + [DisplayName("Color")] public virtual Color Color { get; set; } = new Color(255, 255, 255); protected override IEnumerable CreateTerminalProperties() @@ -44,5 +52,11 @@ protected override IEnumerable CreateTerminalProperties() new MockTerminalProperty("Offset", b => _offset, (b, v) => _offset = v) }); } + + [Obsolete("Use " + nameof(BlinkLength) + " instead.")] + public virtual float BlinkLenght => BlinkLength; + + [Obsolete("Use " + nameof(Radius))] + public virtual float ReflectorRadius => Radius; } } diff --git a/Mockups/Blocks/MockProgrammableBlock.debug.cs b/Mockups/Blocks/MockProgrammableBlock.debug.cs index 0449674..6a7bc77 100644 --- a/Mockups/Blocks/MockProgrammableBlock.debug.cs +++ b/Mockups/Blocks/MockProgrammableBlock.debug.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; @@ -16,6 +17,7 @@ namespace IngameScript.Mockups.Blocks #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Programmable Block")] public partial class MockProgrammableBlock : MockFunctionalBlock, IMyProgrammableBlock { protected string _storage = string.Empty; @@ -49,6 +51,7 @@ protected override IEnumerable CreateTerminalProperties() }); } + [DisplayName("Run")] public virtual bool Run(string argument, UpdateType updateType) { if (!Enabled) diff --git a/Mockups/Blocks/MockTextPanel.debug.cs b/Mockups/Blocks/MockTextPanel.debug.cs index 89db282..1f685d3 100644 --- a/Mockups/Blocks/MockTextPanel.debug.cs +++ b/Mockups/Blocks/MockTextPanel.debug.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; @@ -15,6 +16,7 @@ namespace IngameScript.Mockups.Blocks #if !MOCKUP_DEBUG [System.Diagnostics.DebuggerNonUserCode] #endif + [DisplayName("Text Panel")] public partial class MockTextPanel : MockFunctionalBlock, IMyTextPanel { protected readonly MockTextSurface _surface = new MockTextSurface(new Vector2(512, 512), new Vector2(512, 512)); @@ -27,9 +29,6 @@ public virtual string CurrentlyShownImage set { _surface.CurrentlyShownImage = value; } } - [Obsolete("This property no has meaning in-game. If you need a secondary storage, use CustomData")] - public virtual ShowTextOnScreenFlag ShowOnScreen { get; set; } = ShowTextOnScreenFlag.PUBLIC; - public virtual bool ShowText => _surface.ContentType == ContentType.TEXT_AND_IMAGE; public virtual float FontSize @@ -141,6 +140,21 @@ protected override IEnumerable CreateTerminalProperties() }); } + public virtual string GetPublicTitle() + => _publicTitle.ToString(); + + public virtual bool WritePublicTitle(string value, bool append = false) + { + Debug.Assert(value != null, $"{nameof(value)} cannot be null"); + if (!append) + _publicTitle.Clear(); + + _publicTitle.Append(value); + + return true; + } + + #region Text Surface Proxies public virtual void AddImagesToSelection(List ids, bool checkExistence = false) => _surface.AddImagesToSelection(ids, checkExistence); @@ -152,96 +166,93 @@ public virtual void ClearImagesFromSelection() public virtual void GetFonts(List fonts) => _surface.GetFonts(fonts); - - [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData")] - public virtual string GetPrivateText() - { - throw new NotSupportedException(); - } + public virtual void GetSelectedImages(List output) + => _surface.GetSelectedImages(output); - [Obsolete("This methods no longer have meaning in-game. If you need a secondary storage, use CustomData")] - public virtual string GetPrivateTitle() - { - throw new NotSupportedException(); - } + public virtual void RemoveImageFromSelection(string id, bool removeDuplicates = false) + => _surface.RemoveImageFromSelection(id, removeDuplicates); + + public virtual string GetText() => _surface.GetText(); + public virtual void ReadText(StringBuilder buffer, bool append = false) => _surface.ReadText(buffer, append); + public virtual bool WriteText(string value, bool append = false) => _surface.WriteText(value, append); + public virtual bool WriteText(StringBuilder value, bool append = false) => _surface.WriteText(value, append); + public virtual void GetSprites(List sprites) => _surface.GetSprites(sprites); + public virtual void GetScripts(List scripts) => _surface.GetScripts(scripts); + public virtual MySpriteDrawFrame DrawFrame() => _surface.DrawFrame(); + public virtual Vector2 MeasureStringInPixels(StringBuilder text, string font, float scale) => _surface.MeasureStringInPixels(text, font, scale); + #endregion - public virtual string GetPublicText() => _surface.GetText(); + public virtual void RemoveImagesFromSelection(List ids, bool removeDuplicates = false) + => _surface.RemoveImagesFromSelection(ids, removeDuplicates); - public virtual string GetPublicTitle() => _publicTitle.ToString(); + #region Obsolete Methods and Properties + [Obsolete("This property no has meaning in-game. If you need a secondary storage, use CustomData")] + public virtual ShowTextOnScreenFlag ShowOnScreen { get; set; } = ShowTextOnScreenFlag.PUBLIC; - public virtual void GetSelectedImages(List output) - => _surface.GetSelectedImages(output); + [Obsolete("Use " + nameof(GetText) + ".")] + public virtual string GetPublicText() + => _surface.GetText(); + [Obsolete("Use " + nameof(ReadText) + ".")] public virtual void ReadPublicText(StringBuilder buffer, bool append = false) => _surface.ReadText(buffer, append); - public virtual void RemoveImageFromSelection(string id, bool removeDuplicates = false) - => _surface.RemoveImageFromSelection(id, removeDuplicates); + [Obsolete("Use " + nameof(WriteText) + ".")] + public virtual bool WritePublicText(string value, bool append = false) + => _surface.WriteText(value, append); - public virtual void RemoveImagesFromSelection(List ids, bool removeDuplicates = false) - => _surface.RemoveImagesFromSelection(ids, removeDuplicates); + [Obsolete("Use " + nameof(WriteText) + ".")] + public virtual bool WritePublicText(StringBuilder value, bool append = false) + => _surface.WriteText(value, append); + + [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] + public virtual string GetPrivateText() + { + throw new NotSupportedException(); + } - [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData")] + [Obsolete("This methods no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] + public virtual string GetPrivateTitle() + { + throw new NotSupportedException(); + } + + [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] public virtual void SetShowOnScreen(ShowTextOnScreenFlag set) { throw new NotSupportedException(); } - [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData")] + [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] public virtual void ShowPrivateTextOnScreen() { throw new NotSupportedException(); } - [Obsolete] + [Obsolete("This method no longer have meaning in-game.", true)] public virtual void ShowPublicTextOnScreen() { throw new NotSupportedException(); } - [Obsolete] + [Obsolete("This method no longer have meaning in-game.", true)] public virtual void ShowTextureOnScreen() { throw new NotSupportedException(); } - [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData")] + [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] public virtual bool WritePrivateText(string value, bool append = false) { throw new NotSupportedException(); - } + } - [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData")] + [Obsolete("This method no longer have meaning in-game. If you need a secondary storage, use CustomData", true)] public virtual bool WritePrivateTitle(string value, bool append = false) { throw new NotSupportedException(); } - - public virtual bool WritePublicText(string value, bool append = false) - => _surface.WriteText(value, append); - - public virtual bool WritePublicText(StringBuilder value, bool append = false) - => _surface.WriteText(value, append); - - public virtual bool WritePublicTitle(string value, bool append = false) - { - Debug.Assert(value != null, $"{nameof(value)} cannot be null"); - if (!append) - _publicTitle.Clear(); - - _publicTitle.Append(value); - - return true; - } - - public virtual bool WriteText(string value, bool append = false) => _surface.WriteText(value, append); - public virtual string GetText() => _surface.GetText(); - public virtual bool WriteText(StringBuilder value, bool append = false) => _surface.WriteText(value, append); - public virtual void ReadText(StringBuilder buffer, bool append = false) => _surface.ReadText(buffer, append); - public virtual void GetSprites(List sprites) => _surface.GetSprites(sprites); - public virtual void GetScripts(List scripts) => _surface.GetScripts(scripts); - public virtual MySpriteDrawFrame DrawFrame() => _surface.DrawFrame(); - public virtual Vector2 MeasureStringInPixels(StringBuilder text, string font, float scale) => _surface.MeasureStringInPixels(text, font, scale); + #endregion } } diff --git a/Mockups/MockBlockGroup.debug.cs b/Mockups/MockBlockGroup.debug.cs index 40ae51f..5f93967 100644 --- a/Mockups/MockBlockGroup.debug.cs +++ b/Mockups/MockBlockGroup.debug.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Sandbox.ModAPI.Ingame; namespace IngameScript.Mockups diff --git a/TestScript/TestScript.csproj b/TestScript/TestScript.csproj index 5208591..9ad6a3e 100644 --- a/TestScript/TestScript.csproj +++ b/TestScript/TestScript.csproj @@ -26,6 +26,7 @@ +