mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-25 19:46:50 -05: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.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; }
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
<Compile Include="Enums\eLevelSubType.cs" />
|
||||
<Compile Include="Enums\eMPQFormatVersion.cs" />
|
||||
<Compile Include="Enums\eRenderCellType.cs" />
|
||||
<Compile Include="Enums\eTextAlign.cs" />
|
||||
<Compile Include="Enums\eWildBorder.cs" />
|
||||
<Compile Include="Interfaces\IButton.cs" />
|
||||
<Compile Include="Interfaces\IEngineDataManager.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()
|
||||
|
@ -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<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);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user