1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-05-31 22:41:37 +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:
Andy McFadden 2019-06-26 17:11:58 -07:00
parent 0a96e014e2
commit c13daa7085
13 changed files with 851 additions and 79 deletions

View File

@ -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">

View File

@ -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";

View File

@ -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);

View File

@ -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>

View File

@ -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");
}
}

View File

@ -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>

View File

@ -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}"/>

View File

@ -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*"/>

View File

@ -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
}
}

View 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>

View 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;
}
}
}

View File

@ -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>

View File

@ -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