单机版网页启动程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

178 lines
4.4 KiB

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using CursorType = ZenFulcrum.EmbeddedBrowser.BrowserNative.CursorType;
using Object = UnityEngine.Object;
namespace ZenFulcrum.EmbeddedBrowser {
/**
* Manages finding and copying cursors for you.
* Each instance has one active cursor and a Texture2D you can read from to use it.
*/
public class BrowserCursor {
public class CursorInfo {
public int atlasOffset;
public Vector2 hotspot;
}
private static Dictionary<CursorType, CursorInfo> mapping = new Dictionary<CursorType, CursorInfo>();
private static bool loaded = false;
private static int size;
private static Texture2D allCursors;
/// <summary>
/// Fired when the mouse cursor's appearance or hotspot changes.
/// Also fired when the mouse enters/leaves the browser.
/// </summary>
public event Action cursorChange = () => {};
private static void Load() {
if (loaded) return;
allCursors = Resources.Load<Texture2D>("Browser/Cursors");
if (!allCursors) throw new Exception("Failed to find browser allCursors");
size = allCursors.height;
var listObj = Resources.Load<TextAsset>("Browser/Cursors");
foreach (var row in listObj.text.Split('\n')) {
var info = row.Split(',');
var k = (CursorType)Enum.Parse(typeof(CursorType), info[0]);
var v = new CursorInfo() {
atlasOffset = int.Parse(info[1]),
hotspot = new Vector2(int.Parse(info[2]), int.Parse(info[3])),
};
mapping[k] = v;
}
loaded = true;
}
/**
* Texture for the current cursor.
* If the cursor should be hidden, this will be null.
*/
public virtual Texture2D Texture { get; protected set; }
/**
* Hotspot for the current cursor. (0, 0) indicates the top-left of the texture is the hotspot.
* (1, 1) indicates the bottom-right.
*/
public virtual Vector2 Hotspot { get; protected set; }
private bool _hasMouse;
/// <summary>
/// True when the mouse is over the browser, false otherwise.
/// </summary>
public bool HasMouse {
get {
return _hasMouse;
}
set {
_hasMouse = value;
cursorChange();
}
}
protected Texture2D normalTexture;
protected Texture2D customTexture;
public BrowserCursor() {
Load();
normalTexture = CreateTexture(size, size);
SetActiveCursor(BrowserNative.CursorType.Pointer);
}
private Texture2D CreateTexture(int w, int h) {
#if UNITY_2018_3_OR_NEWER
var tex = new Texture2D(w, h, TextureFormat.RGBA32, false);
#else
var tex = new Texture2D(w, h, TextureFormat.ARGB32, false);
#endif
#if UNITY_EDITOR
tex.alphaIsTransparency = true;
#endif
return tex;
}
/// <summary>
/// Switches the active cursor type. After calling this you can access the cursor image through this.Texture.
/// </summary>
/// <param name="type"></param>
public virtual void SetActiveCursor(CursorType type) {
if (type == CursorType.Custom) throw new ArgumentException("Use SetCustomCursor to set custom cursors.", "type");
if (type == CursorType.None) {
Texture = null;
//Side note: if you copy down a bunch of transparent pixels and try to set the mouse cursor to that
//both OS X and Windows fail to do what you'd expect.
//Edit: OS X is now crashing for me if you try to do that.
cursorChange();
return;
}
var info = mapping[type];
var pixelData = allCursors.GetPixels(info.atlasOffset * size, 0, size, size);
Hotspot = info.hotspot;
normalTexture.SetPixels(pixelData);
normalTexture.Apply(true);
Texture = normalTexture;
cursorChange();
}
/// <summary>
/// Sets a custom cursor.
/// </summary>
/// <param name="cursor">ARGB texture to set</param>
/// <param name="hotspot"></param>
public virtual void SetCustomCursor(Texture2D cursor, Vector2 hotspot) {
var pixels = cursor.GetPixels32();
//First off, is it completely blank? 'Cuz if so that can cause OS X to crash.
var hasData = false;
for (int i = 0; i < pixels.Length; i++) {
if (pixels[i].a != 0) {
hasData = true;
break;
}
}
if (!hasData) {
//it's blank, so handle it like a regular blank cursor
SetActiveCursor(CursorType.None);
return;
}
if (!customTexture || customTexture.width != cursor.width || customTexture.height != cursor.height) {
Object.Destroy(customTexture);
customTexture = CreateTexture(cursor.width, cursor.height);
}
customTexture.SetPixels32(pixels);
customTexture.Apply(true);
this.Hotspot = hotspot;
Texture = customTexture;
cursorChange();
}
}
}