fix(combat): resolve power spans after layout
Derive the dark middle range from live post-anchor sibling geometry instead of freezing the inherited 800-pixel prototype during controller binding. Render the user-directed bright desired-power band independently from the absolute bar-left edge to the green thumb center. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
707add8539
commit
f8c174d707
8 changed files with 129 additions and 24 deletions
|
|
@ -49,6 +49,14 @@ public sealed class UiScrollbar : UiElement
|
|||
public float ScalarRangeLeft { get; set; }
|
||||
public float ScalarRangeWidth { get; set; } = float.PositiveInfinity;
|
||||
/// <summary>
|
||||
/// Optional live range geometry. Imported sibling controls reflow immediately
|
||||
/// before drawing, so combat derives its centered range from their current
|
||||
/// rectangles instead of freezing pre-reflow prototype coordinates.
|
||||
/// </summary>
|
||||
public Func<(float Left, float Width)>? ScalarRangeProvider { get; set; }
|
||||
/// <summary>Draw the scalar fill from the absolute left edge to the thumb center.</summary>
|
||||
public bool ScalarFillFollowsThumb { get; set; }
|
||||
/// <summary>
|
||||
/// Draw the scalar meter from the power end (right) toward the speed end
|
||||
/// (left). This is the authored gmCombatUI power meter direction.
|
||||
/// </summary>
|
||||
|
|
@ -141,14 +149,21 @@ public sealed class UiScrollbar : UiElement
|
|||
if (ScalarRangeSprite != 0)
|
||||
DrawTiled(ctx, resolve, ScalarRangeSprite,
|
||||
rangeLeft, 0f, rangeWidth, Height);
|
||||
if (ScalarFill() is float fill && ScalarFillSprite != 0)
|
||||
float thumbWidth = ScalarThumbWidth(resolve);
|
||||
if (ScalarFillSprite != 0 && ScalarFillFollowsThumb)
|
||||
{
|
||||
var (fillX, visibleWidth) = ScalarThumbFillRect(
|
||||
Width, thumbWidth, ScalarPosition);
|
||||
DrawTiledClipped(ctx, resolve, ScalarFillSprite,
|
||||
0f, fillX, visibleWidth, Height);
|
||||
}
|
||||
else if (ScalarFill() is float fill && ScalarFillSprite != 0)
|
||||
{
|
||||
var (fillX, visibleWidth) = ScalarFillRect(
|
||||
rangeLeft, rangeWidth, fill, ScalarFillFromRight);
|
||||
DrawTiledClipped(ctx, resolve, ScalarFillSprite,
|
||||
rangeLeft, fillX, visibleWidth, Height);
|
||||
}
|
||||
float thumbWidth = ScalarThumbWidth(resolve);
|
||||
float travel = MathF.Max(0f, Width - thumbWidth);
|
||||
float x = travel * ScalarPosition;
|
||||
DrawSprite(ctx, resolve, ThumbSprite, x, 0f, thumbWidth, Height);
|
||||
|
|
@ -233,14 +248,27 @@ public sealed class UiScrollbar : UiElement
|
|||
|
||||
private (float left, float width) ScalarRangeRect()
|
||||
{
|
||||
float left = Math.Clamp(ScalarRangeLeft, 0f, Width);
|
||||
float requestedWidth = float.IsPositiveInfinity(ScalarRangeWidth)
|
||||
(float configuredLeft, float configuredWidth) = ScalarRangeProvider?.Invoke()
|
||||
?? (ScalarRangeLeft, ScalarRangeWidth);
|
||||
float left = Math.Clamp(configuredLeft, 0f, Width);
|
||||
float requestedWidth = float.IsPositiveInfinity(configuredWidth)
|
||||
? Width - left
|
||||
: MathF.Max(0f, ScalarRangeWidth);
|
||||
: MathF.Max(0f, configuredWidth);
|
||||
float width = Math.Clamp(requestedWidth, 0f, Width - left);
|
||||
return (left, width);
|
||||
}
|
||||
|
||||
/// <summary>Returns the absolute-left fill ending at the scalar thumb center.</summary>
|
||||
public static (float x, float width) ScalarThumbFillRect(
|
||||
float totalWidth, float thumbWidth, float position)
|
||||
{
|
||||
float safeWidth = MathF.Max(0f, totalWidth);
|
||||
float safeThumb = Math.Clamp(thumbWidth, 0f, safeWidth);
|
||||
float travel = safeWidth - safeThumb;
|
||||
float center = travel * Math.Clamp(position, 0f, 1f) + safeThumb * 0.5f;
|
||||
return (0f, center);
|
||||
}
|
||||
|
||||
public override bool OnEvent(in UiEvent e)
|
||||
{
|
||||
if (Horizontal && ScalarChanged is not null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue