fix(ui): finish retail stack selector polish
Keep the horizontal thumb at its raw pointer position so both endpoints are reachable, honor the stack entry's authored right alignment, and preserve PublicWeenieDesc plural names from CreateObject through the object table. Port retail's singular s/es fallback when no plural was sent. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
a20e5c68c7
commit
6005c51c4d
22 changed files with 233 additions and 36 deletions
|
|
@ -29,10 +29,14 @@ public sealed class UiScrollbar : UiElement
|
|||
/// Optional scalar mode used by retail's horizontal stack-split control. When set,
|
||||
/// the bar reflects/drives one normalized value rather than a <see cref="UiScrollable"/>.
|
||||
/// </summary>
|
||||
public Func<float>? ScalarValue { get; set; }
|
||||
public float ScalarPosition { get; private set; }
|
||||
public Action<float>? ScalarChanged { get; set; }
|
||||
public bool Horizontal { get; set; }
|
||||
|
||||
/// <summary>Programmatically set retail scrollbar attribute 0x86 without broadcasting.</summary>
|
||||
public void SetScalarPosition(float position)
|
||||
=> ScalarPosition = Math.Clamp(position, 0f, 1f);
|
||||
|
||||
/// <summary>RenderSurface id → (GL tex, w, h). 0 id = skip.</summary>
|
||||
public Func<uint, (uint tex, int w, int h)>? SpriteResolve { get; set; }
|
||||
|
||||
|
|
@ -95,12 +99,12 @@ public sealed class UiScrollbar : UiElement
|
|||
protected override void OnDraw(UiRenderContext ctx)
|
||||
{
|
||||
if (SpriteResolve is not { } resolve) return;
|
||||
if (Horizontal && ScalarValue is not null)
|
||||
if (Horizontal)
|
||||
{
|
||||
DrawTiled(ctx, resolve, TrackSprite, 0f, 0f, Width, Height);
|
||||
float thumbWidth = ScalarThumbWidth(resolve);
|
||||
float travel = MathF.Max(0f, Width - thumbWidth);
|
||||
float x = travel * Math.Clamp(ScalarValue(), 0f, 1f);
|
||||
float x = travel * ScalarPosition;
|
||||
DrawSprite(ctx, resolve, ThumbSprite, x, 0f, thumbWidth, Height);
|
||||
return;
|
||||
}
|
||||
|
|
@ -162,7 +166,7 @@ public sealed class UiScrollbar : UiElement
|
|||
|
||||
public override bool OnEvent(in UiEvent e)
|
||||
{
|
||||
if (Horizontal && ScalarValue is not null && ScalarChanged is not null)
|
||||
if (Horizontal && ScalarChanged is not null)
|
||||
return OnScalarEvent(e);
|
||||
|
||||
if (Model is not { } m) return false;
|
||||
|
|
@ -228,7 +232,7 @@ public sealed class UiScrollbar : UiElement
|
|||
{
|
||||
float thumbWidth = ScalarThumbWidth(SpriteResolve);
|
||||
float travel = MathF.Max(1f, Width - thumbWidth);
|
||||
float thumbX = travel * Math.Clamp(ScalarValue!(), 0f, 1f);
|
||||
float thumbX = travel * ScalarPosition;
|
||||
float x = e.Data1;
|
||||
if (x >= thumbX && x <= thumbX + thumbWidth)
|
||||
{
|
||||
|
|
@ -237,7 +241,7 @@ public sealed class UiScrollbar : UiElement
|
|||
else
|
||||
{
|
||||
_dragOffsetX = thumbWidth * 0.5f;
|
||||
ScalarChanged!(Math.Clamp((x - _dragOffsetX) / travel, 0f, 1f));
|
||||
ChangeScalarPosition((x - _dragOffsetX) / travel);
|
||||
}
|
||||
_draggingThumb = true;
|
||||
return true;
|
||||
|
|
@ -247,7 +251,7 @@ public sealed class UiScrollbar : UiElement
|
|||
{
|
||||
float thumbWidth = ScalarThumbWidth(SpriteResolve);
|
||||
float travel = MathF.Max(1f, Width - thumbWidth);
|
||||
ScalarChanged!(Math.Clamp(((float)e.Data1 - _dragOffsetX) / travel, 0f, 1f));
|
||||
ChangeScalarPosition(((float)e.Data1 - _dragOffsetX) / travel);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -268,4 +272,10 @@ public sealed class UiScrollbar : UiElement
|
|||
}
|
||||
return MathF.Min(16f, Width);
|
||||
}
|
||||
|
||||
private void ChangeScalarPosition(float position)
|
||||
{
|
||||
SetScalarPosition(position);
|
||||
ScalarChanged?.Invoke(ScalarPosition);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue