using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using TradeIdeas.Extensions;
using TradeIdeas.TIProGUI;
namespace TIProDevExtension
{
///
/// A simple way to monitor the GUI thread and see how responsive it is.
///
/// Just display this form and watch it. It will be obvious when the GUI is non-responsive.
/// We also record the largest problems in a log.
///
public partial class IsTheGuiAlive : Form
{
public IsTheGuiAlive()
{
_lastTime = DateTime.Now;
InitializeComponent();
Charts.RegisterIsTheGuiAliveAction(guiCallback: (string text) => { AppendText(text); });
}
///
/// When was the last time the timer woke us. So we know if there was a long delay.
/// If there is a long delay, report it to the log.
///
DateTime _lastTime;
///
/// The timer is set to go off once every 50 milliseconds.
///
/// 100 milliseconds is common for human reaction time. That corresponds to a rate of
/// 10 frames per second. You can get away with this frame rate for a simple animation,
/// but any worse and you'll notice the indivual frames, and the illustion of animation
/// will disappear. 50 milliseconds per frame could do a good job for simple animations.
/// Standard def TV had a frame rate of 33 milliseconds and High Def TV is 17 milliseconds.
///
private static readonly TimeSpan REQUESTED = new TimeSpan(0, 0, 0, 0, 50);
///
/// 150 milliseconds. 3x what we requested.
///
private static readonly TimeSpan WORTH_REPORTING = new TimeSpan(0, 0, 0, 0, 150);
private void timer1_Tick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
TimeSpan elapsed = now - _lastTime;
if (elapsed > WORTH_REPORTING)
{
AppendText(now.ToLongTimeString() + ": Waited " + (elapsed - REQUESTED) + " longer than requested." + Environment.NewLine);
}
_lastTime = now;
// Try to update the animation at the REQUESTED frame rate.
animatedPanel.Invalidate();
}
public void AppendText(string text)
{
logTextBox.AppendText(text);
}
private static readonly Brush BRUSH1 = new SolidBrush(Color.Yellow);
private static readonly Brush BRUSH2 = new SolidBrush(Color.DarkBlue);
///
/// It will take 1 second for one color to be completely replaced by the other.
/// The complete period is 2 seconds.
///
private const double PERIOD_IN_SECONDS = 2;
///
/// 10,000,000 ticks per second.
///
private const long PERIOD_IN_TICKS = (long)(PERIOD_IN_SECONDS * 10000000.0 + 0.5);
///
/// Draw something different at each moment in time. You should see two rectangles side by side.
/// The rectangles will move constantly.
///
///
///
private void animatedPanel_Paint(object sender, PaintEventArgs e)
{ // First fill the entire background with one color.
e.Graphics.FillRectangle(BRUSH1, 0, 0, animatedPanel.Width, animatedPanel.Height);
DateTime now = DateTime.Now;
long position = now.Ticks % PERIOD_IN_TICKS;
float left = (float)((position / (double)PERIOD_IN_TICKS * 2 - 1) * animatedPanel.Width);
// Cover part of the control with the second color. This second rectangle is the same
// size as the control, but we change the position so part of it will be cut off. The
// user has no idea which is BRUSH1 and which is BRUSH2; the effect is totally symmetric.
e.Graphics.FillRectangle(BRUSH2, left, 0, animatedPanel.Width, animatedPanel.Height);
}
}
///
/// The standard way to add an extension to the menu.
///
class IsTheGuiAliveExtension : IMainInit
{
///
/// Normal init for extensions.
///
///
///
public static IList