Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ appsettings.*.json

# Claude Code local settings
.claude/settings.local.json
publish/
44 changes: 21 additions & 23 deletions App/Dialogs/ConnectDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
private const string ProtocolPrefix = "opc.tcp://";
private readonly TextField _endpointField;
private readonly NumericUpDown<int> _publishIntervalField;
private readonly RadioGroup _authTypeRadio;
private readonly OptionSelector _authTypeRadio;
private readonly Label _usernameLabel;
private readonly TextField _usernameField;
private readonly Label _passwordLabel;
Expand All @@ -27,11 +27,13 @@
public bool Confirmed => _confirmed;
public int PublishingInterval => _publishIntervalField.Value;
public AuthenticationType SelectedAuthType =>
_authTypeRadio.SelectedItem == 1 ? AuthenticationType.UserName : AuthenticationType.Anonymous;
_authTypeRadio.Value == 1 ? AuthenticationType.UserName : AuthenticationType.Anonymous;
public string? Username => SelectedAuthType == AuthenticationType.UserName
? _usernameField.Text?.Trim() : null;
// An untouched password box is "no password" (null), not an empty-string password;
// downstream the two are sent identically (Password ?? string.Empty).
public string? Password => SelectedAuthType == AuthenticationType.UserName
? _passwordField.Text : null;
&& !string.IsNullOrEmpty(_passwordField.Text) ? _passwordField.Text : null;

public ConnectDialog(
string? initialEndpoint = null,
Expand Down Expand Up @@ -60,8 +62,7 @@
X = 1,
Y = 2,
Text = ProtocolPrefix,
ColorScheme = theme.MainColorScheme
};
}.WithScheme(theme.MainColorScheme);

_endpointField = new TextField
{
Expand Down Expand Up @@ -95,8 +96,7 @@
X = 1,
Y = 6,
Text = "How often the server sends data updates (100-10000)",
ColorScheme = theme.MainColorScheme
};
}.WithScheme(theme.MainColorScheme);

// Authentication section
var authLabel = new Label
Expand All @@ -106,13 +106,13 @@
Text = "Authentication:"
};

_authTypeRadio = new RadioGroup
_authTypeRadio = new OptionSelector
{
X = 1,
Y = 9,
RadioLabels = ["Anonymous", "Username/Password"],
Labels = ["Anonymous", "Username/Password"],
Orientation = Orientation.Horizontal,
SelectedItem = authType == AuthenticationType.UserName ? 1 : 0
Value = authType == AuthenticationType.UserName ? 1 : 0
};

_usernameLabel = new Label
Expand Down Expand Up @@ -149,9 +149,9 @@
Visible = authType == AuthenticationType.UserName
};

_authTypeRadio.SelectedItemChanged += (_, _) =>
_authTypeRadio.ValueChanged += (_, _) =>
{
var showCredentials = _authTypeRadio.SelectedItem == 1;
var showCredentials = _authTypeRadio.Value == 1;
_usernameLabel.Visible = showCredentials;
_usernameField.Visible = showCredentials;
_passwordLabel.Visible = showCredentials;
Expand All @@ -167,15 +167,14 @@
Y = 14,
Text = $"{theme.ButtonPrefix}Connect{theme.ButtonSuffix}",
IsDefault = true,
ColorScheme = defaultButtonScheme
};
}.WithScheme(defaultButtonScheme);

connectButton.Accepting += (_, _) =>
{
if (ValidateInput())
{
_confirmed = true;
Application.RequestStop();

Check warning on line 177 in App/Dialogs/ConnectDialog.cs

View workflow job for this annotation

GitHub Actions / build

'Application.RequestStop(IRunnable?)' is obsolete: 'The legacy static Application object is going away.'
}
};

Expand All @@ -184,13 +183,12 @@
X = Pos.Center() + 4,
Y = 14,
Text = $"{theme.ButtonPrefix}Cancel{theme.ButtonSuffix}",
ColorScheme = theme.ButtonColorScheme
};
}.WithScheme(theme.ButtonColorScheme);

cancelButton.Accepting += (_, _) =>
{
_confirmed = false;
Application.RequestStop();

Check warning on line 191 in App/Dialogs/ConnectDialog.cs

View workflow job for this annotation

GitHub Actions / build

'Application.RequestStop(IRunnable?)' is obsolete: 'The legacy static Application object is going away.'
};

Add(endpointLabel, protocolLabel, _endpointField,
Expand All @@ -208,7 +206,7 @@

if (string.IsNullOrEmpty(serverAddress))
{
MessageBox.ErrorQuery("Error", "Please enter a server address", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Please enter a server address", "OK");

Check warning on line 209 in App/Dialogs/ConnectDialog.cs

View workflow job for this annotation

GitHub Actions / build

'Application.Instance' is obsolete: 'The legacy static Application object is going away. Use Application.Create() for new code.'
return false;
}

Expand All @@ -217,20 +215,20 @@
var uri = new Uri(EndpointUrl);
if (string.IsNullOrEmpty(uri.Host))
{
MessageBox.ErrorQuery("Error", "Invalid host in server address", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Invalid host in server address", "OK");
return false;
}
}
catch
{
MessageBox.ErrorQuery("Error", "Invalid server address format", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Invalid server address format", "OK");
return false;
}

var interval = _publishIntervalField.Value;
if (interval < 100 || interval > 10000)
{
MessageBox.ErrorQuery("Error", "Publishing interval must be between 100 and 10000 ms", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Publishing interval must be between 100 and 10000 ms", "OK");
return false;
}

Expand All @@ -239,15 +237,15 @@
var username = _usernameField.Text?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(username))
{
MessageBox.ErrorQuery("Error", "Please enter a username", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Please enter a username", "OK");
_usernameField.SetFocus();
return false;
}

var password = _passwordField.Text ?? string.Empty;
if (string.IsNullOrEmpty(password))
{
MessageBox.ErrorQuery("Error", "Please enter a password", "OK");
MessageBox.ErrorQuery(Application.Instance, "Error", "Please enter a password", "OK");
_passwordField.SetFocus();
return false;
}
Expand Down Expand Up @@ -275,7 +273,7 @@
{
_endpointField.Text = cleaned;
// Move cursor to end
_endpointField.CursorPosition = cleaned.Length;
_endpointField.MoveEnd();
}
finally
{
Expand Down
27 changes: 12 additions & 15 deletions App/Dialogs/HelpDialog.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Terminal.Gui;
using Opcilloscope.App.Keybindings;
using Opcilloscope.App.Themes;
using Attribute = Terminal.Gui.Attribute;
using ThemeManager = Opcilloscope.App.Themes.ThemeManager;

namespace Opcilloscope.App.Dialogs;
Expand All @@ -25,7 +24,7 @@ public HelpDialog(KeybindingManager keybindingManager)
var theme = ThemeManager.Current;

// Apply theme styling with emphasized border (double-line)
ColorScheme = theme.MainColorScheme;
SetScheme(theme.MainColorScheme);
BorderStyle = theme.EmphasizedBorderStyle;

// Create content view with the help text
Expand All @@ -37,20 +36,19 @@ public HelpDialog(KeybindingManager keybindingManager)
Height = Dim.Fill(2),
ReadOnly = true,
WordWrap = true,
ColorScheme = new ColorScheme
{
Normal = new Attribute(theme.Foreground, theme.Background),
Focus = new Attribute(theme.Foreground, theme.Background),
HotNormal = new Attribute(theme.Foreground, theme.Background),
HotFocus = new Attribute(theme.Foreground, theme.Background),
Disabled = new Attribute(theme.MutedText, theme.Background)
}
};
}.WithScheme(new Scheme
{
Normal = new Attribute(theme.Foreground, theme.Background),
Focus = new Attribute(theme.Foreground, theme.Background),
HotNormal = new Attribute(theme.Foreground, theme.Background),
HotFocus = new Attribute(theme.Foreground, theme.Background),
Disabled = new Attribute(theme.MutedText, theme.Background)
});

contentView.Text = GenerateHelpFromBindings(keybindingManager);

// OK button - highlighted with accent color (default action)
var defaultButtonScheme = new ColorScheme
var defaultButtonScheme = new Scheme
{
Normal = new Attribute(theme.Accent, theme.Background),
Focus = new Attribute(theme.AccentBright, theme.Background),
Expand All @@ -65,8 +63,7 @@ public HelpDialog(KeybindingManager keybindingManager)
X = Pos.Center(),
Y = Pos.AnchorEnd(1),
IsDefault = true,
ColorScheme = defaultButtonScheme
};
}.WithScheme(defaultButtonScheme);
okButton.Accepting += (_, _) => RequestStop();

Add(contentView);
Expand Down Expand Up @@ -126,7 +123,7 @@ private void OnThemeChanged(AppTheme theme)
{
Application.Invoke(() =>
{
ColorScheme = theme.MainColorScheme;
SetScheme(theme.MainColorScheme);
BorderStyle = theme.EmphasizedBorderStyle;
SetNeedsLayout();
});
Expand Down
19 changes: 7 additions & 12 deletions App/Dialogs/OpenConfigDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public OpenConfigDialog()
Y = 0,
Width = Dim.Fill(1),
Text = configDir,
ColorScheme = theme.MainColorScheme
};
}.WithScheme(theme.MainColorScheme);

// Scan config directory for files sorted by last modified (newest first)
LoadFiles(configDir);
Expand All @@ -61,37 +60,33 @@ public OpenConfigDialog()
Y = 2,
Width = Dim.Fill(1),
Height = Dim.Fill(3),
ColorScheme = theme.MainColorScheme
};
}.WithScheme(theme.MainColorScheme);
_fileListView.SetSource(new System.Collections.ObjectModel.ObservableCollection<string>(displayNames));
_fileListView.OpenSelectedItem += (_, _) => Confirm();
_fileListView.Accepting += (_, _) => Confirm();

var openButton = new Button
{
X = Pos.Center() - 22,
Y = Pos.AnchorEnd(1),
Text = $"{theme.ButtonPrefix}Open{theme.ButtonSuffix}",
IsDefault = true,
ColorScheme = ThemeStyler.CreateAccentButtonScheme(theme)
};
}.WithScheme(ThemeStyler.CreateAccentButtonScheme(theme));
openButton.Accepting += (_, _) => Confirm();

var browseButton = new Button
{
X = Pos.Right(openButton) + 1,
Y = Pos.AnchorEnd(1),
Text = $"{theme.ButtonPrefix}Browse...{theme.ButtonSuffix}",
ColorScheme = theme.ButtonColorScheme
};
}.WithScheme(theme.ButtonColorScheme);
browseButton.Accepting += OnBrowse;

var cancelButton = new Button
{
X = Pos.Right(browseButton) + 1,
Y = Pos.AnchorEnd(1),
Text = $"{theme.ButtonPrefix}Cancel{theme.ButtonSuffix}",
ColorScheme = theme.ButtonColorScheme
};
}.WithScheme(theme.ButtonColorScheme);
cancelButton.Accepting += (_, _) =>
{
_confirmed = false;
Expand Down Expand Up @@ -124,7 +119,7 @@ private void Confirm()
{
if (_fileListView.SelectedItem >= 0 && _fileListView.SelectedItem < _files.Count)
{
SelectedFilePath = _files[_fileListView.SelectedItem].FullName;
SelectedFilePath = _files[_fileListView.SelectedItem!.Value].FullName;
_confirmed = true;
Application.RequestStop();
}
Expand Down
9 changes: 3 additions & 6 deletions App/Dialogs/PasswordPromptDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public PasswordPromptDialog(string username, string endpoint)
X = 1,
Y = 2,
Text = endpoint.Length > 50 ? endpoint[..47] + "..." : endpoint,
ColorScheme = theme.MainColorScheme
};
}.WithScheme(theme.MainColorScheme);

_passwordField = new TextField
{
Expand All @@ -57,8 +56,7 @@ public PasswordPromptDialog(string username, string endpoint)
Y = 6,
Text = $"{theme.ButtonPrefix}OK{theme.ButtonSuffix}",
IsDefault = true,
ColorScheme = defaultButtonScheme
};
}.WithScheme(defaultButtonScheme);

okButton.Accepting += (_, _) =>
{
Expand All @@ -71,8 +69,7 @@ public PasswordPromptDialog(string username, string endpoint)
X = Pos.Center() + 4,
Y = 6,
Text = $"{theme.ButtonPrefix}Cancel{theme.ButtonSuffix}",
ColorScheme = theme.ButtonColorScheme
};
}.WithScheme(theme.ButtonColorScheme);

cancelButton.Accepting += (_, _) =>
{
Expand Down
Loading
Loading