@
feat(D.2b): chat polish — typing fix, opacity, scrollbar 3-slice, retail channel menu Visual-iteration batch (decomp-grounded), each fix verified against the retail screenshots: - typing: UiElement.HitTest aborted on ClickThrough BEFORE walking children, so the ClickThrough UiDatElement panels blocked hit-testing to the input/transcript inside them. Check ClickThrough AFTER the child walk (it only gates whether THIS element claims the hit). Restores input focus + typing. - opacity: UiElement.Opacity + a UiRenderContext alpha stack applied to sprite/rect draws (text bypasses it, stays sharp); chat frame Opacity=0.75 → translucent chat. - brown sliver: grow the transcript panel up 9px to cover the dropped resize-bar strip. - scrollbar: real 3-slice thumb (caps 0x06004C60/66 + tiled mid) + tiled track. - max/min: shifted one button-width left of the scrollbar (dat right-anchors collide). - system text now green (retail ChatMessageType 5; was yellow). - word-wrap: transcript lines wrap to the panel width (greedy, ports GlyphList::Recalculate). - channel menu reworked to retail gmMainChatUI::InitTalkFocusMenu: "Chat" button + a TWO-COLUMN popup of the 14 talk-focus items (Squelch, Tell to Selected, Chat to All, Tell to Fellows, ...) on a tan panel; channel items set the active outbound channel. Build + 392 App tests green. Visual confirmation in progress. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
parent
0ec36f6197
commit
1da697ec2a
7 changed files with 329 additions and 126 deletions
|
|
@ -93,6 +93,11 @@ public abstract class UiElement
|
|||
/// <summary>Painter's-algorithm z-order within siblings. Higher = on top.</summary>
|
||||
public int ZOrder { get; set; }
|
||||
|
||||
/// <summary>Window opacity (0..1) multiplied into this element's and its
|
||||
/// descendants' background + sprite draws (text stays opaque). 1 = fully opaque.
|
||||
/// Set on a top-level window (e.g. the chat frame) for retail's translucent chat.</summary>
|
||||
public float Opacity { get; set; } = 1f;
|
||||
|
||||
/// <summary>If true, a left-drag on this element (or a non-draggable child of
|
||||
/// it) repositions it as a movable window. Intended for top-level panels,
|
||||
/// whose Left/Top are screen coordinates (Root sits at the origin).</summary>
|
||||
|
|
@ -179,8 +184,10 @@ public abstract class UiElement
|
|||
{
|
||||
if (!Visible) return;
|
||||
|
||||
// Translate into our local space.
|
||||
// Translate into our local space + push this window's opacity (multiplies into
|
||||
// descendants' sprite/rect draws; text bypasses the alpha so it stays sharp).
|
||||
ctx.PushTransform(Left, Top);
|
||||
ctx.PushAlpha(Opacity);
|
||||
try
|
||||
{
|
||||
OnDraw(ctx);
|
||||
|
|
@ -201,6 +208,7 @@ public abstract class UiElement
|
|||
}
|
||||
finally
|
||||
{
|
||||
ctx.PopAlpha();
|
||||
ctx.PopTransform();
|
||||
}
|
||||
}
|
||||
|
|
@ -220,9 +228,14 @@ public abstract class UiElement
|
|||
/// </summary>
|
||||
internal UiElement? HitTest(float localX, float localY)
|
||||
{
|
||||
if (!Visible || !Enabled || ClickThrough) return null;
|
||||
if (!Visible || !Enabled) return null;
|
||||
|
||||
// Children first, in reverse Z-order (topmost first).
|
||||
// Children first, in reverse Z-order (topmost first). ClickThrough means
|
||||
// THIS element is transparent to the pointer — but its children are NOT.
|
||||
// A ClickThrough container (e.g. a UiDatElement panel that hosts the chat
|
||||
// input / transcript) must still let the pointer reach its behavioral
|
||||
// children, so the ClickThrough check happens AFTER the child walk, gating
|
||||
// only whether THIS element claims the hit.
|
||||
if (_children.Count > 0)
|
||||
{
|
||||
var ordered = _children.ToArray();
|
||||
|
|
@ -235,6 +248,7 @@ public abstract class UiElement
|
|||
}
|
||||
}
|
||||
|
||||
if (ClickThrough) return null;
|
||||
return OnHitTest(localX, localY) ? this : null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue