mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-26 06:49:19 +00:00
Allow custom colors in Notes
The data structure and project file have always supported arbitrary ARGB colors. Now the editor does as well.
This commit is contained in:
parent
a0bf8b808c
commit
c0de0a8844
@ -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.</p>
|
||||
<p>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
|
||||
<code>#ff0000</code>, while teal is <code>#008080</code>. You can
|
||||
also simply type a color name like "violet" so long as it appears in the
|
||||
<a href="https://docs.microsoft.com/en-us/dotnet/media/art-color-table.png?view=netframework-4.8">list of Microsoft .NET colors</a>.</p>
|
||||
|
||||
<p>Clear the text field to delete the note.</p>
|
||||
<p>You can use Ctrl+Enter as a keyboard shortcut for "OK".</p>
|
||||
|
@ -54,30 +54,44 @@ limitations under the License.
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True" TextWrapping="Wrap"/>
|
||||
|
||||
<GroupBox Grid.Row="2" Header="Select Highlight Color" Width="200" HorizontalAlignment="Left">
|
||||
<GroupBox Grid.Row="2" Header="Select Highlight Color" Width="270" HorizontalAlignment="Left">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RadioButton Name="colorDefaultRadio" Grid.Column="0" Grid.Row="0" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorDefaultRadio" Grid.Column="0" Grid.Row="0" Margin="0,6,0,0"
|
||||
Content="_None"/>
|
||||
<RadioButton Name="colorGreenRadio" Grid.Column="0" Grid.Row="1" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorGreenRadio" Grid.Column="0" Grid.Row="1" Margin="0,6,0,0"
|
||||
Content="_Green" Background="LightGreen"/>
|
||||
<RadioButton Name="colorBlueRadio" Grid.Column="0" Grid.Row="2" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorBlueRadio" Grid.Column="0" Grid.Row="2" Margin="0,6,0,0"
|
||||
Content="_Blue" Background="LightBlue"/>
|
||||
<RadioButton Name="colorYellowRadio" Grid.Column="1" Grid.Row="0" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorYellowRadio" Grid.Column="1" Grid.Row="0" Margin="0,6,0,0"
|
||||
Content="_Yellow" Background="Yellow"/>
|
||||
<RadioButton Name="colorPinkRadio" Grid.Column="1" Grid.Row="1" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorPinkRadio" Grid.Column="1" Grid.Row="1" Margin="0,6,0,0"
|
||||
Content="_Pink" Background="LightPink"/>
|
||||
<RadioButton Name="colorOrangeRadio" Grid.Column="1" Grid.Row="2" Margin="0,4,0,0"
|
||||
<RadioButton Name="colorOrangeRadio" Grid.Column="1" Grid.Row="2" Margin="0,6,0,0"
|
||||
Content="_Orange" Background="Orange"/>
|
||||
<RadioButton Name="colorCustomRadio" Grid.Column="3" Grid.Row="0" Margin="0,6,0,0"
|
||||
Content="_Custom" IsChecked="{Binding IsCustomChecked}"/>
|
||||
<TextBox Name="customColorBox" Grid.Column="3" Grid.Row="1" MaxLength="12" Width="100" Margin="18,2,0,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="CustomColorStr" UpdateSourceTrigger="PropertyChanged" FallbackValue="#008800">
|
||||
<Binding.ValidationRules>
|
||||
<local:ColorRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<Rectangle Grid.Column="3" Grid.Row="2" Fill="{Binding CustomColorBrush}" Margin="18,4,0,0"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
|
@ -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 {
|
||||
/// <summary>
|
||||
/// Note editor.
|
||||
@ -38,13 +40,39 @@ namespace SourceGen.WpfGui {
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user