diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs index 59e612d51..318ecf8b9 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs @@ -159,7 +159,12 @@ namespace Barotrauma child.rect.Y + (rect.Y - prevY), Math.Max(child.rect.Width + (rect.Width - prevWidth),0), Math.Max(child.rect.Height + (rect.Height - prevHeight),0)); - } + } + + if (parent != null && parent is GUIListBox) + { + ((GUIListBox)parent).UpdateScrollBarSize(); + } } } @@ -385,18 +390,9 @@ namespace Barotrauma { spriteBatch.Draw(uiSprite.Sprite.Texture, rect, uiSprite.Sprite.SourceRect, currColor * (currColor.A / 255.0f)); } - - } } } - - //Color newColor = color; - //if (state == ComponentState.Selected) newColor = selectedColor; - //if (state == ComponentState.Hover) newColor = hoverColor; - - //GUI.DrawRectangle(spriteBatch, rect, newColor*alpha, true); - //DrawChildren(spriteBatch); } public void DrawToolTip(SpriteBatch spriteBatch) @@ -460,7 +456,7 @@ namespace Barotrauma } } - public void SetDimensions(Point size, bool expandChildren = false) + public virtual void SetDimensions(Point size, bool expandChildren = false) { Point expandAmount = size - rect.Size; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs index 75dc5e50b..be375920a 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs @@ -180,6 +180,12 @@ namespace Barotrauma } } + public override void SetDimensions(Point size, bool expandChildren = false) + { + base.SetDimensions(size, expandChildren); + frame.SetDimensions(size, expandChildren); + } + private void UpdateChildrenRect(float deltaTime) { int x = rect.X, y = rect.Y; @@ -329,7 +335,7 @@ namespace Barotrauma public void UpdateScrollBarSize() { - totalSize = 0; + totalSize = (int)(padding.Y + padding.W); foreach (GUIComponent child in children) { if (child == frame) continue; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs index 74714d5c3..596b9cef7 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs @@ -1,50 +1,96 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; +using System.Globalization; +using System.Linq; namespace Barotrauma { class GUINumberInput : GUIComponent { - public delegate void OnValueChangedHandler(GUINumberInput numberInput, int number); + public enum NumberType + { + Int, Float + } + + public delegate void OnValueChangedHandler(GUINumberInput numberInput); public OnValueChangedHandler OnValueChanged; private GUITextBox textBox; private GUIButton plusButton, minusButton; - public int? MinValue, MaxValue; - - private int value; - public int Value + private NumberType inputType; + public NumberType InputType { - get { return value; } + get { return inputType; } set { - if (value == this.value) return; - - this.value = value; - if (MinValue != null) - { - this.value = Math.Max(this.value, (int)MinValue); - minusButton.Enabled = this.value > MinValue; - } - if (MaxValue != null) - { - this.value = Math.Min(this.value, (int)MaxValue); - plusButton.Enabled = this.value < MaxValue; - } - textBox.Text = this.value.ToString(); - - if (OnValueChanged != null) OnValueChanged(this, this.value); + inputType = value; + plusButton.Visible = inputType == NumberType.Int; + minusButton.Visible = inputType == NumberType.Int; } } - public GUINumberInput(Rectangle rect, string style, int? minValue = null, int? maxValue = null, GUIComponent parent = null) - : this(rect, style, Alignment.TopLeft, minValue, maxValue, parent) + public float? MinValueFloat, MaxValueFloat; + + private float floatValue; + public float FloatValue + { + get { return floatValue; } + set + { + if (value == floatValue) return; + + floatValue = value; + if (MinValueFloat != null) + { + floatValue = Math.Max(floatValue, MinValueFloat.Value); + minusButton.Enabled = floatValue > MinValueFloat; + } + if (MaxValueFloat != null) + { + floatValue = Math.Min(floatValue, MaxValueFloat.Value); + plusButton.Enabled = floatValue < MaxValueFloat; + } + textBox.Text = floatValue.ToString("G", CultureInfo.InvariantCulture); + + OnValueChanged?.Invoke(this); + } + } + + public int? MinValueInt, MaxValueInt; + + private int intValue; + public int IntValue + { + get { return intValue; } + set + { + if (value == intValue) return; + + intValue = value; + if (MinValueInt != null) + { + intValue = Math.Max(intValue, MinValueInt.Value); + minusButton.Enabled = intValue > MinValueInt; + } + if (MaxValueInt != null) + { + intValue = Math.Min(intValue, MaxValueInt.Value); + plusButton.Enabled = intValue < MaxValueInt; + } + textBox.Text = this.intValue.ToString(); + + OnValueChanged?.Invoke(this); + } + } + + public GUINumberInput(Rectangle rect, string style, NumberType inputType, GUIComponent parent = null) + : this(rect, style, inputType, Alignment.TopLeft, parent) { } - public GUINumberInput(Rectangle rect, string style, Alignment alignment, int? minValue = null, int? maxValue = null, GUIComponent parent = null) + public GUINumberInput(Rectangle rect, string style, NumberType inputType, Alignment alignment, GUIComponent parent = null) : base(style) { this.rect = rect; @@ -55,30 +101,46 @@ namespace Barotrauma parent.AddChild(this); textBox = new GUITextBox(Rectangle.Empty, style, this); - textBox.OnTextChanged += TextChanged; - + plusButton = new GUIButton(new Rectangle(0, 0, 15, rect.Height / 2), "+", null, Alignment.TopRight, Alignment.Center, style, this); - plusButton.OnClicked += ChangeValue; + plusButton.OnClicked += ChangeIntValue; + plusButton.Visible = inputType == NumberType.Int; minusButton = new GUIButton(new Rectangle(0, 0, 15, rect.Height / 2), "-", null, Alignment.BottomRight, Alignment.Center, style, this); - minusButton.OnClicked += ChangeValue; + minusButton.OnClicked += ChangeIntValue; + minusButton.Visible = inputType == NumberType.Int; - MinValue = minValue; - MaxValue = maxValue; + if (inputType == NumberType.Int) + { + textBox.Text = "0"; + textBox.OnDeselected += (txtBox, key) => + { + textBox.Text = IntValue.ToString(); + }; + } + else if (inputType == NumberType.Float) + { + textBox.Text = "0.0"; + textBox.OnDeselected += (txtBox, key) => + { + textBox.Text = FloatValue.ToString("G", CultureInfo.InvariantCulture); + }; + } - value = int.MaxValue; - Value = minValue != null ? (int)minValue : 0; + + + InputType = inputType; } - - private bool ChangeValue(GUIButton button, object userData) + + private bool ChangeIntValue(GUIButton button, object userData) { if (button == plusButton) { - Value++; + IntValue++; } else { - Value--; + IntValue--; } return false; @@ -86,19 +148,44 @@ namespace Barotrauma private bool TextChanged(GUITextBox textBox, string text) { - int newValue = Value; - if (text == "" || text == "-") + switch (InputType) { - Value = 0; - textBox.Text = text; - } - else if (int.TryParse(text, out newValue)) - { - Value = newValue; - } - else - { - textBox.Text = Value.ToString(); + case NumberType.Int: + int newIntValue = IntValue; + if (text == "" || text == "-") + { + IntValue = 0; + textBox.Text = text; + } + else if (int.TryParse(text, out newIntValue)) + { + IntValue = newIntValue; + } + else + { + textBox.Text = IntValue.ToString(); + } + break; + case NumberType.Float: + float newFloatValue = FloatValue; + + text = new string(text.Where(c => char.IsDigit(c) || c == '.' || c == '-').ToArray()); + + if (text == "" || text == "-") + { + FloatValue = 0; + textBox.Text = text; + } + else if (float.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out newFloatValue)) + { + FloatValue = newFloatValue; + textBox.Text = text; + } + /*else + { + textBox.Text = FloatValue.ToString("G", CultureInfo.InvariantCulture); + }*/ + break; } return true; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs index f842fa77b..822b3be2d 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs @@ -72,11 +72,17 @@ namespace Barotrauma child.Rect = new Rectangle(child.Rect.X + value.X - rect.X, child.Rect.Y + value.Y - rect.Y, child.Rect.Width, child.Rect.Height); } + Point moveAmount = value.Location - rect.Location; + rect = value; if (value.Width != rect.Width || value.Height != rect.Height) { SetTextPos(); } + else if (moveAmount != Point.Zero) + { + caretPos += moveAmount.ToVector2(); + } } } @@ -240,7 +246,6 @@ namespace Barotrauma { caretPos = new Vector2(rect.X + size.X, rect.Y) + textPos - origin; } - } private Vector2 MeasureText(string text) @@ -257,6 +262,12 @@ namespace Barotrauma return size; } + protected override void SetAlpha(float a) + { + base.SetAlpha(a); + textColor = new Color(textColor.R, textColor.G, textColor.B, a); + } + public override void Draw(SpriteBatch spriteBatch) { Draw(spriteBatch, Vector2.Zero); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs index bc0185604..f9c02e9a9 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs @@ -11,6 +11,7 @@ namespace Barotrauma class GUITextBox : GUIComponent, IKeyboardSubscriber { public event TextBoxEvent OnSelected; + public event TextBoxEvent OnDeselected; bool caretVisible; float caretTimer; @@ -204,6 +205,8 @@ namespace Barotrauma { Selected = false; if (keyboardDispatcher.Subscriber == this) keyboardDispatcher.Subscriber = null; + + OnDeselected?.Invoke(this, Keys.None); } public override void Flash(Color? color = null) @@ -222,19 +225,17 @@ namespace Barotrauma if (rect.Contains(PlayerInput.MousePosition) && Enabled && (MouseOn == null || MouseOn == this || IsParentOf(MouseOn) || MouseOn.IsParentOf(this))) { - state = ComponentState.Hover; if (PlayerInput.LeftButtonClicked()) { Select(); - if (OnSelected != null) OnSelected(this, Keys.None); + OnSelected?.Invoke(this, Keys.None); } } else { state = ComponentState.None; } - if (CaretEnabled) { @@ -250,7 +251,7 @@ namespace Barotrauma { string input = Text; Text = ""; - OnEnterPressed(this, input); + OnEnterPressed(this, input); } #if LINUX else if (PlayerInput.KeyHit(Keys.Back) && Text.Length>0) @@ -258,7 +259,10 @@ namespace Barotrauma Text = Text.Substring(0, Text.Length-1); } #endif - + } + else if (Selected) + { + Deselect(); } textBlock.State = state; diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemLabel.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemLabel.cs index 1754370fb..662b62f65 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemLabel.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemLabel.cs @@ -34,6 +34,7 @@ namespace Barotrauma.Items.Components set { if (textBlock != null) textBlock.TextColor = value; + textColor = value; } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 9e84f33ab..4054d6a42 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -163,7 +163,7 @@ namespace Barotrauma int width = 450; int height = 150; - int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10; + int x = GameMain.GraphicsWidth / 2 - width / 2, y = 30; /*foreach (var objectProperty in editableProperties) { var editable = objectProperty.Attributes.OfType().FirstOrDefault(); @@ -171,13 +171,12 @@ namespace Barotrauma }*/ editingHUD = new GUIListBox(new Rectangle(x, y, width, height), ""); - //editingHUD.Padding = new Vector4(10, 10, 0, 0); editingHUD.UserData = this; /*new GUITextBlock(new Rectangle(0, 0, 0, 20), prefab.Name, "", Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.LargeFont);*/ - new SerializableEntityEditor(this, inGame, editingHUD); + new SerializableEntityEditor(this, inGame, editingHUD, true); //y += 25; @@ -213,9 +212,9 @@ namespace Barotrauma foreach (ItemComponent ic in components) { if (SerializableProperty.GetProperties(ic).Count == 0) continue; - new SerializableEntityEditor(ic, inGame, editingHUD); + new SerializableEntityEditor(ic, inGame, editingHUD, false); } - + /*foreach (var objectProperty in editableProperties) { int boxHeight = 18; @@ -281,6 +280,10 @@ namespace Barotrauma } y = y + boxHeight + 5; }*/ + + + editingHUD.SetDimensions(new Point(editingHUD.Rect.Width, MathHelper.Clamp(editingHUD.children.Sum(c => c.Rect.Height), 50, editingHUD.Rect.Height))); + return editingHUD; } diff --git a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs index f53365916..1b8e79029 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs @@ -17,7 +17,7 @@ namespace Barotrauma partial class Structure : MapEntity, IDamageable, IServerSerializable { private List convexHulls; - + private void GenerateConvexHull() { // If not null and not empty , remove the hulls from the system @@ -66,6 +66,37 @@ namespace Barotrauma mergedSections.Clear(); } + public override void UpdateEditing(Camera cam) + { + if (editingHUD == null || editingHUD.UserData as Structure != this) + { + editingHUD = CreateEditingHUD(Screen.Selected != GameMain.EditMapScreen); + } + + editingHUD.Update((float)Timing.Step); + } + + private GUIComponent CreateEditingHUD(bool inGame = false) + { + int width = 450; + int height = 150; + int x = GameMain.GraphicsWidth / 2 - width / 2, y = 30; + + editingHUD = new GUIListBox(new Rectangle(x, y, width, height), ""); + editingHUD.UserData = this; + + new SerializableEntityEditor(this, inGame, editingHUD, true); + + editingHUD.SetDimensions(new Point(editingHUD.Rect.Width, MathHelper.Clamp(editingHUD.children.Sum(c => c.Rect.Height), 50, editingHUD.Rect.Height))); + + return editingHUD; + } + + public override void DrawEditing(SpriteBatch spriteBatch, Camera cam) + { + if (editingHUD != null && editingHUD.UserData == this) editingHUD.Draw(spriteBatch); + } + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { if (prefab.sprite == null) return; @@ -82,7 +113,7 @@ namespace Barotrauma { if (prefab.sprite == null) return; - Color color = (isHighlighted) ? Color.Orange : Color.White; + Color color = (isHighlighted) ? Color.Orange : spriteColor; if (IsSelected && editing) { color = Color.Red; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs index 0f845ef5f..b0d984975 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs @@ -267,18 +267,20 @@ namespace Barotrauma.Networking int cargoVal = 0; extraCargo.TryGetValue(pf.Name, out cargoVal); - var amountInput = new GUINumberInput(new Rectangle(160, 0, 50, 20), "", 0, 100, textBlock); - amountInput.Value = cargoVal; + var amountInput = new GUINumberInput(new Rectangle(160, 0, 50, 20), "", GUINumberInput.NumberType.Int, textBlock); + amountInput.MinValueInt = 0; + amountInput.MaxValueInt = 100; + amountInput.IntValue = cargoVal; - amountInput.OnValueChanged += (numberInput, value) => + amountInput.OnValueChanged += (numberInput) => { if (extraCargo.ContainsKey(pf.Name)) { - extraCargo[pf.Name] = value; + extraCargo[pf.Name] = numberInput.IntValue; } else { - extraCargo.Add(pf.Name, value); + extraCargo.Add(pf.Name, numberInput.IntValue); } }; } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/NetworkMember.cs b/Barotrauma/BarotraumaClient/Source/Networking/NetworkMember.cs index 2cf14aa9f..2f0786702 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/NetworkMember.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/NetworkMember.cs @@ -182,10 +182,14 @@ namespace Barotrauma.Networking }; new GUITextBlock(new Rectangle(0, 0, 30, 20), "Days:", "", Alignment.TopLeft, Alignment.CenterLeft, durationContainer); - durationInputDays = new GUINumberInput(new Rectangle(40, 0, 50, 20), "", 0, 1000, durationContainer); + durationInputDays = new GUINumberInput(new Rectangle(40, 0, 50, 20), "", GUINumberInput.NumberType.Int, durationContainer); + durationInputDays.MinValueInt = 0; + durationInputDays.MaxValueFloat = 1000; new GUITextBlock(new Rectangle(100, 0, 30, 20), "Hours:", "", Alignment.TopLeft, Alignment.CenterLeft, durationContainer); - durationInputHours = new GUINumberInput(new Rectangle(150, 0, 50, 20), "", 0, 24, durationContainer); + durationInputHours = new GUINumberInput(new Rectangle(150, 0, 50, 20), "", GUINumberInput.NumberType.Int, durationContainer); + durationInputDays.MinValueInt = 0; + durationInputDays.MaxValueFloat = 24; } banReasonPrompt.Buttons[0].OnClicked += (btn, userData) => @@ -194,7 +198,7 @@ namespace Barotrauma.Networking { if (!permaBanTickBox.Selected) { - TimeSpan banDuration = new TimeSpan(durationInputDays.Value, durationInputHours.Value, 0, 0); + TimeSpan banDuration = new TimeSpan(durationInputDays.IntValue, durationInputHours.IntValue, 0, 0); BanPlayer(clientName, banReasonBox.Text, ban, banDuration); } else diff --git a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs index 0a09fb48e..159fea11f 100644 --- a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs +++ b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs @@ -3,20 +3,27 @@ using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Xna.Framework.Graphics; namespace Barotrauma { class SerializableEntityEditor : GUIComponent { - private GUIComponent editingHUD; - public SerializableEntityEditor(ISerializableEntity entity, bool inGame, GUIComponent parent) : base("") + private static readonly string[] vectorComponentLabels = { "X", "Y", "Z", "W" }; + private static readonly string[] rectComponentLabels = { "X", "Y", "Width", "Height" }; + private static readonly string[] colorComponentLabels = { "R", "G", "B", "A" }; + + //private GUIComponent editingHUD; + + public SerializableEntityEditor(ISerializableEntity entity, bool inGame, GUIComponent parent, bool showName) : base("") { List editableProperties = inGame ? SerializableProperty.GetProperties(entity) : SerializableProperty.GetProperties(entity); + + if (parent != null) + parent.AddChild(this); /*int requiredItemCount = 0; if (!inGame) @@ -31,16 +38,19 @@ namespace Barotrauma { var editable = objectProperty.Attributes.OfType().FirstOrDefault(); if (editable != null) height += (int)(Math.Ceiling(editable.MaxLength / 40.0f) * 18.0f) + 5; - }*/ + } editingHUD = new GUIFrame(new Rectangle(0, 0, 0, 0), null, parent); - editingHUD.Padding = new Vector4(10, 10, 00, 20); - editingHUD.UserData = this; + editingHUD.Padding = new Vector4(10, 0, 0, 10); + editingHUD.UserData = this;*/ - new GUITextBlock(new Rectangle(0, 0, 100, 20), entity.Name, "", - Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.Font); + if (showName) + { + new GUITextBlock(new Rectangle(0, 0, 100, 20), entity.Name, "", + Alignment.TopLeft, Alignment.TopLeft, this, false, GUI.Font); + } - int y = 20, padding = 5; + int y = 30, padding = 10; foreach (var property in editableProperties) { //int boxHeight = 18; @@ -52,23 +62,39 @@ namespace Barotrauma GUIComponent propertyField = null; if (value is bool) { - propertyField = CreateBoolField(entity, property, (bool)value, y, editingHUD); + propertyField = CreateBoolField(entity, property, (bool)value, y, this); } else if (value.GetType().IsEnum) { - propertyField = CreateEnumField(entity, property, value, y, editingHUD); + propertyField = CreateEnumField(entity, property, value, y, this); } else if (value is string) { - propertyField = CreateStringField(entity, property, (string)value, y, editingHUD); + propertyField = CreateStringField(entity, property, (string)value, y, this); } else if (value is int) { - propertyField = CreateIntField(entity, property, (int)value, y, editingHUD); + propertyField = CreateIntField(entity, property, (int)value, y, this); } else if (value is float) { - propertyField = CreateFloatField(entity, property, (float)value, y, editingHUD); + propertyField = CreateFloatField(entity, property, (float)value, y, this); + } + else if (value is Vector2) + { + propertyField = CreateVector2Field(entity, property, (Vector2)value, y, this); + } + else if (value is Vector3) + { + propertyField = CreateVector3Field(entity, property, (Vector3)value, y, this); + } + else if (value is Vector4) + { + propertyField = CreateVector4Field(entity, property, (Vector4)value, y, this); + } + else if (value is Color) + { + propertyField = CreateColorField(entity, property, (Color)value, y, this); } if (propertyField != null) @@ -77,7 +103,14 @@ namespace Barotrauma } } - editingHUD.SetDimensions(new Point(editingHUD.Rect.Width, editingHUD.children.Sum(c => c.Rect.Height) + 10), false); + SetDimensions(new Point(Rect.Width, children.Last().Rect.Bottom - Rect.Y + 10), false); + } + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + + DrawChildren(spriteBatch); } private GUIComponent CreateBoolField(ISerializableEntity entity, SerializableProperty property, bool value, int yPos, GUIComponent parent) @@ -85,6 +118,7 @@ namespace Barotrauma GUITickBox propertyTickBox = new GUITickBox(new Rectangle(10, yPos, 18, 18), property.Name, Alignment.Left, parent); propertyTickBox.Font = GUI.SmallFont; propertyTickBox.Selected = value; + propertyTickBox.ToolTip = property.GetAttribute().ToolTip; propertyTickBox.OnSelected = (tickBox) => { @@ -100,17 +134,21 @@ namespace Barotrauma private GUIComponent CreateIntField(ISerializableEntity entity, SerializableProperty property, int value, int yPos, GUIComponent parent) { - new GUITextBlock(new Rectangle(10, yPos, 100, 18), property.Name, "", parent, GUI.SmallFont); - GUINumberInput numberInput = new GUINumberInput(new Rectangle(180, yPos, 0, 18), "", Alignment.Left, null, null, parent); + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + GUINumberInput numberInput = new GUINumberInput(new Rectangle(180, yPos, 0, 18), "", GUINumberInput.NumberType.Int, Alignment.Left, parent); + numberInput.ToolTip = property.GetAttribute().ToolTip; numberInput.Font = GUI.SmallFont; var editableAttribute = property.GetAttribute(); - numberInput.MinValue = editableAttribute.MinValueInt; - numberInput.MinValue = editableAttribute.MaxValueInt; + numberInput.MinValueInt = editableAttribute.MinValueInt; + numberInput.MaxValueInt = editableAttribute.MaxValueInt; - numberInput.OnValueChanged += (numInput, number) => + numberInput.IntValue = value; + + numberInput.OnValueChanged += (numInput) => { - if (property.TrySetValue(number)) + if (property.TrySetValue(numInput.IntValue)) { TrySendNetworkUpdate(entity, property); } @@ -121,17 +159,36 @@ namespace Barotrauma private GUIComponent CreateFloatField(ISerializableEntity entity, SerializableProperty property, float value, int yPos, GUIComponent parent) { - new GUITextBlock(new Rectangle(10, yPos, 100, 18), property.Name, "", parent, GUI.SmallFont); - GUINumberInput numberInput = new GUINumberInput(new Rectangle(180, yPos, 0, 18), "", Alignment.Left, null, null, parent); + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + GUINumberInput numberInput = new GUINumberInput(new Rectangle(180, yPos, 0, 18), "", GUINumberInput.NumberType.Float, Alignment.Left, parent); + numberInput.ToolTip = property.GetAttribute().ToolTip; numberInput.Font = GUI.SmallFont; + var editableAttribute = property.GetAttribute(); + numberInput.MinValueFloat = editableAttribute.MinValueFloat; + numberInput.MaxValueFloat = editableAttribute.MaxValueFloat; + + numberInput.FloatValue = value; + + numberInput.OnValueChanged += (numInput) => + { + if (property.TrySetValue(numInput.FloatValue)) + { + TrySendNetworkUpdate(entity, property); + } + }; + return numberInput; } private GUIComponent CreateEnumField(ISerializableEntity entity, SerializableProperty property, object value, int yPos, GUIComponent parent) { - new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, editingHUD, false, GUI.SmallFont); + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; GUIDropDown enumDropDown = new GUIDropDown(new Rectangle(180, yPos, 0, 18), "", "", Alignment.TopLeft, parent); + enumDropDown.ToolTip = property.GetAttribute().ToolTip; + foreach (object enumValue in Enum.GetValues(value.GetType())) { var enumTextBlock = new GUITextBlock(new Rectangle(0, 0, 200, 25), enumValue.ToString(), "", enumDropDown); @@ -154,12 +211,17 @@ namespace Barotrauma private GUIComponent CreateStringField(ISerializableEntity entity, SerializableProperty property, string value, int yPos, GUIComponent parent) { - new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); - GUITextBox propertyBox = new GUITextBox(new Rectangle(0, yPos, 250, 18), Alignment.Right, "", parent); - propertyBox.Font = GUI.SmallFont; - //if (boxHeight > 18) propertyBox.Wrap = true; + int boxHeight = 18; + var editable = property.GetAttribute(); + boxHeight = (int)(Math.Ceiling(editable.MaxLength / 40.0f) * boxHeight); - propertyBox.Text = value; + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + GUITextBox propertyBox = new GUITextBox(new Rectangle(0, yPos, 250, boxHeight), Alignment.Right, "", parent); + propertyBox.ToolTip = editable.ToolTip; + propertyBox.Font = GUI.SmallFont; + + propertyBox.Text = value; propertyBox.OnEnterPressed = (textBox, text) => { if (property.TrySetValue(value)) @@ -172,6 +234,150 @@ namespace Barotrauma return propertyBox; } + private GUIComponent CreateVector2Field(ISerializableEntity entity, SerializableProperty property, Vector2 value, int yPos, GUIComponent parent) + { + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + + for (int i = 0; i < 2; i++) + { + new GUITextBlock(new Rectangle(140 + i * 70, yPos, 100, 18), vectorComponentLabels[i], "", Alignment.TopLeft, Alignment.CenterLeft, parent, false, GUI.SmallFont); + GUINumberInput numberInput = new GUINumberInput(new Rectangle(160 + i * 70, yPos, 45, 18), "", GUINumberInput.NumberType.Float, Alignment.Left, parent); + numberInput.Font = GUI.SmallFont; + + int comp = i; + numberInput.OnValueChanged += (numInput) => + { + Vector2 newVal = (Vector2)property.GetValue(); + if (comp == 0) + newVal.X = numInput.FloatValue; + else + newVal.Y = numInput.FloatValue; + + if (property.TrySetValue(newVal)) + { + TrySendNetworkUpdate(entity, property); + } + }; + } + + return label; + } + + private GUIComponent CreateVector3Field(ISerializableEntity entity, SerializableProperty property, Vector3 value, int yPos, GUIComponent parent) + { + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + for (int i = 0; i < 3; i++) + { + new GUITextBlock(new Rectangle(140 + i * 70, yPos, 100, 18), vectorComponentLabels[i], "", Alignment.TopLeft, Alignment.CenterLeft, parent, false, GUI.SmallFont); + GUINumberInput numberInput = new GUINumberInput(new Rectangle(160 + i * 70, yPos, 45, 18), "", GUINumberInput.NumberType.Float, Alignment.Left, parent); + numberInput.Font = GUI.SmallFont; + + int comp = i; + numberInput.OnValueChanged += (numInput) => + { + Vector3 newVal = (Vector3)property.GetValue(); + if (comp == 0) + newVal.X = numInput.FloatValue; + else if (comp == 1) + newVal.Y = numInput.FloatValue; + else + newVal.Z = numInput.FloatValue; + + if (property.TrySetValue(newVal)) + { + TrySendNetworkUpdate(entity, property); + } + }; + } + + return label; + } + + private GUIComponent CreateVector4Field(ISerializableEntity entity, SerializableProperty property, Vector4 value, int yPos, GUIComponent parent) + { + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + for (int i = 0; i < 4; i++) + { + new GUITextBlock(new Rectangle(140 + i * 70, yPos, 100, 18), vectorComponentLabels[i], "", Alignment.TopLeft, Alignment.CenterLeft, parent, false, GUI.SmallFont); + GUINumberInput numberInput = new GUINumberInput(new Rectangle(160 + i * 70, yPos, 45, 18), "", GUINumberInput.NumberType.Float, Alignment.Left, parent); + numberInput.Font = GUI.SmallFont; + + int comp = i; + numberInput.OnValueChanged += (numInput) => + { + Vector4 newVal = (Vector4)property.GetValue(); + if (comp == 0) + newVal.X = numInput.FloatValue; + else if (comp == 1) + newVal.Y = numInput.FloatValue; + else if (comp == 2) + newVal.Z = numInput.FloatValue; + else + newVal.W = numInput.FloatValue; + + if (property.TrySetValue(newVal)) + { + TrySendNetworkUpdate(entity, property); + } + }; + } + + return label; + } + + private GUIComponent CreateColorField(ISerializableEntity entity, SerializableProperty property, Color value, int yPos, GUIComponent parent) + { + var label = new GUITextBlock(new Rectangle(0, yPos, 100, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont); + label.ToolTip = property.GetAttribute().ToolTip; + + var colorBoxBack = new GUIFrame(new Rectangle(110 - 1, yPos - 1, 25 + 2, 18 + 2), Color.Black, Alignment.TopLeft, null, parent); + var colorBox = new GUIFrame(new Rectangle(110, yPos , 25, 18), value, Alignment.TopLeft, null, parent); + + for (int i = 0; i < 4; i++) + { + new GUITextBlock(new Rectangle(140 + i * 70, yPos, 100, 18), colorComponentLabels[i], "", Alignment.TopLeft, Alignment.CenterLeft, parent, false, GUI.SmallFont); + GUINumberInput numberInput = new GUINumberInput(new Rectangle(160 + i * 70, yPos, 45, 18), "", GUINumberInput.NumberType.Float, Alignment.Left, parent); + numberInput.MinValueFloat = 0.0f; + numberInput.MaxValueFloat = 1.0f; + + if (i == 0) + numberInput.FloatValue = value.R / 255.0f; + else if (i == 1) + numberInput.FloatValue = value.G / 255.0f; + else if (i == 2) + numberInput.FloatValue = value.B / 255.0f; + else + numberInput.FloatValue = value.A / 255.0f; + + numberInput.Font = GUI.SmallFont; + + int comp = i; + numberInput.OnValueChanged += (numInput) => + { + Color newVal = (Color)property.GetValue(); + if (comp == 0) + newVal.R = (byte)(numInput.FloatValue * 255); + else if (comp == 1) + newVal.G = (byte)(numInput.FloatValue * 255); + else if (comp == 2) + newVal.B = (byte)(numInput.FloatValue * 255); + else + newVal.A = (byte)(numInput.FloatValue * 255); + + if (property.TrySetValue(newVal)) + { + TrySendNetworkUpdate(entity, property); + colorBox.Color = newVal; + } + }; + } + + return label; + } + private void TrySendNetworkUpdate(ISerializableEntity entity, SerializableProperty property) { if (GameMain.Server != null) @@ -190,7 +396,7 @@ namespace Barotrauma GameMain.Client.CreateEntityEvent(clientSerializable, new object[] { NetEntityEvent.Type.ChangeProperty, property }); } } - } + } } } diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index 94ccb34d2..d3b1f729b 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -1495,8 +1495,8 @@ - - + + diff --git a/Barotrauma/BarotraumaShared/Content/UI/style.xml b/Barotrauma/BarotraumaShared/Content/UI/style.xml index 28bc37af4..fcec58d47 100644 --- a/Barotrauma/BarotraumaShared/Content/UI/style.xml +++ b/Barotrauma/BarotraumaShared/Content/UI/style.xml @@ -271,4 +271,15 @@ + + + + + + \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs index 66f0f4063..c1d1c3230 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs @@ -40,26 +40,27 @@ namespace Barotrauma } } - partial class Structure : MapEntity, IDamageable, IServerSerializable + partial class Structure : MapEntity, IDamageable, IServerSerializable, ISerializableEntity { public static int wallSectionSize = 96; public static List WallList = new List(); - StructurePrefab prefab; + private StructurePrefab prefab; //farseer physics bodies, separated by gaps - List bodies; + private List bodies; + + private bool isHorizontal; + + private SpriteEffects SpriteEffects = SpriteEffects.None; //sections of the wall that are supposed to be rendered - public WallSection[] sections { + public WallSection[] sections + { get; private set; } - bool isHorizontal; - - public SpriteEffects SpriteEffects = SpriteEffects.None; - public bool resizeHorizontal { get { return prefab.resizeHorizontal; } @@ -147,6 +148,14 @@ namespace Barotrauma get { return prefab.tags; } } + protected Color spriteColor; + [Editable, Serialize("1.0,1.0,1.0,1.0", true)] + public Color SpriteColor + { + get { return spriteColor; } + set { spriteColor = value; } + } + public override Rectangle Rect { get @@ -175,7 +184,13 @@ namespace Barotrauma } } - + + public Dictionary SerializableProperties + { + get; + private set; + } + public override void Move(Vector2 amount) { base.Move(amount); @@ -213,11 +228,15 @@ namespace Barotrauma rect = rectangle; prefab = sp; - - isHorizontal = (rect.Width>rect.Height); + + spriteColor = prefab.SpriteColor; + + isHorizontal = (rect.Width > rect.Height); StairDirection = prefab.StairDirection; - + + SerializableProperties = SerializableProperty.GetProperties(this); + if (prefab.HasBody) { bodies = new List(); @@ -230,11 +249,8 @@ namespace Barotrauma newBody.BodyType = BodyType.Static; newBody.Position = ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f)); newBody.Friction = 0.5f; - newBody.OnCollision += OnWallCollision; - newBody.UserData = this; - newBody.CollisionCategories = (prefab.IsPlatform) ? Physics.CollisionPlatform : Physics.CollisionWall; bodies.Add(newBody); @@ -854,6 +870,8 @@ namespace Barotrauma break; } } + + SerializableProperty.DeserializeProperties(s, element); } public override XElement Save(XElement parentElement) @@ -884,6 +902,8 @@ namespace Barotrauma element.Add(sectionElement); } + SerializableProperty.SerializeProperties(this, element); + parentElement.Add(element); return element; diff --git a/Barotrauma/BarotraumaShared/Source/Serialization/SerializableProperty.cs b/Barotrauma/BarotraumaShared/Source/Serialization/SerializableProperty.cs index 4aa5a3037..558fc1958 100644 --- a/Barotrauma/BarotraumaShared/Source/Serialization/SerializableProperty.cs +++ b/Barotrauma/BarotraumaShared/Source/Serialization/SerializableProperty.cs @@ -18,6 +18,8 @@ namespace Barotrauma public int? MinValueInt, MaxValueInt; public float? MinValueFloat, MaxValueFloat; + public string ToolTip; + public Editable(int maxLength = 20) { MaxLength = maxLength;