1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-25 05:29:31 +00:00

Implement "new project"

WPF TreeViews are much different from WinForms.  Unexpectedly, they're
actually simpler and easier to work with.
This commit is contained in:
Andy McFadden 2019-06-22 17:38:07 -07:00
parent 6b29ce98f9
commit b91124999a
8 changed files with 296 additions and 2 deletions

View File

@ -775,6 +775,38 @@ namespace SourceGenWPF {
#region Main window UI event handlers
public void NewProject() {
if (!CloseProject()) {
return;
}
string sysDefsPath = RuntimeDataAccess.GetPathName("SystemDefs.json");
if (sysDefsPath == null) {
MessageBox.Show(Res.Strings.ERR_LOAD_CONFIG_FILE, Res.Strings.OPERATION_FAILED,
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
SystemDefSet sds = null;
try {
sds = SystemDefSet.ReadFile(sysDefsPath);
} catch (Exception ex) {
Debug.WriteLine("Failed loading system def set: " + ex);
MessageBox.Show(Res.Strings.ERR_LOAD_CONFIG_FILE, Res.Strings.OPERATION_FAILED,
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
NewProject dlg = new NewProject(mMainWin, sds);
if (dlg.ShowDialog() != true) {
return;
}
bool ok = PrepareNewProject(Path.GetFullPath(dlg.DataFileName), dlg.SystemDef);
if (ok) {
FinishPrep();
}
}
public void OpenRecentProject(int projIndex) {
if (!CloseProject()) {
return;

View File

@ -35,6 +35,8 @@ limitations under the License.
<system:String x:Key="str_ErrFileReadOnlyFmt">Cannot write to read-only file {0}.</system:String>
<system:String x:Key="str_ErrInvalidIntValue">Could not convert value to integer</system:String>
<system:String x:Key="str_ErrInvalidKeyValue">Key value is out of range</system:String>
<system:String x:Key="str_ErrInvalidSysdef" xml:space="preserve"> - INVALID DEFINITION</system:String>
<system:String x:Key="str_ErrLoadConfigFile">Unable to load config file</system:String>
<system:String x:Key="str_ErrNotProjectFile">This does not appear to be a valid .dis65 project file</system:String>
<system:String x:Key="str_ErrProjectFileCorrupt">Project file may be corrupt</system:String>
<system:String x:Key="str_ErrProjectLoadFail">Unable to load project file</system:String>
@ -43,6 +45,7 @@ limitations under the License.
<system:String x:Key="str_FileFilterCs">C# Source Files(*.cs)|*.cs</system:String>
<system:String x:Key="str_FileFilterDis65">SourceGen projects(*.dis65)|*.dis65</system:String>
<system:String x:Key="str_FileFilterSym65">SourceGen symbols (*.sym65)|*.sym65</system:String>
<system:String x:Key="str_FileInfoFmt">File is {0:N1} KB of raw data.</system:String>
<system:String x:Key="str_GeneratedForVersion">Target assembler: {0} v{1} [{2}]</system:String>
<system:String x:Key="str_InfoFdSumFmt">•Operand format is {0}</system:String>
<system:String x:Key="str_InfoLineSumNonFmt">Line {0}: {1}</system:String>

View File

@ -50,6 +50,10 @@ namespace SourceGenWPF.Res {
(string)Application.Current.FindResource("str_ErrInvalidIntValue");
public static string ERR_INVALID_KEY_VALUE =
(string)Application.Current.FindResource("str_ErrInvalidKeyValue");
public static string ERR_INVALID_SYSDEF =
(string)Application.Current.FindResource("str_ErrInvalidSysdef");
public static string ERR_LOAD_CONFIG_FILE =
(string)Application.Current.FindResource("str_ErrLoadConfigFile");
public static string ERR_NOT_PROJECT_FILE =
(string)Application.Current.FindResource("str_ErrNotProjectFile");
public static string ERR_PROJECT_FILE_CORRUPT =
@ -66,6 +70,8 @@ namespace SourceGenWPF.Res {
(string)Application.Current.FindResource("str_FileFilterDis65");
public static string FILE_FILTER_SYM65 =
(string)Application.Current.FindResource("str_FileFilterSym65");
public static string FILE_INFO_FMT =
(string)Application.Current.FindResource("str_FileInfoFmt");
public static string GENERATED_FOR_VERSION_FMT =
(string)Application.Current.FindResource("str_GeneratedForVersion");
public static string INFO_FD_SUM_FMT =

View File

@ -87,6 +87,9 @@
<Compile Include="WpfGui\EditStatusFlags.xaml.cs">
<DependentUpon>EditStatusFlags.xaml</DependentUpon>
</Compile>
<Compile Include="WpfGui\NewProject.xaml.cs">
<DependentUpon>NewProject.xaml</DependentUpon>
</Compile>
<Compile Include="WpfGui\ProjectLoadIssue.xaml.cs">
<DependentUpon>ProjectLoadIssue.xaml</DependentUpon>
</Compile>
@ -179,6 +182,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="WpfGui\NewProject.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="WpfGui\ProjectLoadIssue.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -71,6 +71,7 @@ limitations under the License.
<KeyGesture>Ctrl+Shift+Minus</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
<RoutedUICommand x:Key="NewProjectCmd" Text="New"/>
<RoutedUICommand x:Key="OpenCmd" Text="Open"/>
<RoutedUICommand x:Key="RemoveHintsCmd" Text="Remove Hints"/>
<RoutedUICommand x:Key="RecentProjectCmd"/>
@ -119,6 +120,8 @@ limitations under the License.
CanExecute="CanNavigateBackward" Executed="NavigateBackwardCmd_Executed"/>
<CommandBinding Command="{StaticResource NavigateForwardCmd}"
CanExecute="CanNavigateForward" Executed="NavigateForwardCmd_Executed"/>
<CommandBinding Command="{StaticResource NewProjectCmd}"
Executed="NewProjectCmd_Executed"/>
<CommandBinding Command="{StaticResource OpenCmd}"
Executed="OpenCmd_Executed"/>
<CommandBinding Command="{StaticResource RemoveHintsCmd}"
@ -141,7 +144,7 @@ limitations under the License.
<DockPanel>
<Menu Name="appMenu" DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="New"/>
<MenuItem Command="{StaticResource NewProjectCmd}"/>
<MenuItem Command="{StaticResource OpenCmd}"/>
<MenuItem Command="Save"/>
<MenuItem Command="SaveAs"/>
@ -351,7 +354,8 @@ limitations under the License.
</StackPanel>
<StackPanel Grid.Row="1" HorizontalAlignment="Left">
<Button Content="Start new project" Width="240" Height="50" Margin="10,30,10,10"/>
<Button Content="Start new project" Width="240" Height="50" Margin="10,30,10,10"
Command="{StaticResource NewProjectCmd}"/>
<Button Content="Open existing project" Width="240" Height="50" Margin="10"
Command="{StaticResource OpenCmd}"/>
<Button Name="recentProjectButton1" Width="240" Height="50" Margin="10"

View File

@ -767,6 +767,10 @@ namespace SourceGenWPF.WpfGui {
mMainCtrl.NavigateForward();
}
private void NewProjectCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.NewProject();
}
private void OpenCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.OpenProject();
}

View File

@ -0,0 +1,65 @@
<!--
Copyright 2019 faddenSoft
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Window x:Class="SourceGenWPF.WpfGui.NewProject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SourceGenWPF.WpfGui"
mc:Ignorable="d"
Title="New Project"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
Loaded="Window_Loaded">
<StackPanel Margin="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="250"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Target System:</TextBlock>
<TreeView Name="targetSystemTree" Grid.Column="0" Grid.Row="1" Margin="0,2,0,0"
SelectedItemChanged="TargetSystemTree_SelectedItemChanged"/>
<TextBlock Grid.Column="2" Grid.Row="0">Details:</TextBlock>
<TextBox Name="systemDescr" Grid.Column="2" Grid.Row="1" Margin="0,2,0,0" IsReadOnly="True"
ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto"/>
</Grid>
<GroupBox Header="Data File" Margin="0,4,0,0">
<StackPanel Margin="4">
<DockPanel>
<Button Name="selectFileButton" DockPanel.Dock="Left" Width="120" Click="SelectFileButton_Click">Select File...</Button>
<TextBox Name="selectedFileText" DockPanel.Dock="Right" IsReadOnly="True" Margin="8,0,0,0">(filename)</TextBox>
</DockPanel>
<TextBlock Name="dataFileDetails" Margin="0,8,0,0">(details)</TextBlock>
</StackPanel>
</GroupBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,8,0,0">
<Button Name="okButton" Content="OK" IsDefault="True"
Width="70" Click="OkButton_Click"/>
<Button Name="cancelButton" Content="Cancel" IsCancel="True"
Width="70" Margin="4,0,0,0"/>
</StackPanel>
</StackPanel>
</Window>

View File

@ -0,0 +1,173 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
namespace SourceGenWPF.WpfGui {
/// <summary>
/// New project creation dialog.
/// </summary>
public partial class NewProject : Window {
private SystemDefSet mSystemDefs;
public SystemDef SystemDef {
get { return (SystemDef)((TreeViewItem)targetSystemTree.SelectedItem).Tag; }
}
public string DataFileName {
get { return selectedFileText.Text; }
}
public NewProject(Window owner, SystemDefSet systemDefs) {
InitializeComponent();
Owner = owner;
dataFileDetails.Text = string.Empty;
selectedFileText.Text = string.Empty;
mSystemDefs = systemDefs;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
LoadSystemDefSet();
}
/// <summary>
/// Initializes the "system definition" tree.
/// </summary>
private void LoadSystemDefSet() {
string prevSelSystem = AppSettings.Global.GetString(AppSettings.NEWP_SELECTED_SYSTEM,
"[nothing!selected]");
TreeViewItem selItem = PopulateNodes(prevSelSystem);
selItem.IsSelected = true;
selItem.BringIntoView();
targetSystemTree.Focus();
Debug.WriteLine("selected is " + targetSystemTree.SelectedItem);
}
/// <summary>
/// Populates the tree view nodes with the contents of the data file.
/// </summary>
/// <param name="tv">TreeView to add items to</param>
/// <param name="prevSelSystem">Name of previously-selected system.</param>
/// <returns>The node that matches prevSelSystem, or null if not found.</returns>
private TreeViewItem PopulateNodes(string prevSelSystem) {
TreeViewItem selItem = null;
TreeView tv = targetSystemTree;
tv.Items.Clear();
if (mSystemDefs.Defs == null || mSystemDefs.Defs.Length == 0) {
Debug.WriteLine("Empty def set found");
TreeViewItem errItem = new TreeViewItem();
errItem.Header = Res.Strings.ERR_LOAD_CONFIG_FILE;
tv.Items.Add(errItem);
return null;
}
var groups = new Dictionary<string, TreeViewItem>();
foreach (SystemDef sd in mSystemDefs.Defs) {
if (!groups.TryGetValue(sd.GroupName, out TreeViewItem groupItem)) {
groupItem = new TreeViewItem();
groupItem.Header = sd.GroupName;
groupItem.IsExpanded = true;
groups[sd.GroupName] = groupItem;
tv.Items.Add(groupItem);
}
bool isValid = sd.Validate();
string treeName = isValid ? sd.Name :
sd.Name + Res.Strings.ERR_INVALID_SYSDEF;
TreeViewItem newItem = new TreeViewItem();
newItem.Header = treeName;
newItem.IsEnabled = isValid;
newItem.Tag = sd;
groupItem.Items.Add(newItem);
if (isValid && sd.Name == prevSelSystem) {
selItem = newItem;
}
}
return selItem;
}
private void TargetSystemTree_SelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e) {
Debug.WriteLine("Now selected: " + targetSystemTree.SelectedItem);
SystemDef sd = (SystemDef)((TreeViewItem)targetSystemTree.SelectedItem).Tag;
if (sd == null) {
systemDescr.Text = string.Empty;
} else {
systemDescr.Text = sd.GetSummaryString();
}
UpdateOKEnabled();
}
/// <summary>
/// Updates the enabled state of the OK button based on the state of the other
/// controls.
/// </summary>
private void UpdateOKEnabled() {
TreeViewItem item = (TreeViewItem)targetSystemTree.SelectedItem;
okButton.IsEnabled = (item.Tag != null) &&
!string.IsNullOrEmpty(selectedFileText.Text);
}
private void OkButton_Click(object sender, RoutedEventArgs e) {
Debug.WriteLine("OK: " + targetSystemTree.SelectedItem);
SystemDef sd = (SystemDef)((TreeViewItem)targetSystemTree.SelectedItem).Tag;
AppSettings.Global.SetString(AppSettings.NEWP_SELECTED_SYSTEM, sd.Name);
DialogResult = true;
}
private void SelectFileButton_Click(object sender, RoutedEventArgs e) {
OpenFileDialog fileDlg = new OpenFileDialog() {
Filter = Res.Strings.FILE_FILTER_ALL,
FilterIndex = 1
};
if (fileDlg.ShowDialog() == true) {
FileInfo fi = new FileInfo(fileDlg.FileName);
if (fi.Length > DisasmProject.MAX_DATA_FILE_SIZE) {
string msg = string.Format(Res.Strings.OPEN_DATA_TOO_LARGE_FMT,
fi.Length / 1024, DisasmProject.MAX_DATA_FILE_SIZE / 1024);
MessageBox.Show(msg, Res.Strings.OPEN_DATA_FAIL_CAPTION,
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
selectedFileText.Text = fileDlg.FileName;
this.dataFileDetails.Text =
string.Format(Res.Strings.FILE_INFO_FMT, fi.Length / 1024.0);
}
UpdateOKEnabled();
}
}
}