blob: 161c786d330a37f0c599cc26618ae1247bff845b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Tango.Logging
{
/// <summary>
/// Represents a debugging (write-only) console emulator.
/// </summary>
public partial class ConsoleWindow : Window
{
private bool _closing;
private SolidColorBrush _currentBrush;
private ConsoleColor _current_color;
/// <summary>
/// Initializes a new instance of the <see cref="ConsoleWindow"/> class.
/// </summary>
public ConsoleWindow()
{
InitializeComponent();
txtLog.Document.LineHeight = 12;
txtLog.Document.PageWidth = 4000;
_currentBrush = Brushes.Gainsboro;
AppendLog("--------------------- Twine Console Emulator ---------------------" + Environment.NewLine + Environment.NewLine);
Closing += ConsoleWindow_Closing;
}
/// <summary>
/// Handles the Closing event of the ConsoleWindow control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
private void ConsoleWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
_closing = true;
}
/// <summary>
/// Appends the specified .
/// </summary>
/// <param name="obj">The object.</param>
public void WriteLine(object obj)
{
AppendLog(obj.ToString() + Environment.NewLine);
}
/// <summary>
/// Writes the specified object.
/// </summary>
/// <param name="obj">The object.</param>
public void Write(object obj)
{
AppendLog(obj.ToString());
}
/// <summary>
/// Sets the console foreground color.
/// </summary>
/// <param name="color">The color.</param>
public void SetColor(ConsoleColor color)
{
if (_current_color != color)
{
_current_color = color;
InvokeUI(() => _currentBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(color.ToString())));
}
}
private void AppendLog(String log)
{
InvokeUI(() =>
{
TextRange tr = new TextRange(txtLog.Document.ContentEnd, txtLog.Document.ContentEnd);
tr.Text = log;
tr.ApplyPropertyValue(TextElement.ForegroundProperty, _currentBrush);
Rect r = txtLog.Document.ContentEnd.GetCharacterRect(LogicalDirection.Forward);
txtLog.ScrollToVerticalOffset(r.Y);
});
}
/// <summary>
/// Opens the console.
/// </summary>
public void Open()
{
Show();
}
/// <summary>
/// Closes the console.
/// </summary>
public new void Close()
{
Close();
}
/// <summary>
/// Waits until user closes the window.
/// </summary>
/// <returns></returns>
public async Task WaitForUserClose()
{
WriteLine("");
WriteLine("Close this window to exit...");
await Task.Factory.StartNew(() =>
{
while (!_closing)
{
Thread.Sleep(10);
}
});
}
/// <summary>
/// Invokes the UI.
/// </summary>
/// <param name="action">The action.</param>
private void InvokeUI(Action action)
{
Dispatcher.Invoke(action);
DoEvents();
}
/// <summary>
/// Forces the next rendering thread frame.
/// </summary>
private void DoEvents()
{
if (Application.Current == null) //Using this to enable processing outside a WPF application.
{
new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
}
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
}
}
}
|