// Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (c) 2006, Alexander Olk // // Authors: // Alexander Olk alex.olk@googlemail.com // // // NOT COMPLETE - work in progress // changed (simplified) by Alexander Tsyganenko using System.Collections; using System.ComponentModel; using System.Drawing; namespace System.Windows.Forms { public class FontDialog : CommonDialog { protected static readonly object EventApply = new object(); private Font font; private Color color = Color.Black; private bool allowSimulations = true; private bool allowVectorFonts = true; private bool allowVerticalFonts = true; private bool allowScriptChange = true; private bool fixedPitchOnly = false; private int maxSize = 0; private int minSize = 0; private bool scriptsOnly = false; private bool showApply = false; private bool showColor = false; private bool showEffects = true; private bool showHelp = false; private bool fontMustExist = false; private Panel examplePanel; private Button okButton; private Button cancelButton; private TextBox fontTextBox; private TextBox fontstyleTextBox; private TextBox fontsizeTextBox; private ListBox fontListBox; private ListBox fontstyleListBox; private ListBox fontsizeListBox; private GroupBox effectsGroupBox; private CheckBox strikethroughCheckBox; private CheckBox underlinedCheckBox; private Label fontLabel; private Label fontstyleLabel; private Label sizeLabel; private GroupBox exampleGroupBox; private string currentFontName; private float currentSize; private FontFamily currentFamily; private System.Drawing.FontStyle currentFontStyle; private bool underlined = false; private bool strikethrough = false; private Hashtable fontHash = new Hashtable(); private int[] a_sizes = { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 }; private string example_panel_text; private bool internal_change = false; #region Public Constructors public FontDialog() { form = new DialogForm(this); example_panel_text = "AaBbYyZz"; okButton = new Button(); cancelButton = new Button(); fontTextBox = new TextBox(); fontstyleTextBox = new TextBox(); fontsizeTextBox = new TextBox(); fontListBox = new ListBox(); fontsizeListBox = new ListBox(); fontstyleListBox = new ListBox(); fontLabel = new Label(); fontstyleLabel = new Label(); sizeLabel = new Label(); exampleGroupBox = new GroupBox(); effectsGroupBox = new GroupBox(); underlinedCheckBox = new CheckBox(); strikethroughCheckBox = new CheckBox(); examplePanel = new Panel(); exampleGroupBox.SuspendLayout(); effectsGroupBox.SuspendLayout(); form.SuspendLayout(); form.FormBorderStyle = FormBorderStyle.FixedDialog; form.MaximizeBox = false; // fontsizeListBox fontsizeListBox.Location = new System.Drawing.Point(284, 47); fontsizeListBox.Size = new System.Drawing.Size(52, 95); fontsizeListBox.TabIndex = 10; fontListBox.Sorted = true; // fontTextBox fontTextBox.Location = new System.Drawing.Point(16, 26); fontTextBox.Size = new System.Drawing.Size(140, 21); fontTextBox.TabIndex = 5; fontTextBox.Text = ""; // fontstyleLabel fontstyleLabel.Location = new System.Drawing.Point(164, 10); fontstyleLabel.Size = new System.Drawing.Size(100, 16); fontstyleLabel.TabIndex = 1; fontstyleLabel.Text = "Font Style:"; // typesizeTextBox fontsizeTextBox.Location = new System.Drawing.Point(284, 26); fontsizeTextBox.Size = new System.Drawing.Size(52, 21); fontsizeTextBox.TabIndex = 7; fontsizeTextBox.Text = ""; fontsizeTextBox.MaxLength = 2; // fontListBox fontListBox.Location = new System.Drawing.Point(16, 47); fontListBox.Size = new System.Drawing.Size(140, 95); fontListBox.TabIndex = 8; fontListBox.Sorted = true; // exampleGroupBox exampleGroupBox.Controls.Add(examplePanel); exampleGroupBox.Location = new System.Drawing.Point(164, 158); exampleGroupBox.Size = new System.Drawing.Size(172, 70); exampleGroupBox.TabIndex = 12; exampleGroupBox.TabStop = false; exampleGroupBox.Text = "Example"; // fontstyleListBox fontstyleListBox.Location = new System.Drawing.Point(164, 47); fontstyleListBox.Size = new System.Drawing.Size(112, 95); fontstyleListBox.TabIndex = 9; // schriftartLabel fontLabel.Location = new System.Drawing.Point(16, 10); fontLabel.Size = new System.Drawing.Size(88, 16); fontLabel.TabIndex = 0; fontLabel.Text = "Font:"; // effectsGroupBox effectsGroupBox.Controls.Add(underlinedCheckBox); effectsGroupBox.Controls.Add(strikethroughCheckBox); effectsGroupBox.Location = new System.Drawing.Point(16, 158); effectsGroupBox.Size = new System.Drawing.Size(140, 70); effectsGroupBox.TabIndex = 11; effectsGroupBox.TabStop = false; effectsGroupBox.Text = "Effects"; // strikethroughCheckBox strikethroughCheckBox.Location = new System.Drawing.Point(12, 20); strikethroughCheckBox.TabIndex = 0; strikethroughCheckBox.Text = "Strikethrough"; // underlinedCheckBox underlinedCheckBox.Location = new System.Drawing.Point(12, 43); underlinedCheckBox.TabIndex = 1; underlinedCheckBox.Text = "Underlined"; // sizeLabel sizeLabel.Location = new System.Drawing.Point(284, 10); sizeLabel.Size = new System.Drawing.Size(100, 16); sizeLabel.TabIndex = 2; sizeLabel.Text = "Size:"; // okButton okButton.Location = new System.Drawing.Point(352, 26); okButton.Size = new System.Drawing.Size(70, 23); okButton.TabIndex = 3; okButton.Text = "OK"; // cancelButton cancelButton.Location = new System.Drawing.Point(352, 52); cancelButton.Size = new System.Drawing.Size(70, 23); cancelButton.TabIndex = 4; cancelButton.Text = "Cancel"; // fontstyleTextBox fontstyleTextBox.Location = new System.Drawing.Point(164, 26); fontstyleTextBox.Size = new System.Drawing.Size(112, 21); fontstyleTextBox.TabIndex = 6; fontstyleTextBox.Text = ""; // examplePanel examplePanel.Location = new System.Drawing.Point(8, 20); examplePanel.TabIndex = 0; examplePanel.Size = new System.Drawing.Size(156, 40); form.AcceptButton = okButton; form.CancelButton = cancelButton; form.Controls.Add(exampleGroupBox); form.Controls.Add(effectsGroupBox); form.Controls.Add(fontsizeListBox); form.Controls.Add(fontstyleListBox); form.Controls.Add(fontListBox); form.Controls.Add(fontsizeTextBox); form.Controls.Add(fontstyleTextBox); form.Controls.Add(fontTextBox); form.Controls.Add(cancelButton); form.Controls.Add(okButton); form.Controls.Add(sizeLabel); form.Controls.Add(fontstyleLabel); form.Controls.Add(fontLabel); exampleGroupBox.ResumeLayout(false); effectsGroupBox.ResumeLayout(false); form.ClientSize = new System.Drawing.Size(434, 244); form.Text = "Font"; form.ResumeLayout(false); cancelButton.Click += new EventHandler(OnClickCancelButton); okButton.Click += new EventHandler(OnClickOkButton); examplePanel.Paint += new PaintEventHandler(OnPaintExamplePanel); fontListBox.SelectedIndexChanged += new EventHandler(OnSelectedIndexChangedFontListBox); fontsizeListBox.SelectedIndexChanged += new EventHandler(OnSelectedIndexChangedSizeListBox); fontstyleListBox.SelectedIndexChanged += new EventHandler(OnSelectedIndexChangedFontStyleListBox); underlinedCheckBox.CheckedChanged += new EventHandler(OnCheckedChangedUnderlinedCheckBox); strikethroughCheckBox.CheckedChanged += new EventHandler(OnCheckedChangedStrikethroughCheckBox); fontTextBox.KeyPress += new KeyPressEventHandler(OnFontTextBoxKeyPress); fontstyleTextBox.KeyPress += new KeyPressEventHandler(OnFontStyleTextBoxKeyPress); fontsizeTextBox.KeyPress += new KeyPressEventHandler(OnFontSizeTextBoxKeyPress); fontTextBox.TextChanged += new EventHandler(OnFontTextBoxTextChanged); fontstyleTextBox.TextChanged += new EventHandler(OnFontStyleTextTextChanged); fontsizeTextBox.TextChanged += new EventHandler(OnFontSizeTextBoxTextChanged); PopulateFontList(); } #endregion // Public Constructors #region Public Instance Properties public Font Font { get { return font; } set { if (value != null) { font = new Font(value, value.Style); currentFontStyle = font.Style; currentSize = font.SizeInPoints; currentFontName = font.Name; strikethroughCheckBox.Checked = font.Strikeout; underlinedCheckBox.Checked = font.Underline; int index = fontListBox.FindString(currentFontName); if (index != -1) { fontListBox.SelectedIndex = index; } else { fontListBox.SelectedIndex = 0; } UpdateFontSizeListBox(); UpdateFontStyleListBox(); fontListBox.TopIndex = fontListBox.SelectedIndex; } } } [DefaultValue(false)] public bool FontMustExist { get { return fontMustExist; } set { fontMustExist = value; } } [DefaultValue("Color [Black]")] public Color Color { set { color = value; examplePanel.Invalidate(); } get { return color; } } [DefaultValue(true)] public bool AllowSimulations { set { allowSimulations = value; } get { return allowSimulations; } } [DefaultValue(true)] public bool AllowVectorFonts { set { allowVectorFonts = value; } get { return allowVectorFonts; } } [DefaultValue(true)] public bool AllowVerticalFonts { set { allowVerticalFonts = value; } get { return allowVerticalFonts; } } [DefaultValue(true)] public bool AllowScriptChange { set { allowScriptChange = value; } get { return allowScriptChange; } } [DefaultValue(false)] public bool FixedPitchOnly { set { if (fixedPitchOnly != value) { fixedPitchOnly = value; PopulateFontList(); } } get { return fixedPitchOnly; } } [DefaultValue(0)] public int MaxSize { set { maxSize = value; if (maxSize < 0) maxSize = 0; if (maxSize < minSize) minSize = maxSize; CreateFontSizeListBoxItems(); } get { return maxSize; } } [DefaultValue(0)] public int MinSize { set { minSize = value; if (minSize < 0) minSize = 0; if (minSize > maxSize) maxSize = minSize; CreateFontSizeListBoxItems(); if (minSize > currentSize) if (font != null) { font.Dispose(); currentSize = minSize; font = new Font(currentFamily, currentSize, currentFontStyle); UpdateExamplePanel(); fontsizeTextBox.Text = currentSize.ToString(); } } get { return minSize; } } [DefaultValue(false)] public bool ScriptsOnly { set { scriptsOnly = value; } get { return scriptsOnly; } } [DefaultValue(false)] public bool ShowApply { set { if (value != showApply) { showApply = value; } } get { return showApply; } } [DefaultValue(false)] public bool ShowColor { set { if (value != showColor) { showColor = value; } } get { return showColor; } } [DefaultValue(true)] public bool ShowEffects { set { if (value != showEffects) { showEffects = value; if (showEffects) effectsGroupBox.Show(); else effectsGroupBox.Hide(); form.Refresh(); } } get { return showEffects; } } [DefaultValue(false)] public bool ShowHelp { set { if (value != showHelp) { showHelp = value; } } get { return showHelp; } } #endregion // Public Instance Properties #region Protected Instance Properties protected int Options { get { return 0; } } #endregion // Protected Instance Properties #region Public Instance Methods public override void Reset() { color = Color.Black; allowSimulations = true; allowVectorFonts = true; allowVerticalFonts = true; allowScriptChange = true; fixedPitchOnly = false; maxSize = 0; minSize = 0; CreateFontSizeListBoxItems(); scriptsOnly = false; showApply = false; showColor = false; showEffects = true; effectsGroupBox.Show(); showHelp = false; form.Refresh(); } public override string ToString() { if (font == null) return base.ToString(); return String.Concat(base.ToString(), ", Font: ", font.ToString()); } #endregion // Public Instance Methods #region Protected Instance Methods protected override bool RunDialog() { return true; } #endregion // Protected Instance Methods void OnClickCancelButton(object sender, EventArgs e) { form.DialogResult = DialogResult.Cancel; } void OnClickOkButton(object sender, EventArgs e) { form.DialogResult = DialogResult.OK; } void OnPaintExamplePanel(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(SystemBrushes.Control, 0, 0, 156, 40); SizeF fontSizeF = e.Graphics.MeasureString(example_panel_text, font); int text_width = (int)fontSizeF.Width; int text_height = (int)fontSizeF.Height; int x = (examplePanel.Width / 2) - (text_width / 2); if (x < 0) x = 0; int y = (examplePanel.Height / 2) - (text_height / 2); e.Graphics.DrawString(example_panel_text, font, SystemBrushes.ControlText, new System.Drawing.Point(x, y)); } void OnSelectedIndexChangedFontListBox(object sender, EventArgs e) { if (fontListBox.SelectedIndex != -1) { currentFamily = FindByName(fontListBox.Items[fontListBox.SelectedIndex].ToString()); fontTextBox.Text = currentFamily.Name; internal_change = true; UpdateFontStyleListBox(); UpdateFontSizeListBox(); UpdateExamplePanel(); fontTextBox.Focus(); internal_change = false; } } void OnSelectedIndexChangedSizeListBox(object sender, EventArgs e) { if (fontsizeListBox.SelectedIndex != -1) { currentSize = (float)System.Convert.ToDouble(fontsizeListBox.Items[fontsizeListBox.SelectedIndex]); } fontsizeTextBox.Text = currentSize.ToString(); UpdateExamplePanel(); if (!internal_change) fontsizeTextBox.Focus(); } void OnSelectedIndexChangedFontStyleListBox(object sender, EventArgs e) { if (fontstyleListBox.SelectedIndex != -1) { switch (fontstyleListBox.SelectedIndex) { case 0: currentFontStyle = System.Drawing.FontStyle.Regular; break; case 1: currentFontStyle = System.Drawing.FontStyle.Bold; break; case 2: currentFontStyle = System.Drawing.FontStyle.Italic; break; case 3: currentFontStyle = System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic; break; default: currentFontStyle = System.Drawing.FontStyle.Regular; break; } if (underlined) currentFontStyle = currentFontStyle | System.Drawing.FontStyle.Underline; if (strikethrough) currentFontStyle = currentFontStyle | System.Drawing.FontStyle.Strikeout; fontstyleTextBox.Text = fontstyleListBox.Items[fontstyleListBox.SelectedIndex].ToString(); if (!internal_change) { UpdateExamplePanel(); fontstyleTextBox.Focus(); } } } void OnCheckedChangedUnderlinedCheckBox(object sender, EventArgs e) { if (underlinedCheckBox.Checked) { currentFontStyle = currentFontStyle | System.Drawing.FontStyle.Underline; underlined = true; } else { currentFontStyle = currentFontStyle ^ System.Drawing.FontStyle.Underline; underlined = false; } UpdateExamplePanel(); } void OnCheckedChangedStrikethroughCheckBox(object sender, EventArgs e) { if (strikethroughCheckBox.Checked) { currentFontStyle = currentFontStyle | System.Drawing.FontStyle.Strikeout; strikethrough = true; } else { currentFontStyle = currentFontStyle ^ System.Drawing.FontStyle.Strikeout; strikethrough = false; } UpdateExamplePanel(); } bool internal_textbox_change = false; void OnFontTextBoxKeyPress(object sender, KeyPressEventArgs e) { internal_textbox_change = true; if (fontListBox.SelectedIndex > -1) fontListBox.SelectedIndex = -1; } void OnFontStyleTextBoxKeyPress(object sender, KeyPressEventArgs e) { internal_textbox_change = true; if (fontstyleListBox.SelectedIndex > -1) fontstyleListBox.SelectedIndex = -1; } void OnFontSizeTextBoxKeyPress(object sender, KeyPressEventArgs e) { if (Char.IsLetter(e.KeyChar) || Char.IsWhiteSpace(e.KeyChar) || Char.IsPunctuation(e.KeyChar) || e.KeyChar == ',') { e.Handled = true; return; } internal_textbox_change = true; } void OnFontTextBoxTextChanged(object sender, EventArgs e) { if (!internal_textbox_change) return; internal_textbox_change = false; string search = fontTextBox.Text; // Look for an exact match int found = fontListBox.FindStringExact(search); if (found != -1) { fontListBox.SelectedIndex = found; return; } // Look for a partial match found = fontListBox.FindString(search); if (found != -1) { fontListBox.TopIndex = found; return; } // No match, scroll to the top if (fontListBox.Items.Count > 0) fontListBox.TopIndex = 0; } void OnFontStyleTextTextChanged(object sender, EventArgs e) { if (!internal_textbox_change) return; internal_textbox_change = false; // Look for an exact match int found = fontstyleListBox.FindStringExact(fontstyleTextBox.Text); if (found != -1) fontstyleListBox.SelectedIndex = found; } void OnFontSizeTextBoxTextChanged(object sender, EventArgs e) { if (!internal_textbox_change) return; internal_textbox_change = false; if (fontsizeTextBox.Text.Length == 0) return; for (int i = 0; i < fontsizeListBox.Items.Count; i++) { string name = fontsizeListBox.Items[i] as string; if (name.StartsWith(fontsizeTextBox.Text)) { if (name == fontsizeTextBox.Text) fontsizeListBox.SelectedIndex = i; else fontsizeListBox.TopIndex = i; break; } } currentSize = (float)System.Convert.ToDouble(fontsizeTextBox.Text); UpdateExamplePanel(); } void UpdateExamplePanel() { if (font != null) font.Dispose(); font = new Font(currentFamily, currentSize, currentFontStyle); examplePanel.Invalidate(); } void UpdateFontSizeListBox() { int index = fontsizeListBox.FindString(((int)Math.Round((currentSize))).ToString()); fontsizeListBox.SelectedIndex = index; } void UpdateFontStyleListBox() { // don't know if that works, IsStyleAvailable returns true for all styles under X fontstyleListBox.BeginUpdate(); fontstyleListBox.Items.Clear(); int index = -1; int to_select = 0; if (currentFamily.IsStyleAvailable(System.Drawing.FontStyle.Regular)) { index = fontstyleListBox.Items.Add("Regular"); if ((currentFontStyle & System.Drawing.FontStyle.Regular) == System.Drawing.FontStyle.Regular) to_select = index; } if (currentFamily.IsStyleAvailable(System.Drawing.FontStyle.Bold)) { index = fontstyleListBox.Items.Add("Bold"); if ((currentFontStyle & System.Drawing.FontStyle.Bold) == System.Drawing.FontStyle.Bold) to_select = index; } if (currentFamily.IsStyleAvailable(System.Drawing.FontStyle.Italic)) { index = fontstyleListBox.Items.Add("Italic"); if ((currentFontStyle & System.Drawing.FontStyle.Italic) == System.Drawing.FontStyle.Italic) to_select = index; } if (currentFamily.IsStyleAvailable(System.Drawing.FontStyle.Bold) && currentFamily.IsStyleAvailable(System.Drawing.FontStyle.Italic)) { index = fontstyleListBox.Items.Add("Bold Italic"); if ((currentFontStyle & (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)) == (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)) to_select = index; } if (fontstyleListBox.Items.Count > 0) { fontstyleListBox.SelectedIndex = to_select; switch ((string)fontstyleListBox.SelectedItem) { case "Regular": currentFontStyle = System.Drawing.FontStyle.Regular; break; case "Bold": currentFontStyle = System.Drawing.FontStyle.Bold; break; case "Italic": currentFontStyle = System.Drawing.FontStyle.Italic; break; case "Bold Italic": currentFontStyle = System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic; break; } if (strikethroughCheckBox.Checked) currentFontStyle |= System.Drawing.FontStyle.Strikeout; if (underlinedCheckBox.Checked) currentFontStyle |= System.Drawing.FontStyle.Underline; } fontstyleListBox.EndUpdate(); } FontFamily FindByName(string name) { return fontHash[name] as FontFamily; } void CreateFontSizeListBoxItems() { fontsizeListBox.BeginUpdate(); fontsizeListBox.Items.Clear(); if (minSize == 0 && maxSize == 0) { foreach (int i in a_sizes) fontsizeListBox.Items.Add(i.ToString()); } else { foreach (int i in a_sizes) { if (i >= minSize && i <= maxSize) fontsizeListBox.Items.Add(i.ToString()); } } fontsizeListBox.EndUpdate(); } #region Private Methods private void PopulateFontList() { fontListBox.Items.Clear(); fontHash.Clear(); fontListBox.BeginUpdate(); foreach (FontFamily ff in FontFamily.Families) { if (!fontHash.ContainsKey(ff.Name)) { if (!fixedPitchOnly || (IsFontFamilyFixedPitch(ff))) { fontListBox.Items.Add(ff.Name); fontHash.Add(ff.Name, ff); } } } fontListBox.EndUpdate(); CreateFontSizeListBoxItems(); if (fixedPitchOnly) this.Font = new Font(FontFamily.GenericMonospace, 8.25f); else this.Font = form.Font; } private bool IsFontFamilyFixedPitch(FontFamily family) { System.Drawing.FontStyle fs; if (family.IsStyleAvailable(System.Drawing.FontStyle.Regular)) fs = System.Drawing.FontStyle.Regular; else if (family.IsStyleAvailable(System.Drawing.FontStyle.Bold)) fs = System.Drawing.FontStyle.Bold; else if (family.IsStyleAvailable(System.Drawing.FontStyle.Italic)) fs = System.Drawing.FontStyle.Italic; else if (family.IsStyleAvailable(System.Drawing.FontStyle.Strikeout)) fs = System.Drawing.FontStyle.Strikeout; else if (family.IsStyleAvailable(System.Drawing.FontStyle.Underline)) fs = System.Drawing.FontStyle.Underline; else return false; Font f = new Font(family.Name, 10, fs); if (TextRenderer.MeasureText("i", f).Width == TextRenderer.MeasureText("w", f).Width) return true; return false; } #endregion } }