mirror of
https://github.com/fadden/6502bench.git
synced 2025-02-08 20:30:47 +00:00
Implemented the first ("Code View") tab of settings
Notable items include the column show/hide buttons, which were straightforward except for the "determine the default width" part, and the font picker, which is no longer a standard dialog. The latter was complicated by the absence of a good way to detect whether a font is mono-spaced or not without calling back into code meant for WinForms font manipulation (with a dash of PInvoke). Yay WPF. Also, enabled character ellipsis for code list items.
This commit is contained in:
parent
0a96e014e2
commit
c13daa7085
@ -48,6 +48,7 @@
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Helper.cs" />
|
||||
<Compile Include="InverseBooleanConverter.cs" />
|
||||
<Compile Include="MultiKeyInputGesture.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
|
@ -86,7 +86,8 @@ namespace SourceGenWPF {
|
||||
|
||||
// Code List View settings.
|
||||
public const string CDLV_COL_WIDTHS = "cdlv-col-widths";
|
||||
public const string CDLV_FONT = "cdlv-font";
|
||||
public const string CDLV_FONT_FAMILY = "cdlv-font-family";
|
||||
public const string CDLV_FONT_SIZE = "cdlv-font-size";
|
||||
|
||||
// Hex dump viewer settings.
|
||||
public const string HEXD_ASCII_ONLY = "hexd-ascii-only";
|
||||
|
@ -140,8 +140,18 @@ namespace SourceGenWPF {
|
||||
/// </summary>
|
||||
private bool mUseMainAppDomainForPlugins = false;
|
||||
|
||||
private enum ColumnIndex {
|
||||
Offset = 0, Address, Bytes, Flags, Attributes, Label, Opcode, Operand, Comment
|
||||
public enum CodeListColumn {
|
||||
Offset = 0, Address, Bytes, Flags, Attributes, Label, Opcode, Operand, Comment,
|
||||
COUNT // must be last; must equal number of columns
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clipboard format enumeration.
|
||||
/// </summary>
|
||||
public enum ClipLineFormat {
|
||||
Unknown = -1,
|
||||
AssemblerSource = 0,
|
||||
Disassembly = 1
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +256,11 @@ namespace SourceGenWPF {
|
||||
settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, false);
|
||||
#endif
|
||||
|
||||
// Make sure we have entries for these.
|
||||
settings.SetString(AppSettings.CDLV_FONT_FAMILY,
|
||||
mMainWin.CodeListFontFamily.ToString());
|
||||
settings.SetInt(AppSettings.CDLV_FONT_SIZE, (int)mMainWin.CodeListFontSize);
|
||||
|
||||
// Load the settings file, and merge it into the globals.
|
||||
string runtimeDataDir = RuntimeDataAccess.GetDirectory();
|
||||
if (runtimeDataDir == null) {
|
||||
@ -392,21 +407,25 @@ namespace SourceGenWPF {
|
||||
settings.GetBool(AppSettings.SYMWIN_SHOW_CONST, false);
|
||||
symbolAddressCheckBox.Checked =
|
||||
settings.GetBool(AppSettings.SYMWIN_SHOW_ADDR, false);
|
||||
|
||||
// Set the code list view font.
|
||||
string fontStr = settings.GetString(AppSettings.CDLV_FONT, null);
|
||||
if (!string.IsNullOrEmpty(fontStr)) {
|
||||
FontConverter cvt = new FontConverter();
|
||||
try {
|
||||
Font font = cvt.ConvertFromInvariantString(fontStr) as Font;
|
||||
codeListView.Font = font;
|
||||
Debug.WriteLine("Set font to " + font.ToString());
|
||||
} catch (Exception ex) {
|
||||
Debug.WriteLine("Font convert failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the configured font info. If nothing is configured, use whatever the
|
||||
// code list happens to be using now.
|
||||
string fontFamilyName = settings.GetString(AppSettings.CDLV_FONT_FAMILY, null);
|
||||
if (fontFamilyName == null) {
|
||||
fontFamilyName = mMainWin.CodeListFontFamily.ToString();
|
||||
}
|
||||
int size = settings.GetInt(AppSettings.CDLV_FONT_SIZE, -1);
|
||||
if (size <= 0) {
|
||||
size = (int)mMainWin.CodeListFontSize;
|
||||
}
|
||||
|
||||
mMainWin.SetCodeListFont(fontFamilyName, size);
|
||||
|
||||
// Update the column widths. This was done earlier during init, but may need to be
|
||||
// repeated if the show/hide buttons were used in Settings.
|
||||
mMainWin.RestoreColumnWidths();
|
||||
|
||||
// Unpack the recent-project list.
|
||||
UnpackRecentProjectList();
|
||||
|
||||
@ -1153,8 +1172,8 @@ namespace SourceGenWPF {
|
||||
/// to the AppSettings.Global object.
|
||||
/// </summary>
|
||||
public void EditSettings() {
|
||||
EditAppSettings dlg = new EditAppSettings(mMainWin, EditAppSettings.Tab.Unknown,
|
||||
AsmGen.AssemblerInfo.Id.Unknown);
|
||||
EditAppSettings dlg = new EditAppSettings(mMainWin, mMainWin, this,
|
||||
EditAppSettings.Tab.Unknown, AsmGen.AssemblerInfo.Id.Unknown);
|
||||
dlg.ShowDialog();
|
||||
}
|
||||
|
||||
@ -1205,39 +1224,39 @@ namespace SourceGenWPF {
|
||||
case LineListGen.Line.Type.Code:
|
||||
case LineListGen.Line.Type.Data:
|
||||
// For code and data, we have to break it down by column.
|
||||
switch ((ColumnIndex)col) {
|
||||
case ColumnIndex.Offset:
|
||||
switch ((CodeListColumn)col) {
|
||||
case CodeListColumn.Offset:
|
||||
// does nothing
|
||||
break;
|
||||
case ColumnIndex.Address:
|
||||
case CodeListColumn.Address:
|
||||
// edit address
|
||||
if (CanEditAddress()) {
|
||||
EditAddress();
|
||||
}
|
||||
break;
|
||||
case ColumnIndex.Bytes:
|
||||
case CodeListColumn.Bytes:
|
||||
#if false
|
||||
if (showHexDumpToolStripMenuItem.Enabled) {
|
||||
ShowHexDump_Click(sender, e);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ColumnIndex.Flags:
|
||||
case CodeListColumn.Flags:
|
||||
if (CanEditStatusFlags()) {
|
||||
EditStatusFlags();
|
||||
}
|
||||
break;
|
||||
case ColumnIndex.Attributes:
|
||||
case CodeListColumn.Attributes:
|
||||
// does nothing
|
||||
break;
|
||||
case ColumnIndex.Label:
|
||||
case CodeListColumn.Label:
|
||||
#if false
|
||||
if (editLabelToolStripMenuItem.Enabled) {
|
||||
EditLabel_Click(sender, e);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ColumnIndex.Opcode:
|
||||
case CodeListColumn.Opcode:
|
||||
// File offset should always be valid, since we excluded the EQU
|
||||
// statements and header comment earlier.
|
||||
if (line.FileOffset >= 0) {
|
||||
@ -1268,14 +1287,14 @@ namespace SourceGenWPF {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ColumnIndex.Operand:
|
||||
case CodeListColumn.Operand:
|
||||
#if false
|
||||
if (editOperandToolStripMenuItem.Enabled) {
|
||||
EditInstrDataOperand_Click(sender, e);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ColumnIndex.Comment:
|
||||
case CodeListColumn.Comment:
|
||||
#if false
|
||||
if (editCommentToolStripMenuItem.Enabled) {
|
||||
EditComment_Click(sender, e);
|
||||
|
@ -54,7 +54,9 @@ limitations under the License.
|
||||
<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_FontDescriptorFmt">{0}-point {1}</system:String>
|
||||
<system:String x:Key="str_GeneratedForVersion">Target assembler: {0} v{1} [{2}]</system:String>
|
||||
<system:String x:Key="str_HideCol">Hide</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>
|
||||
<system:String x:Key="str_InfoLineSumPluralFmt">Line {0}: {1} bytes of {2}</system:String>
|
||||
@ -91,4 +93,5 @@ limitations under the License.
|
||||
<system:String x:Key="str_SaveBeforeAsm">Please save your project before assembling. The generated source code will be placed in the same directory as the project file.</system:String>
|
||||
<system:String x:Key="str_SaveBeforeAsmCaption">Save Project First</system:String>
|
||||
<system:String x:Key="str_SetupSystemSummaryFmt">{1} CPU @ {2} MHz</system:String>
|
||||
<system:String x:Key="str_ShowCol">Show</system:String>
|
||||
</ResourceDictionary>
|
@ -93,8 +93,12 @@ namespace SourceGenWPF.Res {
|
||||
(string)Application.Current.FindResource("str_FileFilterSym65");
|
||||
public static string FILE_INFO_FMT =
|
||||
(string)Application.Current.FindResource("str_FileInfoFmt");
|
||||
public static string FONT_DESCRIPTOR_FMT =
|
||||
(string)Application.Current.FindResource("str_FontDescriptorFmt");
|
||||
public static string GENERATED_FOR_VERSION_FMT =
|
||||
(string)Application.Current.FindResource("str_GeneratedForVersion");
|
||||
public static string HIDE_COL =
|
||||
(string)Application.Current.FindResource("str_HideCol");
|
||||
public static string INFO_FD_SUM_FMT =
|
||||
(string)Application.Current.FindResource("str_InfoFdSumFmt");
|
||||
public static string INFO_LINE_SUM_NON_FMT =
|
||||
@ -167,5 +171,7 @@ namespace SourceGenWPF.Res {
|
||||
(string)Application.Current.FindResource("str_SaveBeforeAsmCaption");
|
||||
public static string SETUP_SYSTEM_SUMMARY_FMT =
|
||||
(string)Application.Current.FindResource("str_SetupSystemSummaryFmt");
|
||||
public static string SHOW_COL =
|
||||
(string)Application.Current.FindResource("str_ShowCol");
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,9 @@
|
||||
<Compile Include="WpfGui\EditAppSettings.xaml.cs">
|
||||
<DependentUpon>EditAppSettings.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\FontPicker.xaml.cs">
|
||||
<DependentUpon>FontPicker.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\WorkProgress.xaml.cs">
|
||||
<DependentUpon>WorkProgress.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -171,6 +174,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\FontPicker.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\WorkProgress.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -162,7 +162,8 @@ See also https://github.com/fadden/DisasmUiTest
|
||||
<DataTemplate x:Key="addrHighlightTemplate">
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=HasAddrLabelHighlight}" Value="True">
|
||||
<Setter Property="TextBlock.Background" Value="{StaticResource HighlightedCellFill}"/>
|
||||
@ -178,7 +179,8 @@ See also https://github.com/fadden/DisasmUiTest
|
||||
<DataTemplate x:Key="labelHighlightTemplate">
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=HasAddrLabelHighlight}" Value="True">
|
||||
<Setter Property="TextBlock.Background" Value="{StaticResource HighlightedCellFill}"/>
|
||||
|
@ -22,21 +22,22 @@ limitations under the License.
|
||||
xmlns:local="clr-namespace:SourceGenWPF.WpfGui"
|
||||
mc:Ignorable="d"
|
||||
Title="Edit Application Settings"
|
||||
Width="680" Height="480" ResizeMode="NoResize"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
|
||||
Width="700" Height="440" ResizeMode="NoResize"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
<DockPanel Margin="8">
|
||||
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Name="applyButton" Content="Apply" Margin="0,0,20,0"
|
||||
Width="70"/>
|
||||
Width="70" IsEnabled="{Binding IsDirty}" Click="ApplyButton_Click"/>
|
||||
<Button Name="okButton" Content="OK" IsDefault="True"
|
||||
Width="70"/>
|
||||
Width="70" Click="OkButton_Click"/>
|
||||
<Button Name="cancelButton" Content="Cancel" IsCancel="True"
|
||||
Width="70" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<TabControl DockPanel.Dock="Top" Margin="0,0,0,8">
|
||||
<TabItem Header="Code View">
|
||||
<TabControl Name="tabControl" DockPanel.Dock="Top" Margin="0,0,0,8">
|
||||
<TabItem Name="codeViewTab" Header="Code View">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.75*"/>
|
||||
@ -53,15 +54,24 @@ limitations under the License.
|
||||
<GroupBox Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Header="Column Visibility"
|
||||
Margin="0,0,10,0">
|
||||
<StackPanel>
|
||||
<Button Content="{}{0} Offset" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Address" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Bytes" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Flags" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Attributes" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Label" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Opcode" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Operand" Width="120" Margin="0,4"/>
|
||||
<Button Content="{}{0} Comment" Width="120" Margin="0,4"/>
|
||||
<Button Name="showCol0" Content="{}{0} Offset" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol1" Content="{}{0} Address" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol2" Content="{}{0} Bytes" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol3" Content="{}{0} Flags" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol4" Content="{}{0} Attributes" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol5" Content="{}{0} Label" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol6" Content="{}{0} Opcode" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol7" Content="{}{0} Operand" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
<Button Name="showCol8" Content="{}{0} Comment" Width="120" Margin="0,4"
|
||||
Click="ColumnVisibilityButton_Click"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
@ -69,24 +79,30 @@ limitations under the License.
|
||||
Margin="5,0,5,0">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="0,4,0,0">Current font:</TextBlock>
|
||||
<TextBlock Margin="0,4,0,0">Constantia, 10pt</TextBlock>
|
||||
<TextBlock Name="codeListFontDesc" Margin="0,4,0,0">10-pt Hoser Sans</TextBlock>
|
||||
<Button Content="Select Font..." Width="120" Margin="0,8,0,0"
|
||||
HorizontalAlignment="Left"/>
|
||||
HorizontalAlignment="Left" Click="SelectFontButton_Click"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="1" Grid.Row="1" Header="Upper Case Display"
|
||||
Margin="5,0,5,0">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Hexadecimal Values" Margin="0,4"/>
|
||||
<CheckBox Content="Opcodes" Margin="0,4"/>
|
||||
<CheckBox Content="Pseudo-opcodes" Margin="0,4"/>
|
||||
<CheckBox Content="Operand A" Margin="0,4"/>
|
||||
<CheckBox Content="Operand S" Margin="0,4"/>
|
||||
<CheckBox Content="Operand X/Y" Margin="0,4"/>
|
||||
<CheckBox Content="Hexadecimal Values" Margin="0,4"
|
||||
IsChecked="{Binding UpperHexValues}"/>
|
||||
<CheckBox Content="Opcodes" Margin="0,4"
|
||||
IsChecked="{Binding UpperOpcodes}"/>
|
||||
<CheckBox Content="Pseudo-opcodes" Margin="0,4"
|
||||
IsChecked="{Binding UpperPseudoOps}"/>
|
||||
<CheckBox Content="Operand A" Margin="0,4"
|
||||
IsChecked="{Binding UpperOperandA}"/>
|
||||
<CheckBox Content="Operand S" Margin="0,4"
|
||||
IsChecked="{Binding UpperOperandS}"/>
|
||||
<CheckBox Content="Operand X/Y" Margin="0,4"
|
||||
IsChecked="{Binding UpperOperandXY}"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="All Lower" Width="75" Margin="0,4,0,0"/>
|
||||
<Button Content="All Upper" Width="75" Margin="8,4,0,0"/>
|
||||
<Button Content="All Lower" Width="75" Margin="0,4,0,0" Click="AllLower_Click"/>
|
||||
<Button Content="All Upper" Width="75" Margin="8,4,0,0" Click="AllUpper_Click"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
@ -95,7 +111,8 @@ limitations under the License.
|
||||
Margin="10,0,0,0">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="0,4,0,0">Format for lines copied to clipboard:</TextBlock>
|
||||
<ComboBox IsReadOnly="True" Margin="0,8,0,0">
|
||||
<ComboBox Name="clipboardFormatComboBox" IsReadOnly="True" Margin="0,8,0,0"
|
||||
SelectionChanged="ClipboardFormatComboBox_SelectionChanged">
|
||||
<ComboBoxItem>Assembler Source</ComboBoxItem>
|
||||
<ComboBoxItem>Disassembly</ComboBoxItem>
|
||||
</ComboBox>
|
||||
@ -104,15 +121,17 @@ limitations under the License.
|
||||
|
||||
<GroupBox Grid.Column="2" Grid.Row="1" Header="Miscellaneous"
|
||||
Margin="10,0,0,0">
|
||||
<CheckBox Content="Add spaces in bytes column" Margin="0,4,0,0"/>
|
||||
<CheckBox Content="Add spaces in bytes column" Margin="0,4,0,0"
|
||||
IsChecked="{Binding SpacesBetweenBytes}"/>
|
||||
</GroupBox>
|
||||
|
||||
<CheckBox Grid.Column="0" Grid.Row="3" Margin="0,16,0,0" Content="Enable DEBUG menu"/>
|
||||
<CheckBox Grid.Column="0" Grid.Row="3" Content="Enable DEBUG menu" Margin="4,16,0,0"
|
||||
IsChecked="{Binding EnableDebugMenu}"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Header="Asm Config">
|
||||
<TabItem Name="asmConfigTab" Header="Asm Config">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Assembler Configuration">
|
||||
<Grid Margin="0,4,0,0">
|
||||
@ -151,20 +170,21 @@ limitations under the License.
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<TextBlock Text="General code generation:" Margin="0,16,0,0"/>
|
||||
<CheckBox Content="Show cycle counts" Margin="0,8,0,0"/>
|
||||
<CheckBox Content="Put long labels on separate line" Margin="0,8,0,0"/>
|
||||
<CheckBox Content="Identify assembler in output" Margin="0,8,0,0"/>
|
||||
<CheckBox Content="Disable label localization" Margin="0,8,0,0"/>
|
||||
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
||||
<CheckBox Content="Show cycle counts" Margin="4,8,0,0"/>
|
||||
<CheckBox Content="Put long labels on separate line" Margin="4,8,0,0"/>
|
||||
<CheckBox Content="Identify assembler in output" Margin="4,8,0,0"/>
|
||||
<CheckBox Content="Disable label localization" Margin="4,8,0,0"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Header="Display Format">
|
||||
<TabItem Name="displayFormatTab" Header="Display Format">
|
||||
<DockPanel LastChildFill="False">
|
||||
<TextBlock DockPanel.Dock="Top"
|
||||
<TextBlock DockPanel.Dock="Top" Margin="4,0,0,0"
|
||||
Text="Configure display format options. This does not affect source code generation."/>
|
||||
<GroupBox Header="Operand Width Disambiguator" Width="300" DockPanel.Dock="Top" HorizontalAlignment="Left">
|
||||
<GroupBox Header="Operand Width Disambiguator" Width="300" DockPanel.Dock="Top"
|
||||
HorizontalAlignment="Left" Margin="0,8,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
@ -204,24 +224,33 @@ limitations under the License.
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,16,0,0">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,16,0,0">
|
||||
<TextBlock Text="Expression style:"/>
|
||||
<ComboBox Width="120" Margin="8,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<GroupBox DockPanel.Dock="Bottom" Header="Quick Set"
|
||||
Width="400" HorizontalAlignment="Right">
|
||||
<DockPanel LastChildFill="False" Margin="8">
|
||||
<Button DockPanel.Dock="Left" Content="Default" Width="75"/>
|
||||
<Button DockPanel.Dock="Right" Content="Set" Width="75" Margin="8,0,0,0"/>
|
||||
<ComboBox DockPanel.Dock="Right" Width="170"/>
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Header="Pseudo-Op">
|
||||
<TabItem Name="pseudoOpTab" Header="Pseudo-Op">
|
||||
<TabItem.Resources>
|
||||
<!-- TextBox spacer -->
|
||||
<Thickness x:Key="TBS" Left="6" Top="0" Right="0" Bottom="0"/>
|
||||
</TabItem.Resources>
|
||||
<DockPanel LastChildFill="False">
|
||||
<TextBlock DockPanel.Dock="Top"
|
||||
<TextBlock DockPanel.Dock="Top" Margin="4,0,0,0"
|
||||
Text="Select pseudo-op names for display. This does not affect source code generation. Blank entries get a default value."/>
|
||||
|
||||
<Grid DockPanel.Dock="Top" Height="240">
|
||||
<Grid DockPanel.Dock="Top" Height="240" Margin="4,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="0.8*"/>
|
||||
|
@ -14,7 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using CommonUtil;
|
||||
|
||||
using AssemblerInfo = SourceGenWPF.AsmGen.AssemblerInfo;
|
||||
using AssemblerConfig = SourceGenWPF.AsmGen.AssemblerConfig;
|
||||
@ -24,7 +31,36 @@ namespace SourceGenWPF.WpfGui {
|
||||
/// <summary>
|
||||
/// Application settings dialog.
|
||||
/// </summary>
|
||||
public partial class EditAppSettings : Window {
|
||||
public partial class EditAppSettings : Window, INotifyPropertyChanged {
|
||||
/// <summary>
|
||||
/// Reference to main window. Needed for examination of the code list font and
|
||||
/// column widths.
|
||||
/// </summary>
|
||||
private MainWindow mMainWin;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to main controller. Needed to push settings out when Apply/OK is clicked.
|
||||
/// </summary>
|
||||
private MainController mMainCtrl;
|
||||
|
||||
/// <summary>
|
||||
/// Copy of settings that we make changes to. On "Apply" or "OK", this is pushed
|
||||
/// into the global settings object, and applied to the ProjectView.
|
||||
/// </summary>
|
||||
private AppSettings mSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Dirty flag, set when anything in mSettings changes.
|
||||
/// </summary>
|
||||
public bool IsDirty {
|
||||
get { return mIsDirty; }
|
||||
set {
|
||||
mIsDirty = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool mIsDirty;
|
||||
|
||||
/// <summary>
|
||||
/// Tab page enumeration. Numbers must match page indices in designer.
|
||||
/// </summary>
|
||||
@ -47,13 +83,426 @@ namespace SourceGenWPF.WpfGui {
|
||||
private AssemblerInfo.Id mInitialAsmId;
|
||||
|
||||
|
||||
public EditAppSettings(Window owner, Tab initialTab,
|
||||
AsmGen.AssemblerInfo.Id initialAsmId) {
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
|
||||
public EditAppSettings(Window owner, MainWindow mainWin, MainController mainCtrl,
|
||||
Tab initialTab, AssemblerInfo.Id initialAsmId) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
mMainWin = mainWin;
|
||||
mMainCtrl = mainCtrl;
|
||||
mInitialTab = initialTab;
|
||||
mInitialAsmId = initialAsmId;
|
||||
|
||||
// Make a work copy, so we can discard changes if the user cancels out of the dialog.
|
||||
// Column width changes don't actively update settings, so grab them.
|
||||
mMainWin.CaptureColumnWidths();
|
||||
mSettings = AppSettings.Global.GetCopy();
|
||||
|
||||
// Put column-width buttons in an array.
|
||||
mColButtons = new Button[] {
|
||||
showCol0, showCol1, showCol2, showCol3, showCol4,
|
||||
showCol5, showCol6, showCol7, showCol8 };
|
||||
Debug.Assert(NUM_COLUMNS == 9);
|
||||
|
||||
// Extract format strings from column-width button labels.
|
||||
for (int i = 0; i < NUM_COLUMNS; i++) {
|
||||
//mColButtons[i].Click += ColumnVisibilityButtonClick;
|
||||
mColumnFormats[i] = (string) mColButtons[i].Content;
|
||||
}
|
||||
|
||||
#if false
|
||||
// Map text boxes to PseudoOpName fields.
|
||||
mPseudoNameMap = new TextBoxPropertyMap[] {
|
||||
new TextBoxPropertyMap(equDirectiveTextBox, "EquDirective"),
|
||||
new TextBoxPropertyMap(orgDirectiveTextBox, "OrgDirective"),
|
||||
new TextBoxPropertyMap(regWidthDirectiveTextBox, "RegWidthDirective"),
|
||||
new TextBoxPropertyMap(defineData1TextBox, "DefineData1"),
|
||||
new TextBoxPropertyMap(defineData2TextBox, "DefineData2"),
|
||||
new TextBoxPropertyMap(defineData3TextBox, "DefineData3"),
|
||||
new TextBoxPropertyMap(defineData4TextBox, "DefineData4"),
|
||||
new TextBoxPropertyMap(defineBigData2TextBox, "DefineBigData2"),
|
||||
new TextBoxPropertyMap(fillTextBox, "Fill"),
|
||||
new TextBoxPropertyMap(denseTextBox, "Dense"),
|
||||
new TextBoxPropertyMap(strGenericTextBox, "StrGeneric"),
|
||||
new TextBoxPropertyMap(strGenericHiTextBox, "StrGenericHi"),
|
||||
new TextBoxPropertyMap(strReverseTextBox, "StrReverse"),
|
||||
new TextBoxPropertyMap(strReverseHiTextBox, "StrReverseHi"),
|
||||
new TextBoxPropertyMap(strLen8TextBox, "StrLen8"),
|
||||
new TextBoxPropertyMap(strLen8HiTextBox, "StrLen8Hi"),
|
||||
new TextBoxPropertyMap(strLen16TextBox, "StrLen16"),
|
||||
new TextBoxPropertyMap(strLen16HiTextBox, "StrLen16Hi"),
|
||||
new TextBoxPropertyMap(strNullTermTextBox, "StrNullTerm"),
|
||||
new TextBoxPropertyMap(strNullTermHiTextBox, "StrNullTermHi"),
|
||||
new TextBoxPropertyMap(strDciTextBox, "StrDci"),
|
||||
new TextBoxPropertyMap(strDciHiTextBox, "StrDciHi"),
|
||||
};
|
||||
|
||||
ConfigureComboBox(asmConfigComboBox);
|
||||
ConfigureComboBox(displayFmtQuickComboBox);
|
||||
ConfigureComboBox(pseudoOpQuickComboBox);
|
||||
|
||||
expressionStyleComboBox.DisplayMember = "Name";
|
||||
foreach (ExpressionStyleItem esi in sExpStyleItems) {
|
||||
expressionStyleComboBox.Items.Add(esi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
PrepCodeView();
|
||||
|
||||
#if false
|
||||
// Assemblers.
|
||||
PopulateAsmConfigItems();
|
||||
showAsmIdentCheckBox.Checked =
|
||||
mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false);
|
||||
disableLabelLocalizationCheckBox.Checked =
|
||||
mSettings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false);
|
||||
longLabelNewLineCheckBox.Checked =
|
||||
mSettings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
||||
showCycleCountsCheckBox.Checked =
|
||||
mSettings.GetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false);
|
||||
|
||||
// Pseudo ops.
|
||||
string opStrCereal = mSettings.GetString(AppSettings.FMT_PSEUDO_OP_NAMES, null);
|
||||
if (!string.IsNullOrEmpty(opStrCereal)) {
|
||||
PseudoOp.PseudoOpNames opNames = PseudoOp.PseudoOpNames.Deserialize(opStrCereal);
|
||||
ImportPseudoOpNames(opNames);
|
||||
} else {
|
||||
// no data available, populate with blanks
|
||||
//PseudoOp.PseudoOpNames opNames = PseudoOp.sDefaultPseudoOpNames;
|
||||
ImportPseudoOpNames(new PseudoOp.PseudoOpNames());
|
||||
}
|
||||
|
||||
PopulateWidthDisamSettings();
|
||||
|
||||
string exprMode = mSettings.GetString(AppSettings.FMT_EXPRESSION_MODE, string.Empty);
|
||||
ExpressionMode mode;
|
||||
if (!Enum.TryParse<ExpressionMode>(exprMode, out mode)) {
|
||||
mode = ExpressionMode.Common;
|
||||
}
|
||||
SetExpressionStyle(mode);
|
||||
#endif
|
||||
|
||||
switch (mInitialTab) {
|
||||
case Tab.CodeView:
|
||||
tabControl.SelectedItem = codeViewTab;
|
||||
break;
|
||||
case Tab.AsmConfig:
|
||||
tabControl.SelectedItem = asmConfigTab;
|
||||
break;
|
||||
case Tab.DisplayFormat:
|
||||
tabControl.SelectedItem = displayFormatTab;
|
||||
break;
|
||||
case Tab.PseudoOp:
|
||||
tabControl.SelectedItem = pseudoOpTab;
|
||||
break;
|
||||
case Tab.Unknown:
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// The various control initializers probably triggered events. Reset the dirty flag.
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||
ApplySettings();
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
private void ApplyButton_Click(object sender, RoutedEventArgs e) {
|
||||
ApplySettings();
|
||||
}
|
||||
|
||||
private void ApplySettings() {
|
||||
#if false
|
||||
PseudoOp.PseudoOpNames opNames = ExportPseudoOpNames();
|
||||
string pseudoCereal = opNames.Serialize();
|
||||
mSettings.SetString(AppSettings.FMT_PSEUDO_OP_NAMES, pseudoCereal);
|
||||
#endif
|
||||
|
||||
mMainCtrl.SetAppSettings(mSettings);
|
||||
AsmGen.AssemblerVersionCache.QueryVersions();
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
|
||||
#region Code View
|
||||
|
||||
private void PrepCodeView() {
|
||||
// Column widths. We called CaptureColumnWidths() during init, so this
|
||||
// should always be a valid serialized string.
|
||||
string widthStr = mSettings.GetString(AppSettings.CDLV_COL_WIDTHS, null);
|
||||
Debug.Assert(!string.IsNullOrEmpty(widthStr));
|
||||
int[] widths = TextUtil.DeserializeIntArray(widthStr);
|
||||
Debug.Assert(widths != null);
|
||||
for (int i = 0; i < NUM_COLUMNS; i++) {
|
||||
SetShowHideButton(i, widths[i]);
|
||||
}
|
||||
|
||||
// Set the string. Note this shows what is currently set in the pending settings
|
||||
// object, *not* what's currently being rendered (until you hit Apply).
|
||||
string fontFamilyName = mSettings.GetString(AppSettings.CDLV_FONT_FAMILY, "BROKEN");
|
||||
int fontSize = mSettings.GetInt(AppSettings.CDLV_FONT_SIZE, 2);
|
||||
codeListFontDesc.Text = string.Format(Res.Strings.FONT_DESCRIPTOR_FMT,
|
||||
fontSize, fontFamilyName);
|
||||
|
||||
// Upper-case formatting.
|
||||
UpperHexValues = mSettings.GetBool(AppSettings.FMT_UPPER_HEX_DIGITS, false);
|
||||
UpperOpcodes = mSettings.GetBool(AppSettings.FMT_UPPER_OP_MNEMONIC, false);
|
||||
UpperPseudoOps = mSettings.GetBool(AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, false);
|
||||
UpperOperandA = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_A, false);
|
||||
UpperOperandS = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_S, false);
|
||||
UpperOperandXY = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
|
||||
|
||||
int clipIndex = mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||
typeof(MainController.ClipLineFormat), 0);
|
||||
if (clipIndex >= 0 && clipIndex < clipboardFormatComboBox.Items.Count) {
|
||||
// NOTE: this couples the ClipLineFormat enum to the XAML.
|
||||
clipboardFormatComboBox.SelectedIndex = clipIndex;
|
||||
}
|
||||
|
||||
SpacesBetweenBytes = mSettings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false);
|
||||
EnableDebugMenu = mSettings.GetBool(AppSettings.DEBUG_MENU_ENABLED, false);
|
||||
}
|
||||
|
||||
// Map buttons to column show/hide buttons.
|
||||
private const int NUM_COLUMNS = (int)MainController.CodeListColumn.COUNT;
|
||||
private string[] mColumnFormats = new string[NUM_COLUMNS];
|
||||
private Button[] mColButtons;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the text on a show/hide column button.
|
||||
/// </summary>
|
||||
/// <param name="index">Column index.</param>
|
||||
/// <param name="width">New width.</param>
|
||||
private void SetShowHideButton(int index, int width) {
|
||||
Button button = mColButtons[index];
|
||||
string fmt = mColumnFormats[index];
|
||||
string show = Res.Strings.SHOW_COL;
|
||||
string hide = Res.Strings.HIDE_COL;
|
||||
button.Content = string.Format(fmt, (width == 0) ? show : hide);
|
||||
}
|
||||
|
||||
private void ColumnVisibilityButton_Click(object sender, RoutedEventArgs e) {
|
||||
int index = -1;
|
||||
for (int i = 0; i < mColButtons.Length; i++) {
|
||||
if (sender == mColButtons[i]) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Debug.Assert(index != -1);
|
||||
|
||||
string widthStr = mSettings.GetString(AppSettings.CDLV_COL_WIDTHS, null);
|
||||
Debug.Assert(!string.IsNullOrEmpty(widthStr));
|
||||
int[] widths = TextUtil.DeserializeIntArray(widthStr);
|
||||
if (widths[index] == 0) {
|
||||
// Expand to default width. The default width changes when the font
|
||||
// changes, so it's best to just reacquire the default width set as needed.
|
||||
int[] defaultWidths = mMainWin.GetDefaultCodeListColumnWidths();
|
||||
widths[index] = defaultWidths[index];
|
||||
} else {
|
||||
widths[index] = 0;
|
||||
}
|
||||
widthStr = TextUtil.SerializeIntArray(widths);
|
||||
mSettings.SetString(AppSettings.CDLV_COL_WIDTHS, widthStr);
|
||||
SetShowHideButton(index, widths[index]);
|
||||
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
private void SelectFontButton_Click(object sender, RoutedEventArgs e) {
|
||||
FontPicker dlg = new FontPicker(this,
|
||||
mSettings.GetString(AppSettings.CDLV_FONT_FAMILY, string.Empty),
|
||||
mSettings.GetInt(AppSettings.CDLV_FONT_SIZE, 12));
|
||||
if (dlg.ShowDialog() == true) {
|
||||
string familyName = dlg.SelectedFamily.ToString();
|
||||
mSettings.SetString(AppSettings.CDLV_FONT_FAMILY, familyName);
|
||||
mSettings.SetInt(AppSettings.CDLV_FONT_SIZE, dlg.SelectedSize);
|
||||
|
||||
codeListFontDesc.Text = string.Format(Res.Strings.FONT_DESCRIPTOR_FMT,
|
||||
dlg.SelectedSize, familyName);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool mUpperHexValues;
|
||||
public bool UpperHexValues {
|
||||
get { return mUpperHexValues; }
|
||||
set {
|
||||
mUpperHexValues = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_HEX_DIGITS, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
private bool mUpperOpcodes;
|
||||
public bool UpperOpcodes {
|
||||
get { return mUpperOpcodes; }
|
||||
set {
|
||||
mUpperOpcodes = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_OP_MNEMONIC, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
private bool mUpperPseudoOps;
|
||||
public bool UpperPseudoOps {
|
||||
get { return mUpperPseudoOps; }
|
||||
set {
|
||||
mUpperPseudoOps = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
private bool mUpperOperandA;
|
||||
public bool UpperOperandA {
|
||||
get { return mUpperOperandA; }
|
||||
set {
|
||||
mUpperOperandA = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_A, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
private bool mUpperOperandS;
|
||||
public bool UpperOperandS {
|
||||
get { return mUpperOperandS; }
|
||||
set {
|
||||
mUpperOperandS = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
private bool mUpperOperandXY;
|
||||
public bool UpperOperandXY {
|
||||
get { return mUpperOperandXY; }
|
||||
set {
|
||||
mUpperOperandXY = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void AllLower_Click(object sender, RoutedEventArgs e) {
|
||||
UpperHexValues = UpperOpcodes = UpperPseudoOps =
|
||||
UpperOperandA = UpperOperandS = UpperOperandXY = false;
|
||||
}
|
||||
|
||||
private void AllUpper_Click(object sender, RoutedEventArgs e) {
|
||||
UpperHexValues = UpperOpcodes = UpperPseudoOps =
|
||||
UpperOperandA = UpperOperandS = UpperOperandXY = true;
|
||||
}
|
||||
|
||||
private void ClipboardFormatComboBox_SelectionChanged(object sender,
|
||||
SelectionChangedEventArgs e) {
|
||||
// NOTE: again, this ties the combo box index to the enum value
|
||||
mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, typeof(MainController.ClipLineFormat),
|
||||
clipboardFormatComboBox.SelectedIndex);
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
private bool mSpacesBetweenBytes;
|
||||
public bool SpacesBetweenBytes {
|
||||
get { return mSpacesBetweenBytes; }
|
||||
set {
|
||||
mSpacesBetweenBytes = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool mEnableDebugMenu;
|
||||
public bool EnableDebugMenu {
|
||||
get { return mEnableDebugMenu; }
|
||||
set {
|
||||
mEnableDebugMenu = value;
|
||||
OnPropertyChanged();
|
||||
mSettings.SetBool(AppSettings.DEBUG_MENU_ENABLED, value);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Code View
|
||||
|
||||
#region Asm Config
|
||||
|
||||
/// <summary>
|
||||
/// Holds an item for the assembler-selection combox box.
|
||||
/// </summary>
|
||||
private class AsmComboItem {
|
||||
// Enumerated ID.
|
||||
public AssemblerInfo.Id AssemblerId { get; private set; }
|
||||
|
||||
// Human-readable name for display.
|
||||
public string Name { get; private set; }
|
||||
|
||||
public AsmComboItem(AssemblerInfo info) {
|
||||
AssemblerId = info.AssemblerId;
|
||||
Name = info.Name;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion AsmConfig
|
||||
|
||||
#region Display Format
|
||||
|
||||
/// <summary>
|
||||
/// Holds an item for the expression style selection combo box.
|
||||
/// </summary>
|
||||
private struct ExpressionStyleItem {
|
||||
// Enumerated mode.
|
||||
public ExpressionMode ExpMode { get; private set; }
|
||||
|
||||
// Human-readable name for display.
|
||||
public string Name { get; private set; }
|
||||
|
||||
public ExpressionStyleItem(ExpressionMode expMode, string name) {
|
||||
ExpMode = expMode;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
private static ExpressionStyleItem[] sExpStyleItems = new ExpressionStyleItem[] {
|
||||
new ExpressionStyleItem(ExpressionMode.Common, "Common"),
|
||||
new ExpressionStyleItem(ExpressionMode.Cc65, "cc65"),
|
||||
new ExpressionStyleItem(ExpressionMode.Merlin, "Merlin"),
|
||||
};
|
||||
|
||||
#endregion Display Format
|
||||
|
||||
#region PseudoOp
|
||||
|
||||
/// <summary>
|
||||
/// Map pseudo-op text entry fields to PseudoOpName properties.
|
||||
/// </summary>
|
||||
private class TextBoxPropertyMap {
|
||||
public TextBox TextBox { get; private set; }
|
||||
public PropertyInfo PropInfo { get; private set; }
|
||||
|
||||
public TextBoxPropertyMap(TextBox textBox, string propName) {
|
||||
TextBox = textBox;
|
||||
PropInfo = typeof(PseudoOp.PseudoOpNames).GetProperty(propName);
|
||||
}
|
||||
}
|
||||
private TextBoxPropertyMap[] mPseudoNameMap;
|
||||
|
||||
#endregion PseudoOp
|
||||
}
|
||||
}
|
||||
|
76
SourceGenWPF/WpfGui/FontPicker.xaml
Normal file
76
SourceGenWPF/WpfGui/FontPicker.xaml
Normal file
@ -0,0 +1,76 @@
|
||||
<!--
|
||||
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.FontPicker"
|
||||
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="Select Font"
|
||||
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
<StackPanel Margin="8">
|
||||
<TextBlock Text="Font family:"/>
|
||||
<!-- thanks:
|
||||
https://searchwindevelopment.techtarget.com/tip/How-to-list-fonts-in-WPF-using-markup-extensions-and-data-templates
|
||||
-->
|
||||
<!--<ListBox DataContext="{x:Static Fonts.SystemFontFamilies}"
|
||||
ItemsSource="{Binding}"
|
||||
/>-->
|
||||
<ListBox Name="fontFamilyListBox"
|
||||
ItemsSource="{Binding MonoFontFamilies}"
|
||||
SelectedItem="{Binding SelectedFamily}"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Height="300" Width="340" Margin="0,4,0,0">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Padding="1" Margin="0,5" BorderBrush="LightBlue" BorderThickness="1">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock VerticalAlignment="Center">
|
||||
<ContentPresenter Content="{TemplateBinding Content}" />
|
||||
</TextBlock>
|
||||
<TextBlock FontFamily="{Binding Source}"
|
||||
VerticalAlignment="Center" Margin="20,3" Foreground="Black"
|
||||
Text="Entry LDA #$0F ;sample"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock Text="Font size:" Margin="0,8,0,0"/>
|
||||
<ComboBox Name="sizeComboBox" IsReadOnly="True" Margin="0,4,0,0" Width="75"
|
||||
HorizontalAlignment="Left">
|
||||
<!-- these are parsed directly, so only use numeric values -->
|
||||
<ComboBoxItem>8</ComboBoxItem>
|
||||
<ComboBoxItem>10</ComboBoxItem>
|
||||
<ComboBoxItem>12</ComboBoxItem>
|
||||
<ComboBoxItem>16</ComboBoxItem>
|
||||
<ComboBoxItem>20</ComboBoxItem>
|
||||
</ComboBox>
|
||||
|
||||
<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>
|
121
SourceGenWPF/WpfGui/FontPicker.xaml.cs
Normal file
121
SourceGenWPF/WpfGui/FontPicker.xaml.cs
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
using CommonWPF;
|
||||
|
||||
namespace SourceGenWPF.WpfGui {
|
||||
/// <summary>
|
||||
/// Simple font picker.
|
||||
/// </summary>
|
||||
public partial class FontPicker : Window {
|
||||
// Used as ItemsSource for the ListBox.
|
||||
public List<FontFamily> MonoFontFamilies { get; private set; }
|
||||
|
||||
// This is bound directly to the ListBox SelectedItem property.
|
||||
public FontFamily SelectedFamily { get; set; }
|
||||
|
||||
// Pulled out of combo box.
|
||||
public int SelectedSize { get; private set; }
|
||||
|
||||
|
||||
public FontPicker(Window owner, string initialFamily, int initialSize) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
GenerateMonoFontList(initialFamily);
|
||||
|
||||
int selIndex = 0;
|
||||
string sizeStr = initialSize.ToString();
|
||||
for (int i = 0; i < sizeComboBox.Items.Count; i++) {
|
||||
ComboBoxItem item = (ComboBoxItem)sizeComboBox.Items[i];
|
||||
if (sizeStr.Equals(item.Content)) {
|
||||
selIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sizeComboBox.SelectedIndex = selIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the MonoFontFamilies list, by finding mono-spaced fonts in the system
|
||||
/// font set.
|
||||
/// </summary>
|
||||
/// <param name="initialFamily">Name of family to select.</param>
|
||||
private void GenerateMonoFontList(string initialFamily) {
|
||||
SortedList<string, FontFamily> tmpList = new SortedList<string, FontFamily>();
|
||||
foreach (Typeface typ in Fonts.SystemTypefaces) {
|
||||
if (typ.Style != FontStyles.Normal) {
|
||||
continue;
|
||||
}
|
||||
if (typ.Weight != FontWeights.Normal) {
|
||||
continue;
|
||||
}
|
||||
if (typ.Stretch != FontStretches.Normal) {
|
||||
continue;
|
||||
}
|
||||
string familyName = typ.FontFamily.ToString();
|
||||
if (string.IsNullOrEmpty(familyName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Unscientific and prone to false-positives. The only alternative seems
|
||||
// to be a PInvoke approach using System.Drawing, which is meant for WinForms
|
||||
// (https://stackoverflow.com/a/225027/294248). Feels a bit weird, but fonts
|
||||
// should be equally mono-spaced regardless of system. The System.Drawing
|
||||
// FontFamily would be mapped back to System.Windows.Media FontFamily by name.
|
||||
const string SAMPLE_STRING1 = "M#w";
|
||||
const string SAMPLE_STRING2 = "i.|";
|
||||
if (Helper.MeasureStringWidth(SAMPLE_STRING1, typ, 10) !=
|
||||
Helper.MeasureStringWidth(SAMPLE_STRING2, typ, 10)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tmpList.Add(familyName, typ.FontFamily);
|
||||
|
||||
if (familyName.Equals(initialFamily)) {
|
||||
SelectedFamily = typ.FontFamily;
|
||||
}
|
||||
}
|
||||
|
||||
MonoFontFamilies = new List<FontFamily>();
|
||||
foreach (FontFamily fam in tmpList.Values) {
|
||||
MonoFontFamilies.Add(fam);
|
||||
}
|
||||
|
||||
// Select the first entry if nothing else is selected.
|
||||
if (SelectedFamily == null && MonoFontFamilies.Count > 0) {
|
||||
SelectedFamily = MonoFontFamilies[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
fontFamilyListBox.Focus();
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||
ComboBoxItem item = (ComboBoxItem)sizeComboBox.SelectedItem;
|
||||
SelectedSize = int.Parse((string)item.Content);
|
||||
DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -389,25 +389,31 @@ limitations under the License.
|
||||
ItemContainerStyle="{StaticResource codeListItemStyle}"
|
||||
SelectionChanged="CodeListView_SelectionChanged"
|
||||
MouseDoubleClick="CodeListView_MouseDoubleClick">
|
||||
<ListView.Resources>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
||||
<!-- <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text }" /> -->
|
||||
</Style>
|
||||
</ListView.Resources>
|
||||
<ListView.View>
|
||||
<GridView AllowsColumnReorder="False">
|
||||
<GridViewColumn Header="Offset" Width="58"
|
||||
DisplayMemberBinding="{Binding Offset}"/>
|
||||
<GridViewColumn Header="Addr" Width="58"
|
||||
CellTemplate="{StaticResource addrHighlightTemplate}"/>
|
||||
<GridViewColumn Header="Bytes" Width="104"
|
||||
<GridViewColumn Header="Bytes" Width="85"
|
||||
DisplayMemberBinding="{Binding Bytes}"/>
|
||||
<GridViewColumn Header="Flags" Width="78"
|
||||
DisplayMemberBinding="{Binding Flags}"/>
|
||||
<GridViewColumn Header="Attr" Width="45"
|
||||
<GridViewColumn Header="Attr" Width="52"
|
||||
DisplayMemberBinding="{Binding Attr}"/>
|
||||
<GridViewColumn Header="Label" Width="91"
|
||||
<GridViewColumn Header="Label" Width="71"
|
||||
CellTemplate="{StaticResource labelHighlightTemplate}"/>
|
||||
<GridViewColumn Header="Opcode" Width="45"
|
||||
<GridViewColumn Header="Opcode" Width="58"
|
||||
DisplayMemberBinding="{Binding Opcode}"/>
|
||||
<GridViewColumn Header="Operand" Width="98"
|
||||
DisplayMemberBinding="{Binding Operand}"/>
|
||||
<GridViewColumn Header="Comment" Width="300"
|
||||
<GridViewColumn Header="Comment" Width="342"
|
||||
DisplayMemberBinding="{Binding Comment}"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
|
@ -225,6 +225,19 @@ namespace SourceGenWPF.WpfGui {
|
||||
get { return mShowCodeListView ? Visibility.Visible : Visibility.Hidden; }
|
||||
}
|
||||
|
||||
public FontFamily CodeListFontFamily {
|
||||
get { return codeListView.FontFamily; }
|
||||
}
|
||||
public double CodeListFontSize {
|
||||
get { return codeListView.FontSize; }
|
||||
}
|
||||
|
||||
public void SetCodeListFont(string familyName, int size) {
|
||||
FontFamily fam = new FontFamily(familyName);
|
||||
codeListView.FontFamily = fam;
|
||||
codeListView.FontSize = size;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles source-initialized event. This happens before Loaded, before the window
|
||||
@ -418,6 +431,45 @@ namespace SourceGenWPF.WpfGui {
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] sSampleStrings = {
|
||||
"+000000", // Offset
|
||||
"00/0000", // Address
|
||||
"00 00 00 00.", // Bytes (optional spaces or ellipsis, but not both)
|
||||
"00000000 0", // Flags
|
||||
"######", // Attributes
|
||||
"MMMMMMMMM", // Label (9 chars)
|
||||
"MMMMMMM", // Opcode
|
||||
"MMMMMMMMMMMMM", // Operand
|
||||
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" // Comment (50 chars)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Computes the default code list column widths, using the currently configured
|
||||
/// code list font.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int[] GetDefaultCodeListColumnWidths() {
|
||||
// Fudge factor, in DIPs. This is necessary because the list view style applies
|
||||
// a margin to the column border.
|
||||
const double FUDGE = 14.0;
|
||||
|
||||
GridView gv = (GridView)codeListView.View;
|
||||
int[] widths = new int[gv.Columns.Count];
|
||||
Debug.Assert(widths.Length == (int)MainController.CodeListColumn.COUNT);
|
||||
Debug.Assert(widths.Length == sSampleStrings.Length);
|
||||
|
||||
Typeface typeface = new Typeface(codeListView.FontFamily, codeListView.FontStyle,
|
||||
codeListView.FontWeight, codeListView.FontStretch);
|
||||
Debug.WriteLine("Default column widths (FUDGE=" + FUDGE + "):");
|
||||
for (int i = 0; i < widths.Length; i++) {
|
||||
double strLen = Helper.MeasureStringWidth(sSampleStrings[i],
|
||||
typeface, codeListView.FontSize);
|
||||
widths[i] = (int)Math.Round(strLen + FUDGE);
|
||||
Debug.WriteLine(" " + i + ":" + widths[i] + " " + sSampleStrings[i]);
|
||||
}
|
||||
return widths;
|
||||
}
|
||||
|
||||
#endregion Column widths
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user