aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Synchronization/Properties
ModeNameSize
-rw-r--r--AssemblyInfo.cs251logstatsplain
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 { }));
        }
    }
}