Fix handling of line height in TextWidget word wrapping

This commit is contained in:
Ritchie Frodomar 2024-07-12 21:31:57 -04:00
parent e7a30c8572
commit aa2850d4a0
8 changed files with 123 additions and 45 deletions

View file

@ -18,8 +18,8 @@ public abstract class ListAdapter<TContainerWidget, TViewHolder> : Widget,
Children.Add(containerWidget);
}
public abstract TViewHolder CreateViewHolder(int itemIndex, Box rootWidget);
public abstract void UpdateView(TViewHolder viewHolder);
protected abstract TViewHolder CreateViewHolder(int itemIndex, Box rootWidget);
protected abstract void UpdateView(TViewHolder viewHolder);
protected virtual void BeforeRemoveItem(TViewHolder viewHolder)
{ }

View file

@ -32,13 +32,13 @@ public sealed class RecyclableWidgetList<TContainerWidget> : ListAdapter<TContai
{
this.controllers.SetItems(widgets);
}
public override RecyclableViewHolder CreateViewHolder(int itemIndex, Box rootWidget)
protected override RecyclableViewHolder CreateViewHolder(int itemIndex, Box rootWidget)
{
return new RecyclableViewHolder(itemIndex, rootWidget);
}
public override void UpdateView(RecyclableViewHolder viewHolder)
protected override void UpdateView(RecyclableViewHolder viewHolder)
{
var controller = controllers[viewHolder.ItemIndex];

View file

@ -6,34 +6,10 @@ namespace AcidicGUI.Widgets;
public sealed class Button :
ContentWidget,
IMouseEnterHandler,
IMouseClickHandler,
IMouseLeaveHandler
IMouseClickHandler
{
private bool hovered;
public event Action? Clicked;
public void OnMouseEnter(MouseMoveEvent e)
{
hovered = true;
InvalidateGeometry();
}
public void OnMouseLeave(MouseMoveEvent e)
{
hovered = false;
InvalidateGeometry();
}
protected override void RebuildGeometry(GeometryHelper geometry)
{
if (hovered)
{
geometry.AddQuad(ContentArea, Color.Red);
}
}
public void OnMouseClick(MouseButtonEvent e)
{
if (e.Button != MouseButton.Left)

View file

@ -214,13 +214,13 @@ public abstract class Dropdown<TItemType, TView> : Widget,
{
this.items.SetItems(dropdown.itemCollection);
}
public override DropdownViewHolder<TItemType, TView> CreateViewHolder(int itemIndex, Box rootWidget)
protected override DropdownViewHolder<TItemType, TView> CreateViewHolder(int itemIndex, Box rootWidget)
{
return new DropdownViewHolder<TItemType, TView>(itemIndex, rootWidget);
}
public override void UpdateView(DropdownViewHolder<TItemType, TView> viewHolder)
protected override void UpdateView(DropdownViewHolder<TItemType, TView> viewHolder)
{
var item = items[viewHolder.ItemIndex];
viewHolder.UpdateView(item, viewHolder.ItemIndex == dropdown.SelectedIndex);

View file

@ -263,9 +263,13 @@ public class TextWidget : Widget
{
if (i == textElements.Count-1)
{
textElements[i].MeasuredSize = (textElements[i].MarkupData.FontOverride ?? font).GetFont(this)
var family = (textElements[i].MarkupData.FontOverride ?? font).GetFont(this);
var newMeasurement = family
.Measure(textElements[i].Text.TrimEnd(), textElements[i].MarkupData.FontSize ?? FontSize,
textElements[i].MarkupData.Weight ?? FontWeight, textElements[i].MarkupData.Italic);
newMeasurement.Y = family.GetLineHeight(textElements[i].MarkupData.FontSize ?? FontSize, textElements[i].MarkupData.Weight ?? FontWeight, textElements[i].MarkupData.Italic);
textElements[i].MeasuredSize = newMeasurement;
}
var measurement = textElements[i].MeasuredSize.GetValueOrDefault();
@ -280,13 +284,19 @@ public class TextWidget : Widget
if (i > 0)
{
offset.X -= textElements[i - 1].MeasuredSize!.Value.X;
textElements[i - 1].MeasuredSize = (textElements[i - 1].MarkupData.FontOverride ?? font)
.GetFont(this)
var newFamily = (textElements[i - 1].MarkupData.FontOverride ?? font).GetFont(this);
var newMeasurement = newFamily
.Measure(textElements[i - 1].Text.TrimEnd(),
textElements[i - 1].MarkupData.FontSize ?? FontSize,
textElements[i - 1].MarkupData.Weight ?? FontWeight,
textElements[i - 1].MarkupData.Italic);
offset.X += textElements[i - 1].MeasuredSize!.Value.X;
newMeasurement.Y = newFamily.GetLineHeight(textElements[i-1].MarkupData.FontSize ?? FontSize, textElements[i-1].MarkupData.Weight ?? FontWeight, textElements[i-1].MarkupData.Italic);
textElements[i - 1].MeasuredSize = newMeasurement;
offset.X += newMeasurement.X;
}
lines.Add((start, i, offset.X));

View file

@ -1,15 +1,28 @@
using AcidicGUI.Events;
using AcidicGUI.Layout;
using AcidicGUI.TextRendering;
using AcidicGUI.Widgets;
using Microsoft.Xna.Framework;
namespace SociallyDistant.Core.UI.Common;
public class TextButton : Widget
public class TextButton : Widget,
IMouseEnterHandler,
IMouseLeaveHandler,
IDragStartHandler,
IDragEndHandler,
IGainFocusHandler,
ILoseFocusHandler
{
private readonly Button button = new();
private readonly Button button = new();
private readonly TextWidget textWidget = new();
private bool isHovered;
private bool isPressed;
public Action? ClickCallback { get; set; }
public bool IsHovered => isHovered;
public bool IsPressed => isPressed;
public string Text
{
@ -22,13 +35,13 @@ public class TextButton : Widget
Children.Add(button);
button.Content = textWidget;
button.Margin = new Padding(15, 0);
textWidget.Padding = new Padding(15, 0);
textWidget.HorizontalAlignment = HorizontalAlignment.Center;
textWidget.VerticalAlignment = VerticalAlignment.Middle;
//textWidget.HorizontalAlignment = HorizontalAlignment.Center;
//textWidget.VerticalAlignment = VerticalAlignment.Middle;
button.Clicked += HandleClicked;
this.textWidget.FontWeight = FontWeight.SemiBold;
}
@ -36,4 +49,51 @@ public class TextButton : Widget
{
ClickCallback?.Invoke();
}
protected override Vector2 GetContentSize(Vector2 availableSize)
{
return base.GetContentSize(availableSize);
}
public void OnMouseEnter(MouseMoveEvent e)
{
isHovered = true;
InvalidateGeometry();
}
public void OnMouseLeave(MouseMoveEvent e)
{
isHovered = false;
InvalidateGeometry();
}
public void OnDragStart(MouseButtonEvent e)
{
if (e.Button != MouseButton.Left)
return;
isPressed = true;
e.RequestFocus();
InvalidateGeometry();
}
public void OnDragEnd(MouseButtonEvent e)
{
if (e.Button != MouseButton.Left)
return;
isPressed = false;
e.Handle();
InvalidateGeometry();
}
public void OnFocusGained(FocusEvent e)
{
InvalidateGeometry();
}
public void OnFocusLost(FocusEvent e)
{
InvalidateGeometry();
}
}

View file

@ -42,6 +42,10 @@ public class SociallyDistantVisualStyle : IVisualStyle
private readonly Color inputActiveBackground = new Color(0x13, 0x85, 0xC3);
private readonly Color inputActiveHoveredBackground = new Color(0x19, 0xA1, 0xEA);
private readonly Color inputActivePressedBackground = new Color(0x13, 0x85, 0xC3);
private readonly Color buttonBackground = new Color(0x44, 0x44, 0x44);
private readonly Color buttonBorder = new Color(0x16, 0x93, 0xD6);
private readonly Color buttonHoveredBackground = new Color(0x0F, 0x73, 0xA9);
private readonly Color buttonPressedBackground = new Color(0x08, 0x53, 0x7B);
private Font iconFont;
private IFontFamily defaultFont = null!;
@ -308,10 +312,38 @@ public class SociallyDistantVisualStyle : IVisualStyle
return Color.White;
}
private void DrawTextButton(TextButton widget, GeometryHelper geometry)
{
var focused = widget.IsFocused;
var hovered = widget.IsHovered;
var pressed = widget.IsPressed;
var background = buttonBackground;
var border = buttonBorder;
if (hovered && pressed)
{
background = buttonPressedBackground;
}
else if (hovered)
{
background = buttonHoveredBackground;
}
geometry.AddRoundedRectangle(widget.ContentArea, 3, background);
if (hovered || pressed || focused)
{
geometry.AddRoundedRectangleOutline(widget.ContentArea, 1, 3, border);
}
}
public void DrawWidgetBackground(Widget widget, GeometryHelper geometryHelper)
{
if (widget is InputField inputField)
DrawInputField(inputField, geometryHelper);
else if (widget is TextButton textButton)
DrawTextButton(textButton, geometryHelper);
else if (widget is IWindowTab tab)
DrawWindowTab(widget, tab, geometryHelper);
else if (widget is DecorativeBlock box)

View file

@ -25,12 +25,12 @@ public sealed class SettingsCategoriesList : ListAdapter<ScrollView, SettingsCat
categories.SetItems(models);
}
public override SettingsCategoriesViewHolder CreateViewHolder(int itemIndex, Box rootWidget)
protected override SettingsCategoriesViewHolder CreateViewHolder(int itemIndex, Box rootWidget)
{
return new SettingsCategoriesViewHolder(itemIndex, rootWidget);
}
public override void UpdateView(SettingsCategoriesViewHolder viewHolder)
protected override void UpdateView(SettingsCategoriesViewHolder viewHolder)
{
var model = categories[viewHolder.ItemIndex];
viewHolder.SetModel(model);