-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGiraffic.cs
142 lines (121 loc) · 5.03 KB
/
Giraffic.cs
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
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using System;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Reflection;
namespace Giraffics
{
/// <summary>
/// A fancy modular window that runs in another thread. A Giraffic is
/// functionally a dynamically paintable canvas which acts as a wrapper for
/// the Windows Forms class and Graphics class for simplicity of drawing.
/// </summary>
public partial class Giraffic : Canvas
{
// Private Giraffic instance variables
private Thread windowThread;
private BufferedWindow window;
//private Bitmap bitmap;
//private Graphics graphics; // This is set to a new instance after every paint.
private SizeF oldGraphicsSize; // Keep track of
// Public instance variables
public bool IsRunning { get; protected set; }
public bool isAntiAlias;
/// <summary>
/// A fancy modular window that runs in another thread. A Giraffic is
/// functionally a dynamically paintable canvas which acts as a wrapper for
/// the Windows Forms class and Graphics class for simplicity of drawing.
/// </summary>
public Giraffic(string name, Size size, FormStartPosition startPos = FormStartPosition.WindowsDefaultLocation): base(size)
{
// Setup window in another thread
windowThread = new Thread(() => InitializeWindow(name, size, startPos));
windowThread.Start();
// Enable anti-aliasing by default.
isAntiAlias = true;
// Create a bitmap and a graphics object to help draw on it.
/*bitmap = new Bitmap(size.Width, size.Height);
graphics = Graphics.FromImage(bitmap);
graphics.SmoothingMode = SmoothingMode.AntiAlias;*/
graphics.SmoothingMode = SmoothingMode.AntiAlias;
oldGraphicsSize = graphics.VisibleClipBounds.Size;
IsRunning = true;
// Wait until the window is completely constructed before return.
while (window == null || !window.IsHandleCreated)
Thread.Sleep(10);
}
/// <summary>Stop the Giraffic and destroy its window. Cannot be started again.</summary>
public void Close()
{
IsRunning = false;
CrossThreadWindowOp(delegate
{
window.Close();
});
}
/// <summary>Show the Giraffic window.</summary>
public void Show()
{
CrossThreadWindowOp(delegate
{
window.Show();
});
}
/// <summary>Hide the Giraffic window.</summary>
public void Hide()
{
CrossThreadWindowOp(delegate
{
window.Hide();
});
}
/// <summary>Force the Giraffic window to display what's on the canvas.</summary>
public void Refresh()
{
CrossThreadWindowOp(delegate
{
window.Refresh();
});
}
/// <summary>Create the Giraffic window and all of its necessary cross-thread
/// interfaces, then run the application.</summary>
private void InitializeWindow(string name, Size size, FormStartPosition startPos)
{
window = new BufferedWindow(name, size);
window.StartPosition = startPos;
// Add some pazzaz
window.BackColor = Color.FromArgb(240, 240, 240);
window.Icon = new Icon(typeof(Giraffic), "giraffe.ico"); // Made by Rfourtytwo MUST CREDIT
// Establish all window-related and user input events
ListenToWindowEvents();
window.Paint += WindowPainter;
// Make sure the window closes properly
WindowClosing += delegate { if (IsRunning) Close(); }; // Properly dispose window and end thread.
IsRunning = true;
Application.Run(window);
}
/// <summary>Draws the bitmap onto the window.</summary>
private void WindowPainter(object sender, PaintEventArgs e)
{
// Reset the bitmap's size to fit the screen if the screen's size has changed.
if (oldGraphicsSize != e.Graphics.VisibleClipBounds.Size)
ChangeSize(window.Size);
oldGraphicsSize = e.Graphics.VisibleClipBounds.Size;
e.Graphics.DrawImageUnscaled(bitmap, 0, 0);
}
/// <summary>Execute some delegate on the same thread as the window.
/// Meant for set operations on window properties. Returns true if success.</summary>
private bool CrossThreadWindowOp(MethodInvoker operation)
{
if (!window.IsHandleCreated || window.IsDisposed)
return false;
try
{
window.Invoke(operation);
} catch (ObjectDisposedException) { return false; }
return true;
}
}
}