mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-26 13:15:56 -04:00
Added support for label and button text wrappping and alignment.
This commit is contained in:
parent
403864fdd1
commit
04498ad9a5
9
OpenDiablo2.Common/Enums/eTextAlign.cs
Normal file
9
OpenDiablo2.Common/Enums/eTextAlign.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace OpenDiablo2.Common.Enums
|
||||||
|
{
|
||||||
|
public enum eTextAlign
|
||||||
|
{
|
||||||
|
Centered = 0,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using OpenDiablo2.Common.Enums;
|
||||||
|
|
||||||
namespace OpenDiablo2.Common.Interfaces
|
namespace OpenDiablo2.Common.Interfaces
|
||||||
{
|
{
|
||||||
@ -9,5 +10,7 @@ namespace OpenDiablo2.Common.Interfaces
|
|||||||
Point Location { get; set; }
|
Point Location { get; set; }
|
||||||
Size TextArea { get; set; }
|
Size TextArea { get; set; }
|
||||||
Color TextColor { get; set; }
|
Color TextColor { get; set; }
|
||||||
|
int MaxWidth { get; set; }
|
||||||
|
eTextAlign Alignment { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
<Compile Include="Enums\eLevelSubType.cs" />
|
<Compile Include="Enums\eLevelSubType.cs" />
|
||||||
<Compile Include="Enums\eMPQFormatVersion.cs" />
|
<Compile Include="Enums\eMPQFormatVersion.cs" />
|
||||||
<Compile Include="Enums\eRenderCellType.cs" />
|
<Compile Include="Enums\eRenderCellType.cs" />
|
||||||
|
<Compile Include="Enums\eTextAlign.cs" />
|
||||||
<Compile Include="Enums\eWildBorder.cs" />
|
<Compile Include="Enums\eWildBorder.cs" />
|
||||||
<Compile Include="Interfaces\IButton.cs" />
|
<Compile Include="Interfaces\IButton.cs" />
|
||||||
<Compile Include="Interfaces\IEngineDataManager.cs" />
|
<Compile Include="Interfaces\IEngineDataManager.cs" />
|
||||||
|
@ -82,7 +82,6 @@ namespace OpenDiablo2.Core.UI
|
|||||||
font = renderWindow.LoadFont(ResourcePaths.FontExocet10, Palettes.Units);
|
font = renderWindow.LoadFont(ResourcePaths.FontExocet10, Palettes.Units);
|
||||||
label = renderWindow.CreateLabel(font);
|
label = renderWindow.CreateLabel(font);
|
||||||
|
|
||||||
|
|
||||||
sprite = renderWindow.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName);
|
sprite = renderWindow.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName);
|
||||||
|
|
||||||
// TODO: Less stupid way of doing this would be nice
|
// TODO: Less stupid way of doing this would be nice
|
||||||
@ -94,6 +93,9 @@ namespace OpenDiablo2.Core.UI
|
|||||||
buttonWidth += sprite.LocalFrameSize.Width;
|
buttonWidth += sprite.LocalFrameSize.Width;
|
||||||
buttonHeight = Math.Max(buttonHeight, sprite.LocalFrameSize.Height);
|
buttonHeight = Math.Max(buttonHeight, sprite.LocalFrameSize.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.MaxWidth = buttonWidth - 8;
|
||||||
|
label.Alignment = Common.Enums.eTextAlign.Centered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Toggle()
|
public bool Toggle()
|
||||||
@ -201,7 +203,8 @@ namespace OpenDiablo2.Core.UI
|
|||||||
label.TextColor = Color.FromArgb(75, 75, 75);
|
label.TextColor = Color.FromArgb(75, 75, 75);
|
||||||
|
|
||||||
var offsetX = (buttonWidth / 2) - (label.TextArea.Width / 2);
|
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()
|
public void Dispose()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using OpenDiablo2.Common.Interfaces;
|
using OpenDiablo2.Common.Enums;
|
||||||
|
using OpenDiablo2.Common.Interfaces;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
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)
|
internal SDL2Label(IFont font, IntPtr renderer)
|
||||||
{
|
{
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.font = font as SDL2Font;
|
this.font = font as SDL2Font;
|
||||||
this.texture = IntPtr.Zero;
|
this.texture = IntPtr.Zero;
|
||||||
|
this.MaxWidth = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Size CalculateSize()
|
internal Size CalculateSize()
|
||||||
{
|
{
|
||||||
int w = 0;
|
if (MaxWidth == -1)
|
||||||
int h = 0;
|
|
||||||
foreach (var ch in text)
|
|
||||||
{
|
{
|
||||||
var metric = font.font.CharacterMetric[(byte)ch];
|
int w = 0;
|
||||||
w += metric.Width;
|
int h = 0;
|
||||||
h = Math.Max(Math.Max(h, metric.Height), font.sprite.FrameSize.Height);
|
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)
|
internal int Pow2(int input)
|
||||||
@ -90,14 +125,65 @@ namespace OpenDiablo2.SDL2_
|
|||||||
SDL.SDL_RenderClear(renderer);
|
SDL.SDL_RenderClear(renderer);
|
||||||
SDL.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
SDL.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||||
|
|
||||||
int cx = 0;
|
if (MaxWidth == -1)
|
||||||
int cy = 0;
|
|
||||||
foreach (var ch in text)
|
|
||||||
{
|
{
|
||||||
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<string>();
|
||||||
|
|
||||||
|
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);
|
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace OpenDiablo2.Scenes
|
|||||||
backgroundSprite = renderWindow.LoadSprite(ResourcePaths.CharacterSelectionBackground, Palettes.Sky);
|
backgroundSprite = renderWindow.LoadSprite(ResourcePaths.CharacterSelectionBackground, Palettes.Sky);
|
||||||
createNewCharacterButton = createButton(eButtonType.Tall);
|
createNewCharacterButton = createButton(eButtonType.Tall);
|
||||||
// TODO: use strCreateNewCharacter -- need to get the text to split after 10 chars though.
|
// 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.Location = new Point(33, 467);
|
||||||
createNewCharacterButton.OnActivate = () => sceneManager.ChangeScene("Select Hero Class");
|
createNewCharacterButton.OnActivate = () => sceneManager.ChangeScene("Select Hero Class");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user