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
60 changes: 60 additions & 0 deletions src/Tedd.TUI.Tests/ListBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,66 @@ public void Render_UsesItemTemplate_WhenSet()
Assert.Equal("Bob", row1);
}

[Fact]
public void OnGotFocus_UpdatesSelectedItemVisualState()
{
// Arrange
var window = new TuiWindow();
var listBox = new ListBox();
window.Content = listBox;
listBox.Items.Add("Item 1");
listBox.Items.Add("Item 2");
listBox.SelectedIndex = 0;
listBox.Measure(new Size(20, 5));
listBox.Arrange(new Rect(0, 0, 20, 5));

var container = listBox.ItemsPanelRoot?.Children[0] as ListBoxItem;
Assert.NotNull(container);
Assert.True(container.IsSelected);

// Before focus, item should show unfocused selection colors
listBox.OnLostFocus();
var unfocusedBg = container.Background;
var unfocusedFg = container.Foreground;

// Act: ListBox gains focus
listBox.OnGotFocus();

// Assert: selected item should now show focused selection colors
Assert.NotEqual(unfocusedBg, container.Background);
Assert.NotEqual(unfocusedFg, container.Foreground);
Assert.Equal(listBox.FocusedSelectionBackground, container.Background);
Assert.Equal(listBox.FocusedSelectionForeground, container.Foreground);
}

[Fact]
public void OnLostFocus_UpdatesSelectedItemVisualState()
{
// Arrange
var window = new TuiWindow();
var listBox = new ListBox();
window.Content = listBox;
listBox.Items.Add("Item 1");
listBox.Items.Add("Item 2");
listBox.SelectedIndex = 0;
listBox.Measure(new Size(20, 5));
listBox.Arrange(new Rect(0, 0, 20, 5));

var container = listBox.ItemsPanelRoot?.Children[0] as ListBoxItem;
Assert.NotNull(container);

// First give focus so item shows focused selection colors
listBox.OnGotFocus();
Assert.Equal(listBox.FocusedSelectionBackground, container.Background);

// Act: ListBox loses focus
listBox.OnLostFocus();

// Assert: selected item should now show unfocused selection colors (ShowSelection=true by default)
Assert.Equal(listBox.SelectionBackground, container.Background);
Assert.Equal(listBox.SelectionForeground, container.Foreground);
}

[Fact]
public void Render_FallsBackToGetItemText_WhenNoTemplate()
{
Expand Down
24 changes: 24 additions & 0 deletions src/Tedd.TUI/ListBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ protected internal override void PrepareContainerForItemOverride(UIElement eleme
}
}

public override void OnGotFocus()
{
base.OnGotFocus();
NotifyContainersVisualStateChanged();
}

public override void OnLostFocus()
{
base.OnLostFocus();
NotifyContainersVisualStateChanged();
}

private void NotifyContainersVisualStateChanged()
{
if (ItemsPanelRoot != null)
{
for (int i = 0; i < ItemsPanelRoot.Children.Count; i++)
{
if (ItemsPanelRoot.Children[i] is ListBoxItem lbi)
lbi.UpdateVisualState();
}
}
}

public override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
Expand Down
2 changes: 1 addition & 1 deletion src/Tedd.TUI/ListBoxItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected override void OnPropertyChanged(DependencyProperty dp)
}
}

private void UpdateVisualState()
internal void UpdateVisualState()
{
// Try to get colors from Parent ListBox if we are inside one.
// If not, use defaults.
Expand Down