-
Notifications
You must be signed in to change notification settings - Fork 2
/
MBW.cs
376 lines (312 loc) · 13.6 KB
/
MBW.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
using System;
using UnityEngine;
using Log = KSPPP.Logging.ConsoleLogger;
namespace KSPPP
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public sealed class WindowInitialsAttribute : Attribute
{
public string Caption { get; set; } // the title of the window
public bool Visible { get; set; } // is this window visible?
public bool IsDragging { get; set; } // is this window being dragged? (moved)
public bool DragEnabled { get; set; } // can this window be dragged?
public bool ClampEnabled { get; set; } // will this window be kept on screen?
public bool TooltipsEnabled { get; set; } // will this window show tooltips?
public bool IsResizing { get; set; } // is this window being resized?
public bool ResizeEnabled { get; set; } // can this window be resized?
public Rect MinSize { get; set; } // the minimum extent of the window
public Rect MaxSize { get; set; } // the maximum extent of the window
}
public abstract class MBW : MBE
{
/*
* MonoBehavior "LifeCycle"
*
* [ Reset ]
* v
* [ Awake ]
* v
* [ OnEnable ]
* v>---------v
* v [ Start ]
* v<---------<
* [ FixedUpdate ]<----o
* v | "Physics Loop"
* [ y4FixedUpdate ] ----o
* v
* [ Update ]
* v
* [ y4null ] -AND-
* [ y4ForSeconds ] -AND-
* [ y4StartLooper]
* v
* [ LateUpdate ]
* v
* [ OnWillRenderObject ]
* v
* ...
* v
* [ OnPostRender ]
* v
* [ OnGUI ]<-----------o "GUI Loop"
* v | 1. <Layout> and <Repaint>
* v | 2. <Layout> and <Keyboard> and <Mouse>
* v---------------o
* [ y4waitEOF ]
* v===========> ^[ FixedUpdate ] "Frame Loop"
* v
* [ OnDisable ]
* v
* [ OnDestroy ]
*
*
* Some notes:
* + These states are **individual** to each gameObject. You can not depend on
* all objects having finished [Start] just because one object is in [FixedUpdate].
* +
* + The "GUI Loop" be run [2..N] times.
* + Adapted from: http://www.richardfine.co.uk/2012/10/unity3d-monobehaviour-lifecycle/
* + Ref: http://docs.unity3d.com/Manual/ExecutionOrder.html
*/
#region "Constructor"
protected MBW() : base() {
//do the assembly name add so we get different windowIDs for multiple plugins
WindowID = UnityEngine.Random.Range(1000, 2000000) + Log._AssemblyName.GetHashCode();
_Visible = false;
Log.Debug("WindowID:{0}", WindowID);
//and look for any customattributes
WindowInitialsAttribute[] attrs = (WindowInitialsAttribute[])Attribute.GetCustomAttributes(GetType(), typeof(WindowInitialsAttribute));
foreach (WindowInitialsAttribute attr in attrs)
{
Visible = attr.Visible;
WindowCaption = attr.Caption;
IsDragging = attr.IsDragging;
DragEnabled = attr.DragEnabled;
ClampEnabled = attr.ClampEnabled;
TooltipsEnabled = attr.TooltipsEnabled;
IsResizing = attr.IsResizing;
ResizeEnabled = attr.ResizeEnabled;
WindowRect_Min = attr.MinSize;
WindowRect_Max = attr.MaxSize;
}
}
#endregion
internal Int32 WindowID { get; private set; }
internal TimeSpan DrawWindowInternalDuration { get; private set; }
private bool _Visible;
protected Rect WindowRect;
protected string WindowCaption;
protected GUIStyle WindowStyle;
internal GUILayoutOption[] WindowOptions;
/* dragging and clamping */
internal Rect DragRect;
public bool DragEnabled = false;
public bool ClampEnabled = true;
internal bool IsDragging = false;
internal RectOffset ClampToScreenOffset = new RectOffset(0, 0, 0, 0);
/* tooltips */
protected bool TooltipShown { get; set; }
internal Rect TooltipPosition { get { return _TooltipPosition; } }
internal Vector2d TooltipMouseOffset = new Vector2d();
private Rect _TooltipPosition = new Rect();
public bool TooltipsEnabled = false;
internal Int32 TooltipDisplayForSecs = 15;
protected Int32 TooltipMaxWidth = 250;
private string strToolTipText = "";
private string strLastTooltipText = "";
private float fltTooltipTime = 0f; // display dt for tooltip
internal bool TooltipStatic = false; // FIXME: unused
/* resizing windows */
public bool ResizeEnabled;
internal bool IsResizing = false;
protected Rect WindowRect_Last;
protected Rect WindowRect_Default;
protected Rect WindowRect_Min;
protected Rect WindowRect_Max;
private static float dragX, dragY;
private static float resizeW = 0, resizeH = 0;
public static bool inRepaint() { return (Event.current.type == EventType.Repaint); }
public static bool inLayout() { return (Event.current.type == EventType.Layout); }
// convenience functions to shorten the task of creating windows
public static void growE() { GUILayout.BeginHorizontal(); }
public static void growS() { GUILayout.BeginVertical(); }
public static void stopE() { GUILayout.EndHorizontal(); }
public static void stopS() { GUILayout.EndVertical(); }
public static void growE(GUIContent c, string s) { GUILayout.BeginHorizontal(c,s); }
public static void growS(GUIContent c, string s) { GUILayout.BeginVertical(c,s); }
public static GUILayoutOption GoE () { return GUILayout.ExpandWidth (true); }
public static GUILayoutOption GoS () { return GUILayout.ExpandHeight (true); }
public static GUILayoutOption NoE () { return GUILayout.ExpandWidth (false); }
public static GUILayoutOption NoS () { return GUILayout.ExpandHeight (false); }
public static GUILayoutOption GoE (bool grow) { return GUILayout.ExpandWidth (grow); }
public static GUILayoutOption GoS (bool grow) { return GUILayout.ExpandHeight (grow); }
// helper functions to include tooltips
public static GUIContent textWithTT (string label, string tooltip) { return new GUIContent(label,tooltip); }
public static GUIContent iconWithTT (Texture tex, string tooltip) { return new GUIContent(tex,tooltip); }
/* resizing functionality */
public void resizeWindow() {
#region top of gui_build()
if (!inRepaint() && IsResizing) {
if (Input.GetMouseButtonUp (0)) {
if (resizeW < WindowRect_Min.width) resizeW = WindowRect_Min.width;
if (resizeH < WindowRect_Min.height) resizeH = WindowRect_Min.height;
if (resizeW > WindowRect_Max.width) resizeW = WindowRect_Max.width;
if (resizeH > WindowRect_Max.height) resizeH = WindowRect_Max.height;
IsResizing = false;
WindowRect_Last = new Rect(0,0,WindowRect.width,WindowRect.height);
} else {
float xx = Input.mousePosition.x;
float yy = Input.mousePosition.y;
resizeW += xx - dragX;
resizeH += yy - dragY;
dragX = xx;
dragY = yy;
WindowRect.width = WindowRect_Last.width + resizeW;
WindowRect.height = WindowRect_Last.height - resizeH;
}
if (Event.current.isMouse) Event.current.Use ();
}
#endregion
// ...
#region middle of gui_build()
float dW = resizeW;
float dH = resizeH;
if (dW < WindowRect_Min.width) dW = WindowRect_Min.width;
if (dH < WindowRect_Min.height) dH = WindowRect_Min.height;
dH = dW / 2f; // aspect ratio fixing
//if (IsResizing) GUILayout.Label("", GUILayout.Width (dW), GUILayout.Height (dH));
//else GUILayout.Label("", map.width, map.height);
//Rect maprect = GUILayoutUtility.GetLastRect ();
//maprect.width = bigmap.mapwidth;
//maprect.height = bigmap.mapheight;
#endregion
// ...
#region later in gui_build()
if (IsResizing) {
//maprect.width = dW;
//maprect.height = dH;
//GUI.DrawTexture (maprect, map, ScaleMode.StretchToFill);
} else {
//GUI.DrawTexture (maprect, map);
}
#endregion
// ...
//float mx = Event.current.mousePosition.x - maprect.x;
//float my = Event.current.mousePosition.y - maprect.y;
// ...
#region fps widget (extra)
//Rect fpswidget = new Rect (maprect.x + maprect.width - 32 , maprect.y + maprect.height + 32 , 32 , 24);
//GUI.Label (fpswidget , fps.Tostring ("N1"));
#endregion
// ...
#region end of gui_build()
//Rect resizer = new Rect (maprect.x + maprect.width - 24 , maprect.y + maprect.height + 8 , 24 , 24);
Rect resizer = new Rect (WindowRect.x + WindowRect.width - 24
,WindowRect.y + WindowRect.height - 24
,24,24);
GUI.Box(resizer,"//",SkinsLibrary.CurrentSkin.box);
if ( Event.current.isMouse
&& Event.current.type == EventType.MouseDown
&& Event.current.button == 0
&& resizer.Contains (Event.current.mousePosition))
{
IsResizing = true;
WindowRect_Last = WindowRect;
dragX = Input.mousePosition.x;
dragY = Input.mousePosition.y;
//resizeW = bigmap.mapwidth;
//resizeH = bigmap.mapheight;
Event.current.Use ();
}
#endregion
}
protected override void Awake() { Log.Debug("New MBWindow Awakened"); }
protected virtual void DrawWindowPre(Int32 id) { }
protected abstract void DrawWindow(Int32 id);
protected virtual void DrawWindowPost(Int32 id) { }
/* tooltip helper functions */
private void SetTooltipText() { if (inRepaint()) { strToolTipText = GUI.tooltip; } }
private bool untimed() { return (TooltipDisplayForSecs == 0); }
private bool hasMoreTime() { return (fltTooltipTime < (float)TooltipDisplayForSecs); }
private bool expired() { return (fltTooltipTime <= 0); }
private bool hasChanged() { return (strToolTipText != strLastTooltipText); }
private bool hasContent() { return (strToolTipText != ""); }
private bool inUseNow() { return ( (untimed() || hasMoreTime()) && (hasContent()) && TooltipsEnabled && Visible); }
public bool Visible {
get { return _Visible; }
set {
if (_Visible != value) {
if (value) {
Log.Debug("Adding Window to PostDrawQueue-{0}", WindowID); RenderingManager.AddToPostDrawQueue(5, this.DrawGUI);
} else {
Log.Debug("Removing Window from PostDrawQueue", WindowID); RenderingManager.RemoveFromPostDrawQueue(5, this.DrawGUI);
}
}
_Visible = value;
}
}
protected void DrawGUI() {
string cc = "";
GUI.skin = SkinsLibrary.CurrentSkin; //this sets the skin on each draw loop
if (ClampEnabled) WindowRect = WindowRect.ClampToScreen(ClampToScreenOffset);
if (ResizeEnabled) cc = WindowCaption + " " + WindowRect.WxH();
else cc = WindowCaption;
if (IsResizing) cc = WindowCaption + " " + WindowRect_Last.WxH () + " -> "+ WindowRect.WxH ();
switch (WindowStyle == null) {
case true: WindowRect = GUILayout.Window(WindowID, WindowRect, DrawWindowInternal, cc, WindowOptions); break;
default: WindowRect = GUILayout.Window(WindowID, WindowRect, DrawWindowInternal, cc, WindowStyle, WindowOptions); break;
}
if (TooltipsEnabled) DrawToolTip(); //Draw the tooltip of its there to be drawn
if (ResizeEnabled) resizeWindow ();
}
private void DrawWindowInternal(Int32 id) {
DateTime Duration = DateTime.Now; // record the start date
DrawWindowPre(id);
DrawWindow(id); // This calls the must be overridden code
DrawWindowPost(id);
if (TooltipsEnabled) SetTooltipText(); //Set the Tooltip variable based on whats in this window
if (ResizeEnabled) { DragRect = new Rect(0,0,WindowRect.width,WindowRect.height); DragRect.height -= 24; }
else { DragRect = new Rect(0,0,0,0); }
if (DragEnabled)
if (DragRect.height == 0 && DragRect.width == 0) GUI.DragWindow();
else GUI.DragWindow(DragRect);
DrawWindowInternalDuration = (DateTime.Now - Duration); //Now calc the duration
}
protected void DrawToolTip() {
// Added drawing check to turn off tooltips when window hides
if (inUseNow()) {
GUIContent contTooltip = new GUIContent(strToolTipText);
GUIStyle styleTooltip = SkinsLibrary.CurrentTooltip;
// if the content of the tooltip changes then reset the counter
if (!TooltipShown || hasChanged()) fltTooltipTime = 0f;
// Calc the size of the Tooltip
_TooltipPosition.x = Event.current.mousePosition.x + (float)TooltipMouseOffset.x;
_TooltipPosition.y = Event.current.mousePosition.y + (float)TooltipMouseOffset.y;
//do max width calc if needed
if (TooltipMaxWidth > 0) {
float minwidth, maxwidth;
SkinsLibrary.CurrentTooltip.CalcMinMaxWidth(contTooltip, out minwidth, out maxwidth); // figure out how wide one line would be
_TooltipPosition.width = Math.Min(TooltipMaxWidth - SkinsLibrary.CurrentTooltip.padding.horizontal, maxwidth); // then work out the height with a max width
_TooltipPosition.height = SkinsLibrary.CurrentTooltip.CalcHeight(contTooltip, TooltipPosition.width); // heres the result
} else { // (TooltipMaxWidth== 0)
Vector2 Size = SkinsLibrary.CurrentTooltip.CalcSize(contTooltip);
_TooltipPosition.width = Size.x;
_TooltipPosition.height = Size.y;
}
styleTooltip.stretchHeight = !(TooltipMaxWidth > 0);
styleTooltip.stretchWidth = !(TooltipMaxWidth > 0);
styleTooltip.wordWrap = (TooltipMaxWidth > 0);
//clamp it accordingly
if (ClampEnabled) _TooltipPosition = _TooltipPosition.ClampToScreen(ClampToScreenOffset);
GUI.Label(TooltipPosition, contTooltip, styleTooltip); // Draw the Tooltip
GUI.depth = 0; // On top of everything
fltTooltipTime += Time.deltaTime; // update how long the tip has been on the screen
TooltipShown = true; // reset the flags
} else {
TooltipShown = false;
} // clear the flags
if (strToolTipText != strLastTooltipText) fltTooltipTime = 0f;
strLastTooltipText = strToolTipText;
}
}
}