feat(vitalsharing): close button on overlay + rename settings button

- Settings tab button renamed from "Open Overlay" to "Toggle Overlay"
  since the same button now closes the overlay if it's already open
  (it already toggled, the old label was misleading).
- Overlay now draws a red X close button in the top-right corner while
  Ctrl is held, matching UB's NetworkUI affordance. Ctrl+left-click on
  the X hides the overlay. Same Ctrl-modifier gate as the drag
  operation so the normal game UI is not affected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-11 15:16:14 +02:00
parent 49ec534514
commit e59e2cdfc3
3 changed files with 38 additions and 2 deletions

View file

@ -40,7 +40,7 @@
<!-- Vital sharing setting -->
<control progid="DecalControls.Checkbox" name="chkVitalSharingEnabled" left="20" top="110" width="200" height="20" text="Vital Sharing (cross-PC)" checked="false"/>
<control progid="DecalControls.PushButton" name="btnVitalSharingOverlay" left="220" top="108" width="100" height="22" text="Open Overlay"/>
<control progid="DecalControls.PushButton" name="btnVitalSharingOverlay" left="220" top="108" width="100" height="22" text="Toggle Overlay"/>
<!-- Verbose logging -->
<control progid="DecalControls.Checkbox" name="chkVerboseLogging" left="20" top="230" width="300" height="20" text="Verbose logging (vital sharing / VTank feed)" checked="false"/>

View file

@ -166,12 +166,28 @@ namespace MosswartMassacre.Views
private const int WM_LBUTTONUP = 0x0202;
private const int VK_CONTROL = 0x11;
private const int CLOSE_BTN_SIZE = 14;
private static Rectangle HudRect()
{
if (_hud == null) return Rectangle.Empty;
return new Rectangle(_hud.Location.X, _hud.Location.Y, HUD_WIDTH, Math.Max(1, _lastRowCount) * ROW_SIZE + 5);
}
/// <summary>Hud-local rect for the close button (only used while Ctrl is held).</summary>
private static Rectangle CloseBtnRectLocal()
{
return new Rectangle(HUD_WIDTH - CLOSE_BTN_SIZE - 2, 2, CLOSE_BTN_SIZE, CLOSE_BTN_SIZE);
}
/// <summary>Screen-space rect for the close button at the current HUD location.</summary>
private static Rectangle CloseBtnRectScreen()
{
if (_hud == null) return Rectangle.Empty;
var local = CloseBtnRectLocal();
return new Rectangle(_hud.Location.X + local.X, _hud.Location.Y + local.Y, local.Width, local.Height);
}
private static void OnWindowMessage(object sender, WindowMessageEventArgs e)
{
try
@ -199,6 +215,13 @@ namespace MosswartMassacre.Views
switch (e.Msg)
{
case WM_LBUTTONDOWN:
// Ctrl+click the close button in the top-right corner to close.
if (CloseBtnRectScreen().Contains(mouse))
{
e.Eat = true;
Hide();
break;
}
if (HudRect().Contains(mouse))
{
_isDragging = true;
@ -306,7 +329,7 @@ namespace MosswartMassacre.Views
offset += ROW_SIZE;
}
// Drag-highlight border when Ctrl is held
// Drag-highlight border + close button when Ctrl is held
if (_isHoldingControl)
{
var w = HUD_WIDTH;
@ -315,6 +338,19 @@ namespace MosswartMassacre.Views
tex.DrawLine(new PointF(w - 1, 0), new PointF(w - 1, h - 1), COLOR_DRAG_BORDER, 1);
tex.DrawLine(new PointF(w - 1, h - 1), new PointF(0, h - 1), COLOR_DRAG_BORDER, 1);
tex.DrawLine(new PointF(0, h - 1), new PointF(0, 0), COLOR_DRAG_BORDER, 1);
// Close button: red box with a white X (top-right corner)
var btn = CloseBtnRectLocal();
tex.Fill(btn, Color.FromArgb(220, 160, 20, 20));
tex.DrawLine(new PointF(btn.Left, btn.Top), new PointF(btn.Right - 1, btn.Top), Color.White, 1);
tex.DrawLine(new PointF(btn.Right - 1, btn.Top), new PointF(btn.Right - 1, btn.Bottom - 1), Color.White, 1);
tex.DrawLine(new PointF(btn.Right - 1, btn.Bottom - 1), new PointF(btn.Left, btn.Bottom - 1), Color.White, 1);
tex.DrawLine(new PointF(btn.Left, btn.Bottom - 1), new PointF(btn.Left, btn.Top), Color.White, 1);
// X glyph
tex.DrawLine(new PointF(btn.Left + 3, btn.Top + 3),
new PointF(btn.Right - 4, btn.Bottom - 4), Color.White, 2);
tex.DrawLine(new PointF(btn.Right - 4, btn.Top + 3),
new PointF(btn.Left + 3, btn.Bottom - 4), Color.White, 2);
}
// Text passes