Skip to content

Commit ce5abb9

Browse files
committed
Sort script list from UI
1 parent 6afa172 commit ce5abb9

2 files changed

Lines changed: 94 additions & 4 deletions

File tree

src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/MainViewModel.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ public bool IsScriptingEnabled
129129
private readonly ObservableCollection<ScriptDisplayEntry> _scriptEntries = new();
130130
public ObservableCollection<ScriptDisplayEntry> ScriptEntries => _scriptEntries;
131131

132+
private ScriptSortColumn _scriptSortColumn = ScriptSortColumn.FileName;
133+
private bool _scriptSortAscending = true;
134+
135+
public string FileNameSortIndicator => SortIndicator(ScriptSortColumn.FileName);
136+
public string StatusSortIndicator => SortIndicator(ScriptSortColumn.Status);
137+
public string YieldSortIndicator => SortIndicator(ScriptSortColumn.YieldType);
138+
public string HooksSortIndicator => SortIndicator(ScriptSortColumn.Hooks);
139+
140+
private string SortIndicator(ScriptSortColumn col) =>
141+
_scriptSortColumn == col ? (_scriptSortAscending ? " ▲" : " ▼") : "";
142+
132143
public bool CanManageScripts { get; }
133144
public bool CanLoadExamples { get; }
134145

@@ -331,6 +342,7 @@ public void RefreshConfigProperties()
331342
public ReactiveCommand<Unit, Unit> LoadExamplesCommand { get; }
332343
public ReactiveCommand<Unit, Unit> RefreshScriptsCommand { get; }
333344
public ReactiveCommand<Unit, Unit> OpenScriptFolderCommand { get; }
345+
public ReactiveCommand<ScriptSortColumn, Unit> SortByColumnCommand { get; }
334346

335347
// Events for script editor dialog (UI operation handled in View code-behind)
336348
public event EventHandler? RequestAddScript;
@@ -677,6 +689,25 @@ public MainViewModel(
677689
null,
678690
RxApp.MainThreadScheduler);
679691

692+
SortByColumnCommand = ReactiveCommandHelper.CreateSafeCommand<ScriptSortColumn>(
693+
col =>
694+
{
695+
if (_scriptSortColumn == col)
696+
_scriptSortAscending = !_scriptSortAscending;
697+
else
698+
{
699+
_scriptSortColumn = col;
700+
_scriptSortAscending = true;
701+
}
702+
ApplyScriptSort();
703+
this.RaisePropertyChanged(nameof(FileNameSortIndicator));
704+
this.RaisePropertyChanged(nameof(StatusSortIndicator));
705+
this.RaisePropertyChanged(nameof(YieldSortIndicator));
706+
this.RaisePropertyChanged(nameof(HooksSortIndicator));
707+
},
708+
null,
709+
RxApp.MainThreadScheduler);
710+
680711
// Emulator Options command - only enabled when emulator is uninitialized
681712
EmulatorOptionsCommand = ReactiveCommandHelper.CreateSafeCommand(
682713
() =>
@@ -866,9 +897,28 @@ private void RefreshScriptStatuses()
866897
foreach (var status in statuses)
867898
_scriptEntries.Add(new ScriptDisplayEntry(status));
868899

900+
ApplyScriptSort();
869901
UpdateScriptsTabHeader();
870902
}
871903

904+
private void ApplyScriptSort()
905+
{
906+
var sorted = (_scriptSortColumn switch
907+
{
908+
ScriptSortColumn.Status => _scriptSortAscending ? _scriptEntries.OrderBy(e => e.Status) : _scriptEntries.OrderByDescending(e => e.Status),
909+
ScriptSortColumn.YieldType => _scriptSortAscending ? _scriptEntries.OrderBy(e => e.YieldType) : _scriptEntries.OrderByDescending(e => e.YieldType),
910+
ScriptSortColumn.Hooks => _scriptSortAscending ? _scriptEntries.OrderBy(e => e.Hooks) : _scriptEntries.OrderByDescending(e => e.Hooks),
911+
_ => _scriptSortAscending ? _scriptEntries.OrderBy(e => e.FileName) : _scriptEntries.OrderByDescending(e => e.FileName),
912+
}).ToList();
913+
914+
for (int i = 0; i < sorted.Count; i++)
915+
{
916+
int current = _scriptEntries.IndexOf(sorted[i]);
917+
if (current != i)
918+
_scriptEntries.Move(current, i);
919+
}
920+
}
921+
872922
private void UpdateScriptsTabHeader()
873923
{
874924
var systemDisabledCount = _scriptEntries.Count(s => s.IsDisabled);
@@ -1070,6 +1120,8 @@ public ScriptDisplayEntry(ScriptStatus scriptStatus)
10701120
}
10711121
}
10721122

1123+
public enum ScriptSortColumn { FileName, Status, YieldType, Hooks }
1124+
10731125
public class DeleteScriptConfirmationEventArgs : EventArgs
10741126
{
10751127
public string FileName { get; }

src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/Views/MainView.axaml

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
<UserControl.Styles>
1616
<!-- Include non-focusable styles -->
1717
<StyleInclude Source="avares://Highbyte.DotNet6502.App.Avalonia.Core/Styles/NonFocusableStyles.axaml"/>
18+
<Style Selector="Button.sort-header">
19+
<Setter Property="Background" Value="Transparent"/>
20+
<Setter Property="BorderThickness" Value="0"/>
21+
<Setter Property="Padding" Value="0"/>
22+
<Setter Property="Cursor" Value="Hand"/>
23+
<Setter Property="VerticalAlignment" Value="Center"/>
24+
</Style>
25+
<Style Selector="Button.sort-header:pointerover /template/ ContentPresenter">
26+
<Setter Property="Background" Value="Transparent"/>
27+
</Style>
1828
</UserControl.Styles>
1929

2030
<Grid ShowGridLines="False">
@@ -492,10 +502,38 @@
492502
<ColumnDefinition Width="80"/>
493503
<ColumnDefinition Width="*"/>
494504
</Grid.ColumnDefinitions>
495-
<TextBlock Grid.Column="5" Text="Script" Classes="small bold" FontSize="10"/>
496-
<TextBlock Grid.Column="6" Text="Status" Classes="small bold" FontSize="10"/>
497-
<TextBlock Grid.Column="7" Text="Yield" Classes="small bold" FontSize="10"/>
498-
<TextBlock Grid.Column="8" Text="Hooks" Classes="small bold" FontSize="10"/>
505+
<Button Grid.Column="5" Classes="sort-header"
506+
Command="{Binding SortByColumnCommand}"
507+
CommandParameter="{x:Static vm:ScriptSortColumn.FileName}">
508+
<StackPanel Orientation="Horizontal">
509+
<TextBlock Text="Script" Classes="small bold" FontSize="10"/>
510+
<TextBlock Text="{Binding FileNameSortIndicator}" Classes="small bold" FontSize="10"/>
511+
</StackPanel>
512+
</Button>
513+
<Button Grid.Column="6" Classes="sort-header"
514+
Command="{Binding SortByColumnCommand}"
515+
CommandParameter="{x:Static vm:ScriptSortColumn.Status}">
516+
<StackPanel Orientation="Horizontal">
517+
<TextBlock Text="Status" Classes="small bold" FontSize="10"/>
518+
<TextBlock Text="{Binding StatusSortIndicator}" Classes="small bold" FontSize="10"/>
519+
</StackPanel>
520+
</Button>
521+
<Button Grid.Column="7" Classes="sort-header"
522+
Command="{Binding SortByColumnCommand}"
523+
CommandParameter="{x:Static vm:ScriptSortColumn.YieldType}">
524+
<StackPanel Orientation="Horizontal">
525+
<TextBlock Text="Yield" Classes="small bold" FontSize="10"/>
526+
<TextBlock Text="{Binding YieldSortIndicator}" Classes="small bold" FontSize="10"/>
527+
</StackPanel>
528+
</Button>
529+
<Button Grid.Column="8" Classes="sort-header"
530+
Command="{Binding SortByColumnCommand}"
531+
CommandParameter="{x:Static vm:ScriptSortColumn.Hooks}">
532+
<StackPanel Orientation="Horizontal">
533+
<TextBlock Text="Hooks" Classes="small bold" FontSize="10"/>
534+
<TextBlock Text="{Binding HooksSortIndicator}" Classes="small bold" FontSize="10"/>
535+
</StackPanel>
536+
</Button>
499537
</Grid>
500538

501539
<!-- Separator -->

0 commit comments

Comments
 (0)