diff --git a/SourceGenWPF/DisplayList.cs b/SourceGenWPF/DisplayList.cs index c646bb2..3784fca 100644 --- a/SourceGenWPF/DisplayList.cs +++ b/SourceGenWPF/DisplayList.cs @@ -43,13 +43,15 @@ namespace SourceGenWPF { /// /// The list is initially filled with null references, with FormattedParts instances /// generated on demand. This is done by requesting individual items from the - /// DisplayListGen object. + /// LineListGen object. + /// + /// NOTE: it may or may not be possible to implement this trivially with an + /// ObservedCollection. At an earlier iteration it wasn't, and I'd like to keep this + /// around even if it is now possible, in case the pendulum swings back the other way. /// public class DisplayList : IList, IList, INotifyCollectionChanged, INotifyPropertyChanged { - // TODO: check VirtualizingStackPanel.VirtualizationMode == recycling (page 259) - /// /// List of formatted parts. DO NOT access this directly outside the event-sending /// method wrappers. @@ -84,41 +86,6 @@ namespace SourceGenWPF { private const string CountString = "Count"; private const string IndexerName = "Item[]"; -#if false - protected override void ClearItems() { - base.ClearItems(); - OnPropertyChanged(CountString); - OnPropertyChanged(IndexerName); - OnCollectionReset(); - } - - protected override void RemoveItem(int index) { - FormattedParts removedItem = this[index]; - - base.RemoveItem(index); - - OnPropertyChanged(CountString); - OnPropertyChanged(IndexerName); - OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index); - } - - protected override void InsertItem(int index, FormattedParts item) { - base.InsertItem(index, item); - - OnPropertyChanged(CountString); - OnPropertyChanged(IndexerName); - OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); - } - - protected override void SetItem(int index, FormattedParts item) { - FormattedParts originalItem = this[index]; - base.SetItem(index, item); - - OnPropertyChanged(IndexerName); - OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index); - } -#endif - protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { PropertyChanged?.Invoke(this, e); } diff --git a/SourceGenWPF/MainController.cs b/SourceGenWPF/MainController.cs index 0146750..5f12fec 100644 --- a/SourceGenWPF/MainController.cs +++ b/SourceGenWPF/MainController.cs @@ -358,9 +358,14 @@ namespace SourceGenWPF { public void OpenRecentProject(int projIndex) { - if (DoClose()) { - //DoOpenFile(mRecentProjectPaths[projIndex]); + if (!DoClose()) { + return; + } + //DoOpenFile(mRecentProjectPaths[projIndex]); + if (projIndex == 0) { DoOpenFile(@"C:\Src\6502bench\EXTRA\ZIPPY#ff2000.dis65"); + } else { + DoOpenFile(@"C:\Src\6502bench\EXTRA\CRYLLAN.MISSION#b30100.dis65"); } } diff --git a/SourceGenWPF/ProjWin/MainWindow.xaml b/SourceGenWPF/ProjWin/MainWindow.xaml index c8584a7..3bec1cf 100644 --- a/SourceGenWPF/ProjWin/MainWindow.xaml +++ b/SourceGenWPF/ProjWin/MainWindow.xaml @@ -45,13 +45,20 @@ limitations under the License. Ctrl+Shift+A - + + + + Ctrl+A + + - + + + @@ -78,7 +85,7 @@ limitations under the License. - + @@ -216,11 +223,11 @@ limitations under the License. private MainController mMainCtrl; + private MethodInfo listViewSetSelectedItems; public MainWindow() { InitializeComponent(); + listViewSetSelectedItems = codeListView.GetType().GetMethod("SetSelectedItems", + BindingFlags.NonPublic | BindingFlags.Instance); + Debug.Assert(listViewSetSelectedItems != null); + this.DataContext = this; CodeDisplayList = new DisplayList(); @@ -82,7 +88,7 @@ namespace SourceGenWPF.ProjWin { /// The CallerMemberName attribute puts the calling property's name in the first arg. /// /// Name of property that changed. - private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { + private void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } @@ -97,8 +103,8 @@ namespace SourceGenWPF.ProjWin { } set { mShowCodeListView = value; - NotifyPropertyChanged("LaunchPanelVisibility"); - NotifyPropertyChanged("CodeListVisibility"); + OnPropertyChanged("LaunchPanelVisibility"); + OnPropertyChanged("CodeListVisibility"); } } @@ -129,19 +135,36 @@ namespace SourceGenWPF.ProjWin { Debug.WriteLine("assembling"); } - private void RecentProject_Executed(object sender, ExecutedRoutedEventArgs e) { + private void SelectAllCmd_Executed(object sender, ExecutedRoutedEventArgs e) { + DateTime start = DateTime.Now; + + codeListView.SelectAll(); + + //codeListView.SelectedItems.Clear(); + //foreach (var item in codeListView.Items) { + // codeListView.SelectedItems.Add(item); + //} + + // This seems to be faster than setting items individually (10x), but is still O(n^2) + // or worse, and hence unsuitable for very large lists. + //codeListView.SelectedItems.Clear(); + //listViewSetSelectedItems.Invoke(codeListView, new object[] { codeListView.Items }); + + Debug.WriteLine("Select All cmd: " + (DateTime.Now - start).Milliseconds + " ms"); + } + + private void RecentProjectCmd_Executed(object sender, ExecutedRoutedEventArgs e) { if (!int.TryParse((string)e.Parameter, out int recentIndex) || - recentIndex < 1 || recentIndex > MainController.MAX_RECENT_PROJECTS) { + recentIndex < 0 || recentIndex >= MainController.MAX_RECENT_PROJECTS) { throw new Exception("Bad parameter: " + e.Parameter); } - recentIndex--; Debug.WriteLine("Recent project #" + recentIndex); mMainCtrl.OpenRecentProject(recentIndex); } private void CodeListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { - Debug.WriteLine("SEL: add " + e.AddedItems.Count + ", rem " + e.RemovedItems.Count); + //Debug.WriteLine("SEL: add " + e.AddedItems.Count + ", rem " + e.RemovedItems.Count); } } } diff --git a/SourceGenWPF/Sandbox/Sponsor.cs b/SourceGenWPF/Sandbox/Sponsor.cs index a8cfc85..d003e2e 100644 --- a/SourceGenWPF/Sandbox/Sponsor.cs +++ b/SourceGenWPF/Sandbox/Sponsor.cs @@ -168,7 +168,12 @@ namespace SourceGenWPF.Sandbox { } if (leaseObj is ILease) { ILease lease = (ILease)leaseObj; - lease.Unregister(this); + try { + lease.Unregister(this); + } catch (InvalidOperationException ex) { + // TODO: not expected -- why did this start happening? + Debug.WriteLine("WARNING: lease.Unregister threw " + ex); + } } mDisposed = true;