diff --git a/CHANGELIST.md b/CHANGELIST.md
index c3555ef6..21fecb78 100644
--- a/CHANGELIST.md
+++ b/CHANGELIST.md
@@ -51,6 +51,7 @@
- Detected type and selected type are different
- Remove message boxes from MainViewModel
- Move MainViewModel to Core
+- Remove LogOutputViewModel
### 2.6.6 (2023-10-04)
diff --git a/MPF.UI.Core/UserControls/LogOutput.xaml.cs b/MPF.UI.Core/UserControls/LogOutput.xaml.cs
index ef9ebffd..7ba86777 100644
--- a/MPF.UI.Core/UserControls/LogOutput.xaml.cs
+++ b/MPF.UI.Core/UserControls/LogOutput.xaml.cs
@@ -1,22 +1,50 @@
using System;
+using System.IO;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Media;
+using System.Windows.Threading;
using MPF.Core.Data;
-using MPF.UI.Core.ViewModels;
namespace MPF.UI.Core.UserControls
{
public partial class LogOutput : UserControl
{
///
- /// Read-only access to the current log output view model
+ /// Document representing the text
///
- public LogOutputViewModel LogOutputViewModel => DataContext as LogOutputViewModel;
+ internal FlowDocument Document { get; private set; }
+
+ ///
+ /// Queue of items that need to be logged
+ ///
+ internal ProcessingQueue LogQueue { get; private set; }
+
+ ///
+ /// Paragraph backing the log
+ ///
+ private readonly Paragraph _paragraph;
+
+ ///
+ /// Cached value of the last line written
+ ///
+ private Run lastLine = null;
public LogOutput()
{
InitializeComponent();
- DataContext = new LogOutputViewModel(Dispatcher);
+
+ // Update the internal state
+ Document = new FlowDocument()
+ {
+ Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20))
+ };
+ _paragraph = new Paragraph();
+ Document.Blocks.Add(_paragraph);
+
+ // Setup the processing queue
+ LogQueue = new ProcessingQueue(ProcessLogLine);
// Add handlers
OutputViewer.SizeChanged += OutputViewerSizeChanged;
@@ -25,7 +53,7 @@ namespace MPF.UI.Core.UserControls
SaveButton.Click += OnSaveButton;
// Update the internal state
- Output.Document = LogOutputViewModel.Document;
+ Output.Document = Document;
}
#region Logging
@@ -42,13 +70,129 @@ namespace MPF.UI.Core.UserControls
return;
// Enqueue the text
- LogOutputViewModel.LogQueue.Enqueue(new LogOutputViewModel.LogLine(text, logLevel));
+ LogQueue.Enqueue(new LogLine(text, logLevel));
+ }
+
+ ///
+ /// Log line wrapper
+ ///
+ internal readonly struct LogLine
+ {
+ public readonly string Text;
+ public readonly LogLevel LogLevel;
+
+ public LogLine(string text, LogLevel logLevel)
+ {
+ this.Text = text;
+ this.LogLevel = logLevel;
+ }
+
+ ///
+ /// Get the foreground Brush for the current LogLevel
+ ///
+ /// Brush representing the color
+ public Brush GetForegroundColor()
+ {
+ switch (this.LogLevel)
+ {
+ case LogLevel.SECRET:
+ return Brushes.Blue;
+ case LogLevel.ERROR:
+ return Brushes.Red;
+ case LogLevel.VERBOSE:
+ return Brushes.Yellow;
+ case LogLevel.USER:
+ default:
+ return Brushes.White;
+ }
+ }
+
+ ///
+ /// Generate a Run object from the current LogLine
+ ///
+ /// Run object based on internal values
+ public Run GenerateRun()
+ {
+ return new Run { Text = this.Text, Foreground = GetForegroundColor() };
+ }
+ }
+
+ ///
+ /// Process the log lines in the queue
+ ///
+ /// LogLine item to process
+ internal void ProcessLogLine(LogLine nextLogLine)
+ {
+ // Null text gets ignored
+ string nextText = nextLogLine.Text;
+ if (nextText == null)
+ return;
+
+ try
+ {
+ if (nextText.StartsWith("\r"))
+ ReplaceLastLine(nextLogLine);
+ else
+ AppendToTextBox(nextLogLine);
+ }
+ catch (Exception ex)
+ {
+ // In the event that something fails horribly, we want to log
+ AppendToTextBox(new LogLine(ex.ToString(), LogLevel.ERROR));
+ }
+ }
+
+ ///
+ /// Append log line to the log text box
+ ///
+ /// LogLine value to append
+ private void AppendToTextBox(LogLine logLine)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ var run = logLine.GenerateRun();
+ _paragraph.Inlines.Add(run);
+ lastLine = run;
+ });
+ }
+
+ ///
+ /// Replace the last line written to the log text box
+ ///
+ /// LogLine value to append
+ private void ReplaceLastLine(LogLine logLine)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ lastLine.Text = logLine.Text;
+ lastLine.Foreground = logLine.GetForegroundColor();
+ });
}
#endregion
#region Helpers
+ ///
+ /// Clear all inlines of the paragraph
+ ///
+ private void ClearInlines() => _paragraph.Inlines.Clear();
+
+ ///
+ /// Save all inlines to console.log
+ ///
+ private void SaveInlines()
+ {
+ using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
+ {
+ foreach (var inline in _paragraph.Inlines)
+ {
+ if (inline is Run run)
+ tw.Write(run.Text);
+ }
+ }
+ }
+
///
/// Scroll the current view to the bottom
///
@@ -59,12 +203,10 @@ namespace MPF.UI.Core.UserControls
#region EventHandlers
private void OnClearButton(object sender, EventArgs e)
- {
- LogOutputViewModel.ClearInlines();
- }
+ => ClearInlines();
private void OnSaveButton(object sender, EventArgs e)
- => LogOutputViewModel.SaveInlines();
+ => SaveInlines();
private void OnTextChanged(object sender, TextChangedEventArgs e)
=> ScrollToBottom();
diff --git a/MPF.UI.Core/ViewModels/LogOutputViewModel.cs b/MPF.UI.Core/ViewModels/LogOutputViewModel.cs
deleted file mode 100644
index 8642f129..00000000
--- a/MPF.UI.Core/ViewModels/LogOutputViewModel.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-using System;
-using System.IO;
-using System.Windows.Documents;
-using System.Windows.Media;
-using System.Windows.Threading;
-using MPF.Core.Data;
-
-namespace MPF.UI.Core.ViewModels
-{
- public class LogOutputViewModel
- {
- ///
- /// Document representing the text
- ///
- internal FlowDocument Document { get; private set; }
-
- ///
- /// Queue of items that need to be logged
- ///
- internal ProcessingQueue LogQueue { get; private set; }
-
- ///
- /// Dispatcher from the parent view for invocation
- ///
- internal Dispatcher Dispatcher { get; private set; }
-
- ///
- /// Paragraph backing the log
- ///
- private readonly Paragraph _paragraph;
-
- ///
- /// Cached value of the last line written
- ///
- private Run lastLine = null;
-
- public LogOutputViewModel(Dispatcher dispatcher)
- {
- // Update the internal state
- Document = new FlowDocument()
- {
- Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20))
- };
- _paragraph = new Paragraph();
- Document.Blocks.Add(_paragraph);
-
- // Setup the processing queue
- LogQueue = new ProcessingQueue(ProcessLogLine);
- Dispatcher = dispatcher;
- }
-
- ///
- /// Clear all inlines of the paragraph
- ///
- public void ClearInlines() => _paragraph.Inlines.Clear();
-
- ///
- /// Save all inlines to console.log
- ///
- public void SaveInlines()
- {
- using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
- {
- foreach (var inline in _paragraph.Inlines)
- {
- if (inline is Run run)
- tw.Write(run.Text);
- }
- }
- }
-
- ///
- /// Log line wrapper
- ///
- internal struct LogLine
- {
- public readonly string Text;
- public readonly LogLevel LogLevel;
-
- public LogLine(string text, LogLevel logLevel)
- {
- this.Text = text;
- this.LogLevel = logLevel;
- }
-
- ///
- /// Get the foreground Brush for the current LogLevel
- ///
- /// Brush representing the color
- public Brush GetForegroundColor()
- {
- switch (this.LogLevel)
- {
- case LogLevel.SECRET:
- return Brushes.Blue;
- case LogLevel.ERROR:
- return Brushes.Red;
- case LogLevel.VERBOSE:
- return Brushes.Yellow;
- case LogLevel.USER:
- default:
- return Brushes.White;
- }
- }
-
- ///
- /// Generate a Run object from the current LogLine
- ///
- /// Run object based on internal values
- public Run GenerateRun()
- {
- return new Run { Text = this.Text, Foreground = GetForegroundColor() };
- }
- }
-
- ///
- /// Enqueue text to the log with formatting
- ///
- /// Text to write to the log
- /// LogLevel for the log
- internal void LogInternal(string text, LogLevel logLevel)
- {
- // Null text gets ignored
- if (text == null)
- return;
-
- // Enqueue the text
- LogQueue.Enqueue(new LogLine(text, logLevel));
- }
-
- ///
- /// Process the log lines in the queue
- ///
- /// LogLine item to process
- internal void ProcessLogLine(LogLine nextLogLine)
- {
- // Null text gets ignored
- string nextText = nextLogLine.Text;
- if (nextText == null)
- return;
-
- try
- {
- if (nextText.StartsWith("\r"))
- ReplaceLastLine(nextLogLine);
- else
- AppendToTextBox(nextLogLine);
- }
- catch (Exception ex)
- {
- // In the event that something fails horribly, we want to log
- AppendToTextBox(new LogLine(ex.ToString(), LogLevel.ERROR));
- }
- }
-
- ///
- /// Append log line to the log text box
- ///
- /// LogLine value to append
- private void AppendToTextBox(LogLine logLine)
- {
- Dispatcher.Invoke(() =>
- {
- var run = logLine.GenerateRun();
- _paragraph.Inlines.Add(run);
- lastLine = run;
- });
- }
-
- ///
- /// Replace the last line written to the log text box
- ///
- /// LogLine value to append
- private void ReplaceLastLine(LogLine logLine)
- {
- Dispatcher.Invoke(() =>
- {
- lastLine.Text = logLine.Text;
- lastLine.Foreground = logLine.GetForegroundColor();
- });
- }
- }
-}