Net.Like.Xue.Tokyo/Assets/Plugins/Dreamteck/Utilities/Editor/WelcomeWindow.cs

556 lines
19 KiB
C#

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
namespace Dreamteck
{
public class WelcomeWindow : EditorWindow
{
public delegate void EmptyHandler();
protected WindowPanel[] panels = new WindowPanel[0];
protected Texture2D header;
protected static GUIStyle wrapText;
protected static GUIStyle buttonTitleText;
protected static GUIStyle warningText;
protected static GUIStyle titleText;
protected bool _hasSentImageRequest;
protected List<UnityWebRequest> _textureWebRequests;
protected Data _bannerData;
protected string headerTitle = "";
private static bool init = true;
protected virtual Vector2 _windowSize => new Vector2(450, 500);
public virtual void Load()
{
minSize = maxSize = _windowSize;
buttonTitleText = new GUIStyle(GUI.skin.GetStyle("label"));
buttonTitleText.fontStyle = FontStyle.Bold;
titleText = new GUIStyle(GUI.skin.GetStyle("label"));
titleText.fontSize = 25;
titleText.fontStyle = FontStyle.Bold;
titleText.alignment = TextAnchor.MiddleLeft;
titleText.normal.textColor = Color.white;
warningText = new GUIStyle(GUI.skin.GetStyle("label"));
warningText.fontSize = 18;
warningText.fontStyle = FontStyle.Bold;
warningText.normal.textColor = Color.red;
warningText.alignment = TextAnchor.MiddleCenter;
wrapText = new GUIStyle(GUI.skin.GetStyle("label"));
wrapText.wordWrap = true;
init = false;
}
protected virtual void SetTitle(string titleBar, string header)
{
titleContent = new GUIContent(titleBar);
headerTitle = header;
}
protected virtual void GetHeader()
{
header = null;
}
protected void OnEnable()
{
init = true;
}
protected void OnGUI()
{
if (init)
{
Load();
}
if (header == null) GetHeader();
GUI.DrawTexture(new Rect(0, 0, maxSize.x, 82), header, ScaleMode.StretchToFill);
GUI.Label(new Rect(90, 15, Screen.width - 95, 50), headerTitle, titleText);
for (int i = 0; i < panels.Length; i++)
{
panels[i].Draw();
}
Repaint();
}
protected Data LoadBannersData(string url, string savePrefKey)
{
var data = default(Data);
using (var mainDataReq = UnityWebRequest.Get(url))
{
mainDataReq.SendWebRequest();
while (!mainDataReq.isDone || mainDataReq.result == UnityWebRequest.Result.InProgress)
{
}
if (mainDataReq.result == UnityWebRequest.Result.ProtocolError ||
mainDataReq.result == UnityWebRequest.Result.DataProcessingError ||
mainDataReq.result == UnityWebRequest.Result.ConnectionError)
{
Debug.LogError("An error occured while fetching the banners data.");
}
else
{
var jObj = JsonUtility.FromJson<Data>(mainDataReq.downloadHandler.text);
data = new Data();
data.version = jObj.version;
data.banners = jObj.banners;
var currentVersion = EditorPrefs.GetInt(savePrefKey, -1);
if (currentVersion < 0 || currentVersion < data.version)
{
EditorPrefs.SetInt(savePrefKey, data.version);
}
}
}
return data;
}
protected void OnEditorUpdate()
{
if (!_hasSentImageRequest)
{
_hasSentImageRequest = false;
EditorApplication.update -= OnEditorUpdate;
return;
}
for (int i = 0; i < _textureWebRequests.Count; i++)
{
var request = _textureWebRequests[i];
if (!request.isDone || request.result == UnityWebRequest.Result.InProgress)
{
if (request.result == UnityWebRequest.Result.ConnectionError ||
request.result == UnityWebRequest.Result.ProtocolError ||
request.result == UnityWebRequest.Result.DataProcessingError)
{
_textureWebRequests.RemoveAt(i);
i--;
Debug.LogError("A banner request failed for the spline welcome screen! Please investigate!");
}
return;
}
}
for (int i = 0; i < _textureWebRequests.Count; i++)
{
var request = _textureWebRequests[i];
if (request.result == UnityWebRequest.Result.Success)
{
var texture = DownloadHandlerTexture.GetContent(request);
var data = _bannerData.banners[i];
var banner = new WindowPanel.Banner(texture, data.title, data.description, 400f, 70f, new ActionLink(data.forwardUrl));
panels[0].elements.Add(new WindowPanel.Space(400, 10));
panels[0].elements.Add(banner);
request.Dispose();
}
}
DrawFooter();
_hasSentImageRequest = false;
_textureWebRequests.Clear();
_textureWebRequests = null;
EditorApplication.update -= OnEditorUpdate;
}
protected virtual void DrawFooter()
{
}
public class WindowPanel
{
public WindowPanel back = null;
public float slideStart = 0f;
public float slideDuration = 1f;
public enum SlideDiretion { Left, Right, Up, Down }
public SlideDiretion openDirection = SlideDiretion.Left;
public SlideDiretion closeDirection = SlideDiretion.Right;
private Vector2 origin = Vector2.zero;
private bool open = false;
private bool goingBack = false;
public List<Element> elements = new List<Element>();
public WindowPanel(string title, bool o, float slideDur = 1f)
{
slideDuration = slideDur;
SetState(o, false);
}
public WindowPanel(string title, bool o, WindowPanel backPanel, float slideDur = 1f)
{
slideDuration = slideDur;
SetState(o, false);
back = backPanel;
}
public bool isActive
{
get
{
return open || Time.realtimeSinceStartup - slideStart <= slideDuration;
}
}
public void Back()
{
Close(true, true);
back.Open(true, true);
}
public void Close(bool useTransition, bool goBack = false)
{
SetState(false, useTransition, goBack);
}
public void Open(bool useTransition, bool goBack = false)
{
goingBack = false;
SetState(true, useTransition, goBack);
}
Vector2 GetSize()
{
return new Vector2(Screen.width, Screen.height- 82);
}
void HandleOrigin()
{
float percent = Mathf.Clamp01((Time.realtimeSinceStartup - slideStart) / slideDuration);
Vector2 size = GetSize();
SlideDiretion dir = openDirection;
if (goingBack) dir = closeDirection;
if (open)
{
switch (dir)
{
case SlideDiretion.Left:
origin.x = Mathf.SmoothStep(size.x, 0f, percent);
origin.y = 0f;
break;
case SlideDiretion.Right:
origin.x = Mathf.SmoothStep(-size.x, 0f, percent);
origin.y = 0f;
break;
case SlideDiretion.Up:
origin.x = 0f;
origin.y = Mathf.SmoothStep(size.y, 0f, percent);
break;
case SlideDiretion.Down:
origin.x = 0f;
origin.y = Mathf.SmoothStep(-size.y, 0f, percent);
break;
}
}
else
{
switch (dir)
{
case SlideDiretion.Left:
origin.x = Mathf.SmoothStep(0f, -size.x, percent);
origin.y = 0f;
break;
case SlideDiretion.Right:
origin.x = Mathf.SmoothStep(0f, size.x, percent);
origin.y = 0f;
break;
case SlideDiretion.Up:
origin.x = 0f;
origin.y = Mathf.SmoothStep(0f, -size.y, percent);
break;
case SlideDiretion.Down:
origin.x = 0f;
origin.y = Mathf.SmoothStep(0f, -size.y, percent);
break;
}
}
}
void SetState(bool state, bool useTransition, bool goBack = false)
{
if (open == state) return;
open = state;
if (useTransition) slideStart = Time.realtimeSinceStartup;
else slideStart = Time.realtimeSinceStartup + slideDuration;
goingBack = goBack;
}
public void Draw()
{
if (!isActive) return;
HandleOrigin();
Vector2 size = GetSize();
GUILayout.BeginArea(new Rect(origin.x + 25, origin.y + 85, size.x - 25, size.y));
//Back button
if (back != null)
{
if (GUILayout.Button("◄", GUILayout.Width(45), GUILayout.Height(25)))
{
Back();
}
}
for (int i = 0; i < elements.Count; i++) elements[i].Draw();
GUILayout.EndArea();
}
public class Element
{
protected Vector2 size = Vector2.zero;
public ActionLink action = null;
public Element(float x, float y, ActionLink a = null)
{
size = new Vector2(x, y);
action = a;
}
internal virtual void Draw()
{
}
}
public class Space : Element
{
public Space(float x, float y) : base(x, y)
{
}
internal override void Draw()
{
GUILayoutUtility.GetRect(size.x, size.y);
}
}
public class Button : Element
{
string text = "";
public Button(float x, float y, string t, ActionLink a) : base(x, y, a)
{
text = t;
}
internal override void Draw()
{
base.Draw();
if(GUILayout.Button(text, GUILayout.Width(size.x), GUILayout.Height(size.y)))
{
if (action != null) action.Do();
}
}
}
public class Banner : Element
{
private string _title;
private string _description;
private Texture _image;
public Banner(float x, float y, ActionLink a = null) : base(x, y, a) { }
public Banner(Texture image, string title, string description, float x, float y, ActionLink a = null) : this(x, y, a)
{
_title = title;
_description = description;
_image = image;
size = new Vector2(image.width, image.height);
}
internal override void Draw()
{
Rect rect = GUILayoutUtility.GetRect(size.x, size.y);
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
GUI.BeginGroup(rect);
if (GUI.Button(new Rect(0, 0, size.x, size.y), "")) action.Do();
GUI.DrawTexture(new Rect(Vector2.one, size), _image, ScaleMode.StretchToFill);
var hoverRect = new Rect(0, 0, size.x, size.y);
if (hoverRect.Contains(Event.current.mousePosition))
{
EditorGUI.DrawRect(hoverRect, new Color(1, 1, 1, 0.5f));
}
var titleStyle = new GUIStyle();
titleStyle.fontSize = 19;
titleStyle.fontStyle = FontStyle.Bold;
titleStyle.alignment = TextAnchor.MiddleLeft;
titleStyle.normal.textColor = Color.white;
EditorGUI.DropShadowLabel(new Rect(6, 5, 370 - 65, 18), _title, titleStyle);
var descriptionStyle = new GUIStyle();
descriptionStyle.fontSize = 11;
descriptionStyle.wordWrap = true;
descriptionStyle.fontStyle = FontStyle.Bold;
descriptionStyle.alignment = TextAnchor.MiddleLeft;
descriptionStyle.normal.textColor = Color.white;
EditorGUI.DropShadowLabel(new Rect(6, 20, 380, 40), _description, descriptionStyle);
GUI.EndGroup();
GUILayout.Space(5);
}
}
public class Thumbnail : Element
{
private string thumbnailPath = "";
private string thumbnailName = "";
private Texture2D thumbnail = null;
public string title = "";
public string description = "";
public Thumbnail(string path, string fileName, string t, string d, ActionLink a, float x = 400, float y = 60) : base(x, y, a)
{
title = t;
description = d;
thumbnailPath = path;
thumbnailName = fileName;
thumbnail = ResourceUtility.EditorLoadTexture(thumbnailPath, thumbnailName);
}
internal override void Draw()
{
Rect rect = GUILayoutUtility.GetRect(size.x, size.y);
Color buttonColor = Color.clear;
if (rect.Contains(Event.current.mousePosition)) buttonColor = Color.white;
GUI.BeginGroup(rect);
GUI.color = buttonColor;
if (GUI.Button(new Rect(0, 0, size.x, size.y), "")) action.Do();
GUI.color = Color.white;
if (thumbnail != null)
{
Vector2 offset = new Vector2(5, (size.y - 50) / 2);
GUI.DrawTexture(new Rect(offset, Vector2.one * 50), thumbnail, ScaleMode.StretchToFill);
}
GUI.Label(new Rect(60, 5, 370 - 65, 16), title, buttonTitleText);
GUI.Label(new Rect(60, 20, 370 - 65, 40), description, wrapText);
GUI.EndGroup();
GUILayout.Space(5);
}
}
public class ScrollText : Element
{
Vector2 scroll = Vector2.zero;
string text = "";
public ScrollText(float x, float y, string t) : base(x, y)
{
text = t;
}
internal override void Draw()
{
base.Draw();
scroll = GUILayout.BeginScrollView(scroll, GUILayout.Width(size.x), GUILayout.MaxHeight(size.y));
EditorGUILayout.LabelField(text, wrapText, GUILayout.Width(size.x - 30));
GUILayout.EndScrollView();
}
}
public class Label : Element
{
string text = "";
Color color;
GUIStyle style = null;
public Label(string t, GUIStyle s, Color col) : base(400, 30)
{
color = col;
text = t;
style = s;
}
public Label(string t, GUIStyle s, Color col, float x, float y) : base(x, y)
{
color = col;
text = t;
style = s;
}
internal override void Draw()
{
base.Draw();
Color prev = GUI.color;
GUI.color = color;
if(style == null) EditorGUILayout.LabelField(text, GUILayout.Width(size.x), GUILayout.Height(size.y));
else EditorGUILayout.LabelField(text, style, GUILayout.Width(size.x), GUILayout.Height(size.y));
GUI.color = prev;
}
}
}
public class ActionLink {
private string URL = "";
private WindowPanel currentPanel = null;
private WindowPanel targetPanel = null;
private EmptyHandler customHandler = null;
public ActionLink(string u)
{
URL = u;
}
public ActionLink(EmptyHandler handler)
{
customHandler = handler;
}
public ActionLink(WindowPanel target, WindowPanel current)
{
currentPanel = current;
targetPanel = target;
}
public void Do()
{
if (customHandler != null) customHandler();
else if(URL != "") Application.OpenURL(URL);
else if(targetPanel != null && currentPanel != null)
{
currentPanel.Close(true);
targetPanel.Open(true);
}
}
}
[System.Serializable]
public class Data
{
public BannerData[] banners;
public int version;
}
[System.Serializable]
public class BannerData
{
public string title;
public string description;
public string bannerUrl;
public string forwardUrl;
public int height;
}
}
}