Fix tags font color in dark mode
This commit is contained in:
parent
c4827fc761
commit
7658f21d7c
@ -51,7 +51,7 @@
|
|||||||
<DataGridTemplateColumn Width="Auto" Header="Tag">
|
<DataGridTemplateColumn Width="Auto" Header="Tag">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextPresenter Height="18" Margin="10,0,10,0" VerticalAlignment="Center" Text="{Binding Item1}" />
|
<TextBlock Height="18" Margin="10,0,10,0" VerticalAlignment="Center" Text="{Binding Item1}" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
@ -59,7 +59,7 @@
|
|||||||
<DataGridTemplateColumn Width="Auto" Header="Description">
|
<DataGridTemplateColumn Width="Auto" Header="Description">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextPresenter
|
<TextBlock
|
||||||
Height="18"
|
Height="18"
|
||||||
Margin="10,0,10,0"
|
Margin="10,0,10,0"
|
||||||
VerticalAlignment="Center" Text="{Binding Item2}" />
|
VerticalAlignment="Center" Text="{Binding Item2}" />
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Documents;
|
using Avalonia.Controls.Documents;
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Avalonia.Styling;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
using LibationFileManager;
|
using LibationFileManager;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -11,175 +11,175 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace LibationAvalonia.Dialogs
|
namespace LibationAvalonia.Dialogs;
|
||||||
|
|
||||||
|
public partial class EditTemplateDialog : DialogWindow
|
||||||
{
|
{
|
||||||
public partial class EditTemplateDialog : DialogWindow
|
private EditTemplateViewModel _viewModel;
|
||||||
|
|
||||||
|
public EditTemplateDialog()
|
||||||
{
|
{
|
||||||
private EditTemplateViewModel _viewModel;
|
InitializeComponent();
|
||||||
|
|
||||||
public EditTemplateDialog()
|
if (Design.IsDesignMode)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
_ = Configuration.Instance.LibationFiles;
|
||||||
|
RequestedThemeVariant = ThemeVariant.Dark;
|
||||||
if (Design.IsDesignMode)
|
var editor = TemplateEditor<Templates.FileTemplate>.CreateFilenameEditor(Configuration.Instance.Books, Configuration.Instance.FileTemplate);
|
||||||
{
|
_viewModel = new(Configuration.Instance, editor);
|
||||||
_ = Configuration.Instance.LibationFiles;
|
_viewModel.ResetTextBox(editor.EditingTemplate.TemplateText);
|
||||||
var editor = TemplateEditor<Templates.FileTemplate>.CreateFilenameEditor(Configuration.Instance.Books, Configuration.Instance.FileTemplate);
|
Title = $"Edit {editor.TemplateName}";
|
||||||
_viewModel = new(Configuration.Instance, editor);
|
|
||||||
_viewModel.ResetTextBox(editor.EditingTemplate.TemplateText);
|
|
||||||
Title = $"Edit {editor.TemplateName}";
|
|
||||||
DataContext = _viewModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditTemplateDialog(ITemplateEditor templateEditor) : this()
|
|
||||||
{
|
|
||||||
ArgumentValidator.EnsureNotNull(templateEditor, nameof(templateEditor));
|
|
||||||
|
|
||||||
_viewModel = new EditTemplateViewModel(Configuration.Instance, templateEditor);
|
|
||||||
_viewModel.ResetTextBox(templateEditor.EditingTemplate.TemplateText);
|
|
||||||
Title = $"Edit {templateEditor.TemplateName}";
|
|
||||||
DataContext = _viewModel;
|
DataContext = _viewModel;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditTemplateDialog(ITemplateEditor templateEditor) : this()
|
||||||
|
{
|
||||||
|
ArgumentValidator.EnsureNotNull(templateEditor, nameof(templateEditor));
|
||||||
|
|
||||||
|
_viewModel = new EditTemplateViewModel(Configuration.Instance, templateEditor);
|
||||||
|
_viewModel.ResetTextBox(templateEditor.EditingTemplate.TemplateText);
|
||||||
|
Title = $"Edit {templateEditor.TemplateName}";
|
||||||
|
DataContext = _viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void EditTemplateViewModel_DoubleTapped(object sender, Avalonia.Input.TappedEventArgs e)
|
public void EditTemplateViewModel_DoubleTapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||||
|
{
|
||||||
|
var dataGrid = sender as DataGrid;
|
||||||
|
|
||||||
|
var item = (dataGrid.SelectedItem as Tuple<string, string, string>).Item3;
|
||||||
|
if (string.IsNullOrWhiteSpace(item)) return;
|
||||||
|
|
||||||
|
var text = userEditTbox.Text;
|
||||||
|
|
||||||
|
userEditTbox.Text = text.Insert(Math.Min(Math.Max(0, userEditTbox.CaretIndex), text.Length), item);
|
||||||
|
userEditTbox.CaretIndex += item.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task SaveAndCloseAsync()
|
||||||
|
{
|
||||||
|
if (!await _viewModel.Validate())
|
||||||
|
return;
|
||||||
|
|
||||||
|
await base.SaveAndCloseAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SaveButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
=> await SaveAndCloseAsync();
|
||||||
|
|
||||||
|
private class EditTemplateViewModel : ViewModels.ViewModelBase
|
||||||
|
{
|
||||||
|
private readonly Configuration config;
|
||||||
|
public InlineCollection Inlines { get; } = new();
|
||||||
|
public ITemplateEditor TemplateEditor { get; }
|
||||||
|
public EditTemplateViewModel(Configuration configuration, ITemplateEditor templates)
|
||||||
{
|
{
|
||||||
var dataGrid = sender as DataGrid;
|
config = configuration;
|
||||||
|
TemplateEditor = templates;
|
||||||
|
Description = templates.TemplateDescription;
|
||||||
|
ListItems
|
||||||
|
= new AvaloniaList<Tuple<string, string, string>>(
|
||||||
|
TemplateEditor
|
||||||
|
.EditingTemplate
|
||||||
|
.TagsRegistered
|
||||||
|
.Cast<TemplateTags>()
|
||||||
|
.Select(
|
||||||
|
t => new Tuple<string, string, string>(
|
||||||
|
$"<{t.TagName}>",
|
||||||
|
t.Description,
|
||||||
|
t.DefaultValue)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var item = (dataGrid.SelectedItem as Tuple<string, string, string>).Item3;
|
|
||||||
if (string.IsNullOrWhiteSpace(item)) return;
|
|
||||||
|
|
||||||
var text = userEditTbox.Text;
|
|
||||||
|
|
||||||
userEditTbox.Text = text.Insert(Math.Min(Math.Max(0, userEditTbox.CaretIndex), text.Length), item);
|
|
||||||
userEditTbox.CaretIndex += item.Length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task SaveAndCloseAsync()
|
// hold the work-in-progress value. not guaranteed to be valid
|
||||||
|
private string _userTemplateText;
|
||||||
|
public string UserTemplateText
|
||||||
{
|
{
|
||||||
if (!await _viewModel.Validate())
|
get => _userTemplateText;
|
||||||
return;
|
set
|
||||||
|
|
||||||
await base.SaveAndCloseAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void SaveButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
|
||||||
=> await SaveAndCloseAsync();
|
|
||||||
|
|
||||||
private class EditTemplateViewModel : ViewModels.ViewModelBase
|
|
||||||
{
|
|
||||||
private readonly Configuration config;
|
|
||||||
public InlineCollection Inlines { get; } = new();
|
|
||||||
public ITemplateEditor TemplateEditor { get; }
|
|
||||||
public EditTemplateViewModel(Configuration configuration, ITemplateEditor templates)
|
|
||||||
{
|
{
|
||||||
config = configuration;
|
this.RaiseAndSetIfChanged(ref _userTemplateText, value);
|
||||||
TemplateEditor = templates;
|
templateTb_TextChanged();
|
||||||
Description = templates.TemplateDescription;
|
}
|
||||||
ListItems
|
}
|
||||||
= new AvaloniaList<Tuple<string, string, string>>(
|
|
||||||
|
private string _warningText;
|
||||||
|
public string WarningText { get => _warningText; set => this.RaiseAndSetIfChanged(ref _warningText, value); }
|
||||||
|
|
||||||
|
public string Description { get; }
|
||||||
|
|
||||||
|
public AvaloniaList<Tuple<string, string, string>> ListItems { get; set; }
|
||||||
|
|
||||||
|
public void ResetTextBox(string value) => UserTemplateText = value;
|
||||||
|
public void ResetToDefault() => ResetTextBox(TemplateEditor.DefaultTemplate);
|
||||||
|
|
||||||
|
public async Task<bool> Validate()
|
||||||
|
{
|
||||||
|
if (TemplateEditor.EditingTemplate.IsValid)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var errors
|
||||||
|
= TemplateEditor
|
||||||
|
.EditingTemplate
|
||||||
|
.Errors
|
||||||
|
.Select(err => $"- {err}")
|
||||||
|
.Aggregate((a, b) => $"{a}\r\n{b}");
|
||||||
|
await MessageBox.Show($"This template text is not valid. Errors:\r\n{errors}", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void templateTb_TextChanged()
|
||||||
|
{
|
||||||
|
TemplateEditor.SetTemplateText(UserTemplateText);
|
||||||
|
|
||||||
|
const char ZERO_WIDTH_SPACE = '\u200B';
|
||||||
|
var sing = $"{Path.DirectorySeparatorChar}";
|
||||||
|
|
||||||
|
// result: can wrap long paths. eg:
|
||||||
|
// |-- LINE WRAP BOUNDARIES --|
|
||||||
|
// \books\author with a very <= normal line break on space between words
|
||||||
|
// long name\narrator narrator
|
||||||
|
// \title <= line break on the zero-with space we added before slashes
|
||||||
|
string slashWrap(string val) => val.Replace(sing, $"{ZERO_WIDTH_SPACE}{sing}");
|
||||||
|
|
||||||
|
WarningText
|
||||||
|
= !TemplateEditor.EditingTemplate.HasWarnings
|
||||||
|
? ""
|
||||||
|
: "Warning:\r\n" +
|
||||||
TemplateEditor
|
TemplateEditor
|
||||||
.EditingTemplate
|
.EditingTemplate
|
||||||
.TagsRegistered
|
.Warnings
|
||||||
.Cast<TemplateTags>()
|
.Select(err => $"- {err}")
|
||||||
.Select(
|
.Aggregate((a, b) => $"{a}\r\n{b}");
|
||||||
t => new Tuple<string, string, string>(
|
|
||||||
$"<{t.TagName}>",
|
|
||||||
t.Description,
|
|
||||||
t.DefaultValue)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
var bold = FontWeight.Bold;
|
||||||
|
var reg = FontWeight.Normal;
|
||||||
|
|
||||||
// hold the work-in-progress value. not guaranteed to be valid
|
Inlines.Clear();
|
||||||
private string _userTemplateText;
|
|
||||||
public string UserTemplateText
|
if (!TemplateEditor.IsFilePath)
|
||||||
{
|
{
|
||||||
get => _userTemplateText;
|
Inlines.Add(new Run(TemplateEditor.GetName()) { FontWeight = bold });
|
||||||
set
|
return;
|
||||||
{
|
|
||||||
this.RaiseAndSetIfChanged(ref _userTemplateText, value);
|
|
||||||
templateTb_TextChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _warningText;
|
var folder = TemplateEditor.GetFolderName();
|
||||||
public string WarningText { get => _warningText; set => this.RaiseAndSetIfChanged(ref _warningText, value); }
|
var file = TemplateEditor.GetFileName();
|
||||||
|
var ext = config.DecryptToLossy ? "mp3" : "m4b";
|
||||||
|
|
||||||
public string Description { get; }
|
Inlines.Add(new Run(slashWrap(TemplateEditor.BaseDirectory.PathWithoutPrefix)) { FontWeight = reg });
|
||||||
|
Inlines.Add(new Run(sing) { FontWeight = reg });
|
||||||
|
|
||||||
public AvaloniaList<Tuple<string, string, string>> ListItems { get; set; }
|
Inlines.Add(new Run(slashWrap(folder)) { FontWeight = TemplateEditor.IsFolder ? bold : reg });
|
||||||
|
|
||||||
public void ResetTextBox(string value) => UserTemplateText = value;
|
Inlines.Add(new Run(sing));
|
||||||
public void ResetToDefault() => ResetTextBox(TemplateEditor.DefaultTemplate);
|
|
||||||
|
|
||||||
public async Task<bool> Validate()
|
Inlines.Add(new Run(slashWrap(file)) { FontWeight = TemplateEditor.IsFolder ? reg : bold });
|
||||||
{
|
|
||||||
if (TemplateEditor.EditingTemplate.IsValid)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var errors
|
Inlines.Add(new Run($".{ext}"));
|
||||||
= TemplateEditor
|
|
||||||
.EditingTemplate
|
|
||||||
.Errors
|
|
||||||
.Select(err => $"- {err}")
|
|
||||||
.Aggregate((a, b) => $"{a}\r\n{b}");
|
|
||||||
await MessageBox.Show($"This template text is not valid. Errors:\r\n{errors}", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void templateTb_TextChanged()
|
|
||||||
{
|
|
||||||
TemplateEditor.SetTemplateText(UserTemplateText);
|
|
||||||
|
|
||||||
const char ZERO_WIDTH_SPACE = '\u200B';
|
|
||||||
var sing = $"{Path.DirectorySeparatorChar}";
|
|
||||||
|
|
||||||
// result: can wrap long paths. eg:
|
|
||||||
// |-- LINE WRAP BOUNDARIES --|
|
|
||||||
// \books\author with a very <= normal line break on space between words
|
|
||||||
// long name\narrator narrator
|
|
||||||
// \title <= line break on the zero-with space we added before slashes
|
|
||||||
string slashWrap(string val) => val.Replace(sing, $"{ZERO_WIDTH_SPACE}{sing}");
|
|
||||||
|
|
||||||
WarningText
|
|
||||||
= !TemplateEditor.EditingTemplate.HasWarnings
|
|
||||||
? ""
|
|
||||||
: "Warning:\r\n" +
|
|
||||||
TemplateEditor
|
|
||||||
.EditingTemplate
|
|
||||||
.Warnings
|
|
||||||
.Select(err => $"- {err}")
|
|
||||||
.Aggregate((a, b) => $"{a}\r\n{b}");
|
|
||||||
|
|
||||||
var bold = FontWeight.Bold;
|
|
||||||
var reg = FontWeight.Normal;
|
|
||||||
|
|
||||||
Inlines.Clear();
|
|
||||||
|
|
||||||
if (!TemplateEditor.IsFilePath)
|
|
||||||
{
|
|
||||||
Inlines.Add(new Run(TemplateEditor.GetName()) { FontWeight = bold });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var folder = TemplateEditor.GetFolderName();
|
|
||||||
var file = TemplateEditor.GetFileName();
|
|
||||||
var ext = config.DecryptToLossy ? "mp3" : "m4b";
|
|
||||||
|
|
||||||
Inlines.Add(new Run(slashWrap(TemplateEditor.BaseDirectory.PathWithoutPrefix)) { FontWeight = reg });
|
|
||||||
Inlines.Add(new Run(sing) { FontWeight = reg });
|
|
||||||
|
|
||||||
Inlines.Add(new Run(slashWrap(folder)) { FontWeight = TemplateEditor.IsFolder ? bold : reg });
|
|
||||||
|
|
||||||
Inlines.Add(new Run(sing));
|
|
||||||
|
|
||||||
Inlines.Add(new Run(slashWrap(file)) { FontWeight = TemplateEditor.IsFolder ? reg : bold });
|
|
||||||
|
|
||||||
Inlines.Add(new Run($".{ext}"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user