Co-locate the two cockpit-pod projects into a single repository:
- Console/ : TeslaConsole, the net48 WinForms operator console (decompiled
reconstruction) plus its differential + catalog test suite.
- Launcher/ : TeslaLauncher, the net6 pod-side Service + Agent rewrite.
Adds a combined TeslaSuite.sln, root README documenting the shared wire
contract (and its current duplication, the main follow-up), and a root
.gitignore. Histories were not preserved per request; this is a fresh start
from the current working state of both projects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
504 lines
12 KiB
C#
504 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
namespace TeslaConsole;
|
|
|
|
public class NotificationAlert : Form
|
|
{
|
|
private const double FadeInDuration = 0.3;
|
|
|
|
private const double FadeOutDuration = 0.3;
|
|
|
|
private const int AlertSpacing = 0;
|
|
|
|
private static List<NotificationAlert> mAlerts = new List<NotificationAlert>();
|
|
|
|
private double mDoubleTop;
|
|
|
|
private double mDestTop;
|
|
|
|
private bool mMoving;
|
|
|
|
private IContainer components;
|
|
|
|
private PictureBox picIcon;
|
|
|
|
private Label lblMessage;
|
|
|
|
private Button cmdRightButton;
|
|
|
|
private Button cmdCenterButton;
|
|
|
|
private Button cmdLeftButton;
|
|
|
|
private Timer tmrFadeIn;
|
|
|
|
private Timer tmrFadeOut;
|
|
|
|
private Timer tmrSlideDown;
|
|
|
|
private TextBox txtInput;
|
|
|
|
private Timer tmrSlideUp;
|
|
|
|
public string Title
|
|
{
|
|
get
|
|
{
|
|
return base.Text;
|
|
}
|
|
set
|
|
{
|
|
base.Text = value;
|
|
}
|
|
}
|
|
|
|
public override string Text
|
|
{
|
|
get
|
|
{
|
|
if (lblMessage == null)
|
|
{
|
|
return null;
|
|
}
|
|
return lblMessage.Text;
|
|
}
|
|
set
|
|
{
|
|
if (lblMessage != null)
|
|
{
|
|
lblMessage.Text = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public new Image Icon
|
|
{
|
|
get
|
|
{
|
|
return picIcon.Image;
|
|
}
|
|
set
|
|
{
|
|
picIcon.Image = value;
|
|
}
|
|
}
|
|
|
|
public bool LeftButton
|
|
{
|
|
get
|
|
{
|
|
return cmdLeftButton.Visible;
|
|
}
|
|
set
|
|
{
|
|
cmdLeftButton.Visible = value;
|
|
}
|
|
}
|
|
|
|
public string LeftButtonText
|
|
{
|
|
get
|
|
{
|
|
return cmdLeftButton.Text;
|
|
}
|
|
set
|
|
{
|
|
cmdLeftButton.Text = value;
|
|
}
|
|
}
|
|
|
|
public DialogResult LeftButtonDialogResult
|
|
{
|
|
get
|
|
{
|
|
return cmdLeftButton.DialogResult;
|
|
}
|
|
set
|
|
{
|
|
cmdLeftButton.DialogResult = value;
|
|
}
|
|
}
|
|
|
|
public bool CenterButton
|
|
{
|
|
get
|
|
{
|
|
return cmdCenterButton.Visible;
|
|
}
|
|
set
|
|
{
|
|
cmdCenterButton.Visible = value;
|
|
}
|
|
}
|
|
|
|
public string CenterButtonText
|
|
{
|
|
get
|
|
{
|
|
return cmdCenterButton.Text;
|
|
}
|
|
set
|
|
{
|
|
cmdCenterButton.Text = value;
|
|
}
|
|
}
|
|
|
|
public DialogResult CenterButtonDialogResult
|
|
{
|
|
get
|
|
{
|
|
return cmdCenterButton.DialogResult;
|
|
}
|
|
set
|
|
{
|
|
cmdCenterButton.DialogResult = value;
|
|
}
|
|
}
|
|
|
|
public bool RightButton
|
|
{
|
|
get
|
|
{
|
|
return cmdRightButton.Visible;
|
|
}
|
|
set
|
|
{
|
|
cmdRightButton.Visible = value;
|
|
}
|
|
}
|
|
|
|
public string RightButtonText
|
|
{
|
|
get
|
|
{
|
|
return cmdRightButton.Text;
|
|
}
|
|
set
|
|
{
|
|
cmdRightButton.Text = value;
|
|
}
|
|
}
|
|
|
|
public DialogResult RightButtonDialogResult
|
|
{
|
|
get
|
|
{
|
|
return cmdRightButton.DialogResult;
|
|
}
|
|
set
|
|
{
|
|
cmdRightButton.DialogResult = value;
|
|
}
|
|
}
|
|
|
|
public bool ShowInput
|
|
{
|
|
get
|
|
{
|
|
return txtInput.Visible;
|
|
}
|
|
set
|
|
{
|
|
if (value != txtInput.Visible)
|
|
{
|
|
txtInput.Visible = value;
|
|
if (value)
|
|
{
|
|
base.Height += txtInput.Height + txtInput.Margin.Bottom;
|
|
}
|
|
else
|
|
{
|
|
base.Height -= txtInput.Height + txtInput.Margin.Bottom;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public event EventHandler<AlertButtonClickEventArgs> AlertButtonClick;
|
|
|
|
public NotificationAlert()
|
|
{
|
|
InitializeComponent();
|
|
mAlerts.Add(this);
|
|
base.Opacity = 0.01;
|
|
ShowInput = false;
|
|
}
|
|
|
|
public new void Show()
|
|
{
|
|
mMoving = true;
|
|
base.Left = Screen.PrimaryScreen.WorkingArea.Right - base.Width - 30;
|
|
base.Top = Screen.PrimaryScreen.WorkingArea.Bottom - base.Height - 30;
|
|
mMoving = false;
|
|
base.Opacity = 0.01;
|
|
base.Show();
|
|
tmrFadeIn.Stop();
|
|
tmrFadeIn.Start();
|
|
int num = mAlerts.IndexOf(this);
|
|
if (num > 0)
|
|
{
|
|
NotificationAlert notificationAlert = mAlerts[num - 1];
|
|
notificationAlert.mDoubleTop = notificationAlert.Top;
|
|
notificationAlert.mDestTop = base.Top - notificationAlert.Height;
|
|
notificationAlert.tmrSlideUp.Tag = num - 1;
|
|
notificationAlert.tmrSlideUp.Stop();
|
|
notificationAlert.tmrSlideUp.Start();
|
|
}
|
|
}
|
|
|
|
private void tmrFadeIn_Tick(object sender, EventArgs e)
|
|
{
|
|
double num = (double)tmrFadeIn.Interval / 1000.0;
|
|
base.Opacity += 3.3333333333333335 * num;
|
|
if (base.Opacity >= 1.0)
|
|
{
|
|
base.Opacity = 1.0;
|
|
tmrFadeIn.Stop();
|
|
}
|
|
}
|
|
|
|
private void tmrFadeOut_Tick(object sender, EventArgs e)
|
|
{
|
|
double num = (double)tmrFadeIn.Interval / 1000.0;
|
|
base.Opacity -= 3.3333333333333335 * num;
|
|
if (base.Opacity <= 0.01)
|
|
{
|
|
base.Opacity = 0.01;
|
|
Close();
|
|
tmrFadeOut.Stop();
|
|
}
|
|
}
|
|
|
|
private void tmrSlideUp_Tick(object sender, EventArgs e)
|
|
{
|
|
double dT = (double)tmrSlideUp.Interval / 1000.0;
|
|
SlideUp((int)tmrSlideUp.Tag, dT);
|
|
if (mDoubleTop <= mDestTop)
|
|
{
|
|
tmrSlideUp.Stop();
|
|
}
|
|
}
|
|
|
|
private void tmrSlideDown_Tick(object sender, EventArgs e)
|
|
{
|
|
double dT = (double)tmrSlideDown.Interval / 1000.0;
|
|
SlideDown((int)tmrSlideDown.Tag, dT);
|
|
if (mDoubleTop >= mDestTop)
|
|
{
|
|
tmrSlideDown.Stop();
|
|
}
|
|
}
|
|
|
|
private void NotificationAlert_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (e.CloseReason != CloseReason.UserClosing || !(base.Opacity > 0.01))
|
|
{
|
|
return;
|
|
}
|
|
e.Cancel = true;
|
|
tmrFadeOut.Stop();
|
|
tmrFadeOut.Start();
|
|
int num = mAlerts.IndexOf(this);
|
|
if (num > 0)
|
|
{
|
|
NotificationAlert notificationAlert = mAlerts[num - 1];
|
|
notificationAlert.mDoubleTop = notificationAlert.Top;
|
|
if (num == mAlerts.Count - 1)
|
|
{
|
|
notificationAlert.mDestTop = (double)(Screen.PrimaryScreen.WorkingArea.Bottom - notificationAlert.Height) - 30.0;
|
|
}
|
|
else
|
|
{
|
|
notificationAlert.mDestTop = mAlerts[num + 1].Top - notificationAlert.Height;
|
|
}
|
|
notificationAlert.tmrSlideDown.Tag = num - 1;
|
|
notificationAlert.tmrSlideDown.Stop();
|
|
notificationAlert.tmrSlideDown.Start();
|
|
}
|
|
}
|
|
|
|
private static void SlideUp(int index, double dT)
|
|
{
|
|
if (index >= 0 && index <= mAlerts.Count)
|
|
{
|
|
for (int i = 0; i <= index; i++)
|
|
{
|
|
NotificationAlert notificationAlert = mAlerts[i];
|
|
notificationAlert.mDoubleTop -= (double)notificationAlert.Height / 0.3 * dT;
|
|
notificationAlert.mMoving = true;
|
|
notificationAlert.Top = (int)Math.Round(notificationAlert.mDoubleTop);
|
|
notificationAlert.mMoving = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void SlideDown(int index, double dT)
|
|
{
|
|
if (index >= 0 && index <= mAlerts.Count)
|
|
{
|
|
for (int num = index; num >= 0; num--)
|
|
{
|
|
NotificationAlert notificationAlert = mAlerts[num];
|
|
notificationAlert.mDoubleTop += (double)notificationAlert.Height / 0.3 * dT;
|
|
notificationAlert.mMoving = true;
|
|
notificationAlert.Top = (int)Math.Round(notificationAlert.mDoubleTop);
|
|
notificationAlert.mMoving = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void NotificationAlert_Move(object sender, EventArgs e)
|
|
{
|
|
if (mMoving)
|
|
{
|
|
return;
|
|
}
|
|
int num = mAlerts.IndexOf(this);
|
|
mAlerts.Remove(this);
|
|
if (num > 0)
|
|
{
|
|
NotificationAlert notificationAlert = mAlerts[num - 1];
|
|
notificationAlert.mDoubleTop = notificationAlert.Top;
|
|
if (num == mAlerts.Count)
|
|
{
|
|
notificationAlert.mDestTop = (double)(Screen.PrimaryScreen.WorkingArea.Bottom - notificationAlert.Height) - 30.0;
|
|
}
|
|
else
|
|
{
|
|
notificationAlert.mDestTop = mAlerts[num].Top - notificationAlert.Height;
|
|
}
|
|
notificationAlert.tmrSlideDown.Tag = num - 1;
|
|
notificationAlert.tmrSlideDown.Stop();
|
|
notificationAlert.tmrSlideDown.Start();
|
|
}
|
|
}
|
|
|
|
private void cmdButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (sender is Button button && this.AlertButtonClick != null)
|
|
{
|
|
this.AlertButtonClick(this, new AlertButtonClickEventArgs(button.DialogResult, ShowInput ? txtInput.Text : null));
|
|
}
|
|
}
|
|
|
|
private void txtInput_TextChanged(object sender, EventArgs e)
|
|
{
|
|
int selectionStart = txtInput.SelectionStart;
|
|
int selectionLength = txtInput.SelectionLength;
|
|
txtInput.Text = txtInput.Text.ToUpper();
|
|
txtInput.Select(selectionStart, selectionLength);
|
|
}
|
|
|
|
private void txtInput_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (e.KeyChar == '\r')
|
|
{
|
|
cmdCenterButton.PerformClick();
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing && components != null)
|
|
{
|
|
components.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
this.components = new System.ComponentModel.Container();
|
|
this.picIcon = new System.Windows.Forms.PictureBox();
|
|
this.lblMessage = new System.Windows.Forms.Label();
|
|
this.cmdRightButton = new System.Windows.Forms.Button();
|
|
this.cmdCenterButton = new System.Windows.Forms.Button();
|
|
this.cmdLeftButton = new System.Windows.Forms.Button();
|
|
this.tmrFadeIn = new System.Windows.Forms.Timer(this.components);
|
|
this.tmrFadeOut = new System.Windows.Forms.Timer(this.components);
|
|
this.tmrSlideDown = new System.Windows.Forms.Timer(this.components);
|
|
this.txtInput = new System.Windows.Forms.TextBox();
|
|
this.tmrSlideUp = new System.Windows.Forms.Timer(this.components);
|
|
((System.ComponentModel.ISupportInitialize)this.picIcon).BeginInit();
|
|
base.SuspendLayout();
|
|
this.picIcon.Location = new System.Drawing.Point(12, 12);
|
|
this.picIcon.Name = "picIcon";
|
|
this.picIcon.Size = new System.Drawing.Size(40, 40);
|
|
this.picIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
|
|
this.picIcon.TabIndex = 0;
|
|
this.picIcon.TabStop = false;
|
|
this.lblMessage.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.lblMessage.Location = new System.Drawing.Point(58, 12);
|
|
this.lblMessage.Name = "lblMessage";
|
|
this.lblMessage.Size = new System.Drawing.Size(206, 40);
|
|
this.lblMessage.TabIndex = 1;
|
|
this.lblMessage.Text = "Message";
|
|
this.cmdRightButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
|
this.cmdRightButton.Location = new System.Drawing.Point(189, 77);
|
|
this.cmdRightButton.Name = "cmdRightButton";
|
|
this.cmdRightButton.Size = new System.Drawing.Size(75, 23);
|
|
this.cmdRightButton.TabIndex = 2;
|
|
this.cmdRightButton.Text = "Cancel";
|
|
this.cmdRightButton.UseVisualStyleBackColor = true;
|
|
this.cmdRightButton.Click += new System.EventHandler(cmdButton_Click);
|
|
this.cmdCenterButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
|
this.cmdCenterButton.Location = new System.Drawing.Point(108, 77);
|
|
this.cmdCenterButton.Name = "cmdCenterButton";
|
|
this.cmdCenterButton.Size = new System.Drawing.Size(75, 23);
|
|
this.cmdCenterButton.TabIndex = 3;
|
|
this.cmdCenterButton.Text = "Okay";
|
|
this.cmdCenterButton.UseVisualStyleBackColor = true;
|
|
this.cmdCenterButton.Visible = false;
|
|
this.cmdCenterButton.Click += new System.EventHandler(cmdButton_Click);
|
|
this.cmdLeftButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
|
this.cmdLeftButton.Location = new System.Drawing.Point(27, 77);
|
|
this.cmdLeftButton.Name = "cmdLeftButton";
|
|
this.cmdLeftButton.Size = new System.Drawing.Size(75, 23);
|
|
this.cmdLeftButton.TabIndex = 4;
|
|
this.cmdLeftButton.Text = "Yes";
|
|
this.cmdLeftButton.UseVisualStyleBackColor = true;
|
|
this.cmdLeftButton.Visible = false;
|
|
this.cmdLeftButton.Click += new System.EventHandler(cmdButton_Click);
|
|
this.tmrFadeIn.Interval = 50;
|
|
this.tmrFadeIn.Tick += new System.EventHandler(tmrFadeIn_Tick);
|
|
this.tmrFadeOut.Interval = 50;
|
|
this.tmrFadeOut.Tick += new System.EventHandler(tmrFadeOut_Tick);
|
|
this.tmrSlideDown.Interval = 50;
|
|
this.tmrSlideDown.Tick += new System.EventHandler(tmrSlideDown_Tick);
|
|
this.txtInput.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.txtInput.Location = new System.Drawing.Point(61, 54);
|
|
this.txtInput.Name = "txtInput";
|
|
this.txtInput.Size = new System.Drawing.Size(203, 20);
|
|
this.txtInput.TabIndex = 5;
|
|
this.txtInput.Visible = false;
|
|
this.txtInput.TextChanged += new System.EventHandler(txtInput_TextChanged);
|
|
this.txtInput.KeyPress += new System.Windows.Forms.KeyPressEventHandler(txtInput_KeyPress);
|
|
this.tmrSlideUp.Interval = 50;
|
|
this.tmrSlideUp.Tick += new System.EventHandler(tmrSlideUp_Tick);
|
|
base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 13f);
|
|
base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
base.ClientSize = new System.Drawing.Size(276, 112);
|
|
base.Controls.Add(this.txtInput);
|
|
base.Controls.Add(this.cmdLeftButton);
|
|
base.Controls.Add(this.cmdCenterButton);
|
|
base.Controls.Add(this.cmdRightButton);
|
|
base.Controls.Add(this.lblMessage);
|
|
base.Controls.Add(this.picIcon);
|
|
base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
|
base.Name = "NotificationAlert";
|
|
base.ShowInTaskbar = false;
|
|
base.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
|
this.Text = "NotificationAlert";
|
|
base.TopMost = true;
|
|
base.Move += new System.EventHandler(NotificationAlert_Move);
|
|
base.FormClosing += new System.Windows.Forms.FormClosingEventHandler(NotificationAlert_FormClosing);
|
|
((System.ComponentModel.ISupportInitialize)this.picIcon).EndInit();
|
|
base.ResumeLayout(false);
|
|
base.PerformLayout();
|
|
}
|
|
}
|