2019-07-14 00:04:47 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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.ComponentModel;
|
|
|
|
|
using System.Diagnostics;
|
2020-03-13 20:58:52 +00:00
|
|
|
|
using System.Globalization;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
2020-03-13 20:58:52 +00:00
|
|
|
|
using CommonWPF;
|
|
|
|
|
|
2019-07-20 20:28:10 +00:00
|
|
|
|
namespace SourceGen.WpfGui {
|
2019-07-14 00:04:47 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Note editor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class EditNote : Window, INotifyPropertyChanged {
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Note result object. Will be set to null if the note was deleted.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public MultiLineComment Note { get; private set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Text input by user. This is bound to the input TextBox.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string UserInput {
|
|
|
|
|
get { return mUserInput; }
|
2020-03-13 20:58:52 +00:00
|
|
|
|
set { mUserInput = value; OnPropertyChanged(); }
|
|
|
|
|
}
|
|
|
|
|
private string mUserInput;
|
|
|
|
|
|
|
|
|
|
public string CustomColorStr {
|
|
|
|
|
get { return mCustomColorStr; }
|
2019-07-14 00:04:47 +00:00
|
|
|
|
set {
|
2020-03-13 20:58:52 +00:00
|
|
|
|
mCustomColorStr = value;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
OnPropertyChanged();
|
2020-03-13 20:58:52 +00:00
|
|
|
|
UpdateCustomColor();
|
|
|
|
|
if (mIsInitialized) {
|
|
|
|
|
Debug.WriteLine("SET CUSTOM");
|
|
|
|
|
IsCustomChecked = true;
|
|
|
|
|
}
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-13 20:58:52 +00:00
|
|
|
|
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;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
private enum ColorList {
|
|
|
|
|
None = 0, Green, Blue, Yellow, Pink, Orange
|
|
|
|
|
}
|
|
|
|
|
private static Color[] sColors = new Color[] {
|
Improve save & restore of top line
Whenever the display list gets regenerated, we need to restore the
code list view scroll position to the previous location in the file.
This gets tricky when multiple lines are appearing or disappearing.
We were saving the file offset of the line, but that works poorly
when there's a multi-line comment associated with that offset,
because we end up scrolling to the top of the comment whenever any
part of the comment is at the top of the screen.
We now track the file offset and the number of lines we were from
the top of that offset's content. This works well unless we remove
a lot of lines. If the adjusted line index would put us into a
different file offset, we punt and just scroll to the top of the item.
Also, fix a crasher in Edit Note.
Also, fix behavior when the list shrinks while a line near the end
of the file is selected.
Also, change a few instances of "Color.FromArgb(0,0,0,0)" to use a
common constant.
2019-07-17 20:47:43 +00:00
|
|
|
|
CommonWPF.Helper.ZeroColor, // no highlight
|
2019-07-14 00:04:47 +00:00
|
|
|
|
Colors.LightGreen,
|
|
|
|
|
Colors.LightBlue,
|
|
|
|
|
Colors.Yellow, //LightGoldenrodYellow,
|
|
|
|
|
Colors.LightPink,
|
|
|
|
|
Colors.Orange
|
|
|
|
|
};
|
|
|
|
|
private RadioButton[] mColorButtons;
|
|
|
|
|
|
2020-03-13 20:58:52 +00:00
|
|
|
|
private bool mIsInitialized = false;
|
|
|
|
|
|
2019-07-14 00:04:47 +00:00
|
|
|
|
// INotifyPropertyChanged implementation
|
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
|
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
|
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public EditNote(Window owner, MultiLineComment note) {
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
Owner = owner;
|
|
|
|
|
DataContext = this;
|
|
|
|
|
|
Improve save & restore of top line
Whenever the display list gets regenerated, we need to restore the
code list view scroll position to the previous location in the file.
This gets tricky when multiple lines are appearing or disappearing.
We were saving the file offset of the line, but that works poorly
when there's a multi-line comment associated with that offset,
because we end up scrolling to the top of the comment whenever any
part of the comment is at the top of the screen.
We now track the file offset and the number of lines we were from
the top of that offset's content. This works well unless we remove
a lot of lines. If the adjusted line index would put us into a
different file offset, we punt and just scroll to the top of the item.
Also, fix a crasher in Edit Note.
Also, fix behavior when the list shrinks while a line near the end
of the file is selected.
Also, change a few instances of "Color.FromArgb(0,0,0,0)" to use a
common constant.
2019-07-17 20:47:43 +00:00
|
|
|
|
if (note == null) {
|
|
|
|
|
Note = new MultiLineComment(string.Empty);
|
|
|
|
|
} else {
|
|
|
|
|
Note = note;
|
|
|
|
|
}
|
2019-07-14 00:04:47 +00:00
|
|
|
|
|
|
|
|
|
mColorButtons = new RadioButton[] {
|
|
|
|
|
colorDefaultRadio,
|
|
|
|
|
colorGreenRadio,
|
|
|
|
|
colorBlueRadio,
|
|
|
|
|
colorYellowRadio,
|
|
|
|
|
colorPinkRadio,
|
|
|
|
|
colorOrangeRadio
|
|
|
|
|
};
|
|
|
|
|
Debug.Assert(mColorButtons.Length == sColors.Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
|
|
|
|
UserInput = Note.Text;
|
|
|
|
|
|
|
|
|
|
// Configure radio buttons.
|
|
|
|
|
colorDefaultRadio.IsChecked = true;
|
|
|
|
|
if (Note != null) {
|
2020-03-13 20:58:52 +00:00
|
|
|
|
bool found = false;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
Color curColor = Note.BackgroundColor;
|
|
|
|
|
for (int i = 0; i < sColors.Length; i++) {
|
|
|
|
|
if (sColors[i].Equals(curColor)) {
|
|
|
|
|
mColorButtons[i].IsChecked = true;
|
2020-03-13 20:58:52 +00:00
|
|
|
|
found = true;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-13 20:58:52 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
Improve save & restore of top line
Whenever the display list gets regenerated, we need to restore the
code list view scroll position to the previous location in the file.
This gets tricky when multiple lines are appearing or disappearing.
We were saving the file offset of the line, but that works poorly
when there's a multi-line comment associated with that offset,
because we end up scrolling to the top of the comment whenever any
part of the comment is at the top of the screen.
We now track the file offset and the number of lines we were from
the top of that offset's content. This works well unless we remove
a lot of lines. If the adjusted line index would put us into a
different file offset, we punt and just scroll to the top of the item.
Also, fix a crasher in Edit Note.
Also, fix behavior when the list shrinks while a line near the end
of the file is selected.
Also, change a few instances of "Color.FromArgb(0,0,0,0)" to use a
common constant.
2019-07-17 20:47:43 +00:00
|
|
|
|
inputTextBox.Focus();
|
2020-03-13 20:58:52 +00:00
|
|
|
|
mIsInitialized = true;
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle Ctrl+Enter as a way to close the dialog, since plain Enter just
|
|
|
|
|
// moves to a new line.
|
|
|
|
|
private void CloseCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
|
|
|
|
|
DialogResult = true;
|
|
|
|
|
}
|
|
|
|
|
public void OkButton_Click(object sender, RoutedEventArgs e) {
|
|
|
|
|
DialogResult = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Window_Closing(object sender, CancelEventArgs e) {
|
|
|
|
|
if (DialogResult != true) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(UserInput)) {
|
|
|
|
|
Note = null;
|
|
|
|
|
} else {
|
2020-03-13 20:58:52 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Note = new MultiLineComment(UserInput, bkgndColor);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-13 20:58:52 +00:00
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|
2020-03-13 20:58:52 +00:00
|
|
|
|
|
|
|
|
|
#endregion Validation rules
|
2019-07-14 00:04:47 +00:00
|
|
|
|
}
|