diff --git a/Intersect (Core)/Config/MapOptions.cs b/Intersect (Core)/Config/MapOptions.cs
index 2cd9a3bba0..1bfa643575 100644
--- a/Intersect (Core)/Config/MapOptions.cs
+++ b/Intersect (Core)/Config/MapOptions.cs
@@ -64,6 +64,9 @@ public bool EnableDiagonalMovement
///
public int TileWidth { get; set; } = 32;
+ [JsonIgnore]
+ public float TileScale => 32f / Math.Min(TileWidth, TileHeight);
+
///
/// The time, in milliseconds, until the map is cleaned up.
///
diff --git a/Intersect.Client.Framework/Database/GameDatabase.cs b/Intersect.Client.Framework/Database/GameDatabase.cs
index 012cf8cbfd..3818e111cf 100644
--- a/Intersect.Client.Framework/Database/GameDatabase.cs
+++ b/Intersect.Client.Framework/Database/GameDatabase.cs
@@ -62,12 +62,16 @@ public abstract partial class GameDatabase
public TypewriterBehavior TypewriterBehavior { get; set; }
+ public float UIScale { get; set; } = 1.0f;
+
+ public float WorldZoom { get; set; } = 1.0f;
+
public abstract void DeletePreference(string key);
public abstract bool HasPreference(string key);
//Saving password, other stuff we don't want in the games directory
- public abstract void SavePreference(string key, object value);
+ public abstract void SavePreference(string key, TValue value);
public abstract string LoadPreference(string key);
@@ -128,6 +132,8 @@ public virtual void LoadPreferences()
ShowHealthAsPercentage = LoadPreference(nameof(ShowHealthAsPercentage), false);
ShowManaAsPercentage = LoadPreference(nameof(ShowManaAsPercentage), false);
TypewriterBehavior = LoadPreference(nameof(TypewriterBehavior), TypewriterBehavior.Word);
+ UIScale = LoadPreference(nameof(UIScale), 1.0f);
+ WorldZoom = LoadPreference(nameof(WorldZoom), 1.0f);
}
///
@@ -162,6 +168,8 @@ public virtual void SavePreferences()
SavePreference(nameof(ShowHealthAsPercentage), ShowHealthAsPercentage);
SavePreference(nameof(ShowManaAsPercentage), ShowManaAsPercentage);
SavePreference(nameof(TypewriterBehavior), TypewriterBehavior);
+ SavePreference(nameof(UIScale), UIScale);
+ SavePreference(nameof(WorldZoom), WorldZoom);
}
public abstract bool LoadConfig();
diff --git a/Intersect.Client.Framework/Entities/IPlayer.cs b/Intersect.Client.Framework/Entities/IPlayer.cs
index 069b4dcdcf..6386790771 100644
--- a/Intersect.Client.Framework/Entities/IPlayer.cs
+++ b/Intersect.Client.Framework/Entities/IPlayer.cs
@@ -33,7 +33,7 @@ public interface IPlayer : IEntity
bool TryTarget();
bool TryTarget(IEntity entity, bool force = false);
void AutoTarget();
- void ClearTarget();
+ bool ClearTarget();
void AddToHotbar(int hotbarSlot, sbyte itemType, int itemSlot);
int FindHotbarItem(IHotbarInstance hotbarInstance);
int FindHotbarSpell(IHotbarInstance hotbarInstance);
diff --git a/Intersect.Client.Framework/GenericClasses/FloatRect.cs b/Intersect.Client.Framework/GenericClasses/FloatRect.cs
index fc09742b57..681548ad79 100644
--- a/Intersect.Client.Framework/GenericClasses/FloatRect.cs
+++ b/Intersect.Client.Framework/GenericClasses/FloatRect.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
namespace Intersect.Client.Framework.GenericClasses
{
@@ -116,6 +117,34 @@ public bool Contains(Point pt)
return Contains(pt.X, pt.Y);
}
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FloatRect operator *(FloatRect lhs, float rhs)
+ {
+ return new FloatRect(
+ lhs.X * rhs,
+ lhs.Y * rhs,
+ lhs.Width * rhs,
+ lhs.Height * rhs
+ );
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FloatRect operator *(float lhs, FloatRect rhs) => rhs * lhs;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FloatRect operator /(FloatRect lhs, float rhs)
+ {
+ return new FloatRect(
+ lhs.X / rhs,
+ lhs.Y / rhs,
+ lhs.Width / rhs,
+ lhs.Height / rhs
+ );
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static FloatRect operator /(float lhs, FloatRect rhs) => rhs / lhs;
+
+ public override string ToString() => $"{Left},{Top} + {Width},{Height} -> {Right},{Bottom}";
+ }
}
diff --git a/Intersect.Client.Framework/Graphics/GameRenderer.cs b/Intersect.Client.Framework/Graphics/GameRenderer.cs
index 12360683af..620cdd3084 100644
--- a/Intersect.Client.Framework/Graphics/GameRenderer.cs
+++ b/Intersect.Client.Framework/Graphics/GameRenderer.cs
@@ -25,6 +25,23 @@ public GameRenderer()
public Resolution PreferredResolution { get; set; }
+ protected float _scale = 1.0f;
+
+ public float Scale
+ {
+ get => _scale;
+ set
+ {
+ if (Math.Abs(_scale - value) < 0.001)
+ {
+ return;
+ }
+
+ _scale = value;
+ RecreateSpriteBatch();
+ }
+ }
+
public abstract void Init();
///
@@ -35,6 +52,8 @@ public GameRenderer()
public abstract bool BeginScreenshot();
+ protected abstract bool RecreateSpriteBatch();
+
///
/// Called when the frame is done being drawn, generally used to finally display the content to the screen.
///
diff --git a/Intersect.Client.Framework/Gwen/Control/Base.cs b/Intersect.Client.Framework/Gwen/Control/Base.cs
index 7953daf68a..a085cd1469 100644
--- a/Intersect.Client.Framework/Gwen/Control/Base.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Base.cs
@@ -72,6 +72,7 @@ internal bool InheritParentEnablementProperties
private Point mAlignmentTransform;
private Rectangle mBounds;
+ private Rectangle mBoundsOnDisk;
private bool mCacheTextureDirty;
@@ -797,34 +798,12 @@ public void RemoveAlignments()
mAlignments.Clear();
}
- public virtual string GetJsonUI()
+ public virtual string GetJsonUI(bool isRoot = false)
{
- return JsonConvert.SerializeObject(GetJson(), Formatting.Indented);
+ return JsonConvert.SerializeObject(GetJson(isRoot), Formatting.Indented);
}
- public virtual void WriteBaseUIJson(string path, bool includeBounds = true, bool onlyChildren = false)
- {
- if (onlyChildren)
- {
- if (HasNamedChildren())
- {
- foreach (var ctrl in mChildren)
- {
- if (!string.IsNullOrEmpty(ctrl.Name))
- {
- ctrl.WriteBaseUIJson(path);
- }
- }
- }
- }
- else
- {
- path = Path.Combine(path, Name + ".json");
- File.WriteAllText(path, JsonConvert.SerializeObject(GetJson(), Formatting.Indented));
- }
- }
-
- public virtual JObject GetJson()
+ public virtual JObject GetJson(bool isRoot = default)
{
var alignments = new List();
foreach (var alignment in mAlignments)
@@ -832,8 +811,13 @@ public virtual JObject GetJson()
alignments.Add(alignment.ToString());
}
+ isRoot |= Parent == default;
+
+ var boundsToWrite = isRoot
+ ? new Rectangle(mBoundsOnDisk.X, mBoundsOnDisk.Y, mBounds.Width, mBounds.Height)
+ : mBounds;
var o = new JObject(
- new JProperty("Bounds", Rectangle.ToString(mBounds)),
+ new JProperty("Bounds", Rectangle.ToString(boundsToWrite)),
new JProperty("Padding", Padding.ToString(mPadding)),
new JProperty("AlignmentEdgeDistances", Padding.ToString(mAlignmentDistance)),
new JProperty("AlignmentTransform", Point.ToString(mAlignmentTransform)),
@@ -896,7 +880,7 @@ public void LoadJsonUi(GameContentManager.UI stage, string resolution, bool save
if (obj != null)
{
- LoadJson(obj);
+ LoadJson(obj, true);
ProcessAlignments();
}
}
@@ -909,12 +893,12 @@ public void LoadJsonUi(GameContentManager.UI stage, string resolution, bool save
if (!cacheHit && saveOutput)
{
- GameContentManager.Current?.SaveUIJson(stage, Name, GetJsonUI(), resolution);
+ GameContentManager.Current?.SaveUIJson(stage, Name, GetJsonUI(true), resolution);
}
});
}
- public virtual void LoadJson(JToken obj)
+ public virtual void LoadJson(JToken obj, bool isRoot = default)
{
if (obj["Alignments"] != null)
{
@@ -964,7 +948,16 @@ public virtual void LoadJson(JToken obj)
if (obj["Bounds"] != null)
{
- SetBounds(Rectangle.FromString((string) obj["Bounds"]));
+ mBoundsOnDisk = Rectangle.FromString((string)obj["Bounds"]);
+ isRoot = isRoot || Parent == default;
+ if (isRoot)
+ {
+ SetSize(mBoundsOnDisk.Width, mBoundsOnDisk.Height);
+ }
+ else
+ {
+ SetBounds(mBoundsOnDisk);
+ }
}
if (obj["Padding"] != null)
diff --git a/Intersect.Client.Framework/Gwen/Control/Button.cs b/Intersect.Client.Framework/Gwen/Control/Button.cs
index b8d160f88d..fd6d36458d 100644
--- a/Intersect.Client.Framework/Gwen/Control/Button.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Button.cs
@@ -171,9 +171,9 @@ public bool ToggleState
///
public event GwenEventHandler ToggledOff;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
if (this.GetType() != typeof(CheckBox))
{
obj.Add("NormalImage", GetImageFilename(ControlState.Normal));
@@ -194,15 +194,15 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["NormalImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["NormalImage"]
- ), (string) obj["NormalImage"], ControlState.Normal
+ Framework.Content.TextureType.Gui, (string)obj["NormalImage"]
+ ), (string)obj["NormalImage"], ControlState.Normal
);
}
@@ -210,8 +210,8 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["HoveredImage"]
- ), (string) obj["HoveredImage"], ControlState.Hovered
+ Framework.Content.TextureType.Gui, (string)obj["HoveredImage"]
+ ), (string)obj["HoveredImage"], ControlState.Hovered
);
}
@@ -219,8 +219,8 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["ClickedImage"]
- ), (string) obj["ClickedImage"], ControlState.Clicked
+ Framework.Content.TextureType.Gui, (string)obj["ClickedImage"]
+ ), (string)obj["ClickedImage"], ControlState.Clicked
);
}
@@ -228,36 +228,36 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["DisabledImage"]
- ), (string) obj["DisabledImage"], ControlState.Disabled
+ Framework.Content.TextureType.Gui, (string)obj["DisabledImage"]
+ ), (string)obj["DisabledImage"], ControlState.Disabled
);
}
if (obj["CenterImage"] != null)
{
- mCenterImage = (bool) obj["CenterImage"];
+ mCenterImage = (bool)obj["CenterImage"];
}
if (this.GetType() != typeof(ComboBox) && this.GetType() != typeof(CheckBox))
{
if (obj["HoverSound"] != null)
{
- mHoverSound = (string) obj["HoverSound"];
+ mHoverSound = (string)obj["HoverSound"];
}
if (obj["MouseUpSound"] != null)
{
- mMouseUpSound = (string) obj["MouseUpSound"];
+ mMouseUpSound = (string)obj["MouseUpSound"];
}
if (obj["MouseDownSound"] != null)
{
- mMouseDownSound = (string) obj["MouseDownSound"];
+ mMouseDownSound = (string)obj["MouseDownSound"];
}
if (obj["ClickSound"] != null)
{
- mClickSound = (string) obj["ClickSound"];
+ mClickSound = (string)obj["ClickSound"];
}
}
}
diff --git a/Intersect.Client.Framework/Gwen/Control/CheckBox.cs b/Intersect.Client.Framework/Gwen/Control/CheckBox.cs
index 3ee93fd507..38a438e741 100644
--- a/Intersect.Client.Framework/Gwen/Control/CheckBox.cs
+++ b/Intersect.Client.Framework/Gwen/Control/CheckBox.cs
@@ -83,9 +83,9 @@ public bool IsChecked
///
protected virtual bool AllowUncheck => true;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("NormalImage", GetImageFilename(ControlState.Normal));
obj.Add("CheckedImage", GetImageFilename(ControlState.CheckedNormal));
obj.Add("DisabledImage", GetImageFilename(ControlState.Disabled));
@@ -96,15 +96,15 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["NormalImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["NormalImage"]
- ), (string) obj["NormalImage"], ControlState.Normal
+ Framework.Content.TextureType.Gui, (string)obj["NormalImage"]
+ ), (string)obj["NormalImage"], ControlState.Normal
);
}
@@ -112,8 +112,8 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["CheckedImage"]
- ), (string) obj["CheckedImage"], ControlState.CheckedNormal
+ Framework.Content.TextureType.Gui, (string)obj["CheckedImage"]
+ ), (string)obj["CheckedImage"], ControlState.CheckedNormal
);
}
@@ -121,8 +121,8 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["DisabledImage"]
- ), (string) obj["DisabledImage"], ControlState.Disabled
+ Framework.Content.TextureType.Gui, (string)obj["DisabledImage"]
+ ), (string)obj["DisabledImage"], ControlState.Disabled
);
}
@@ -130,19 +130,19 @@ public override void LoadJson(JToken obj)
{
SetImage(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["CheckedDisabledImage"]
- ), (string) obj["CheckedDisabledImage"], ControlState.CheckedDisabled
+ Framework.Content.TextureType.Gui, (string)obj["CheckedDisabledImage"]
+ ), (string)obj["CheckedDisabledImage"], ControlState.CheckedDisabled
);
}
if (obj["CheckedSound"] != null)
{
- mCheckSound = (string) obj["CheckedSound"];
+ mCheckSound = (string)obj["CheckedSound"];
}
if (obj["UncheckedSound"] != null)
{
- mUncheckedSound = (string) obj["UncheckedSound"];
+ mUncheckedSound = (string)obj["UncheckedSound"];
}
}
diff --git a/Intersect.Client.Framework/Gwen/Control/ComboBox.cs b/Intersect.Client.Framework/Gwen/Control/ComboBox.cs
index 2f8278c748..27b69baae9 100644
--- a/Intersect.Client.Framework/Gwen/Control/ComboBox.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ComboBox.cs
@@ -111,9 +111,9 @@ public void SetMenuBelow()
}
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("MenuAbove", mMenuAbove);
obj.Add("Menu", mMenu.GetJson());
obj.Add("DropDownButton", mButton.GetJson());
@@ -126,12 +126,12 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["MenuAbove"] != null)
{
- mMenuAbove = (bool) obj["MenuAbove"];
+ mMenuAbove = (bool)obj["MenuAbove"];
}
if (obj["Menu"] != null)
@@ -146,27 +146,27 @@ public override void LoadJson(JToken obj)
if (obj["OpenMenuSound"] != null)
{
- mOpenMenuSound = (string) obj["OpenMenuSound"];
+ mOpenMenuSound = (string)obj["OpenMenuSound"];
}
if (obj["CloseMenuSound"] != null)
{
- mCloseMenuSound = (string) obj["CloseMenuSound"];
+ mCloseMenuSound = (string)obj["CloseMenuSound"];
}
if (obj["HoverMenuSound"] != null)
{
- mHoverMenuSound = (string) obj["HoverMenuSound"];
+ mHoverMenuSound = (string)obj["HoverMenuSound"];
}
if (obj["ItemHoverSound"] != null)
{
- mHoverItemSound = (string) obj["ItemHoverSound"];
+ mHoverItemSound = (string)obj["ItemHoverSound"];
}
if (obj["SelectItemSound"] != null)
{
- mSelectItemSound = (string) obj["SelectItemSound"];
+ mSelectItemSound = (string)obj["SelectItemSound"];
}
foreach (var child in Children)
diff --git a/Intersect.Client.Framework/Gwen/Control/HorizontalSlider.cs b/Intersect.Client.Framework/Gwen/Control/HorizontalSlider.cs
index a79f888d01..e990efff96 100644
--- a/Intersect.Client.Framework/Gwen/Control/HorizontalSlider.cs
+++ b/Intersect.Client.Framework/Gwen/Control/HorizontalSlider.cs
@@ -58,7 +58,7 @@ protected override void Layout(Skin.Base skin)
/// Skin to use.
protected override void Render(Skin.Base skin)
{
- skin.DrawSlider(this, true, mSnapToNotches ? mNotchCount : 0, mSliderBar.Width);
+ skin.DrawSlider(this, true, Notches, mSnapToNotches ? mNotchCount : 0, mSliderBar.Width);
}
}
diff --git a/Intersect.Client.Framework/Gwen/Control/ImagePanel.cs b/Intersect.Client.Framework/Gwen/Control/ImagePanel.cs
index 6440aff364..4941466247 100644
--- a/Intersect.Client.Framework/Gwen/Control/ImagePanel.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ImagePanel.cs
@@ -89,9 +89,9 @@ public override void Dispose()
base.Dispose();
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("Texture", TextureFilename);
obj.Add("HoverSound", mHoverSound);
obj.Add("LeftMouseClickSound", mLeftMouseClickSound);
@@ -100,7 +100,7 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["Texture"] != null)
diff --git a/Intersect.Client.Framework/Gwen/Control/Label.cs b/Intersect.Client.Framework/Gwen/Control/Label.cs
index 632119ad16..96a79aa51a 100644
--- a/Intersect.Client.Framework/Gwen/Control/Label.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Label.cs
@@ -211,9 +211,9 @@ public Padding TextPadding
}
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
if (typeof(Label) == GetType())
{
obj.Add("BackgroundTemplate", mBackgroundTemplateFilename);
@@ -232,7 +232,7 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (typeof(Label) == GetType() && obj["BackgroundTemplate"] != null)
diff --git a/Intersect.Client.Framework/Gwen/Control/LabeledCheckBox.cs b/Intersect.Client.Framework/Gwen/Control/LabeledCheckBox.cs
index 58d4a64bce..89ab6010a4 100644
--- a/Intersect.Client.Framework/Gwen/Control/LabeledCheckBox.cs
+++ b/Intersect.Client.Framework/Gwen/Control/LabeledCheckBox.cs
@@ -41,7 +41,7 @@ public LabeledCheckBox(Base parent, string name = "") : base(parent, name)
Dock = Pos.Fill,
IsTabable = false
};
- mLabel.Clicked += delegate(Base control, ClickedEventArgs args) { mCheckBox.Press(control); };
+ mLabel.Clicked += delegate (Base control, ClickedEventArgs args) { mCheckBox.Press(control); };
IsTabable = false;
}
@@ -79,16 +79,16 @@ public string Text
///
public event GwenEventHandler CheckChanged;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("Label", mLabel.GetJson());
obj.Add("Checkbox", mCheckBox.GetJson());
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["Label"] != null)
diff --git a/Intersect.Client.Framework/Gwen/Control/LabeledHorizontalSlider.cs b/Intersect.Client.Framework/Gwen/Control/LabeledHorizontalSlider.cs
new file mode 100644
index 0000000000..2bd2793248
--- /dev/null
+++ b/Intersect.Client.Framework/Gwen/Control/LabeledHorizontalSlider.cs
@@ -0,0 +1,153 @@
+using System;
+
+using Intersect.Client.Framework.File_Management;
+using Intersect.Client.Framework.GenericClasses;
+using Intersect.Client.Framework.Graphics;
+using Intersect.Client.Framework.Gwen.ControlInternal;
+using Intersect.Client.Framework.Gwen.Input;
+
+using Newtonsoft.Json.Linq;
+
+namespace Intersect.Client.Framework.Gwen.Control
+{
+
+ ///
+ /// Base slider.
+ ///
+ public partial class LabeledHorizontalSlider : Base
+ {
+ private readonly Label _label;
+ private readonly HorizontalSlider _slider;
+ private readonly ImagePanel _sliderBackground;
+ private readonly TextBoxNumeric _sliderValue;
+ private double _scale = 1.0;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Parent control.
+ public LabeledHorizontalSlider(Base parent, string name = "") : base(parent, name)
+ {
+ SetBounds(new Rectangle(0, 0, 32, 128));
+
+ _label = new Label(this, "SliderLabel");
+
+ _sliderBackground = new ImagePanel(this, "SliderBackground");
+ _slider = new HorizontalSlider(_sliderBackground, "Slider");
+ _sliderValue = new TextBoxNumeric(_sliderBackground, "SliderValue");
+
+ _slider.ValueChanged += (sender, arguments) =>
+ {
+ if (sender == _sliderValue)
+ {
+ return;
+ }
+
+ _sliderValue.Value = _slider.Value * _scale;
+ ValueChanged?.Invoke(sender, arguments);
+ };
+
+ _sliderValue.TextChanged += (sender, arguments) =>
+ {
+ if (sender == _slider)
+ {
+ return;
+ }
+
+ _slider.Value = _sliderValue.Value / _scale;
+ ValueChanged?.Invoke(sender, arguments);
+ };
+
+ KeyboardInputEnabled = true;
+ IsTabable = true;
+ }
+
+ public string Label
+ {
+ get => _label.Text;
+ set => _label.Text = value;
+ }
+
+ ///
+ /// Number of notches on the slider axis.
+ ///
+ public int NotchCount
+ {
+ get => _slider.NotchCount;
+ set => _slider.NotchCount = value;
+ }
+
+ public double[] Notches
+ {
+ get => _slider.Notches;
+ set => _slider.Notches = value;
+ }
+
+ ///
+ /// Determines whether the slider should snap to notches.
+ ///
+ public bool SnapToNotches
+ {
+ get => _slider.SnapToNotches;
+ set => _slider.SnapToNotches = value;
+ }
+
+ ///
+ /// Minimum value.
+ ///
+ public double Min
+ {
+ get => _slider.Min;
+ set => _slider.Min = value;
+ }
+
+ ///
+ /// Maximum value.
+ ///
+ public double Max
+ {
+ get => _slider.Max;
+ set => _slider.Max = value;
+ }
+
+ public double Scale
+ {
+ get => _scale;
+ set
+ {
+ _scale = value;
+ _sliderValue.Value = _slider.Value * _scale;
+ }
+ }
+
+ ///
+ /// Current value.
+ ///
+ public double Value
+ {
+ get => _slider.Value;
+ set
+ {
+ _slider.Value = value;
+ _sliderValue.Value = _slider.Value * _scale;
+ }
+ }
+
+ ///
+ /// Invoked when the value has been changed.
+ ///
+ public event GwenEventHandler ValueChanged;
+
+ public override JObject GetJson(bool isRoot = default)
+ {
+ var obj = base.GetJson(isRoot);
+
+ return base.FixJson(obj);
+ }
+
+ public override void LoadJson(JToken obj, bool isRoot = default)
+ {
+ base.LoadJson(obj);
+ }
+ }
+}
diff --git a/Intersect.Client.Framework/Gwen/Control/Layout/Table.cs b/Intersect.Client.Framework/Gwen/Control/Layout/Table.cs
index a34271c357..8bf4b5d879 100644
--- a/Intersect.Client.Framework/Gwen/Control/Layout/Table.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Layout/Table.cs
@@ -159,9 +159,9 @@ protected virtual void OnDataChanged(object sender, TableDataChangedEventArgs ar
row.SetCellText(args.Column, args.NewValue?.ToString());
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("SizeToContents", mSizeToContents);
obj.Add("DefaultRowHeight", mDefaultRowHeight);
obj.Add(nameof(ColumnAlignments), new JArray(ColumnAlignments.Select(alignment => alignment.ToString() as object).ToArray()));
@@ -172,7 +172,7 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj[nameof(SizeToContents)] != null)
@@ -445,7 +445,7 @@ protected virtual (int width, int height) ComputeColumnWidths()
height += row.Height;
}
- // sum all column widths
+ // sum all column widths
width += mColumnWidths.Take(ColumnCount).Sum();
return (width, height);
diff --git a/Intersect.Client.Framework/Gwen/Control/ListBox.cs b/Intersect.Client.Framework/Gwen/Control/ListBox.cs
index 4fb647eb45..71d7bd1fdb 100644
--- a/Intersect.Client.Framework/Gwen/Control/ListBox.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ListBox.cs
@@ -120,7 +120,7 @@ public IEnumerable SelectedRows
var tmp = new List();
foreach (var row in mSelectedRows)
{
- tmp.Add((TableRow) row);
+ tmp.Add((TableRow)row);
}
return tmp;
@@ -222,9 +222,9 @@ public Color TextColorOverride
});
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("SizeToContents", mSizeToContents);
obj.Add("MultiSelect", AllowMultiSelect);
obj.Add("IsToggle", IsToggle);
@@ -238,43 +238,43 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["SizeToContents"] != null)
{
- mSizeToContents = (bool) obj["SizeToContents"];
+ mSizeToContents = (bool)obj["SizeToContents"];
}
if (obj["MultiSelect"] != null)
{
- AllowMultiSelect = (bool) obj["MultiSelect"];
+ AllowMultiSelect = (bool)obj["MultiSelect"];
}
if (obj["IsToggle"] != null)
{
- IsToggle = (bool) obj["IsToggle"];
+ IsToggle = (bool)obj["IsToggle"];
}
if (obj["ItemHoverSound"] != null)
{
- mItemHoverSound = (string) obj["ItemHoverSound"];
+ mItemHoverSound = (string)obj["ItemHoverSound"];
}
if (obj["ItemClickSound"] != null)
{
- mItemClickSound = (string) obj["ItemClickSound"];
+ mItemClickSound = (string)obj["ItemClickSound"];
}
if (obj["ItemRightClickSound"] != null)
{
- mItemRightClickSound = (string) obj["ItemRightClickSound"];
+ mItemRightClickSound = (string)obj["ItemRightClickSound"];
}
if (obj["Font"] != null && obj["Font"].Type != JTokenType.Null)
{
- var fontArr = ((string) obj["Font"]).Split(',');
- mFontInfo = (string) obj["Font"];
+ var fontArr = ((string)obj["Font"]).Split(',');
+ mFontInfo = (string)obj["Font"];
mFont = GameContentManager.Current.GetFont(fontArr[0], int.Parse(fontArr[1]));
}
@@ -290,7 +290,7 @@ public override void LoadJson(JToken obj)
foreach (var itm in mTable.Children)
{
- var row = (ListBoxRow) itm;
+ var row = (ListBoxRow)itm;
row.HoverSound = mItemHoverSound;
row.ClickSound = mItemClickSound;
row.RightClickSound = mItemRightClickSound;
diff --git a/Intersect.Client.Framework/Gwen/Control/Menu.cs b/Intersect.Client.Framework/Gwen/Control/Menu.cs
index 43a8e42020..9c34cc5622 100644
--- a/Intersect.Client.Framework/Gwen/Control/Menu.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Menu.cs
@@ -318,9 +318,9 @@ public override bool SizeToChildren(bool width = true, bool height = true)
return true;
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
if (!(this is CheckBox))
{
obj.Add("BackgroundTemplate", mBackgroundTemplateFilename);
@@ -332,32 +332,32 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["BackgroundTemplate"] != null)
{
SetBackgroundTemplate(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["BackgroundTemplate"]
- ), (string) obj["BackgroundTemplate"]
+ Framework.Content.TextureType.Gui, (string)obj["BackgroundTemplate"]
+ ), (string)obj["BackgroundTemplate"]
);
}
if (obj["ItemTextColor"] != null)
{
- mItemNormalTextColor = Color.FromString((string) obj["ItemTextColor"]);
+ mItemNormalTextColor = Color.FromString((string)obj["ItemTextColor"]);
}
if (obj["ItemHoveredTextColor"] != null)
{
- mItemHoverTextColor = Color.FromString((string) obj["ItemHoveredTextColor"]);
+ mItemHoverTextColor = Color.FromString((string)obj["ItemHoveredTextColor"]);
}
if (obj["ItemFont"] != null && obj["ItemFont"].Type != JTokenType.Null)
{
- var fontArr = ((string) obj["ItemFont"]).Split(',');
- mItemFontInfo = (string) obj["ItemFont"];
+ var fontArr = ((string)obj["ItemFont"]).Split(',');
+ mItemFontInfo = (string)obj["ItemFont"];
mItemFont = GameContentManager.Current.GetFont(fontArr[0], int.Parse(fontArr[1]));
}
@@ -369,7 +369,7 @@ private void UpdateItemStyles()
var menuItems = Children.Where(x => x is MenuItem).ToArray();
foreach (var item in menuItems)
{
- var itm = (MenuItem) item;
+ var itm = (MenuItem)item;
if (mItemFont != null)
{
itm.Font = mItemFont;
diff --git a/Intersect.Client.Framework/Gwen/Control/ResizableControl.cs b/Intersect.Client.Framework/Gwen/Control/ResizableControl.cs
index 45f043df40..fb545ad3a1 100644
--- a/Intersect.Client.Framework/Gwen/Control/ResizableControl.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ResizableControl.cs
@@ -90,20 +90,20 @@ public bool ClampMovement
///
public event GwenEventHandler Resized;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("ClampMovement", ClampMovement);
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["ClampMovement"] != null)
{
- ClampMovement = (bool) obj["ClampMovement"];
+ ClampMovement = (bool)obj["ClampMovement"];
}
}
diff --git a/Intersect.Client.Framework/Gwen/Control/RichLabel.cs b/Intersect.Client.Framework/Gwen/Control/RichLabel.cs
index bd67368ce6..618104206d 100644
--- a/Intersect.Client.Framework/Gwen/Control/RichLabel.cs
+++ b/Intersect.Client.Framework/Gwen/Control/RichLabel.cs
@@ -34,7 +34,7 @@ public partial class RichLabel : Base
/// Parent control.
public RichLabel(Base parent, string name = "") : base(parent, name)
{
- mNewline = new string[] {Environment.NewLine, "\n"};
+ mNewline = new string[] { Environment.NewLine, "\n" };
mTextBlocks = new List();
}
@@ -43,27 +43,28 @@ public RichLabel(Base parent, string name = "") : base(parent, name)
///
public void AddLineBreak()
{
- var block = new TextBlock {Type = BlockType.NewLine};
+ var block = new TextBlock { Type = BlockType.NewLine };
mTextBlocks.Add(block);
}
///
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["Font"] != null && obj["Font"].Type != JTokenType.Null)
{
- var fontArr = ((string) obj["Font"]).Split(',');
- mFontInfo = (string) obj["Font"];
+ var fontArr = ((string)obj["Font"]).Split(',');
+ mFontInfo = (string)obj["Font"];
mFont = GameContentManager.Current.GetFont(fontArr[0], int.Parse(fontArr[1]));
}
}
+ ///
///
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("Font", mFontInfo);
return base.FixJson(obj);
diff --git a/Intersect.Client.Framework/Gwen/Control/ScrollBar.cs b/Intersect.Client.Framework/Gwen/Control/ScrollBar.cs
index e1bf94ef33..8f71fa60c6 100644
--- a/Intersect.Client.Framework/Gwen/Control/ScrollBar.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ScrollBar.cs
@@ -116,9 +116,9 @@ public float ViewableContentSize
///
public event GwenEventHandler BarMoved;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("BackgroundTemplate", mBackgroundTemplateFilename);
obj.Add("UpOrLeftButton", mScrollButton[0].GetJson());
obj.Add("Bar", mBar.GetJson());
@@ -127,15 +127,15 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["BackgroundTemplate"] != null)
{
SetBackgroundTemplate(
GameContentManager.Current.GetTexture(
- Framework.Content.TextureType.Gui, (string) obj["BackgroundTemplate"]
- ), (string) obj["BackgroundTemplate"]
+ Framework.Content.TextureType.Gui, (string)obj["BackgroundTemplate"]
+ ), (string)obj["BackgroundTemplate"]
);
}
diff --git a/Intersect.Client.Framework/Gwen/Control/ScrollControl.cs b/Intersect.Client.Framework/Gwen/Control/ScrollControl.cs
index f5c56b208e..d30acfcb53 100644
--- a/Intersect.Client.Framework/Gwen/Control/ScrollControl.cs
+++ b/Intersect.Client.Framework/Gwen/Control/ScrollControl.cs
@@ -129,9 +129,9 @@ protected bool VScrollRequired
}
}
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("CanScrollH", mCanScrollH);
obj.Add("CanScrollV", mCanScrollV);
obj.Add("AutoHideBars", mAutoHideBars);
@@ -142,22 +142,22 @@ public override JObject GetJson()
return base.FixJson(obj);
}
- public override void LoadJson(JToken obj)
+ public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["CanScrollH"] != null)
{
- mCanScrollH = (bool) obj["CanScrollH"];
+ mCanScrollH = (bool)obj["CanScrollH"];
}
if (obj["CanScrollV"] != null)
{
- mCanScrollV = (bool) obj["CanScrollV"];
+ mCanScrollV = (bool)obj["CanScrollV"];
}
if (obj["AutoHideBars"] != null)
{
- mAutoHideBars = (bool) obj["AutoHideBars"];
+ mAutoHideBars = (bool)obj["AutoHideBars"];
}
if (obj["InnerPanel"] != null)
@@ -322,10 +322,10 @@ public virtual void UpdateScrollBars()
}
var wPercent = Width /
- (float) (childrenWidth + (mVerticalScrollBar.IsHidden ? 0 : mVerticalScrollBar.Width));
+ (float)(childrenWidth + (mVerticalScrollBar.IsHidden ? 0 : mVerticalScrollBar.Width));
var hPercent = Height /
- (float) (childrenHeight +
+ (float)(childrenHeight +
(mHorizontalScrollBar.IsHidden ? 0 : mHorizontalScrollBar.Height));
if (mCanScrollV)
@@ -360,7 +360,7 @@ public virtual void UpdateScrollBars()
if (CanScrollV && !mVerticalScrollBar.IsHidden)
{
newInnerPanelPosY =
- (int) (-(mInnerPanel.Height -
+ (int)(-(mInnerPanel.Height -
Height +
(mHorizontalScrollBar.IsHidden ? 0 : mHorizontalScrollBar.Height)) *
mVerticalScrollBar.ScrollAmount);
@@ -369,7 +369,7 @@ public virtual void UpdateScrollBars()
if (CanScrollH && !mHorizontalScrollBar.IsHidden)
{
newInnerPanelPosX =
- (int) (-(mInnerPanel.Width -
+ (int)(-(mInnerPanel.Width -
Width +
(mVerticalScrollBar.IsHidden ? 0 : mVerticalScrollBar.Width)) *
mHorizontalScrollBar.ScrollAmount);
diff --git a/Intersect.Client.Framework/Gwen/Control/Slider.cs b/Intersect.Client.Framework/Gwen/Control/Slider.cs
index 52d223df2d..8e9cd51041 100644
--- a/Intersect.Client.Framework/Gwen/Control/Slider.cs
+++ b/Intersect.Client.Framework/Gwen/Control/Slider.cs
@@ -1,5 +1,5 @@
using System;
-
+using System.Linq;
using Intersect.Client.Framework.File_Management;
using Intersect.Client.Framework.GenericClasses;
using Intersect.Client.Framework.Graphics;
@@ -29,6 +29,8 @@ public partial class Slider : Base
protected int mNotchCount;
+ protected double[] _notches;
+
protected bool mSnapToNotches;
protected double mValue;
@@ -64,6 +66,12 @@ public int NotchCount
set => mNotchCount = value;
}
+ public double[] Notches
+ {
+ get => _notches;
+ set => _notches = value;
+ }
+
///
/// Determines whether the slider should snap to notches.
///
@@ -121,37 +129,55 @@ public double Value
///
public event GwenEventHandler ValueChanged;
- public override JObject GetJson()
+ public override JObject GetJson(bool isRoot = default)
{
- var obj = base.GetJson();
+ var obj = base.GetJson(isRoot);
obj.Add("BackgroundImage", GetImageFilename());
obj.Add("SnapToNotches", mSnapToNotches);
obj.Add("NotchCount", mNotchCount);
+ var notches = (Notches == default || Notches.Length < 1)
+ ? default
+ : new JArray(Notches.Cast