1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-12-01 22:50:35 +00:00
6502bench/SourceGen/WpfGui/FontPicker.xaml.cs
Andy McFadden 0878854759 Fix crash in font picker
It's possible to have multiple fonts with the same font family.
Don't use the list add method that throws an exception when it
finds a duplicate key.
2022-04-29 09:00:01 -07:00

122 lines
4.5 KiB
C#

/*
* 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 SourceGen.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[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;
}
}
}