Add project files.
This commit is contained in:
34
Assets/Cryville/Common/Unity/CallHelper.cs
Normal file
34
Assets/Cryville/Common/Unity/CallHelper.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
static class CallHelper {
|
||||
public static bool HasFlag(this Enum obj, Enum flag) {
|
||||
ulong num = Convert.ToUInt64(flag);
|
||||
ulong num2 = Convert.ToUInt64(obj);
|
||||
return (num2 & num) == num;
|
||||
}
|
||||
|
||||
public static void ShowException(Exception ex) {
|
||||
ShowMessageBox(ex.ToString());
|
||||
}
|
||||
|
||||
public static void ShowMessageBox(string message) {
|
||||
GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Popup")).GetComponent<Popup>().Message = message;
|
||||
}
|
||||
|
||||
public static void Purge(Transform obj) {
|
||||
foreach (Transform i in obj)
|
||||
GameObject.Destroy(i.gameObject);
|
||||
}
|
||||
|
||||
/*public static void DownloadAndUnzip(string url, FileInfo file) {
|
||||
using (DownloadDialog d = new DownloadDialog()) {
|
||||
d.Download(url, file);
|
||||
}
|
||||
using (ZipFile z = new ZipFile(file.FullName)) {
|
||||
z.ExtractAll(file.DirectoryName, ExtractExistingFileAction.OverwriteSilently);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/CallHelper.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/CallHelper.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98b3d4b7cc1ce054598780159356da35
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
142
Assets/Cryville/Common/Unity/FileDialog.cs
Normal file
142
Assets/Cryville/Common/Unity/FileDialog.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class FileDialog : MonoBehaviour {
|
||||
Transform panel;
|
||||
Transform title;
|
||||
Transform drives;
|
||||
Transform dirs;
|
||||
Transform files;
|
||||
|
||||
public Action Callback { private get; set; }
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR_WIN
|
||||
string androidStorage = "";
|
||||
#endif
|
||||
|
||||
string fileName = "";
|
||||
public string FileName {
|
||||
get { return fileName; }
|
||||
}
|
||||
|
||||
public string[] m_filter = new string[]{};
|
||||
public string[] Filter {
|
||||
set { m_filter = value; }
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
panel = gameObject.transform.Find("Panel");
|
||||
title = panel.Find("Title/Text");
|
||||
drives = panel.Find("Drives/DrivesInner");
|
||||
dirs = panel.Find("Directories/DirectoriesInner");
|
||||
files = panel.Find("Files/FilesInner");
|
||||
if (CurrentDirectory == null) {
|
||||
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
|
||||
CurrentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||
#elif UNITY_ANDROID
|
||||
using (AndroidJavaClass ajc=new AndroidJavaClass("android.os.Environment"))
|
||||
using (AndroidJavaObject file=ajc.CallStatic<AndroidJavaObject>("getExternalStorageDirectory")) {
|
||||
androidStorage = file.Call<string>("getAbsolutePath");
|
||||
CurrentDirectory = new DirectoryInfo(androidStorage);
|
||||
}
|
||||
#else
|
||||
#error No default directory
|
||||
#endif
|
||||
}
|
||||
UpdateGUI();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
public void Show() {
|
||||
fileName = null;
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void Close() {
|
||||
if (Callback != null) Callback.Invoke();
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public DirectoryInfo CurrentDirectory;
|
||||
|
||||
void OnDriveChanged(string s) {
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
CurrentDirectory = new DirectoryInfo(s);
|
||||
#elif UNITY_ANDROID
|
||||
switch (s) {
|
||||
case "?storage":
|
||||
CurrentDirectory = new DirectoryInfo(androidStorage);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
#error No change drive logic
|
||||
#endif
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
void OnDirectoryChanged(string s) {
|
||||
CurrentDirectory = new DirectoryInfo(CurrentDirectory.FullName + "/" + s);
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
void OnFileChanged(string s) {
|
||||
fileName = s;
|
||||
Close();
|
||||
}
|
||||
|
||||
void UpdateGUI() {
|
||||
title.GetComponent<Text>().text = CurrentDirectory.FullName;
|
||||
|
||||
CallHelper.Purge(drives);
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
var dl = Directory.GetLogicalDrives();
|
||||
foreach (string d in dl) {
|
||||
GameObject btn = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Button"));
|
||||
btn.GetComponentInChildren<Text>().text = d;
|
||||
var ts = d;
|
||||
btn.GetComponentInChildren<Button>().onClick.AddListener(() => OnDriveChanged(ts));
|
||||
btn.transform.SetParent(drives, false);
|
||||
}
|
||||
#elif UNITY_ANDROID
|
||||
GameObject sbtn = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Button"));
|
||||
sbtn.GetComponentInChildren<Text>().text = "Storage";
|
||||
sbtn.GetComponentInChildren<Button>().onClick.AddListener(() => OnDriveChanged("?storage"));
|
||||
sbtn.transform.SetParent(drives, false);
|
||||
#else
|
||||
#error No update GUI logic
|
||||
#endif
|
||||
|
||||
CallHelper.Purge(dirs);
|
||||
DirectoryInfo[] subdirs = CurrentDirectory.GetDirectories();
|
||||
GameObject pbtn = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Button"));
|
||||
pbtn.GetComponentInChildren<Text>().text = "..";
|
||||
pbtn.GetComponentInChildren<Button>().onClick.AddListener(() => OnDirectoryChanged(".."));
|
||||
pbtn.transform.SetParent(dirs, false);
|
||||
foreach (DirectoryInfo d in subdirs) {
|
||||
GameObject btn = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Button"));
|
||||
btn.GetComponentInChildren<Text>().text = d.Name;
|
||||
var ts = d.Name;
|
||||
btn.GetComponentInChildren<Button>().onClick.AddListener(() => OnDirectoryChanged(ts));
|
||||
btn.transform.SetParent(dirs, false);
|
||||
}
|
||||
|
||||
CallHelper.Purge(files);
|
||||
FileInfo[] fl = CurrentDirectory.GetFiles();
|
||||
foreach (FileInfo d in fl) {
|
||||
foreach (string ext in m_filter)
|
||||
if (d.Extension == ext) goto ext_matched;
|
||||
continue;
|
||||
ext_matched:
|
||||
GameObject btn = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Button"));
|
||||
btn.GetComponentInChildren<Text>().text = d.Name + " / " + (d.Length / 1024.0).ToString("0.0 KiB");
|
||||
var ts = d.FullName;
|
||||
btn.GetComponentInChildren<Button>().onClick.AddListener(() => OnFileChanged(ts));
|
||||
btn.transform.SetParent(files, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/FileDialog.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/FileDialog.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9865f498871e30548959e6b28f91feae
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
9
Assets/Cryville/Common/Unity/Input.meta
Normal file
9
Assets/Cryville/Common/Unity/Input.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7548d5a078795b04b8c54524389ba0fe
|
||||
folderAsset: yes
|
||||
timeCreated: 1611035780
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
102
Assets/Cryville/Common/Unity/Input/InputHandler.cs
Normal file
102
Assets/Cryville/Common/Unity/Input/InputHandler.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public delegate void InputEventDelegate(InputIdentifier id, InputVector vec);
|
||||
public abstract class InputHandler : IDisposable {
|
||||
public InputEventDelegate Callback { private get; set; }
|
||||
|
||||
~InputHandler() {
|
||||
Dispose(false);
|
||||
}
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public abstract void Activate();
|
||||
public abstract void Deactivate();
|
||||
public abstract void Dispose(bool disposing);
|
||||
public abstract bool IsNullable(int type);
|
||||
public abstract byte GetDimension(int type);
|
||||
public abstract string GetTypeName(int type);
|
||||
public abstract double GetCurrentTimestamp();
|
||||
protected void OnInput(int type, int id, InputVector vec) {
|
||||
if (Callback != null) Callback(new InputIdentifier { Source = new InputSource { Handler = this, Type = type }, Id = id }, vec);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputSource : IEquatable<InputSource> {
|
||||
public InputHandler Handler { get; set; }
|
||||
public int Type { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputSource)) return false;
|
||||
return Equals((InputSource)obj);
|
||||
}
|
||||
public bool Equals(InputSource other) {
|
||||
return Handler == other.Handler && Type == other.Type;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Handler.GetHashCode() ^ Type;
|
||||
}
|
||||
public static bool operator ==(InputSource lhs, InputSource rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputSource lhs, InputSource rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputIdentifier : IEquatable<InputIdentifier> {
|
||||
public InputSource Source { get; set; }
|
||||
public int Id { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputIdentifier)) return false;
|
||||
return Equals((InputIdentifier)obj);
|
||||
}
|
||||
public bool Equals(InputIdentifier other) {
|
||||
return Source == other.Source && Id == other.Id;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Source.GetHashCode() ^ ((Id << 16) | (Id >> 16));
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0},{1}", Source, Id);
|
||||
}
|
||||
public static bool operator ==(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputEvent {
|
||||
public InputIdentifier Id { get; set; }
|
||||
public InputVector From { get; set; }
|
||||
public InputVector To { get; set; }
|
||||
public override string ToString() {
|
||||
return string.Format("[{0}] {1} -> {2}", Id, From, To);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputVector {
|
||||
public double Time { get; set; }
|
||||
public bool IsNull { get; set; }
|
||||
public Vector3 Vector { get; set; }
|
||||
public InputVector(double time) {
|
||||
Time = time;
|
||||
IsNull = true;
|
||||
Vector = default(Vector3);
|
||||
}
|
||||
public InputVector(double time, Vector3 vector) {
|
||||
Time = time;
|
||||
IsNull = false;
|
||||
Vector = vector;
|
||||
}
|
||||
public override string ToString() {
|
||||
if (IsNull) return string.Format("null@{0}", Time);
|
||||
else return string.Format("{0}@{1}", Vector.ToString("G9"), Time);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Unity/Input/InputHandler.cs.meta
Normal file
11
Assets/Cryville/Common/Unity/Input/InputHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 139cf0675329c9d46b902249fecdb500
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
194
Assets/Cryville/Common/Unity/Input/InputManager.cs
Normal file
194
Assets/Cryville/Common/Unity/Input/InputManager.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
/*public class InputManager {
|
||||
int newId = 0;
|
||||
int GetNewId() {
|
||||
newId++;
|
||||
return newId;
|
||||
}
|
||||
PointerHandler ptrHandler;
|
||||
readonly Queue<PointerInfo> ptrEv = new Queue<PointerInfo>();
|
||||
readonly Dictionary<int, PointerInfo> ptr
|
||||
= new Dictionary<int, PointerInfo>();
|
||||
double originTime;
|
||||
void Callback(int id, PointerInfo info) {
|
||||
/*if (info.Phase != PointerPhase.Update)
|
||||
Logger.Log(
|
||||
"main", 0, "Input",
|
||||
"[{0}, p{1}] {2} {3} {4} at {5} (cs:{6}, ori:{7}, prs:{8})",
|
||||
info.EventTime, info.ProcessTime, info.Type,
|
||||
id, info.Phase, info.Position,
|
||||
info.ContactSize, info.Orientation, info.Pressure
|
||||
);*
|
||||
lock (ptrEv) {
|
||||
ptrEv.Enqueue(info);
|
||||
ptr[id] = info;
|
||||
}
|
||||
}
|
||||
public void Init() {
|
||||
try {
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
|
||||
if (WindowsPointerHandler.IsSupported()) {
|
||||
ptrHandler = new WindowsPointerHandler(true, GetNewId, Callback);
|
||||
Logger.Log("main", 1, "Input", "Initialized windows pointer handler");
|
||||
}
|
||||
else if (UnityTouchHandler.IsSupported()) {
|
||||
ptrHandler = new UnityTouchHandler(GetNewId, Callback);
|
||||
Logger.Log("main", 1, "Input", "Initialized multi-platform pointer handler");
|
||||
}
|
||||
}
|
||||
else if (Application.platform == RuntimePlatform.Android) {
|
||||
/*if (AndroidTouchHandler.IsSupported()) {
|
||||
|
||||
}
|
||||
else*
|
||||
if (UnityTouchHandler.IsSupported()) {
|
||||
ptrHandler = new UnityTouchHandler(GetNewId, Callback);
|
||||
Logger.Log("main", 1, "Input", "Initialized multi-platform pointer handler");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*if (UnityPointerHandler.IsSupported()) {
|
||||
enableUnityTouch();
|
||||
}*
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Log("main", 4, "Input", "An error occured while initializing pointer handler:\n{0}", ex);
|
||||
}
|
||||
if (ptrHandler == null) Logger.Log("main", 3, "Input", "Pointer input is not supported on this device");
|
||||
}
|
||||
public void Activate() {
|
||||
if (ptrHandler != null) ptrHandler.Activate();
|
||||
}
|
||||
public void Deactivate() {
|
||||
if (ptrHandler != null) ptrHandler.Deactivate();
|
||||
ptr.Clear(); ptrEv.Clear();
|
||||
}
|
||||
public void Dispose() {
|
||||
ptrHandler.Dispose();
|
||||
}
|
||||
public void EnumeratePtrEvents(Action<PointerInfo> callback) {
|
||||
lock (ptrEv) {
|
||||
while (ptrEv.Count > 0) {
|
||||
var raw = ptrEv.Dequeue();
|
||||
raw.OffsetTime(originTime);
|
||||
callback(raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void EnumeratePointers(Action<PointerInfo> callback) {
|
||||
lock (ptrEv) {
|
||||
var upid = new List<int>();
|
||||
var rmid = new List<int>();
|
||||
foreach (var p in ptr) {
|
||||
var raw = p.Value;
|
||||
if (raw.Phase == PointerPhase.Stationary)
|
||||
raw.EventTime = raw.ProcessTime = Time;
|
||||
else raw.OffsetTime(originTime);
|
||||
callback(raw);
|
||||
if (raw.Phase == PointerPhase.Begin || raw.Phase == PointerPhase.Update)
|
||||
upid.Add(p.Key);
|
||||
if (raw.Phase == PointerPhase.End || raw.Phase == PointerPhase.Cancel)
|
||||
rmid.Add(p.Key);
|
||||
}
|
||||
foreach (var i in upid) {
|
||||
var p = ptr[i];
|
||||
p.Phase = PointerPhase.Stationary;
|
||||
ptr[i] = p;
|
||||
}
|
||||
foreach (var i in rmid) ptr.Remove(i);
|
||||
// Logger.Log("main", 0, "Input", "Ptr count {0}", ptr.Count);
|
||||
}
|
||||
}
|
||||
public double Time {
|
||||
get {
|
||||
if (ptrHandler != null) return ptrHandler.GetCurrentTimestamp() - originTime;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
public void SyncTime(double t) {
|
||||
if (ptrHandler != null) {
|
||||
originTime = ptrHandler.GetCurrentTimestamp() - t;
|
||||
Logger.Log("main", 0, "Input", "Sync time {0}", originTime);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
public class InputManager {
|
||||
static readonly List<Type> HandlerRegistries = new List<Type> {
|
||||
typeof(WindowsPointerHandler),
|
||||
typeof(UnityKeyHandler<UnityKeyboardReceiver>),
|
||||
typeof(UnityKeyHandler<UnityMouseButtonReceiver>),
|
||||
typeof(UnityMouseHandler),
|
||||
typeof(UnityTouchHandler),
|
||||
};
|
||||
readonly List<InputHandler> _handlers = new List<InputHandler>();
|
||||
readonly Dictionary<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||
readonly object _lock = new object();
|
||||
readonly Dictionary<InputIdentifier, InputVector> _vectors = new Dictionary<InputIdentifier, InputVector>();
|
||||
readonly List<InputEvent> _events = new List<InputEvent>();
|
||||
public InputManager() {
|
||||
var cb = new InputEventDelegate(Callback);
|
||||
foreach (var t in HandlerRegistries) {
|
||||
try {
|
||||
if (!typeof(InputHandler).IsAssignableFrom(t)) continue;
|
||||
var h = (InputHandler)ReflectionHelper.InvokeEmptyConstructor(t);
|
||||
h.Callback = Callback;
|
||||
_handlers.Add(h);
|
||||
_timeOrigins.Add(h, 0);
|
||||
Logger.Log("main", 1, "Input", "Initialized {0}", ReflectionHelper.GetSimpleName(t));
|
||||
}
|
||||
catch (TargetInvocationException ex) {
|
||||
Logger.Log("main", 1, "Input", "Cannot initialize {0}: {1}", ReflectionHelper.GetSimpleName(t), ex.InnerException.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Activate() {
|
||||
lock (_lock) {
|
||||
_events.Clear();
|
||||
}
|
||||
foreach (var h in _handlers) h.Activate();
|
||||
}
|
||||
public void SyncTime(double time) {
|
||||
foreach (var h in _handlers) {
|
||||
_timeOrigins[h] = time - h.GetCurrentTimestamp();
|
||||
}
|
||||
}
|
||||
public void Deactivate() {
|
||||
foreach (var h in _handlers) h.Deactivate();
|
||||
}
|
||||
void Callback(InputIdentifier id, InputVector vec) {
|
||||
lock (_lock) {
|
||||
double timeOrigin = _timeOrigins[id.Source.Handler];
|
||||
vec.Time += timeOrigin;
|
||||
InputVector vec0;
|
||||
if (_vectors.TryGetValue(id, out vec0)) {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = vec0,
|
||||
To = vec,
|
||||
});
|
||||
if (vec.IsNull) _vectors.Remove(id);
|
||||
else _vectors[id] = vec;
|
||||
}
|
||||
else {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = new InputVector(vec.Time),
|
||||
To = vec,
|
||||
});
|
||||
_vectors.Add(id, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void EnumerateEvents(Action<InputEvent> cb) {
|
||||
lock (_lock) {
|
||||
foreach (var ev in _events) cb(ev);
|
||||
_events.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/Input/InputManager.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Input/InputManager.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf7daeaf7afb3146b3eea2a07f88055
|
||||
timeCreated: 1611035810
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
528
Assets/Cryville/Common/Unity/Input/Messages.cs
Normal file
528
Assets/Cryville/Common/Unity/Input/Messages.cs
Normal file
@@ -0,0 +1,528 @@
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public enum WindowMessages : uint {
|
||||
WM_NULL = 0x0000,
|
||||
WM_CREATE = 0x0001,
|
||||
WM_DESTROY = 0x0002,
|
||||
WM_MOVE = 0x0003,
|
||||
WM_SIZE = 0x0005,
|
||||
|
||||
WM_ACTIVATE = 0x0006,
|
||||
/*
|
||||
* WM_ACTIVATE state values
|
||||
*/
|
||||
WA_INACTIVE = 0,
|
||||
WA_ACTIVE = 1,
|
||||
WA_CLICKACTIVE = 2,
|
||||
|
||||
WM_SETFOCUS = 0x0007,
|
||||
WM_KILLFOCUS = 0x0008,
|
||||
WM_ENABLE = 0x000A,
|
||||
WM_SETREDRAW = 0x000B,
|
||||
WM_SETTEXT = 0x000C,
|
||||
WM_GETTEXT = 0x000D,
|
||||
WM_GETTEXTLENGTH = 0x000E,
|
||||
WM_PAINT = 0x000F,
|
||||
WM_CLOSE = 0x0010,
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_QUERYENDSESSION = 0x0011,
|
||||
WM_QUERYOPEN = 0x0013,
|
||||
WM_ENDSESSION = 0x0016,
|
||||
//#endif
|
||||
WM_QUIT = 0x0012,
|
||||
WM_ERASEBKGND = 0x0014,
|
||||
WM_SYSCOLORCHANGE = 0x0015,
|
||||
WM_SHOWWINDOW = 0x0018,
|
||||
WM_WININICHANGE = 0x001A,
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_SETTINGCHANGE = WM_WININICHANGE,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
WM_DEVMODECHANGE = 0x001B,
|
||||
WM_ACTIVATEAPP = 0x001C,
|
||||
WM_FONTCHANGE = 0x001D,
|
||||
WM_TIMECHANGE = 0x001E,
|
||||
WM_CANCELMODE = 0x001F,
|
||||
WM_SETCURSOR = 0x0020,
|
||||
WM_MOUSEACTIVATE = 0x0021,
|
||||
WM_CHILDACTIVATE = 0x0022,
|
||||
WM_QUEUESYNC = 0x0023,
|
||||
|
||||
WM_GETMINMAXINFO = 0x0024,
|
||||
WM_PAINTICON = 0x0026,
|
||||
WM_ICONERASEBKGND = 0x0027,
|
||||
WM_NEXTDLGCTL = 0x0028,
|
||||
WM_SPOOLERSTATUS = 0x002A,
|
||||
WM_DRAWITEM = 0x002B,
|
||||
WM_MEASUREITEM = 0x002C,
|
||||
WM_DELETEITEM = 0x002D,
|
||||
WM_VKEYTOITEM = 0x002E,
|
||||
WM_CHARTOITEM = 0x002F,
|
||||
WM_SETFONT = 0x0030,
|
||||
WM_GETFONT = 0x0031,
|
||||
WM_SETHOTKEY = 0x0032,
|
||||
WM_GETHOTKEY = 0x0033,
|
||||
WM_QUERYDRAGICON = 0x0037,
|
||||
WM_COMPAREITEM = 0x0039,
|
||||
//#if(WINVER >= 0x0500)
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_GETOBJECT = 0x003D,
|
||||
//#endif
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
WM_COMPACTING = 0x0041,
|
||||
WM_COMMNOTIFY = 0x0044, /* no longer suported */
|
||||
WM_WINDOWPOSCHANGING = 0x0046,
|
||||
WM_WINDOWPOSCHANGED = 0x0047,
|
||||
|
||||
WM_POWER = 0x0048,
|
||||
/*
|
||||
* wParam for WM_POWER window message and DRV_POWER driver notification
|
||||
*/
|
||||
/*PWR_OK = 1,
|
||||
PWR_FAIL = (-1),
|
||||
PWR_SUSPENDREQUEST = 1,
|
||||
PWR_SUSPENDRESUME = 2,
|
||||
PWR_CRITICALRESUME = 3,*/
|
||||
|
||||
WM_COPYDATA = 0x004A,
|
||||
WM_CANCELJOURNAL = 0x004B,
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_NOTIFY = 0x004E,
|
||||
WM_INPUTLANGCHANGEREQUEST = 0x0050,
|
||||
WM_INPUTLANGCHANGE = 0x0051,
|
||||
WM_TCARD = 0x0052,
|
||||
WM_HELP = 0x0053,
|
||||
WM_USERCHANGED = 0x0054,
|
||||
WM_NOTIFYFORMAT = 0x0055,
|
||||
|
||||
NFR_ANSI = 1,
|
||||
NFR_UNICODE = 2,
|
||||
NF_QUERY = 3,
|
||||
NF_REQUERY = 4,
|
||||
|
||||
WM_CONTEXTMENU = 0x007B,
|
||||
WM_STYLECHANGING = 0x007C,
|
||||
WM_STYLECHANGED = 0x007D,
|
||||
WM_DISPLAYCHANGE = 0x007E,
|
||||
WM_GETICON = 0x007F,
|
||||
WM_SETICON = 0x0080,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_NCCREATE = 0x0081,
|
||||
WM_NCDESTROY = 0x0082,
|
||||
WM_NCCALCSIZE = 0x0083,
|
||||
WM_NCHITTEST = 0x0084,
|
||||
WM_NCPAINT = 0x0085,
|
||||
WM_NCACTIVATE = 0x0086,
|
||||
WM_GETDLGCODE = 0x0087,
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_SYNCPAINT = 0x0088,
|
||||
//#endif
|
||||
WM_NCMOUSEMOVE = 0x00A0,
|
||||
WM_NCLBUTTONDOWN = 0x00A1,
|
||||
WM_NCLBUTTONUP = 0x00A2,
|
||||
WM_NCLBUTTONDBLCLK = 0x00A3,
|
||||
WM_NCRBUTTONDOWN = 0x00A4,
|
||||
WM_NCRBUTTONUP = 0x00A5,
|
||||
WM_NCRBUTTONDBLCLK = 0x00A6,
|
||||
WM_NCMBUTTONDOWN = 0x00A7,
|
||||
WM_NCMBUTTONUP = 0x00A8,
|
||||
WM_NCMBUTTONDBLCLK = 0x00A9,
|
||||
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_NCXBUTTONDOWN = 0x00AB,
|
||||
WM_NCXBUTTONUP = 0x00AC,
|
||||
WM_NCXBUTTONDBLCLK = 0x00AD,
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_INPUT_DEVICE_CHANGE = 0x00FE,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_INPUT = 0x00FF,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
WM_KEYFIRST = 0x0100,
|
||||
WM_KEYDOWN = 0x0100,
|
||||
WM_KEYUP = 0x0101,
|
||||
WM_CHAR = 0x0102,
|
||||
WM_DEADCHAR = 0x0103,
|
||||
WM_SYSKEYDOWN = 0x0104,
|
||||
WM_SYSKEYUP = 0x0105,
|
||||
WM_SYSCHAR = 0x0106,
|
||||
WM_SYSDEADCHAR = 0x0107,
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_UNICHAR = 0x0109,
|
||||
WM_KEYLAST = 0x0109,
|
||||
UNICODE_NOCHAR = 0xFFFF,
|
||||
//#else
|
||||
WM_KEYLAST__WIN2000 = 0x0108,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_STARTCOMPOSITION = 0x010D,
|
||||
WM_IME_ENDCOMPOSITION = 0x010E,
|
||||
WM_IME_COMPOSITION = 0x010F,
|
||||
WM_IME_KEYLAST = 0x010F,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_INITDIALOG = 0x0110,
|
||||
WM_COMMAND = 0x0111,
|
||||
WM_SYSCOMMAND = 0x0112,
|
||||
WM_TIMER = 0x0113,
|
||||
WM_HSCROLL = 0x0114,
|
||||
WM_VSCROLL = 0x0115,
|
||||
WM_INITMENU = 0x0116,
|
||||
WM_INITMENUPOPUP = 0x0117,
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_GESTURE = 0x0119,
|
||||
WM_GESTURENOTIFY = 0x011A,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
WM_MENUSELECT = 0x011F,
|
||||
WM_MENUCHAR = 0x0120,
|
||||
WM_ENTERIDLE = 0x0121,
|
||||
//#if(WINVER >= 0x0500)
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_MENURBUTTONUP = 0x0122,
|
||||
WM_MENUDRAG = 0x0123,
|
||||
WM_MENUGETOBJECT = 0x0124,
|
||||
WM_UNINITMENUPOPUP = 0x0125,
|
||||
WM_MENUCOMMAND = 0x0126,
|
||||
|
||||
//#ifndef _WIN32_WCE
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_CHANGEUISTATE = 0x0127,
|
||||
WM_UPDATEUISTATE = 0x0128,
|
||||
WM_QUERYUISTATE = 0x0129,
|
||||
|
||||
/*
|
||||
* LOWORD(wParam) values in WM_*UISTATE*
|
||||
*/
|
||||
UIS_SET = 1,
|
||||
UIS_CLEAR = 2,
|
||||
UIS_INITIALIZE = 3,
|
||||
|
||||
/*
|
||||
* HIWORD(wParam) values in WM_*UISTATE*
|
||||
*/
|
||||
UISF_HIDEFOCUS = 0x1,
|
||||
UISF_HIDEACCEL = 0x2,
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
UISF_ACTIVE = 0x4,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
//#endif
|
||||
|
||||
//#endif
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
|
||||
WM_CTLCOLORMSGBOX = 0x0132,
|
||||
WM_CTLCOLOREDIT = 0x0133,
|
||||
WM_CTLCOLORLISTBOX = 0x0134,
|
||||
WM_CTLCOLORBTN = 0x0135,
|
||||
WM_CTLCOLORDLG = 0x0136,
|
||||
WM_CTLCOLORSCROLLBAR = 0x0137,
|
||||
WM_CTLCOLORSTATIC = 0x0138,
|
||||
MN_GETHMENU = 0x01E1,
|
||||
|
||||
WM_MOUSEFIRST = 0x0200,
|
||||
WM_MOUSEMOVE = 0x0200,
|
||||
WM_LBUTTONDOWN = 0x0201,
|
||||
WM_LBUTTONUP = 0x0202,
|
||||
WM_LBUTTONDBLCLK = 0x0203,
|
||||
WM_RBUTTONDOWN = 0x0204,
|
||||
WM_RBUTTONUP = 0x0205,
|
||||
WM_RBUTTONDBLCLK = 0x0206,
|
||||
WM_MBUTTONDOWN = 0x0207,
|
||||
WM_MBUTTONUP = 0x0208,
|
||||
WM_MBUTTONDBLCLK = 0x0209,
|
||||
//#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
||||
WM_MOUSEWHEEL = 0x020A,
|
||||
//#endif
|
||||
//#if (_WIN32_WINNT >= 0x0500)
|
||||
WM_XBUTTONDOWN = 0x020B,
|
||||
WM_XBUTTONUP = 0x020C,
|
||||
WM_XBUTTONDBLCLK = 0x020D,
|
||||
//#endif
|
||||
//#if (_WIN32_WINNT >= 0x0600)
|
||||
WM_MOUSEHWHEEL = 0x020E,
|
||||
//#endif
|
||||
|
||||
//#if (_WIN32_WINNT >= 0x0600)
|
||||
WM_MOUSELAST = 0x020E,
|
||||
//#elif (_WIN32_WINNT >= 0x0500)
|
||||
WM_MOUSELAST__WIN2000 = 0x020D,
|
||||
//#elif (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
||||
WM_MOUSELAST__WIN4 = 0x020A,
|
||||
//#else
|
||||
WM_MOUSELAST__WIN3 = 0x0209,
|
||||
//#endif /* (_WIN32_WINNT >= 0x0600) */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0400)
|
||||
/* Value for rolling one detent */
|
||||
WHEEL_DELTA = 120,
|
||||
//GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
|
||||
|
||||
/* Setting to scroll one page for SPI_GET/SETWHEELSCROLLLINES */
|
||||
WHEEL_PAGESCROLL = (uint.MaxValue),
|
||||
//#endif /* _WIN32_WINNT >= 0x0400 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
//GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
|
||||
//GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam))
|
||||
//GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
|
||||
|
||||
/* XButton values are WORD flags */
|
||||
XBUTTON1 = 0x0001,
|
||||
XBUTTON2 = 0x0002,
|
||||
/* Were there to be an XBUTTON3, its value would be 0x0004 */
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
WM_PARENTNOTIFY = 0x0210,
|
||||
WM_ENTERMENULOOP = 0x0211,
|
||||
WM_EXITMENULOOP = 0x0212,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_NEXTMENU = 0x0213,
|
||||
WM_SIZING = 0x0214,
|
||||
WM_CAPTURECHANGED = 0x0215,
|
||||
WM_MOVING = 0x0216,
|
||||
WM_POWERBROADCAST = 0x0218,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_DEVICECHANGE = 0x0219,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_MDICREATE = 0x0220,
|
||||
WM_MDIDESTROY = 0x0221,
|
||||
WM_MDIACTIVATE = 0x0222,
|
||||
WM_MDIRESTORE = 0x0223,
|
||||
WM_MDINEXT = 0x0224,
|
||||
WM_MDIMAXIMIZE = 0x0225,
|
||||
WM_MDITILE = 0x0226,
|
||||
WM_MDICASCADE = 0x0227,
|
||||
WM_MDIICONARRANGE = 0x0228,
|
||||
WM_MDIGETACTIVE = 0x0229,
|
||||
|
||||
|
||||
WM_MDISETMENU = 0x0230,
|
||||
WM_ENTERSIZEMOVE = 0x0231,
|
||||
WM_EXITSIZEMOVE = 0x0232,
|
||||
WM_DROPFILES = 0x0233,
|
||||
WM_MDIREFRESHMENU = 0x0234,
|
||||
|
||||
//#if(WINVER >= 0x0602)
|
||||
WM_POINTERDEVICECHANGE = 0x238,
|
||||
WM_POINTERDEVICEINRANGE = 0x239,
|
||||
WM_POINTERDEVICEOUTOFRANGE = 0x23A,
|
||||
//#endif /* WINVER >= 0x0602 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_TOUCH = 0x0240,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
|
||||
//#if(WINVER >= 0x0602)
|
||||
WM_NCPOINTERUPDATE = 0x0241,
|
||||
WM_NCPOINTERDOWN = 0x0242,
|
||||
WM_NCPOINTERUP = 0x0243,
|
||||
WM_POINTERUPDATE = 0x0245,
|
||||
WM_POINTERDOWN = 0x0246,
|
||||
WM_POINTERUP = 0x0247,
|
||||
WM_POINTERENTER = 0x0249,
|
||||
WM_POINTERLEAVE = 0x024A,
|
||||
WM_POINTERACTIVATE = 0x024B,
|
||||
WM_POINTERCAPTURECHANGED = 0x024C,
|
||||
WM_TOUCHHITTESTING = 0x024D,
|
||||
WM_POINTERWHEEL = 0x024E,
|
||||
WM_POINTERHWHEEL = 0x024F,
|
||||
DM_POINTERHITTEST = 0x0250,
|
||||
WM_POINTERROUTEDTO = 0x0251,
|
||||
WM_POINTERROUTEDAWAY = 0x0252,
|
||||
WM_POINTERROUTEDRELEASED = 0x0253,
|
||||
//#endif /* WINVER >= 0x0602 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_SETCONTEXT = 0x0281,
|
||||
WM_IME_NOTIFY = 0x0282,
|
||||
WM_IME_CONTROL = 0x0283,
|
||||
WM_IME_COMPOSITIONFULL = 0x0284,
|
||||
WM_IME_SELECT = 0x0285,
|
||||
WM_IME_CHAR = 0x0286,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
//#if(WINVER >= 0x0500)
|
||||
WM_IME_REQUEST = 0x0288,
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_KEYDOWN = 0x0290,
|
||||
WM_IME_KEYUP = 0x0291,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#if((_WIN32_WINNT >= 0x0400) || (WINVER >= 0x0500))
|
||||
WM_MOUSEHOVER = 0x02A1,
|
||||
WM_MOUSELEAVE = 0x02A3,
|
||||
//#endif
|
||||
//#if(WINVER >= 0x0500)
|
||||
WM_NCMOUSEHOVER = 0x02A0,
|
||||
WM_NCMOUSELEAVE = 0x02A2,
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_WTSSESSION_CHANGE = 0x02B1,
|
||||
|
||||
WM_TABLET_FIRST = 0x02c0,
|
||||
WM_TABLET_LAST = 0x02df,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_DPICHANGED = 0x02E0,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
//#if(WINVER >= 0x0605)
|
||||
WM_DPICHANGED_BEFOREPARENT = 0x02E2,
|
||||
WM_DPICHANGED_AFTERPARENT = 0x02E3,
|
||||
WM_GETDPISCALEDSIZE = 0x02E4,
|
||||
//#endif /* WINVER >= 0x0605 */
|
||||
|
||||
|
||||
WM_CUT = 0x0300,
|
||||
WM_COPY = 0x0301,
|
||||
WM_PASTE = 0x0302,
|
||||
WM_CLEAR = 0x0303,
|
||||
WM_UNDO = 0x0304,
|
||||
WM_RENDERFORMAT = 0x0305,
|
||||
WM_RENDERALLFORMATS = 0x0306,
|
||||
WM_DESTROYCLIPBOARD = 0x0307,
|
||||
WM_DRAWCLIPBOARD = 0x0308,
|
||||
WM_PAINTCLIPBOARD = 0x0309,
|
||||
WM_VSCROLLCLIPBOARD = 0x030A,
|
||||
WM_SIZECLIPBOARD = 0x030B,
|
||||
WM_ASKCBFORMATNAME = 0x030C,
|
||||
WM_CHANGECBCHAIN = 0x030D,
|
||||
WM_HSCROLLCLIPBOARD = 0x030E,
|
||||
WM_QUERYNEWPALETTE = 0x030F,
|
||||
WM_PALETTEISCHANGING = 0x0310,
|
||||
WM_PALETTECHANGED = 0x0311,
|
||||
WM_HOTKEY = 0x0312,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_PRINT = 0x0317,
|
||||
WM_PRINTCLIENT = 0x0318,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_APPCOMMAND = 0x0319,
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_THEMECHANGED = 0x031A,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_CLIPBOARDUPDATE = 0x031D,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0600)
|
||||
WM_DWMCOMPOSITIONCHANGED = 0x031E,
|
||||
WM_DWMNCRENDERINGCHANGED = 0x031F,
|
||||
WM_DWMCOLORIZATIONCOLORCHANGED= 0x0320,
|
||||
WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
|
||||
//#endif /* _WIN32_WINNT >= 0x0600 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0601)
|
||||
WM_DWMSENDICONICTHUMBNAIL = 0x0323,
|
||||
WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326,
|
||||
//#endif /* _WIN32_WINNT >= 0x0601 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0600)
|
||||
WM_GETTITLEBARINFOEX = 0x033F,
|
||||
//#endif /* WINVER >= 0x0600 */
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_HANDHELDFIRST = 0x0358,
|
||||
WM_HANDHELDLAST = 0x035F,
|
||||
|
||||
WM_AFXFIRST = 0x0360,
|
||||
WM_AFXLAST = 0x037F,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_PENWINFIRST = 0x0380,
|
||||
WM_PENWINLAST = 0x038F,
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_APP = 0x8000,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: All Message Numbers below 0x0400 are RESERVED.
|
||||
*
|
||||
* Private Window Messages Start Here:
|
||||
*/
|
||||
WM_USER = 0x0400,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
|
||||
/* wParam for WM_SIZING message */
|
||||
WMSZ_LEFT = 1,
|
||||
WMSZ_RIGHT = 2,
|
||||
WMSZ_TOP = 3,
|
||||
WMSZ_TOPLEFT = 4,
|
||||
WMSZ_TOPRIGHT = 5,
|
||||
WMSZ_BOTTOM = 6,
|
||||
WMSZ_BOTTOMLEFT = 7,
|
||||
WMSZ_BOTTOMRIGHT = 8,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#ifndef NONCMESSAGES
|
||||
|
||||
/*
|
||||
* WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
|
||||
*/
|
||||
/*HTERROR = (-2),
|
||||
HTTRANSPARENT = (-1),
|
||||
HTNOWHERE = 0,
|
||||
HTCLIENT = 1,
|
||||
HTCAPTION = 2,
|
||||
HTSYSMENU = 3,
|
||||
HTGROWBOX = 4,
|
||||
HTSIZE = HTGROWBOX,
|
||||
HTMENU = 5,
|
||||
HTHSCROLL = 6,
|
||||
HTVSCROLL = 7,
|
||||
HTMINBUTTON = 8,
|
||||
HTMAXBUTTON = 9,
|
||||
HTLEFT = 10,
|
||||
HTRIGHT = 11,
|
||||
HTTOP = 12,
|
||||
HTTOPLEFT = 13,
|
||||
HTTOPRIGHT = 14,
|
||||
HTBOTTOM = 15,
|
||||
HTBOTTOMLEFT = 16,
|
||||
HTBOTTOMRIGHT = 17,
|
||||
HTBORDER = 18,
|
||||
HTREDUCE = HTMINBUTTON,
|
||||
HTZOOM = HTMAXBUTTON,
|
||||
HTSIZEFIRST = HTLEFT,
|
||||
HTSIZELAST = HTBOTTOMRIGHT,
|
||||
//#if(WINVER >= 0x0400)
|
||||
HTOBJECT = 19,
|
||||
HTCLOSE = 20,
|
||||
HTHELP = 21,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/Input/Messages.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Input/Messages.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 466300df0840ba54d95240e3a800a642
|
||||
timeCreated: 1611373988
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
253
Assets/Cryville/Common/Unity/Input/NativeMethods.cs
Normal file
253
Assets/Cryville/Common/Unity/Input/NativeMethods.cs
Normal file
@@ -0,0 +1,253 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
static class NativeMethods {
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MONITORINFO {
|
||||
public int cbSize;
|
||||
public RECT rcMonitor;
|
||||
public RECT rcWork;
|
||||
public uint dwFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT {
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom) {
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public int X {
|
||||
get { return Left; }
|
||||
set {
|
||||
Right -= (Left - value);
|
||||
Left = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Y {
|
||||
get { return Top; }
|
||||
set {
|
||||
Bottom -= (Top - value);
|
||||
Top = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Height {
|
||||
get { return Bottom - Top; }
|
||||
set { Bottom = value + Top; }
|
||||
}
|
||||
|
||||
public int Width {
|
||||
get { return Right - Left; }
|
||||
set { Right = value + Left; }
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetTouchInputInfo(IntPtr hTouchInput, int cInputs, [Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOUCHINPUT {
|
||||
public int x;
|
||||
public int y;
|
||||
public IntPtr hSource;
|
||||
public int dwID;
|
||||
public TOUCHINPUT_Flags dwFlags;
|
||||
public TOUCHINPUT_Mask dwMask;
|
||||
public int dwTime;
|
||||
public IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Flags : int {
|
||||
TOUCHEVENTF_MOVE = 0x0001,
|
||||
TOUCHEVENTF_DOWN = 0x0002,
|
||||
TOUCHEVENTF_UP = 0x0004,
|
||||
TOUCHEVENTF_INRANGE = 0x0008,
|
||||
TOUCHEVENTF_PRIMARY = 0x0010,
|
||||
TOUCHEVENTF_NOCOALESCE = 0x0020,
|
||||
TOUCHEVENTF_PEN = 0x0040,
|
||||
TOUCHEVENTF_PALM = 0x0080,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Mask : int {
|
||||
TOUCHINPUTMASKF_CONTACTAREA = 0x0004,
|
||||
TOUCHINPUTMASKF_EXTRAINFO = 0x0002,
|
||||
TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerInfo(int pointerID, ref POINTER_INFO pPointerInfo);
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct POINTER_INFO {
|
||||
public POINTER_INPUT_TYPE pointerType;
|
||||
public UInt32 pointerId;
|
||||
public UInt32 frameId;
|
||||
public POINTER_FLAGS pointerFlags;
|
||||
public IntPtr sourceDevice;
|
||||
public IntPtr hwndTarget;
|
||||
public POINT ptPixelLocation;
|
||||
public POINT ptHimetricLocation;
|
||||
public POINT ptPixelLocationRaw;
|
||||
public POINT ptHimetricLocationRaw;
|
||||
public UInt32 dwTime;
|
||||
public UInt32 historyCount;
|
||||
public Int32 inputData;
|
||||
public UInt32 dwKeyStates;
|
||||
public UInt64 PerformanceCount;
|
||||
public POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
}
|
||||
public enum POINTER_INPUT_TYPE {
|
||||
PT_POINTER = 0x00000001,
|
||||
PT_TOUCH = 0x00000002,
|
||||
PT_PEN = 0x00000003,
|
||||
PT_MOUSE = 0x00000004,
|
||||
PT_TOUCHPAD = 0x00000005,
|
||||
}
|
||||
[Flags]
|
||||
public enum POINTER_FLAGS {
|
||||
POINTER_FLAG_NONE = 0x00000000,
|
||||
POINTER_FLAG_NEW = 0x00000001,
|
||||
POINTER_FLAG_INRANGE = 0x00000002,
|
||||
POINTER_FLAG_INCONTACT = 0x00000004,
|
||||
POINTER_FLAG_FIRSTBUTTON = 0x00000010,
|
||||
POINTER_FLAG_SECONDBUTTON = 0x00000020,
|
||||
POINTER_FLAG_THIRDBUTTON = 0x00000040,
|
||||
POINTER_FLAG_FOURTHBUTTON = 0x00000080,
|
||||
POINTER_FLAG_FIFTHBUTTON = 0x00000100,
|
||||
POINTER_FLAG_PRIMARY = 0x00002000,
|
||||
POINTER_FLAG_CONFIDENCE = 0x00004000,
|
||||
POINTER_FLAG_CANCELED = 0x00008000,
|
||||
POINTER_FLAG_DOWN = 0x00010000,
|
||||
POINTER_FLAG_UPDATE = 0x00020000,
|
||||
POINTER_FLAG_UP = 0x00040000,
|
||||
POINTER_FLAG_WHEEL = 0x00080000,
|
||||
POINTER_FLAG_HWHEEL = 0x00100000,
|
||||
POINTER_FLAG_CAPTURECHANGED = 0x00200000,
|
||||
POINTER_FLAG_HASTRANSFORM = 0x00400000,
|
||||
}
|
||||
public enum POINTER_BUTTON_CHANGE_TYPE {
|
||||
POINTER_CHANGE_NONE,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT {
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerTouchInfo(int pointerId, ref POINTER_TOUCH_INFO touchInfo);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTER_TOUCH_INFO {
|
||||
public POINTER_INFO pointerInfo;
|
||||
public TOUCH_FLAGS touchFlags;
|
||||
public TOUCH_MASK touchMask;
|
||||
public RECT rcContact;
|
||||
public RECT rcContactRaw;
|
||||
public uint orientation;
|
||||
public uint pressure;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_FLAGS {
|
||||
TOUCH_FLAG_NONE = 0x00000000,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_MASK {
|
||||
TOUCH_MASK_NONE = 0x00000000,
|
||||
TOUCH_MASK_CONTACTAREA = 0x00000001,
|
||||
TOUCH_MASK_ORIENTATION = 0x00000002,
|
||||
TOUCH_MASK_PRESSURE = 0x00000004,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr EnableMouseInPointer(bool value);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetCurrentThreadId();
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd,IntPtr lParam);
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool EnumThreadWindows(uint dwThreadId, EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
public static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RegisterTouchWindow(IntPtr hWnd, TOUCH_WINDOW_FLAGS ulFlags);
|
||||
[Flags]
|
||||
public enum TOUCH_WINDOW_FLAGS {
|
||||
TWF_FINETOUCH = 1,
|
||||
TWF_WANTPALM = 2,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnregisterTouchWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern void CloseTouchInputHandle(IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern ushort GlobalAddAtom(string lpString);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
public static extern ushort GlobalDeleteAtom(ushort nAtom);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int SetProp(IntPtr hWnd, string lpString, int hData);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int RemoveProp(IntPtr hWnd, string lpString);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceFrequency(out Int64 lpFrequency);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceCounter(out Int64 lpPerformanceCount);
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/Input/NativeMethods.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Input/NativeMethods.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6ff72ea2b7f71345aa19940faf026e8
|
||||
timeCreated: 1622589747
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
57
Assets/Cryville/Common/Unity/Input/PointerHandler.cs
Normal file
57
Assets/Cryville/Common/Unity/Input/PointerHandler.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
#if false
|
||||
[Obsolete]
|
||||
public abstract class PointerHandler {
|
||||
protected Func<int> newIdCallback;
|
||||
protected Action<int, PointerInfo> callback;
|
||||
|
||||
public PointerHandler(Func<int> newIdCallback, Action<int, PointerInfo> callback) {
|
||||
this.newIdCallback = newIdCallback;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public abstract void Activate();
|
||||
public abstract void Deactivate();
|
||||
|
||||
public abstract void Dispose();
|
||||
|
||||
public abstract double GetCurrentTimestamp();
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public struct PointerInfo {
|
||||
public int Id;
|
||||
public double EventTime;
|
||||
public double ProcessTime;
|
||||
public PointerPhase Phase;
|
||||
public PointerType Type;
|
||||
public Vector2 Position;
|
||||
public Vector2? ContactSize;
|
||||
public uint? Orientation;
|
||||
public uint? Pressure;
|
||||
public double Time {
|
||||
// get { return EventTime == 0 ? ProcessTime : EventTime; }
|
||||
get { return ProcessTime; }
|
||||
}
|
||||
public void OffsetTime(double originTime) {
|
||||
if (EventTime != 0) EventTime -= originTime;
|
||||
if (ProcessTime != 0) ProcessTime -= originTime;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public enum PointerPhase {
|
||||
Begin = 0,
|
||||
Update = 2, Stationary = 3,
|
||||
End = 4, Cancel = 5
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public enum PointerType {
|
||||
Unknown, Mouse, Touch, Pen, TouchPad
|
||||
}
|
||||
#endif
|
||||
}
|
12
Assets/Cryville/Common/Unity/Input/PointerHandler.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Input/PointerHandler.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f0a4eae2ebff4d4d93e2f9fe31c1383
|
||||
timeCreated: 1611272693
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
112
Assets/Cryville/Common/Unity/Input/UnityKeyHandler.cs
Normal file
112
Assets/Cryville/Common/Unity/Input/UnityKeyHandler.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class UnityKeyHandler<T> : InputHandler where T : UnityKeyReceiver<T> {
|
||||
GameObject receiver;
|
||||
T recvcomp;
|
||||
|
||||
public UnityKeyHandler() { }
|
||||
|
||||
public override void Activate() {
|
||||
receiver = new GameObject("__keyrecv__");
|
||||
recvcomp = receiver.AddComponent<T>();
|
||||
recvcomp.SetCallback(OnInput);
|
||||
}
|
||||
|
||||
public override void Deactivate() {
|
||||
if (receiver) GameObject.Destroy(receiver);
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
return recvcomp.GetKeyName(type);
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
return Time.timeAsDouble;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class UnityKeyReceiver<T> : MonoBehaviour where T : UnityKeyReceiver<T> {
|
||||
protected Action<int, int, InputVector> Callback;
|
||||
protected readonly List<int> Keys = new List<int>();
|
||||
public void SetCallback(Action<int, int, InputVector> h) {
|
||||
Callback = h;
|
||||
}
|
||||
public abstract string GetKeyName(int type);
|
||||
void Update() {
|
||||
double time = Time.timeAsDouble;
|
||||
foreach (var k in Keys) {
|
||||
Callback(k, 0, new InputVector(time, Vector3.zero));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UnityKeyboardReceiver : UnityKeyReceiver<UnityKeyboardReceiver> {
|
||||
public override string GetKeyName(int type) {
|
||||
return Enum.GetName(typeof(KeyCode), type);
|
||||
}
|
||||
void OnGUI() {
|
||||
var e = Event.current;
|
||||
if (e.keyCode == KeyCode.None) return;
|
||||
double time = Time.timeAsDouble;
|
||||
var key = (int)e.keyCode;
|
||||
switch (e.type) {
|
||||
case EventType.KeyDown:
|
||||
if (!Keys.Contains(key)) {
|
||||
Callback(key, 0, new InputVector(time, Vector3.zero));
|
||||
Keys.Add(key);
|
||||
}
|
||||
break;
|
||||
case EventType.KeyUp:
|
||||
Keys.Remove(key);
|
||||
Callback(key, 0, new InputVector(time));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UnityMouseButtonReceiver : UnityKeyReceiver<UnityMouseButtonReceiver> {
|
||||
public override string GetKeyName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Left";
|
||||
case 1: return "Right";
|
||||
case 2: return "Middle";
|
||||
default: return string.Format("Button {0}", type);
|
||||
}
|
||||
}
|
||||
void OnGUI() {
|
||||
var e = Event.current;
|
||||
double time = Time.timeAsDouble;
|
||||
var key = e.button;
|
||||
switch (e.type) {
|
||||
case EventType.MouseDown:
|
||||
if (!Keys.Contains(key)) {
|
||||
Callback(key, 0, new InputVector(time, Vector3.zero));
|
||||
Keys.Add(key);
|
||||
}
|
||||
break;
|
||||
case EventType.MouseUp:
|
||||
Keys.Remove(key);
|
||||
Callback(key, 0, new InputVector(time));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Unity/Input/UnityKeyHandler.cs.meta
Normal file
11
Assets/Cryville/Common/Unity/Input/UnityKeyHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8aa36fa1966064f489cf5c318f576d3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
64
Assets/Cryville/Common/Unity/Input/UnityMouseHandler.cs
Normal file
64
Assets/Cryville/Common/Unity/Input/UnityMouseHandler.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class UnityMouseHandler : InputHandler {
|
||||
GameObject receiver;
|
||||
|
||||
public UnityMouseHandler() {
|
||||
if (!unity::Input.mousePresent) {
|
||||
throw new NotSupportedException("Unity mouse is not supported on this device");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Activate() {
|
||||
receiver = new GameObject("__mouserecv__");
|
||||
receiver.AddComponent<UnityMouseReceiver>().SetHandler(this);
|
||||
}
|
||||
|
||||
public override void Deactivate() {
|
||||
if (receiver) GameObject.Destroy(receiver);
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
|
||||
return 2;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Unity Mouse";
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type));
|
||||
}
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
return Time.timeAsDouble;
|
||||
}
|
||||
|
||||
public class UnityMouseReceiver : MonoBehaviour {
|
||||
UnityMouseHandler handler;
|
||||
public void SetHandler(UnityMouseHandler h) {
|
||||
handler = h;
|
||||
}
|
||||
void Update() {
|
||||
double time = Time.timeAsDouble;
|
||||
Vector2 pos = unity::Input.mousePosition;
|
||||
pos.y = Screen.height - pos.y;
|
||||
handler.OnInput(0, 0, new InputVector(time, pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Unity/Input/UnityMouseHandler.cs.meta
Normal file
11
Assets/Cryville/Common/Unity/Input/UnityMouseHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 946e4d6c783bbd645a484b5612476526
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
74
Assets/Cryville/Common/Unity/Input/UnityTouchHandler.cs
Normal file
74
Assets/Cryville/Common/Unity/Input/UnityTouchHandler.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using unity = UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class UnityTouchHandler : InputHandler {
|
||||
GameObject receiver;
|
||||
|
||||
public UnityTouchHandler() {
|
||||
if (!unity::Input.touchSupported) {
|
||||
throw new NotSupportedException("Unity touch is not supported on this device");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Activate() {
|
||||
receiver = new GameObject("__touchrecv__");
|
||||
receiver.AddComponent<UnityPointerReceiver>().SetHandler(this);
|
||||
}
|
||||
|
||||
public override void Deactivate() {
|
||||
if (receiver) GameObject.Destroy(receiver);
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
|
||||
return true;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
|
||||
return 2;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Unity Touch";
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type));
|
||||
}
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
return Time.timeAsDouble;
|
||||
}
|
||||
|
||||
public class UnityPointerReceiver : MonoBehaviour {
|
||||
UnityTouchHandler handler;
|
||||
public void SetHandler(UnityTouchHandler h) {
|
||||
handler = h;
|
||||
}
|
||||
void Update() {
|
||||
double time = Time.timeAsDouble;
|
||||
for (int i = 0; i < unity::Input.touchCount; i++) {
|
||||
var t = unity::Input.GetTouch(i);
|
||||
Vector2 pos = t.position;
|
||||
pos.y = Screen.height - pos.y;
|
||||
var vec = new InputVector(time, pos);
|
||||
if (t.phase == TouchPhase.Began || t.phase == TouchPhase.Stationary || t.phase == TouchPhase.Moved) {
|
||||
handler.OnInput(0, t.fingerId, vec);
|
||||
}
|
||||
else if (t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled) {
|
||||
handler.OnInput(0, t.fingerId, vec);
|
||||
handler.OnInput(0, t.fingerId, new InputVector(time));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/Input/UnityTouchHandler.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Input/UnityTouchHandler.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93f60577ebaa5824dba5f322bbd1ad26
|
||||
timeCreated: 1618910605
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
360
Assets/Cryville/Common/Unity/Input/WindowsPointerHandler.cs
Normal file
360
Assets/Cryville/Common/Unity/Input/WindowsPointerHandler.cs
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* @author Valentin Simonov / http://va.lent.in/
|
||||
* @author Valentin Frolov
|
||||
* @author Andrew David Griffiths
|
||||
* @author Cryville:Lime
|
||||
*/
|
||||
using AOT;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class WindowsPointerHandler : InputHandler {
|
||||
static WindowsPointerHandler Instance;
|
||||
|
||||
const string PRESS_AND_HOLD_ATOM = "MicrosoftTabletPenServiceProperty";
|
||||
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
public const int MONITOR_DEFAULTTONEAREST = 2;
|
||||
readonly IntPtr hMainWindow;
|
||||
IntPtr oldWndProcPtr;
|
||||
IntPtr newWndProcPtr;
|
||||
WndProcDelegate newWndProc;
|
||||
ushort pressAndHoldAtomID;
|
||||
|
||||
readonly int touchInputSize;
|
||||
readonly long freq;
|
||||
static bool usePointerMessage;
|
||||
|
||||
public WindowsPointerHandler() {
|
||||
if (Instance != null)
|
||||
throw new InvalidOperationException("WindowsPointerHandler already created");
|
||||
Instance = this;
|
||||
usePointerMessage = true;
|
||||
|
||||
hMainWindow = GetUnityWindowHandle();
|
||||
if (hMainWindow == IntPtr.Zero) {
|
||||
throw new InvalidOperationException("Cannot find the game window");
|
||||
}
|
||||
NativeMethods.QueryPerformanceFrequency(out freq);
|
||||
retry:
|
||||
if (usePointerMessage) {
|
||||
try {
|
||||
NativeMethods.EnableMouseInPointer(true);
|
||||
Logger.Log("main", 0, "Input", "Touch input frequency: {0}", freq);
|
||||
}
|
||||
catch (TypeLoadException) {
|
||||
usePointerMessage = false;
|
||||
Logger.Log("main", 2, "Input", "Advanced touch handling not supported");
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else {
|
||||
touchInputSize = Marshal.SizeOf(typeof(NativeMethods.TOUCHINPUT));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Activate() {
|
||||
RegisterWindowProc(WndProc);
|
||||
if (!NativeMethods.RegisterTouchWindow(hMainWindow, NativeMethods.TOUCH_WINDOW_FLAGS.TWF_WANTPALM)) {
|
||||
throw new InvalidOperationException("Failed to register touch window");
|
||||
}
|
||||
DisablePressAndHold();
|
||||
}
|
||||
|
||||
public override void Deactivate() {
|
||||
EnablePressAndHold();
|
||||
if (!NativeMethods.UnregisterTouchWindow(hMainWindow)) {
|
||||
throw new InvalidOperationException("Failed to unregister touch window");
|
||||
}
|
||||
UnregisterWindowProc();
|
||||
}
|
||||
|
||||
void RegisterWindowProc(WndProcDelegate windowProc) {
|
||||
newWndProc = windowProc;
|
||||
newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newWndProc);
|
||||
oldWndProcPtr = SetWindowLongPtr(hMainWindow, -4, newWndProcPtr);
|
||||
}
|
||||
|
||||
void UnregisterWindowProc() {
|
||||
SetWindowLongPtr(hMainWindow, -4, oldWndProcPtr);
|
||||
newWndProcPtr = IntPtr.Zero;
|
||||
newWndProc = null;
|
||||
}
|
||||
|
||||
public const int TABLET_DISABLE_PRESSANDHOLD = 0x00000001;
|
||||
public const int TABLET_DISABLE_PENTAPFEEDBACK = 0x00000008;
|
||||
public const int TABLET_DISABLE_PENBARRELFEEDBACK = 0x00000010;
|
||||
public const int TABLET_DISABLE_FLICKS = 0x00010000;
|
||||
|
||||
protected void DisablePressAndHold() {
|
||||
pressAndHoldAtomID = NativeMethods.GlobalAddAtom(PRESS_AND_HOLD_ATOM);
|
||||
NativeMethods.SetProp(hMainWindow, PRESS_AND_HOLD_ATOM,
|
||||
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
|
||||
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
|
||||
TABLET_DISABLE_FLICKS // disables pen flicks (back, forward, drag down, drag up);
|
||||
);
|
||||
}
|
||||
|
||||
protected void EnablePressAndHold() {
|
||||
if (pressAndHoldAtomID != 0) {
|
||||
NativeMethods.RemoveProp(hMainWindow, PRESS_AND_HOLD_ATOM);
|
||||
NativeMethods.GlobalDeleteAtom(pressAndHoldAtomID);
|
||||
}
|
||||
}
|
||||
|
||||
const string UnityWindowClassName = "UnityWndClass";
|
||||
|
||||
static IntPtr _windowHandle;
|
||||
public static IntPtr GetUnityWindowHandle() {
|
||||
uint threadId = NativeMethods.GetCurrentThreadId();
|
||||
NativeMethods.EnumThreadWindows(
|
||||
threadId,
|
||||
UnityWindowFilter,
|
||||
IntPtr.Zero
|
||||
);
|
||||
return _windowHandle;
|
||||
}
|
||||
|
||||
[MonoPInvokeCallback(typeof(NativeMethods.EnumWindowsProc))]
|
||||
public static bool UnityWindowFilter(IntPtr hWnd, IntPtr lParam) {
|
||||
var classText = new StringBuilder(UnityWindowClassName.Length + 1);
|
||||
NativeMethods.GetClassName(hWnd, classText, classText.Capacity);
|
||||
if (classText.ToString() == UnityWindowClassName) {
|
||||
_windowHandle = hWnd;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Windows Pointer Unknown";
|
||||
case 1: return "Windows Pointer Pointer";
|
||||
case 2: return "Windows Pointer Touch";
|
||||
case 3: return "Windows Pointer Pen";
|
||||
case 4: return "Windows Pointer Mouse";
|
||||
case 5: return "Windows Pointer Touch Pad";
|
||||
case 255: return "Windows Touch";
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type));
|
||||
}
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
long tick;
|
||||
NativeMethods.QueryPerformanceCounter(out tick);
|
||||
return (double)tick / freq;
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
Deactivate();
|
||||
if (usePointerMessage)
|
||||
NativeMethods.EnableMouseInPointer(false);
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
[MonoPInvokeCallback(typeof(WndProcDelegate))]
|
||||
static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) {
|
||||
try {
|
||||
var m = (WindowMessages)msg;
|
||||
/*if (m >= WindowMessages.WM_MOUSEFIRST && m <= WindowMessages.WM_MOUSELAST) {
|
||||
if (!usePointerMessage)
|
||||
Instance.handleMouseMsg(msg, wParam, lParam);
|
||||
}
|
||||
else*/
|
||||
switch (m) {
|
||||
case WindowMessages.WM_TOUCH:
|
||||
if (usePointerMessage)
|
||||
NativeMethods.CloseTouchInputHandle(lParam);
|
||||
else
|
||||
Instance.HandleTouchMsg(wParam, lParam);
|
||||
break;
|
||||
case WindowMessages.WM_POINTERDOWN:
|
||||
case WindowMessages.WM_POINTERUP:
|
||||
case WindowMessages.WM_POINTERUPDATE:
|
||||
if (usePointerMessage)
|
||||
Instance.HandlePointerMsg(msg, wParam, lParam);
|
||||
break;
|
||||
case WindowMessages.WM_CLOSE:
|
||||
Instance.Dispose();
|
||||
// Calling oldWndProcPtr here would crash the application
|
||||
Application.Quit();
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
return NativeMethods.CallWindowProc(Instance.oldWndProcPtr, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Log("main", 4, "Input", "An error occured while handling pointer:\n{0}", ex);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePointerMsg(uint msg, IntPtr wParam, IntPtr lParam) {
|
||||
int id = LOWORD(wParam.ToInt32());
|
||||
|
||||
var rawpinfo = new NativeMethods.POINTER_INFO();
|
||||
if (!NativeMethods.GetPointerInfo(id, ref rawpinfo))
|
||||
throw new InvalidOperationException("Failed to get pointer info");
|
||||
|
||||
/*
|
||||
Vector2? _cs = null;
|
||||
uint? orientation = null;
|
||||
uint? pressure = null;
|
||||
if (pointerInfo.pointerType == NativeMethods.POINTER_INPUT_TYPE.PT_TOUCH) {
|
||||
var pointerTouchInfo = new NativeMethods.POINTER_TOUCH_INFO();
|
||||
NativeMethods.GetPointerTouchInfo(pointerId, ref pointerTouchInfo);
|
||||
if (pointerTouchInfo.touchMask.HasFlag(NativeMethods.TOUCH_MASK.TOUCH_MASK_CONTACTAREA)) {
|
||||
Vector2 cs;
|
||||
cs.x = pointerTouchInfo.rcContact.Width;
|
||||
cs.y = pointerTouchInfo.rcContact.Height;
|
||||
_cs = cs;
|
||||
}
|
||||
if (pointerTouchInfo.touchMask.HasFlag(NativeMethods.TOUCH_MASK.TOUCH_MASK_ORIENTATION)) {
|
||||
orientation = pointerTouchInfo.orientation;
|
||||
}
|
||||
if (pointerTouchInfo.touchMask.HasFlag(NativeMethods.TOUCH_MASK.TOUCH_MASK_PRESSURE)) {
|
||||
pressure = pointerTouchInfo.pressure;
|
||||
}
|
||||
}*/
|
||||
|
||||
NativeMethods.POINT p = rawpinfo.ptPixelLocation;
|
||||
NativeMethods.ScreenToClient(hMainWindow, ref p);
|
||||
Vector2 _p = new Vector2(p.X, p.Y);
|
||||
|
||||
double time = (double)rawpinfo.PerformanceCount / freq;
|
||||
|
||||
int type;
|
||||
switch (rawpinfo.pointerType) {
|
||||
case NativeMethods.POINTER_INPUT_TYPE.PT_POINTER : type = 1; break;
|
||||
case NativeMethods.POINTER_INPUT_TYPE.PT_TOUCH : type = 2; break;
|
||||
case NativeMethods.POINTER_INPUT_TYPE.PT_PEN : type = 3; break;
|
||||
case NativeMethods.POINTER_INPUT_TYPE.PT_MOUSE : type = 4; break;
|
||||
case NativeMethods.POINTER_INPUT_TYPE.PT_TOUCHPAD: type = 5; break;
|
||||
default: type = 0; break;
|
||||
}
|
||||
if (rawpinfo.pointerFlags.HasFlag(NativeMethods.POINTER_FLAGS.POINTER_FLAG_CANCELED)) {
|
||||
OnInput(type, id, new InputVector(time));
|
||||
return;
|
||||
}
|
||||
|
||||
InputVector vec = new InputVector(time, _p);
|
||||
|
||||
switch ((WindowMessages)msg) {
|
||||
case WindowMessages.WM_POINTERDOWN:
|
||||
case WindowMessages.WM_POINTERUPDATE:
|
||||
OnInput(type, id, vec);
|
||||
break;
|
||||
case WindowMessages.WM_POINTERUP:
|
||||
OnInput(type, id, vec);
|
||||
OnInput(type, id, new InputVector(time));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*void handleMouseMsg(uint msg, IntPtr wParam, IntPtr lParam) {
|
||||
int id = mouseId;
|
||||
double procTime = diag::Stopwatch.GetTimestamp()
|
||||
/ (double)diag::Stopwatch.Frequency;
|
||||
Vector2 _p;
|
||||
_p.x = ((int)(short)LOWORD(lParam.ToInt32()));
|
||||
_p.y = ((int)(short)HIWORD(lParam.ToInt32()));
|
||||
PointerPhase phase;
|
||||
switch ((WindowMessages)msg) {
|
||||
case WindowMessages.WM_LBUTTONDOWN:
|
||||
case WindowMessages.WM_LBUTTONDBLCLK:
|
||||
phase = PointerPhase.Begin;
|
||||
id = mouseId = newIdCallback();
|
||||
break;
|
||||
case WindowMessages.WM_MOUSEMOVE:
|
||||
if (mouseId == 0)
|
||||
return;
|
||||
phase = PointerPhase.Update;
|
||||
break;
|
||||
case WindowMessages.WM_LBUTTONUP:
|
||||
phase = PointerPhase.End;
|
||||
mouseId = 0;
|
||||
break;
|
||||
case WindowMessages.WM_MOUSELEAVE:
|
||||
phase = PointerPhase.Cancel;
|
||||
mouseId = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
callback(id, new PointerInfo() {
|
||||
Id = id,
|
||||
ProcessTime = procTime,
|
||||
Phase = phase,
|
||||
Type = PointerType.Mouse,
|
||||
Position = _p,
|
||||
});
|
||||
}*/
|
||||
|
||||
void HandleTouchMsg(IntPtr wParam, IntPtr lParam) {
|
||||
int inputCount = LOWORD(wParam.ToInt32());
|
||||
NativeMethods.TOUCHINPUT[] inputs = new NativeMethods.TOUCHINPUT[inputCount];
|
||||
|
||||
if (!NativeMethods.GetTouchInputInfo(lParam, inputCount, inputs, touchInputSize))
|
||||
throw new InvalidOperationException("Failed to get touch input info");
|
||||
|
||||
for (int i = 0; i < inputCount; i++) {
|
||||
NativeMethods.TOUCHINPUT touch = inputs[i];
|
||||
|
||||
NativeMethods.POINT p = new NativeMethods.POINT {
|
||||
X = touch.x / 100,
|
||||
Y = touch.y / 100
|
||||
};
|
||||
NativeMethods.ScreenToClient(hMainWindow, ref p);
|
||||
Vector2 _p = new Vector2(p.X, p.Y);
|
||||
|
||||
/*Vector2? _cs = null;
|
||||
if (touch.dwMask.HasFlag(NativeMethods.TOUCHINPUT_Mask.TOUCHINPUTMASKF_CONTACTAREA)) {
|
||||
Vector2 cs;
|
||||
cs.x = touch.cxContact / 100;
|
||||
cs.y = touch.cyContact / 100;
|
||||
_cs = cs;
|
||||
}*/
|
||||
|
||||
int id = touch.dwID;
|
||||
double time = touch.dwTime / 1000.0;
|
||||
InputVector vec = new InputVector(time, _p);
|
||||
|
||||
if (touch.dwFlags.HasFlag(NativeMethods.TOUCHINPUT_Flags.TOUCHEVENTF_MOVE) ||
|
||||
touch.dwFlags.HasFlag(NativeMethods.TOUCHINPUT_Flags.TOUCHEVENTF_DOWN)) {
|
||||
OnInput(255, id, vec);
|
||||
}
|
||||
else if (touch.dwFlags.HasFlag(NativeMethods.TOUCHINPUT_Flags.TOUCHEVENTF_UP)) {
|
||||
OnInput(255, id, vec);
|
||||
OnInput(255, id, new InputVector(time));
|
||||
}
|
||||
}
|
||||
|
||||
NativeMethods.CloseTouchInputHandle(lParam);
|
||||
}
|
||||
|
||||
public static int LOWORD(int value) {
|
||||
return value & 0xffff;
|
||||
}
|
||||
|
||||
public static int HIWORD(int value) {
|
||||
return (value & (0xffff << 16)) >> 16;
|
||||
}
|
||||
|
||||
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong) {
|
||||
if (IntPtr.Size == 8)
|
||||
return NativeMethods.SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
|
||||
return new IntPtr(NativeMethods.SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1b353deb73c51b409b15e54c54a6bb1
|
||||
timeCreated: 1611282071
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
138
Assets/Cryville/Common/Unity/NetworkTaskWorker.cs
Normal file
138
Assets/Cryville/Common/Unity/NetworkTaskWorker.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.Rendering;
|
||||
using static UnityEngine.Networking.UnityWebRequest;
|
||||
|
||||
#endif
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class NetworkTaskWorker {
|
||||
bool suspended;
|
||||
NetworkTask currentNetworkTask;
|
||||
readonly Queue<NetworkTask> networkTasks = new Queue<NetworkTask>();
|
||||
|
||||
public int TaskCount { get { return networkTasks.Count; } }
|
||||
|
||||
public void SubmitNetworkTask(NetworkTask task) {
|
||||
networkTasks.Enqueue(task);
|
||||
}
|
||||
|
||||
public WorkerStatus TickBackgroundTasks() {
|
||||
if (suspended) return WorkerStatus.Suspended;
|
||||
if (currentNetworkTask != null) {
|
||||
if (currentNetworkTask.Canceled) currentNetworkTask = null;
|
||||
else if (currentNetworkTask.Done()) currentNetworkTask = null;
|
||||
}
|
||||
while (networkTasks.Count > 0 && currentNetworkTask == null) {
|
||||
var task = networkTasks.Dequeue();
|
||||
if (task.Canceled) continue;
|
||||
currentNetworkTask = task;
|
||||
currentNetworkTask.Start();
|
||||
}
|
||||
return currentNetworkTask == null ? WorkerStatus.Idle : WorkerStatus.Working;
|
||||
}
|
||||
|
||||
public void SuspendBackgroundTasks() {
|
||||
suspended = true;
|
||||
if (currentNetworkTask != null) {
|
||||
currentNetworkTask.Cancel();
|
||||
currentNetworkTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResumeBackgroundTasks() {
|
||||
suspended = false;
|
||||
}
|
||||
}
|
||||
|
||||
public enum WorkerStatus {
|
||||
Idle, Working, Suspended,
|
||||
}
|
||||
|
||||
public abstract class NetworkTask {
|
||||
protected NetworkTask(string uri) {
|
||||
Uri = uri;
|
||||
}
|
||||
|
||||
public string Uri { get; private set; }
|
||||
|
||||
public bool Canceled { get; private set; }
|
||||
|
||||
public virtual void Cancel() {
|
||||
Canceled = true;
|
||||
}
|
||||
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
protected UnityWebRequest www;
|
||||
public virtual void Start() {
|
||||
www = new UnityWebRequest(Uri);
|
||||
www.SendWebRequest();
|
||||
}
|
||||
public virtual bool Done() {
|
||||
if (!www.isDone) return false;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
protected WWW www;
|
||||
public virtual WWW Start() {
|
||||
return new WWW(Uri);
|
||||
}
|
||||
public abstract void Done();
|
||||
#endif
|
||||
}
|
||||
public class LoadTextureTask : NetworkTask {
|
||||
public LoadTextureTask(string uri, Action<bool, Texture2D> callback) : base(uri) {
|
||||
Callback = callback;
|
||||
}
|
||||
|
||||
public Action<bool, Texture2D> Callback { get; private set; }
|
||||
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
DownloadHandlerTexture handler;
|
||||
public override void Start() {
|
||||
handler = new DownloadHandlerTexture();
|
||||
www = new UnityWebRequest(Uri, "GET", handler, null);
|
||||
www.SendWebRequest();
|
||||
}
|
||||
public override bool Done() {
|
||||
if (!handler.isDone) return false;
|
||||
if (handler.texture != null) {
|
||||
var buffer = handler.texture;
|
||||
/*var result = new Texture2D(buffer.width, buffer.height, buffer.format, true);
|
||||
if (SystemInfo.copyTextureSupport.HasFlag(CopyTextureSupport.Basic)) {
|
||||
Graphics.CopyTexture(buffer, 0, 0, result, 0, 0);
|
||||
}
|
||||
else {
|
||||
result.LoadImage(handler.data);
|
||||
}
|
||||
result.Apply(true, true);
|
||||
Texture2D.Destroy(buffer);
|
||||
Callback(true, result);*/
|
||||
Callback(true, buffer);
|
||||
}
|
||||
else {
|
||||
Callback(false, null);
|
||||
}
|
||||
www.Dispose();
|
||||
handler.Dispose();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
public override void PostProcess(WWW www) {
|
||||
bool succeeded = string.IsNullOrEmpty(www.error);
|
||||
if (succeeded) {
|
||||
var buffer = www.texture;
|
||||
var result = new Texture2D(buffer.width, buffer.height, buffer.format, true);
|
||||
result.SetPixels(buffer.GetPixels());
|
||||
result.Apply(true, true);
|
||||
Texture2D.Destroy(buffer);
|
||||
Callback(true, result);
|
||||
}
|
||||
else Callback(false, null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/NetworkTaskWorker.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/NetworkTaskWorker.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1641131deb5de004a9a6d7ddb03d9dac
|
||||
timeCreated: 1637837586
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
29
Assets/Cryville/Common/Unity/Popup.cs
Normal file
29
Assets/Cryville/Common/Unity/Popup.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class Popup : MonoBehaviour {
|
||||
|
||||
public string Message = "";
|
||||
|
||||
LayoutElement layout;
|
||||
|
||||
float timer = 0;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
layout = GetComponent<LayoutElement>();
|
||||
GetComponentInChildren<Text>().text = Message;
|
||||
transform.SetParent(GameObject.Find("PopupList").transform);
|
||||
layout.minHeight = 0;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (timer <= 0.8f) layout.minHeight = timer * 50;
|
||||
else if (timer >= 5f) GameObject.Destroy(gameObject);
|
||||
else if (timer >= 4.2f) layout.minHeight = (300 - timer) * 50;
|
||||
timer += Time.deltaTime;
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/Popup.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/Popup.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b4b06c6db17f5a498bf12bb00aa07cf
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
145
Assets/Cryville/Common/Unity/PropItem.cs
Normal file
145
Assets/Cryville/Common/Unity/PropItem.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class PropItem : MonoBehaviour {
|
||||
public object Target;
|
||||
public PropertyEditor editor;
|
||||
public DirectoryInfo ContextPath;
|
||||
|
||||
public string PropertyName = "";
|
||||
InputField valueObj;
|
||||
string value;
|
||||
string desc = "";
|
||||
PropertyInfo prop;
|
||||
Type bindToType;
|
||||
TypeConverter converter;
|
||||
|
||||
bool mustExpand = false;
|
||||
bool readOnly = false;
|
||||
string[] filter = null;
|
||||
FileDialog fdialog;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
transform.Find("Value").GetComponent<InputField>().onEndEdit.AddListener(s => OnValueChanged(s));
|
||||
var entry = new EventTrigger.Entry(){
|
||||
eventID = EventTriggerType.PointerClick,
|
||||
callback = new EventTrigger.TriggerEvent()
|
||||
};
|
||||
entry.callback.AddListener(e => OnClick(e));
|
||||
transform.Find("Value").GetComponent<EventTrigger>().triggers.Add(entry);
|
||||
}
|
||||
|
||||
void Start() {
|
||||
transform.Find("Name").GetComponent<Text>().text = PropertyName;
|
||||
valueObj = transform.Find("Value").GetComponent<InputField>();
|
||||
prop = Target.GetType().GetProperty(PropertyName);
|
||||
bindToType = prop.PropertyType;
|
||||
converter = TypeDescriptor.GetConverter(bindToType);
|
||||
|
||||
var descattr = (DescriptionAttribute[])prop.GetCustomAttributes(typeof(DescriptionAttribute), true);
|
||||
if (descattr.Length > 0) desc = descattr[0].Description;
|
||||
|
||||
var roattr = (ReadOnlyAttribute[])prop.GetCustomAttributes(typeof(ReadOnlyAttribute), true);
|
||||
if (roattr.Length > 0) if (roattr[0].IsReadOnly == true) {
|
||||
readOnly = true;
|
||||
valueObj.enabled = false;
|
||||
valueObj.transform.Find("ValueString").GetComponent<Text>().color = Color.gray;
|
||||
}
|
||||
|
||||
if (converter == null || !converter.CanConvertFrom(typeof(string)) || converter.GetPropertiesSupported()){
|
||||
mustExpand = true;
|
||||
valueObj.enabled = false;
|
||||
}
|
||||
|
||||
var fsattr = (FileStringAttribute[])prop.GetCustomAttributes(typeof(FileStringAttribute), true);
|
||||
if (fsattr.Length > 0) {
|
||||
valueObj.enabled = false;
|
||||
filter = fsattr[0].Filter;
|
||||
}
|
||||
|
||||
UpdateValue();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
void OnFileDialogClosed() {
|
||||
var file = fdialog.GetComponent<FileDialog>().FileName;
|
||||
if (file != "") {
|
||||
var f = new FileInfo(file);
|
||||
if (f.Directory.FullName != ContextPath.FullName) {
|
||||
string targetFile = ContextPath.FullName + "\\" + f.Name;
|
||||
f.CopyTo(targetFile, true);
|
||||
}
|
||||
OnValueChanged(f.Name);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateValue() {
|
||||
object v;
|
||||
valueObj.placeholder.GetComponent<Text>().text = "";
|
||||
v = prop.GetValue(Target, new object[]{ });
|
||||
if (v == null) {
|
||||
DefaultValueAttribute[] defvattr = (DefaultValueAttribute[])prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
|
||||
if (defvattr.Length > 0) {
|
||||
v = defvattr[0].Value;
|
||||
if (v == null) {
|
||||
v = "";
|
||||
valueObj.placeholder.GetComponent<Text>().text = "null";
|
||||
}
|
||||
}
|
||||
else {
|
||||
v = "";
|
||||
valueObj.placeholder.GetComponent<Text>().text = "null";
|
||||
}
|
||||
}
|
||||
|
||||
if (mustExpand || readOnly || filter != null) {
|
||||
valueObj.transform.Find("ValueString").GetComponent<Text>().text = v.ToString();
|
||||
}
|
||||
else {
|
||||
valueObj.text = v.ToString();
|
||||
}
|
||||
value = valueObj.text;
|
||||
}
|
||||
|
||||
void OnClick(BaseEventData e) {
|
||||
if (mustExpand && !readOnly) {
|
||||
GameObject subeditor = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/PropertyEditor"));
|
||||
object obj = prop.GetValue(Target, new object[]{ });
|
||||
subeditor.GetComponent<PropertyEditor>().TargetObject = obj;
|
||||
}
|
||||
else if (filter != null && !readOnly) {
|
||||
fdialog = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/FileDialog")).GetComponent<FileDialog>();
|
||||
fdialog.Filter = filter;
|
||||
fdialog.CurrentDirectory = ContextPath;
|
||||
fdialog.Callback = () => OnFileDialogClosed();
|
||||
}
|
||||
editor.SetDescription(PropertyName, desc);
|
||||
UpdateValue();
|
||||
}
|
||||
|
||||
void OnValueChanged(string s) {
|
||||
if (s == value) return;
|
||||
object v = null;
|
||||
if (!(mustExpand || readOnly)) {
|
||||
try {
|
||||
v = converter.ConvertFrom(s);
|
||||
prop.SetValue(Target, v, new object[]{ });
|
||||
}
|
||||
catch (TargetInvocationException ex) {
|
||||
CallHelper.ShowMessageBox(ex.InnerException.Message);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
CallHelper.ShowMessageBox(ex.Message);
|
||||
}
|
||||
}
|
||||
UpdateValue();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/PropItem.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/PropItem.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 499dc47d3f108de4eb80b2d73e5851c5
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
61
Assets/Cryville/Common/Unity/PropertyEditor.cs
Normal file
61
Assets/Cryville/Common/Unity/PropertyEditor.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class PropertyEditor : MonoBehaviour {
|
||||
|
||||
private object target;
|
||||
public object TargetObject {
|
||||
get { return target; }
|
||||
set {
|
||||
target = value;
|
||||
ReloadProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private Text desc;
|
||||
private Transform list;
|
||||
|
||||
public Action Callback;
|
||||
|
||||
private void ReloadProperties() {
|
||||
foreach (Transform p in list) {
|
||||
GameObject.Destroy(p.gameObject);
|
||||
}
|
||||
PropertyInfo[] props = target.GetType().GetProperties();
|
||||
foreach (PropertyInfo m in props) {
|
||||
var brattr = (BrowsableAttribute[])m.GetCustomAttributes(typeof(BrowsableAttribute), true);
|
||||
if (brattr.Length > 0)
|
||||
if (brattr[0].Browsable == false)
|
||||
continue;
|
||||
GameObject mi = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/PropItem"));
|
||||
mi.transform.SetParent(list, false);
|
||||
mi.GetComponent<PropItem>().PropertyName = m.Name;
|
||||
mi.GetComponent<PropItem>().Target = target;
|
||||
mi.GetComponent<PropItem>().editor = this;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
Transform panel = transform.Find("Panel");
|
||||
desc = panel.Find("Description").GetComponent<Text>();
|
||||
list = panel.Find("PropList").Find("PropListInner");
|
||||
SetDescription("(Property)", "");
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
public void SetDescription(string n, string d) {
|
||||
desc.text = "<b>" + n + "</b>\n" + d;
|
||||
}
|
||||
|
||||
public void Close() {
|
||||
if (Callback != null) Callback.Invoke();
|
||||
GameObject.Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/PropertyEditor.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/PropertyEditor.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de5a0d32ac5669347ac4570c014967d1
|
||||
timeCreated: 1608801356
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
9
Assets/Cryville/Common/Unity/UI.meta
Normal file
9
Assets/Cryville/Common/Unity/UI.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad2666f1d55eb0441b21a72be30b919e
|
||||
folderAsset: yes
|
||||
timeCreated: 1637223163
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
104
Assets/Cryville/Common/Unity/UI/AspectRatioLayoutElement.cs
Normal file
104
Assets/Cryville/Common/Unity/UI/AspectRatioLayoutElement.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public class AspectRatioLayoutElement : UIBehaviour, ILayoutElement {
|
||||
[SerializeField]
|
||||
private RectTransform m_containerTransform = null;
|
||||
public RectTransform ContainerTransform {
|
||||
get { return m_containerTransform; }
|
||||
set { SetProperty(ref m_containerTransform, value); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float m_aspectRatio = 1;
|
||||
public float AspectRatio {
|
||||
get { return m_aspectRatio; }
|
||||
set { SetProperty(ref m_aspectRatio, value); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_isVertical = false;
|
||||
public bool IsVertical {
|
||||
get { return m_isVertical; }
|
||||
set { SetProperty(ref m_isVertical, value); }
|
||||
}
|
||||
|
||||
private void SetProperty<T>(ref T prop, T value) {
|
||||
if (Equals(prop, value)) return;
|
||||
prop = value;
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
private void SetDirty() {
|
||||
if (!IsActive()) return;
|
||||
LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
||||
}
|
||||
|
||||
public float minWidth {
|
||||
get {
|
||||
return m_isVertical
|
||||
? m_containerTransform.rect.width
|
||||
: m_containerTransform.rect.height * m_aspectRatio;
|
||||
}
|
||||
}
|
||||
public float preferredWidth { get { return minWidth; } }
|
||||
public float flexibleWidth { get { return 0; } }
|
||||
|
||||
public float minHeight {
|
||||
get {
|
||||
return m_isVertical
|
||||
? m_containerTransform.rect.width / m_aspectRatio
|
||||
: m_containerTransform.rect.height;
|
||||
}
|
||||
}
|
||||
public float preferredHeight { get { return minHeight; } }
|
||||
public float flexibleHeight { get { return 0; } }
|
||||
|
||||
public int layoutPriority { get { return 1; } }
|
||||
|
||||
private bool isRootLayoutGroup {
|
||||
get {
|
||||
Transform parent = transform.parent;
|
||||
return parent == null || transform.parent.GetComponent(typeof(ILayoutGroup)) == null;
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateLayoutInputHorizontal() { }
|
||||
|
||||
public void CalculateLayoutInputVertical() { }
|
||||
|
||||
protected override void OnDidApplyAnimationProperties() {
|
||||
base.OnDidApplyAnimationProperties();
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnDisable() {
|
||||
LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
protected override void OnEnable() {
|
||||
base.OnEnable();
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnRectTransformDimensionsChange() {
|
||||
base.OnRectTransformDimensionsChange();
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnTransformParentChanged() {
|
||||
base.OnTransformParentChanged();
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
new void OnValidate() {
|
||||
SetDirty();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4152cfa558755cd44bf81d408a0fdeb6
|
||||
timeCreated: 1638428042
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public sealed class DockAspectRatioLayoutGroup : DockLayoutGroup {
|
||||
[SerializeField]
|
||||
private float m_dockAspectRatio = 1;
|
||||
public float DockAspectRatio {
|
||||
get { return m_dockAspectRatio; }
|
||||
set { base.SetProperty(ref m_dockAspectRatio, value); }
|
||||
}
|
||||
|
||||
protected override float GetDockElementSize(Vector2 groupSize) {
|
||||
return groupSize.y * m_dockAspectRatio;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f56dd50c0bf4a1341bcaa95451a735c8
|
||||
timeCreated: 1637546486
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
74
Assets/Cryville/Common/Unity/UI/DockLayoutGroup.cs
Normal file
74
Assets/Cryville/Common/Unity/UI/DockLayoutGroup.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public abstract class DockLayoutGroup : LayoutGroup {
|
||||
public enum Side {
|
||||
Top = 0,
|
||||
Right = 1,
|
||||
Bottom = 2,
|
||||
Left = 3,
|
||||
}
|
||||
[SerializeField]
|
||||
private Side m_side;
|
||||
public Side DockSide {
|
||||
get { return m_side; }
|
||||
set { base.SetProperty(ref m_side, value); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float m_slideIndex;
|
||||
public float SlideIndex {
|
||||
get { return m_slideIndex; }
|
||||
set { base.SetProperty(ref m_slideIndex, value); }
|
||||
}
|
||||
|
||||
public sealed override void CalculateLayoutInputHorizontal() { base.CalculateLayoutInputHorizontal(); }
|
||||
public sealed override void CalculateLayoutInputVertical() { }
|
||||
public sealed override void SetLayoutHorizontal() { SetChildrenAlongAxis(0); }
|
||||
public sealed override void SetLayoutVertical() { SetChildrenAlongAxis(1); }
|
||||
|
||||
private float GetSlidePosition(float groupHeight, float dockHeight) {
|
||||
bool d = Mathf.FloorToInt(m_slideIndex - Mathf.Floor(m_slideIndex / 2) * 2) == 0;
|
||||
int l = Mathf.FloorToInt(m_slideIndex / 2);
|
||||
float p = m_slideIndex - Mathf.Floor(m_slideIndex);
|
||||
if (d) return l * groupHeight + p * dockHeight;
|
||||
else return l * groupHeight + dockHeight + p * (groupHeight - dockHeight);
|
||||
}
|
||||
|
||||
private void SetChildrenAlongAxis(int axis) {
|
||||
int isHorizontal = (int)m_side & 1;
|
||||
bool isReversed = m_side == Side.Right || m_side == Side.Bottom;
|
||||
var rect = rectTransform.rect;
|
||||
if ((isHorizontal ^ axis) == 1) {
|
||||
float p0 = isHorizontal == 1 ? m_Padding.left : m_Padding.top;
|
||||
float p1 = isHorizontal == 1 ? m_Padding.right : m_Padding.bottom;
|
||||
var gs = rect.size - new Vector2(m_Padding.horizontal, m_Padding.vertical);
|
||||
if (isHorizontal == 0) gs = new Vector2(gs.y, gs.x);
|
||||
float s1 = GetDockElementSize(gs);
|
||||
float s0 = GetSlidePosition(gs.x, s1);
|
||||
float a1 = (isHorizontal == 0 ? rect.height : rect.width) - p0 - p1;
|
||||
for (int i = 0; i < base.rectChildren.Count; i++) {
|
||||
var c = base.rectChildren[i];
|
||||
bool d = i % 2 == 0;
|
||||
int l = i / 2;
|
||||
if (isReversed)
|
||||
base.SetChildAlongAxis(c, axis, (d ? a1 - s1 + p0 : p0) - a1 * l + s0, d ? s1 : a1 - s1);
|
||||
else
|
||||
base.SetChildAlongAxis(c, axis, (d ? p0 : s1 + p0) - s0 + a1 * l, d ? s1 : a1 - s1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float p0 = isHorizontal == 0 ? m_Padding.left : m_Padding.top;
|
||||
float p1 = isHorizontal == 0 ? m_Padding.right : m_Padding.bottom;
|
||||
var height = (isHorizontal == 1 ? rect.height : rect.width) - p0 - p1;
|
||||
for (int i = 0; i < base.rectChildren.Count; i++) {
|
||||
base.SetChildAlongAxis(base.rectChildren[i], axis, p0, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract float GetDockElementSize(Vector2 groupSize);
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/UI/DockLayoutGroup.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/UI/DockLayoutGroup.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 452470fc804a21741b5b4b0b64f14d0b
|
||||
timeCreated: 1637543050
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public sealed class DockOccupiedRatioLayoutGroup : DockLayoutGroup {
|
||||
[SerializeField]
|
||||
private float m_dockOccupiedRatio = 1;
|
||||
public float DockOccupiedRatio {
|
||||
get { return m_dockOccupiedRatio; }
|
||||
set { base.SetProperty(ref m_dockOccupiedRatio, value); }
|
||||
}
|
||||
|
||||
protected override float GetDockElementSize(Vector2 groupSize) {
|
||||
return groupSize.x * m_dockOccupiedRatio;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9139d5b66d1eb140856a276012df0b8
|
||||
timeCreated: 1637546712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
36
Assets/Cryville/Common/Unity/UI/GridLayoutSizeFitter.cs
Normal file
36
Assets/Cryville/Common/Unity/UI/GridLayoutSizeFitter.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
[RequireComponent(typeof(GridLayoutGroup))]
|
||||
public class GridLayoutSizeFitter : MonoBehaviour {
|
||||
RectTransform rectTransform;
|
||||
GridLayoutGroup gridLayoutGroup;
|
||||
Canvas canvas;
|
||||
public int GroupItemCount = 3;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
rectTransform = GetComponent<RectTransform>();
|
||||
gridLayoutGroup = GetComponent<GridLayoutGroup>();
|
||||
canvas = GetComponentInParent<Canvas>();
|
||||
}
|
||||
void Update() {
|
||||
var cellSize = gridLayoutGroup.cellSize;
|
||||
var frameSize = rectTransform.sizeDelta;
|
||||
int lineCount = Mathf.CeilToInt((float)transform.childCount / GroupItemCount);
|
||||
var rect = RectTransformUtility.PixelAdjustRect((RectTransform)transform, canvas);
|
||||
if (gridLayoutGroup.startAxis == GridLayoutGroup.Axis.Horizontal) {
|
||||
cellSize.x = rect.width / GroupItemCount;
|
||||
frameSize.y = cellSize.y * lineCount;
|
||||
}
|
||||
else {
|
||||
cellSize.y = rect.height / GroupItemCount;
|
||||
frameSize.x = cellSize.x * lineCount;
|
||||
}
|
||||
gridLayoutGroup.cellSize = cellSize;
|
||||
rectTransform.sizeDelta = frameSize;
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/UI/GridLayoutSizeFitter.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/UI/GridLayoutSizeFitter.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45ec4804e78a14a489a6fae9197e9b57
|
||||
timeCreated: 1637231253
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
160
Assets/Cryville/Common/Unity/UI/ImageSliced3.cs
Normal file
160
Assets/Cryville/Common/Unity/UI/ImageSliced3.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Sprites;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
/// <summary>
|
||||
/// An image that is sliced into three parts, with the middle part stretched and the two borders preserved their aspect ratio.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public class ImageSliced3 : MaskableGraphic {
|
||||
[SerializeField]
|
||||
private Sprite m_sprite;
|
||||
/// <summary>
|
||||
/// The sliced sprite.
|
||||
/// </summary>
|
||||
public Sprite Sprite {
|
||||
get { return m_sprite; }
|
||||
set { m_sprite = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The mode how a sliced image is generated when it is too compact.
|
||||
/// </summary>
|
||||
public enum CompactMode {
|
||||
/// <summary>
|
||||
/// Squeezes both the left border and the right border.
|
||||
/// </summary>
|
||||
SqueezeBoth = 0,
|
||||
/// <summary>
|
||||
/// Squeezes the left border and preserves the width of the right border.
|
||||
/// </summary>
|
||||
SqueezeLeft = 2,
|
||||
/// <summary>
|
||||
/// Squeezes the right border and preserves the width of the left border.
|
||||
/// </summary>
|
||||
SqueezeRight = 3,
|
||||
/// <summary>
|
||||
/// Squeezes the lower edge of the left border and the upper edge of the right border.
|
||||
/// </summary>
|
||||
DiagonalLeft = 4,
|
||||
/// <summary>
|
||||
/// Squeezes the upper edge of the left border and the lower edge of the right border.
|
||||
/// </summary>
|
||||
DiagonalRight = 5,
|
||||
}
|
||||
[SerializeField]
|
||||
private CompactMode m_compact;
|
||||
/// <summary>
|
||||
/// The mode how a sliced image is generated when it is too compact.
|
||||
/// </summary>
|
||||
public CompactMode Compact {
|
||||
get { return m_compact; }
|
||||
set { m_compact = value; }
|
||||
}
|
||||
|
||||
public override Texture mainTexture {
|
||||
get { return Sprite == null ? s_WhiteTexture : Sprite.texture; }
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh) {
|
||||
float actualWidth = rectTransform.rect.width;
|
||||
|
||||
Vector4 uv = DataUtility.GetOuterUV(Sprite);
|
||||
|
||||
float cornerLeftSizeRatio = Sprite.border.x / Sprite.rect.height;
|
||||
float actualLeftCornerWidth = cornerLeftSizeRatio * rectTransform.rect.height;
|
||||
float actualLeftUVWidth = (uv.w - uv.y) * (Sprite.border.x / Sprite.rect.width);
|
||||
|
||||
float cornerRightSizeRatio = Sprite.border.z / Sprite.rect.height;
|
||||
float actualRightCornerWidth = cornerRightSizeRatio * rectTransform.rect.height;
|
||||
float actualRightUVWidth = (uv.w - uv.y) * (Sprite.border.z / Sprite.rect.width);
|
||||
|
||||
float actualTotalCornerWidth = actualLeftCornerWidth + actualRightCornerWidth;
|
||||
|
||||
Vector2 corner1 = new Vector2(0f, 0f);
|
||||
Vector2 corner2 = new Vector2(1f, 1f);
|
||||
|
||||
corner1.x -= rectTransform.pivot.x;
|
||||
corner1.y -= rectTransform.pivot.y;
|
||||
corner2.x -= rectTransform.pivot.x;
|
||||
corner2.y -= rectTransform.pivot.y;
|
||||
|
||||
corner1.x *= actualWidth;
|
||||
corner1.y *= rectTransform.rect.height;
|
||||
corner2.x *= actualWidth;
|
||||
corner2.y *= rectTransform.rect.height;
|
||||
|
||||
if (Sprite == null) {
|
||||
throw new UnityException("No sprite");
|
||||
}
|
||||
else if (Sprite.border == Vector4.zero) {
|
||||
throw new UnityException("No sprite border");
|
||||
}
|
||||
|
||||
float w3, w4, w5, w6;
|
||||
if (actualTotalCornerWidth > actualWidth) {
|
||||
switch (Compact) {
|
||||
case CompactMode.SqueezeBoth:
|
||||
w3 = w4 = actualLeftCornerWidth / actualTotalCornerWidth * actualWidth;
|
||||
w5 = w6 = actualRightCornerWidth / actualTotalCornerWidth * actualWidth;
|
||||
break;
|
||||
case CompactMode.SqueezeLeft:
|
||||
w3 = w4 = actualWidth - actualRightCornerWidth;
|
||||
w5 = w6 = actualRightCornerWidth;
|
||||
break;
|
||||
case CompactMode.SqueezeRight:
|
||||
w3 = w4 = actualLeftCornerWidth;
|
||||
w5 = w6 = actualWidth - actualLeftCornerWidth;
|
||||
break;
|
||||
case CompactMode.DiagonalLeft:
|
||||
w3 = actualLeftCornerWidth;
|
||||
w4 = actualWidth - actualRightCornerWidth;
|
||||
w5 = actualWidth - actualLeftCornerWidth;
|
||||
w6 = actualRightCornerWidth;
|
||||
break;
|
||||
case CompactMode.DiagonalRight:
|
||||
w3 = actualWidth - actualRightCornerWidth;
|
||||
w4 = actualLeftCornerWidth;
|
||||
w5 = actualRightCornerWidth;
|
||||
w6 = actualWidth - actualLeftCornerWidth;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("Compact");
|
||||
}
|
||||
}
|
||||
else {
|
||||
w3 = w4 = actualLeftCornerWidth;
|
||||
w5 = w6 = actualRightCornerWidth;
|
||||
}
|
||||
|
||||
vh.Clear();
|
||||
vh.AddVert(new Vector3(corner1.x, corner2.y), color, new Vector2(uv.x, uv.w));
|
||||
vh.AddVert(new Vector3(corner1.x, corner1.y), color, new Vector2(uv.x, uv.y));
|
||||
vh.AddVert(new Vector3(corner1.x + w3, corner2.y), color, new Vector2(uv.x + actualLeftUVWidth, uv.w));
|
||||
vh.AddVert(new Vector3(corner1.x + w4, corner1.y), color, new Vector2(uv.x + actualLeftUVWidth, uv.y));
|
||||
vh.AddVert(new Vector3(corner2.x - w5, corner2.y), color, new Vector2(uv.z - actualRightUVWidth, uv.w));
|
||||
vh.AddVert(new Vector3(corner2.x - w6, corner1.y), color, new Vector2(uv.z - actualRightUVWidth, uv.y));
|
||||
vh.AddVert(new Vector3(corner2.x, corner2.y), color, new Vector2(uv.z, uv.w));
|
||||
vh.AddVert(new Vector3(corner2.x, corner1.y), color, new Vector2(uv.z, uv.y));
|
||||
|
||||
if (((int)Compact & 0x1) == 0) {
|
||||
vh.AddTriangle(2, 1, 0);
|
||||
vh.AddTriangle(1, 2, 3);
|
||||
vh.AddTriangle(4, 3, 2);
|
||||
vh.AddTriangle(3, 4, 5);
|
||||
vh.AddTriangle(6, 5, 4);
|
||||
vh.AddTriangle(5, 6, 7);
|
||||
}
|
||||
else {
|
||||
vh.AddTriangle(3, 1, 0);
|
||||
vh.AddTriangle(0, 2, 3);
|
||||
vh.AddTriangle(5, 3, 2);
|
||||
vh.AddTriangle(2, 4, 5);
|
||||
vh.AddTriangle(7, 5, 4);
|
||||
vh.AddTriangle(4, 6, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Unity/UI/ImageSliced3.cs.meta
Normal file
11
Assets/Cryville/Common/Unity/UI/ImageSliced3.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a17c6b12c477af44bbfd74a46ed0c72
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
42
Assets/Cryville/Common/Unity/UI/LayoutAspectRatioFitter.cs
Normal file
42
Assets/Cryville/Common/Unity/UI/LayoutAspectRatioFitter.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public class LayoutAspectRatioFitter : MonoBehaviour {
|
||||
[SerializeField]
|
||||
private float m_aspectRatioPerElement = 1;
|
||||
public float AspectRatioPerElement {
|
||||
get { return m_aspectRatioPerElement; }
|
||||
set { m_aspectRatioPerElement = value; }
|
||||
}
|
||||
|
||||
AspectRatioFitter aspectRatioFitter;
|
||||
DockAspectRatioLayoutGroup syncTo;
|
||||
int axis;
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
aspectRatioFitter = GetComponent<AspectRatioFitter>();
|
||||
if (aspectRatioFitter == null) {
|
||||
syncTo = GetComponentInParent<DockAspectRatioLayoutGroup>();
|
||||
axis = (syncTo.DockSide == DockLayoutGroup.Side.Top || syncTo.DockSide == DockLayoutGroup.Side.Bottom) ? 1 : 0;
|
||||
}
|
||||
else axis = aspectRatioFitter.aspectMode == AspectRatioFitter.AspectMode.WidthControlsHeight ? 1 : 0;
|
||||
OnTransformChildrenChanged();
|
||||
}
|
||||
void OnTransformChildrenChanged() {
|
||||
float r;
|
||||
switch (axis) {
|
||||
case 0:
|
||||
r = AspectRatioPerElement * transform.childCount;
|
||||
break;
|
||||
case 1:
|
||||
r = AspectRatioPerElement / transform.childCount;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
if (aspectRatioFitter != null) aspectRatioFitter.aspectRatio = r;
|
||||
else syncTo.DockAspectRatio = r;
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6a0bd7b6df9009488cf6694cb73422c
|
||||
timeCreated: 1637570493
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
27
Assets/Cryville/Common/Unity/UI/ProgressBar.cs
Normal file
27
Assets/Cryville/Common/Unity/UI/ProgressBar.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public class ProgressBar : Slider {
|
||||
[SerializeField][Range(0f, 1f)]
|
||||
float m_smooth = 0;
|
||||
public float Smooth {
|
||||
get { return m_smooth; }
|
||||
set { m_smooth = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
float m_targetValue;
|
||||
public override float value {
|
||||
get { return base.value; }
|
||||
set { m_targetValue = value; }
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
protected override void Update() {
|
||||
base.value = (base.value - m_targetValue) * m_smooth + m_targetValue;
|
||||
base.Update();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Unity/UI/ProgressBar.cs.meta
Normal file
11
Assets/Cryville/Common/Unity/UI/ProgressBar.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1a44bd454a0aa64e835b9e309c79bff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
209
Assets/Cryville/Common/Unity/UI/ScrollableItemGrid.cs
Normal file
209
Assets/Cryville/Common/Unity/UI/ScrollableItemGrid.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public sealed class ScrollableItemGrid : MonoBehaviour {
|
||||
[SerializeField]
|
||||
private GameObject m_itemTemplate;
|
||||
public GameObject ItemTemplate {
|
||||
get { return m_itemTemplate; }
|
||||
set { m_itemTemplate = value; OnTemplateUpdate(); }
|
||||
}
|
||||
public Func<int, GameObject, bool> LoadItem { private get; set; }
|
||||
|
||||
public enum Corner {
|
||||
UpperLeft = 0,
|
||||
UpperRight = 1,
|
||||
LowerLeft = 2,
|
||||
LowerRight = 3,
|
||||
}
|
||||
[SerializeField]
|
||||
private Corner m_startCorner; // TODO
|
||||
public Corner StartCorner {
|
||||
get { return m_startCorner; }
|
||||
set { m_startCorner = value; OnFrameUpdate(); }
|
||||
}
|
||||
|
||||
public enum Axis {
|
||||
Horizontal = 0, Vertical = 1,
|
||||
}
|
||||
[SerializeField]
|
||||
private Axis m_startAxis;
|
||||
public Axis StartAxis {
|
||||
get { return m_startAxis; }
|
||||
set { m_startAxis = value; OnFrameUpdate(); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 m_spacing; // TODO
|
||||
public Vector2 Spacing {
|
||||
get { return m_spacing; }
|
||||
set { m_spacing = value; OnFrameUpdate(); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int m_itemCount = 3;
|
||||
public int ItemCount {
|
||||
get { return m_itemCount; }
|
||||
set { m_itemCount = value; OnRefresh(); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int m_lineItemCount = 3;
|
||||
public int LineItemCount {
|
||||
get { return m_lineItemCount; }
|
||||
set { m_lineItemCount = value; OnFrameUpdate(); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float m_lineHeight = 100;
|
||||
public float LineHeight {
|
||||
get { return m_lineHeight; }
|
||||
set { m_lineHeight = value; OnFrameUpdate(); }
|
||||
}
|
||||
|
||||
private int LineCount {
|
||||
get { return Mathf.CeilToInt((float)m_itemCount / m_lineItemCount); }
|
||||
}
|
||||
private float GroupHeight {
|
||||
get { return m_lineHeight * LineCount; }
|
||||
}
|
||||
private Vector2 VisibleSize {
|
||||
get {
|
||||
Rect parentRect = ((RectTransform)transform.parent).rect;
|
||||
return new Vector2(
|
||||
m_startAxis == Axis.Horizontal ? parentRect.width : parentRect.height,
|
||||
m_startAxis == Axis.Horizontal ? parentRect.height : parentRect.width
|
||||
);
|
||||
}
|
||||
}
|
||||
public int VisibleLines {
|
||||
get {
|
||||
return Mathf.CeilToInt(VisibleSize.y / m_lineHeight) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private bool initialized;
|
||||
private GameObject[][] lines;
|
||||
private int[] refl;
|
||||
Vector2 cpos = new Vector2(0, 1);
|
||||
Vector2 pprectsize;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
GetComponentInParent<ScrollRect>().onValueChanged.AddListener(OnScroll);
|
||||
initialized = true;
|
||||
OnFrameUpdate();
|
||||
}
|
||||
|
||||
void Update() {
|
||||
Vector2 cprectsize = ((RectTransform)transform.parent).rect.size;
|
||||
if (cprectsize != pprectsize) {
|
||||
OnFrameUpdate();
|
||||
pprectsize = cprectsize;
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private void OnFrameUpdate() {
|
||||
if (!initialized) return;
|
||||
if (lines != null) for (int i = 0; i < lines.Length; i++)
|
||||
if (lines[i] != null) foreach (GameObject c in lines[i])
|
||||
GameObject.Destroy(c);
|
||||
lines = new GameObject[VisibleLines][];
|
||||
refl = new int[VisibleLines];
|
||||
for (int i = 0; i < refl.Length; i++) refl[i] = i;
|
||||
ResetLines();
|
||||
SetCells();
|
||||
ResizeGroup();
|
||||
}
|
||||
|
||||
private void OnTemplateUpdate() {
|
||||
if (!initialized) return;
|
||||
ResetLines();
|
||||
SetCells();
|
||||
}
|
||||
|
||||
private void ResetLines() {
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
if (lines[i] != null) foreach (GameObject c in lines[i])
|
||||
GameObject.Destroy(c);
|
||||
lines[i] = new GameObject[LineItemCount];
|
||||
GenerateLine(i, refl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void OnScroll(Vector2 scrpos) {
|
||||
cpos = scrpos;
|
||||
int l0 = GetFirstVisibleLine(cpos);
|
||||
int l1 = l0 + VisibleLines - 1;
|
||||
for (int l = l0; l <= l1; l++) {
|
||||
if (Array.IndexOf(refl, l) != -1) continue;
|
||||
int repl = Array.FindIndex(refl, i => i < l0 || i > l1);
|
||||
if (repl == -1) return;
|
||||
LoadLine(repl, l);
|
||||
SetCells(repl);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRefresh() {
|
||||
if (!initialized) return;
|
||||
int l0 = GetFirstVisibleLine(cpos);
|
||||
int l1 = l0 + VisibleLines - 1;
|
||||
int i = 0;
|
||||
for (int l = l0; l <= l1; i++, l++) {
|
||||
LoadLine(i, l);
|
||||
SetCells(i);
|
||||
}
|
||||
ResizeGroup();
|
||||
}
|
||||
|
||||
void ResizeGroup() {
|
||||
((RectTransform)transform).sizeDelta = m_startAxis == 0
|
||||
? new Vector2(0, GroupHeight)
|
||||
: new Vector2(GroupHeight, 0);
|
||||
}
|
||||
|
||||
int GetFirstVisibleLine(Vector2 scrpos) {
|
||||
float scr = m_startAxis == Axis.Horizontal ? 1 - scrpos.y : scrpos.x;
|
||||
float maxScroll = Mathf.Max(0, GroupHeight - VisibleSize.y);
|
||||
if (maxScroll == 0) return 0;
|
||||
return Mathf.FloorToInt(scr * maxScroll / LineHeight);
|
||||
}
|
||||
|
||||
void GenerateLine(int index, int line) {
|
||||
for (int j = 0; j < LineItemCount; j++) {
|
||||
var child = GameObject.Instantiate(m_itemTemplate);
|
||||
child.transform.SetParent(transform, false);
|
||||
lines[index][j] = child;
|
||||
}
|
||||
LoadLine(index, line);
|
||||
}
|
||||
|
||||
void LoadLine(int index, int line) {
|
||||
refl[index] = line;
|
||||
for (int j = 0; j < LineItemCount; j++) {
|
||||
var id = line * m_lineItemCount + j;
|
||||
if (id < 0 || id >= m_itemCount || LoadItem == null) lines[index][j].SetActive(false);
|
||||
else lines[index][j].SetActive(LoadItem(id, lines[index][j]));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCells() {
|
||||
for (int i = 0; i < VisibleLines; i++) SetCells(i);
|
||||
}
|
||||
|
||||
private void SetCells(int index) {
|
||||
float itemWidth = VisibleSize[0] / m_lineItemCount;
|
||||
for (int j = 0; j < LineItemCount; j++) {
|
||||
((RectTransform)lines[index][j].transform).anchoredPosition = m_startAxis == 0
|
||||
? new Vector2(j * itemWidth, -refl[index] * m_lineHeight)
|
||||
: new Vector2(refl[index] * m_lineHeight, -j * itemWidth);
|
||||
((RectTransform)lines[index][j].transform).sizeDelta = m_startAxis == 0
|
||||
? new Vector2(itemWidth, m_lineHeight)
|
||||
: new Vector2(m_lineHeight, itemWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Common/Unity/UI/ScrollableItemGrid.cs.meta
Normal file
12
Assets/Cryville/Common/Unity/UI/ScrollableItemGrid.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e3bba63289205243bdddd79b4341bc4
|
||||
timeCreated: 1637504893
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user