diff --git a/OpenDiablo2.Common/Enums/eTextAlign.cs b/OpenDiablo2.Common/Enums/eTextAlign.cs
new file mode 100644
index 00000000..6201688e
--- /dev/null
+++ b/OpenDiablo2.Common/Enums/eTextAlign.cs
@@ -0,0 +1,9 @@
+namespace OpenDiablo2.Common.Enums
+{
+ public enum eTextAlign
+ {
+ Centered = 0,
+ Left,
+ Right
+ }
+}
diff --git a/OpenDiablo2.Common/Interfaces/ILabel.cs b/OpenDiablo2.Common/Interfaces/ILabel.cs
index 5739d5df..757dfd33 100644
--- a/OpenDiablo2.Common/Interfaces/ILabel.cs
+++ b/OpenDiablo2.Common/Interfaces/ILabel.cs
@@ -1,5 +1,6 @@
using System;
using System.Drawing;
+using OpenDiablo2.Common.Enums;
namespace OpenDiablo2.Common.Interfaces
{
@@ -9,5 +10,7 @@ namespace OpenDiablo2.Common.Interfaces
Point Location { get; set; }
Size TextArea { get; set; }
Color TextColor { get; set; }
+ int MaxWidth { get; set; }
+ eTextAlign Alignment { get; set; }
}
}
diff --git a/OpenDiablo2.Common/OpenDiablo2.Common.csproj b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
index aeb2f4c2..748279df 100644
--- a/OpenDiablo2.Common/OpenDiablo2.Common.csproj
+++ b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
@@ -77,6 +77,7 @@
+
diff --git a/OpenDiablo2.Core/UI/Button.cs b/OpenDiablo2.Core/UI/Button.cs
index 7f8544df..998d9428 100644
--- a/OpenDiablo2.Core/UI/Button.cs
+++ b/OpenDiablo2.Core/UI/Button.cs
@@ -82,7 +82,6 @@ namespace OpenDiablo2.Core.UI
font = renderWindow.LoadFont(ResourcePaths.FontExocet10, Palettes.Units);
label = renderWindow.CreateLabel(font);
-
sprite = renderWindow.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName);
// TODO: Less stupid way of doing this would be nice
@@ -94,6 +93,9 @@ namespace OpenDiablo2.Core.UI
buttonWidth += sprite.LocalFrameSize.Width;
buttonHeight = Math.Max(buttonHeight, sprite.LocalFrameSize.Height);
}
+
+ label.MaxWidth = buttonWidth - 8;
+ label.Alignment = Common.Enums.eTextAlign.Centered;
}
public bool Toggle()
@@ -201,7 +203,8 @@ namespace OpenDiablo2.Core.UI
label.TextColor = Color.FromArgb(75, 75, 75);
var offsetX = (buttonWidth / 2) - (label.TextArea.Width / 2);
- labelOffset = new Point(offsetX, -5);
+ var offsetY = (buttonHeight / 2) - (label.TextArea.Height / 2);
+ labelOffset = new Point(offsetX, offsetY - 5);
}
public void Dispose()
diff --git a/OpenDiablo2.SDL2/SDL2Label.cs b/OpenDiablo2.SDL2/SDL2Label.cs
index cee260e3..ee7b4cd7 100644
--- a/OpenDiablo2.SDL2/SDL2Label.cs
+++ b/OpenDiablo2.SDL2/SDL2Label.cs
@@ -1,4 +1,5 @@
-using OpenDiablo2.Common.Interfaces;
+using OpenDiablo2.Common.Enums;
+using OpenDiablo2.Common.Interfaces;
using SDL2;
using System;
using System.Collections.Generic;
@@ -43,25 +44,59 @@ namespace OpenDiablo2.SDL2_
}
}
+ public int MaxWidth { get; set; }
+ public eTextAlign Alignment { get; set; }
+
internal SDL2Label(IFont font, IntPtr renderer)
{
this.renderer = renderer;
this.font = font as SDL2Font;
this.texture = IntPtr.Zero;
+ this.MaxWidth = -1;
}
internal Size CalculateSize()
{
- int w = 0;
- int h = 0;
- foreach (var ch in text)
+ if (MaxWidth == -1)
{
- var metric = font.font.CharacterMetric[(byte)ch];
- w += metric.Width;
- h = Math.Max(Math.Max(h, metric.Height), font.sprite.FrameSize.Height);
+ int w = 0;
+ int h = 0;
+ foreach (var ch in text)
+ {
+ var metric = font.font.CharacterMetric[(byte)ch];
+ w += metric.Width;
+ h = Math.Max(Math.Max(h, metric.Height), font.sprite.FrameSize.Height);
+ }
+
+ return new Size(w, h);
}
- return new Size(w, h);
+ if (MaxWidth < (font.sprite.FrameSize.Width))
+ throw new ApplicationException("Max label width cannot be smaller than a single character.");
+
+ var lastWordIndex = 0;
+ var width = 0;
+ var maxWidth = 0;
+ var height = font.sprite.FrameSize.Height;
+ for (int idx = 0; idx < text.Length; idx++)
+ {
+ width += font.font.CharacterMetric[(byte)text[idx]].Width;
+
+ if (width >= MaxWidth)
+ {
+ idx = lastWordIndex;
+ height += font.font.CharacterMetric[(byte)'|'].Height + 6;
+ width = 0;
+ continue;
+ }
+ maxWidth = Math.Max(width, maxWidth);
+
+ if (idx > 0 && (text[idx - 1] == ' ') && (text[idx] != ' '))
+ lastWordIndex = idx;
+ }
+
+ return new Size(maxWidth, height);
+
}
internal int Pow2(int input)
@@ -90,14 +125,65 @@ namespace OpenDiablo2.SDL2_
SDL.SDL_RenderClear(renderer);
SDL.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
- int cx = 0;
- int cy = 0;
- foreach (var ch in text)
+ if (MaxWidth == -1)
{
- WriteCharacter(cx, cy, (byte)ch);
- cx += font.font.CharacterMetric[(byte)ch].Width;
- }
+ int cx = 0;
+ int cy = 0;
+ foreach (var ch in text)
+ {
+ WriteCharacter(cx, cy, (byte)ch);
+ cx += font.font.CharacterMetric[(byte)ch].Width;
+ }
+ }
+ else
+ {
+ var linesToRender = new List();
+
+ var lastWordIndex = 0;
+ var width = 0;
+ var lastStartX = 0;
+ for (int idx = 0; idx < text.Length; idx++)
+ {
+ width += font.font.CharacterMetric[(byte)text[idx]].Width;
+
+ if (width >= MaxWidth)
+ {
+ idx = lastWordIndex;
+ linesToRender.Add(text.Substring(lastStartX, lastWordIndex- lastStartX));
+ lastStartX = idx;
+ width = 0;
+ continue;
+ }
+
+ if (idx > 0 && text[idx - 1] == ' ' && text[idx] != ' ')
+ lastWordIndex = idx;
+ }
+
+ var lastLine = text.Substring(lastStartX)?.Trim();
+ if (!String.IsNullOrEmpty(lastLine))
+ linesToRender.Add(lastLine);
+
+ var y = 0;
+ foreach(var line in linesToRender)
+ {
+ var lineWidth = (line.Sum(c => font.font.CharacterMetric[(byte)c].Width));
+ var x = 0;
+
+ if (Alignment == eTextAlign.Centered)
+ x = (TextArea.Width / 2) - (lineWidth / 2);
+ else if (Alignment == eTextAlign.Right)
+ x = TextArea.Width - lineWidth;
+
+ foreach (var ch in line)
+ {
+ WriteCharacter(x, y, (byte)ch);
+ x += font.font.CharacterMetric[(byte)ch].Width;
+ }
+
+ y += font.font.CharacterMetric[(byte)'|'].Height + 6;
+ }
+ }
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
}
diff --git a/OpenDiablo2.Scenes/CharacterSelection.cs b/OpenDiablo2.Scenes/CharacterSelection.cs
index ebea62a1..4bf53c9c 100644
--- a/OpenDiablo2.Scenes/CharacterSelection.cs
+++ b/OpenDiablo2.Scenes/CharacterSelection.cs
@@ -26,7 +26,7 @@ namespace OpenDiablo2.Scenes
backgroundSprite = renderWindow.LoadSprite(ResourcePaths.CharacterSelectionBackground, Palettes.Sky);
createNewCharacterButton = createButton(eButtonType.Tall);
// TODO: use strCreateNewCharacter -- need to get the text to split after 10 chars though.
- createNewCharacterButton.Text = "Create New".ToUpper();
+ createNewCharacterButton.Text = textDictionary.Translate("strCreateNewCharacter");// "Create New".ToUpper();
createNewCharacterButton.Location = new Point(33, 467);
createNewCharacterButton.OnActivate = () => sceneManager.ChangeScene("Select Hero Class");