Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ partial class ItemLabel : ItemComponent, IDrawableComponent, IHasExtraTextPicker

private Vector4 padding;

[Serialize("0,0,0,0", IsPropertySaveable.Yes, description: "The amount of padding around the text in pixels (left,top,right,bottom).")]
[Editable(DecimalCount = 0, VectorComponentLabels = new string[] { "inputtype.left", "inputtype.up", "inputtype.right", "inputtype.down" }), Serialize("0,0,0,0", IsPropertySaveable.Yes, description: "The amount of padding around the text in pixels.")]
public Vector4 Padding
{
get { return padding; }
Expand All @@ -40,6 +40,14 @@ public Vector4 Padding
}
}

private Alignment alignment;
[Editable, Serialize(Alignment.Center, IsPropertySaveable.Yes, description: "The alignment of the label's text.")]
public Alignment TextAlignment
{
get => alignment;
set => alignment = textBlock.TextAlignment = value;
}

private string text;
[Serialize("", IsPropertySaveable.Yes, translationTextTag: "Label.", description: "The text displayed in the label.", alwaysUseInstanceValues: true), Editable(MaxLength = 100)]
public string Text
Expand All @@ -60,6 +68,14 @@ public string Text
}
}

private GUIFont font;
[Editable, Serialize("UnscaledSmallFont", IsPropertySaveable.Yes, "The label's font.")]
public GUIFont Font
{
get => font;
set => font = textBlock.Font = value;
}

private bool ignoreLocalization;

[Editable, Serialize(false, IsPropertySaveable.Yes, "Whether or not to skip localization and always display the raw value.")]
Expand Down Expand Up @@ -118,7 +134,6 @@ public bool Scrollable
scrollable = value;
IsActive = value || parseSpecialTextTagOnStart;
TextBlock.Wrap = !scrollable;
TextBlock.TextAlignment = scrollable ? Alignment.CenterLeft : Alignment.Center;
}
}

Expand Down Expand Up @@ -164,12 +179,14 @@ private void SetScrollingText()
needsScrolling = true;
float spaceWidth = textBlock.Font.MeasureChar(' ').X * TextBlock.TextScale;
scrollingText = new string(' ', (int)Math.Ceiling(textAreaWidth / spaceWidth)) + DisplayText.Value;
TextBlock.TextAlignment = Alignment.CenterLeft;
}
else
{
//whole text can fit in the textblock, no need to scroll
needsScrolling = false;
TextBlock.Text = scrollingText = DisplayText.Value;
TextBlock.TextAlignment = alignment;
scrollPadding = 0;
scrollAmount = 0.0f;
scrollIndex = 0;
Expand Down Expand Up @@ -215,7 +232,7 @@ private void SetDisplayText(string value)
private void RecreateTextBlock()
{
textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "",
textColor: textColor, font: GUIStyle.UnscaledSmallFont, textAlignment: scrollable ? Alignment.CenterLeft : Alignment.Center, wrap: !scrollable, style: null)
textColor: textColor, font: font, textAlignment: needsScrolling ? Alignment.CenterLeft : alignment, wrap: !scrollable, style: null)
{
TextDepth = item.SpriteDepth - 0.00001f,
RoundToNearestPixel = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sealed class SerializableEntityEditor : GUIComponent
public bool Readonly
{
get => isReadonly;
set
set
{
foreach (var component in Fields.SelectMany(f => f.Value))
{
Expand Down Expand Up @@ -317,8 +317,8 @@ public void UpdateValue(SerializableProperty property, object newValue, bool fla
}

public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, bool inGame, bool showName, string style = "", int elementHeight = 24, GUIFont titleFont = null)
: this(parent, entity, inGame ?
SerializableProperty.GetProperties<InGameEditable>(entity).Union(SerializableProperty.GetProperties<ConditionallyEditable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? false))
: this(parent, entity, inGame ?
SerializableProperty.GetProperties<InGameEditable>(entity).Union(SerializableProperty.GetProperties<ConditionallyEditable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? false))
: SerializableProperty.GetProperties<Editable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? true), showName, style, elementHeight, titleFont)
{
}
Expand All @@ -344,10 +344,10 @@ public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity
};
}

List<Header> headers = new List<Header>()
List<Header> headers = new List<Header>()
{
//"no header" comes first = properties under no header are listed first
null
null
};
//check which header each property is under
Dictionary<SerializableProperty, Header> propertyHeaders = new Dictionary<SerializableProperty, Header>();
Expand All @@ -360,11 +360,11 @@ public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity
prevHeader = header;
//Attribute.Equals is based on the equality of the fields,
//so in practice we treat identical headers split into different files/classes as the same header
if (!headers.Contains(header))
{
if (!headers.Contains(header))
{
//collect headers into a list in the order they're encountered in
//(to keep them in the same order as they're defined in the code, as the dictionary is not in any particular order)
headers.Add(header);
headers.Add(header);
}
}
propertyHeaders[property] = prevHeader;
Expand Down Expand Up @@ -430,9 +430,9 @@ public GUIComponent CreateNewField(SerializableProperty property, ISerializableE
displayName = TextManager.Get(fallbackTag, $"sp.{fallbackTag}.name".ToIdentifier());
}
}

if (displayName.IsNullOrEmpty())
{
{
displayName = property.Name.FormatCamelCaseWithSpaces();
#if DEBUG
InGameEditable editable = property.GetAttribute<InGameEditable>();
Expand Down Expand Up @@ -523,58 +523,62 @@ public GUIComponent CreateNewField(SerializableProperty property, ISerializableE
{
propertyField = CreateStringField(entity, property, value.ToString(), displayName, toolTip);
}
else if (value is GUIFont font)
{
propertyField = CreateFontField(entity, property, font, displayName, toolTip);
}
return propertyField;
}

public GUIComponent CreateBoolField(ISerializableEntity entity, SerializableProperty property, bool value, LocalizedString displayName, LocalizedString toolTip)
{
var editableAttribute = property.GetAttribute<Editable>();
if (editableAttribute.ReadOnly)
{
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUIStyle.SmallFont)
{
ToolTip = toolTip
};
var valueField = new GUITextBlock(new RectTransform(new Vector2(inputFieldWidth, 1), frame.RectTransform, Anchor.TopRight), value.ToString())
var editableAttribute = property.GetAttribute<Editable>();
if (editableAttribute.ReadOnly)
{
ToolTip = toolTip,
Font = GUIStyle.SmallFont
};
return valueField;
}
else
{
GUITickBox propertyTickBox = new GUITickBox(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), displayName)
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUIStyle.SmallFont)
{
ToolTip = toolTip
};
var valueField = new GUITextBlock(new RectTransform(new Vector2(inputFieldWidth, 1), frame.RectTransform, Anchor.TopRight), value.ToString())
{
ToolTip = toolTip,
Font = GUIStyle.SmallFont
};
return valueField;
}
else
{
Font = GUIStyle.SmallFont,
Enabled = !Readonly,
Selected = value,
ToolTip = toolTip,
OnSelected = (tickBox) =>
GUITickBox propertyTickBox = new GUITickBox(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), displayName)
{
if (SetPropertyValue(property, entity, tickBox.Selected))
{
TrySendNetworkUpdate(entity, property);
}
// Ensure that the values stay in sync (could be that we force the value in the property accessor).
bool propertyValue = (bool)property.GetValue(entity);
if (tickBox.Selected != propertyValue)
Font = GUIStyle.SmallFont,
Enabled = !Readonly,
Selected = value,
ToolTip = toolTip,
OnSelected = (tickBox) =>
{
tickBox.Selected = propertyValue;
tickBox.Flash(Color.Red);
if (SetPropertyValue(property, entity, tickBox.Selected))
{
TrySendNetworkUpdate(entity, property);
}
// Ensure that the values stay in sync (could be that we force the value in the property accessor).
bool propertyValue = (bool)property.GetValue(entity);
if (tickBox.Selected != propertyValue)
{
tickBox.Selected = propertyValue;
tickBox.Flash(Color.Red);
}
return true;
}
return true;
}
};
refresh += () =>
{
propertyTickBox.Selected = (bool)property.GetValue(entity);
};
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name.ToIdentifier(), new GUIComponent[] { propertyTickBox }); }
return propertyTickBox;
};
refresh += () =>
{
propertyTickBox.Selected = (bool)property.GetValue(entity);
};
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name.ToIdentifier(), new GUIComponent[] { propertyTickBox }); }
return propertyTickBox;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why this method was modified (seems unrelated to the rest of the changes in the PR) or what was actually modified about it.

Copy link
Author

@Jade-Harleyy Jade-Harleyy Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the new commit has made it show the changes.
From the looks of it, it seems autoformatting has struck again, fixing broken spacing.
Most likely not a problem, but can be reverted if necessary.

}
}

public GUIComponent CreateIntField(ISerializableEntity entity, SerializableProperty property, int value, LocalizedString displayName, LocalizedString toolTip)
{
Expand Down Expand Up @@ -1511,6 +1515,38 @@ public void CreateTextPicker(string textTag, ISerializableEntity entity, Seriali
}
}

public GUIComponent CreateFontField(ISerializableEntity entity, SerializableProperty property, GUIFont value, LocalizedString displayName, LocalizedString toolTip)
{
GUIFrame frame = new(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
GUITextBlock label = new(new RectTransform(new Vector2(1f - inputFieldWidth, 1f), frame.RectTransform), displayName, font: GUIStyle.SmallFont)
{
ToolTip = toolTip
};
GUIDropDown dropDown = new GUIDropDown(new RectTransform(new Vector2(inputFieldWidth, 1), frame.RectTransform, Anchor.TopRight), elementCount: GUIStyle.Fonts.Count)
{
ToolTip = toolTip
};
foreach ((Identifier fontIdentifier, GUIFont font) in GUIStyle.Fonts)
{
dropDown.AddItem(fontIdentifier.Value, font);
}
dropDown.SelectItem(value);
dropDown.OnSelected += (selected, val) =>
{
if (SetPropertyValue(property, entity, val))
{
TrySendNetworkUpdate(entity, property);
}
return true;
};
refresh += () =>
{
if (!dropDown.Dropped) { dropDown.SelectItem(property.GetValue(entity)); }
};
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name.ToIdentifier(), new GUIComponent[] { dropDown }); }
return frame;
}

private static void TrySendNetworkUpdate(ISerializableEntity entity, SerializableProperty property)
{
if (IsEntityRemoved(entity)) { return; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ public sealed class SerializableProperty
{ typeof(Rectangle), "rectangle" },
{ typeof(Color), "color" },
{ typeof(string[]), "stringarray" },
{ typeof(Identifier[]), "identifierarray" }
{ typeof(Identifier[]), "identifierarray" },
#if CLIENT
{ typeof(GUIFont), "font" }
#endif
}.ToImmutableDictionary();

private static readonly Dictionary<Type, Dictionary<Identifier, SerializableProperty>> cachedProperties =
Expand Down Expand Up @@ -219,6 +222,11 @@ public bool TrySetValue(object parentObject, string value)
case "identifierarray":
PropertyInfo.SetValue(parentObject, ParseIdentifierArray(value));
break;
#if CLIENT
case "font":
PropertyInfo.SetValue(parentObject, GUIStyle.Fonts.TryGetValue(new(value), out GUIFont font) ? font : null);
break;
#endif
}
}
catch (Exception e)
Expand Down Expand Up @@ -314,6 +322,11 @@ public bool TrySetValue(object parentObject, object value)
case "identifierarray":
PropertyInfo.SetValue(parentObject, ParseIdentifierArray((string)value));
return true;
#if CLIENT
case "font":
PropertyInfo.SetValue(parentObject, GUIStyle.Fonts.TryGetValue(new((string)value), out GUIFont font) ? font : null);
return true;
#endif
default:
DebugConsole.ThrowError($"Failed to set the value of the property \"{Name}\" of \"{parentObject}\" to {value}");
DebugConsole.ThrowError($"(Cannot convert a string to a {PropertyType})");
Expand Down Expand Up @@ -943,6 +956,11 @@ public static void SerializeProperties(ISerializableEntity obj, XElement element
Identifier[] identifierArray = (Identifier[])value;
stringValue = identifierArray != null ? string.Join(';', identifierArray) : "";
break;
#if CLIENT
case "font":
stringValue = ((GUIFont)value).Identifier.Value;
break;
#endif
default:
stringValue = value.ToString();
break;
Expand Down