diff --git a/SourceGen/RuntimeData/Help/editors.html b/SourceGen/RuntimeData/Help/editors.html index b6b7db9..f02d514 100644 --- a/SourceGen/RuntimeData/Help/editors.html +++ b/SourceGen/RuntimeData/Help/editors.html @@ -315,6 +315,12 @@ stand out. You may want to assign certain colors to specific things, e.g. blue for "I don't know what this is" or green for "this is a bookmark for the really interesting stuff". The color will be applied to the note in the code list and in the "Notes" window.

+

If you don't like the standard colors you can define your own. +You can do this with web RGB syntax, which uses a '#' followed by +two hex digits per channel. For example, bright red is +#ff0000, while teal is #008080. You can +also simply type a color name like "violet" so long as it appears in the +list of Microsoft .NET colors.

Clear the text field to delete the note.

You can use Ctrl+Enter as a keyboard shortcut for "OK".

diff --git a/SourceGen/WpfGui/EditNote.xaml b/SourceGen/WpfGui/EditNote.xaml index 654a0bb..1e1dabd 100644 --- a/SourceGen/WpfGui/EditNote.xaml +++ b/SourceGen/WpfGui/EditNote.xaml @@ -54,30 +54,44 @@ limitations under the License. VerticalScrollBarVisibility="Auto" AcceptsReturn="True" TextWrapping="Wrap"/> - + + + - - - + + + - - - - - - + + + + + + + + + + + diff --git a/SourceGen/WpfGui/EditNote.xaml.cs b/SourceGen/WpfGui/EditNote.xaml.cs index bb76721..c5af860 100644 --- a/SourceGen/WpfGui/EditNote.xaml.cs +++ b/SourceGen/WpfGui/EditNote.xaml.cs @@ -14,15 +14,17 @@ * limitations under the License. */ using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Globalization; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using CommonWPF; + namespace SourceGen.WpfGui { /// /// Note editor. @@ -38,13 +40,39 @@ namespace SourceGen.WpfGui { /// public string UserInput { get { return mUserInput; } - set { - mUserInput = value; - OnPropertyChanged(); - } + set { mUserInput = value; OnPropertyChanged(); } } private string mUserInput; + public string CustomColorStr { + get { return mCustomColorStr; } + set { + mCustomColorStr = value; + OnPropertyChanged(); + UpdateCustomColor(); + if (mIsInitialized) { + Debug.WriteLine("SET CUSTOM"); + IsCustomChecked = true; + } + } + } + private string mCustomColorStr; + + public bool IsCustomChecked { + get { return mIsCustomChecked; } + set { mIsCustomChecked = value; OnPropertyChanged(); } + } + private bool mIsCustomChecked; + + public Brush CustomColorBrush { + get { return mCustomColorBrush; } + set { mCustomColorBrush = value; OnPropertyChanged(); } + } + private Brush mCustomColorBrush = Brushes.Transparent; + + // This is static so it carries over between edits. + private static Color mCustomColor = Helper.ZeroColor; + // Highlight color palette. Unless the user has funky theme, the color will be // replacing a white background, and will be overlaid with black text, so should // be on the lighter end of the spectrum. @@ -61,6 +89,8 @@ namespace SourceGen.WpfGui { }; private RadioButton[] mColorButtons; + private bool mIsInitialized = false; + // INotifyPropertyChanged implementation public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = "") { @@ -96,16 +126,32 @@ namespace SourceGen.WpfGui { // Configure radio buttons. colorDefaultRadio.IsChecked = true; if (Note != null) { + bool found = false; Color curColor = Note.BackgroundColor; for (int i = 0; i < sColors.Length; i++) { if (sColors[i].Equals(curColor)) { mColorButtons[i].IsChecked = true; + found = true; break; } } + + if (!found) { + IsCustomChecked = true; + mCustomColor = curColor; + } + } + + if (mCustomColor.A == 0xff) { + CustomColorStr = string.Format("#{0:X2}{1:X2}{2:X2}", + mCustomColor.R, mCustomColor.G, mCustomColor.B); + } else { + CustomColorStr = string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", + mCustomColor.A, mCustomColor.R, mCustomColor.G, mCustomColor.B); } inputTextBox.Focus(); + mIsInitialized = true; } // Handle Ctrl+Enter as a way to close the dialog, since plain Enter just @@ -119,22 +165,68 @@ namespace SourceGen.WpfGui { private void Window_Closing(object sender, CancelEventArgs e) { if (DialogResult != true) { - Debug.WriteLine("Skip it"); return; } if (string.IsNullOrEmpty(UserInput)) { Note = null; } else { - Color bkgndColor = Colors.Fuchsia; - for (int i = 0; i < mColorButtons.Length; i++) { - if (mColorButtons[i].IsChecked == true) { - bkgndColor = sColors[i]; - break; + Color bkgndColor = Colors.Fuchsia; // make it obvious if we screw up + if (IsCustomChecked) { + if (Validation.GetHasError(customColorBox)) { + bkgndColor = Helper.ZeroColor; + } else { + bkgndColor = mCustomColor; + } + } else { + for (int i = 0; i < mColorButtons.Length; i++) { + if (mColorButtons[i].IsChecked == true) { + bkgndColor = sColors[i]; + break; + } } } Note = new MultiLineComment(UserInput, bkgndColor); } } + + private void UpdateCustomColor() { + Color cl; + try { + cl = (Color)ColorConverter.ConvertFromString(CustomColorStr); + } catch (FormatException ex) { + // no dice + Debug.WriteLine("Unable to convert color '" + CustomColorStr + "': " + ex.Message); + CustomColorBrush = Brushes.Transparent; + mCustomColor = Helper.ZeroColor; + return; + } + + mCustomColor = cl; + CustomColorBrush = new SolidColorBrush(cl); + } } + + #region Validation rules + + public class ColorRule : ValidationRule { + public override ValidationResult Validate(object value, CultureInfo cultureInfo) { + string strValue = Convert.ToString(value); + if (strValue == null) { + return new ValidationResult(false, "could not convert to string"); + } + if (string.IsNullOrEmpty(strValue)) { + return new ValidationResult(false, "empty color string"); + } + + try { + ColorConverter.ConvertFromString(strValue); + return ValidationResult.ValidResult; + } catch (Exception) { + return new ValidationResult(false, "invalid color value"); + } + } + } + + #endregion Validation rules }