Select Git revision
BrowserView.cs
-
Bjoern Esswein authoredBjoern Esswein authored
WebViewComponent.cs 8.73 KiB
using bessw.Unity.WebView.ChromeDevTools;
using bessw.Unity.WebView.ChromeDevTools.Protocol.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace bessw.Unity.WebView
{
[RequireComponent(typeof(RawImage))]
public class WebViewComponent : MonoBehaviour, IPointerDownHandler, IPointerMoveHandler, IPointerUpHandler, IPointerEnterHandler, IDropHandler, IPointerExitHandler
{
#region json serializer
/// <summary>
/// Json serializer settings for the user space objects (e.g. transfering objects that have been droped on the BrowserView)
/// Users are allowed to change serializer settings to their liking.
/// </summary>
public static JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter>()
{
new ColorConverter(),
new Vector2Converter(),
new Vector3Converter(),
new Vector4Converter()
}
};
/// <summary>
/// JsonSerializer for the user space objects (e.g. transfering objects that have been droped on the BrowserView)
/// Users are allowed to change serializer settings to their liking.
/// </summary>
public static JsonSerializer serializer = JsonSerializer.Create(serializerSettings);
#endregion json serializer
private Browser browser;
protected BrowserTab tab;
private RawImage rawImage;
private RectTransform rectTransform;
public bool headlessBrowser = true;
//TODO: handle changed targetUrl
public string targetUrl = "https://google.de";
// Start is called before the first frame update
private void Start()
{
Debug.LogWarning("start Webview");
rawImage = this.gameObject.GetComponent<RawImage>();
rectTransform = this.gameObject.GetComponent<RectTransform>();
}
private void OnEnable()
{
Debug.LogWarning("enable Webview");
Browser.headless = headlessBrowser;
browser = Browser.getInstance();
//StartCoroutine(GetOpenTabs());
var c = StartCoroutine(browser.OpenNewTab(targetUrl, (BrowserTab bt) =>
{
tab = bt;
StartCoroutine(tab.Update());
//StartCoroutine(createScreenshots());
StartCoroutine(tab.StartStream(900, 560, (frame) =>
{
Debug.LogWarning("stream");
rawImage.texture = frame;
rawImage.SetNativeSize();
}));
}));
}
public IEnumerator createScreenshots ()
{
yield return tab.CreateScreenshot(900, 560, (screenshot) =>
{
rawImage.texture = screenshot;
StartCoroutine(createScreenshots());
});
}
private IEnumerator getDropzoneState ()
{
Debug.LogWarning($"dropzone pre");
DomNodeWrapper doc = null;
yield return DomNodeWrapper.getDocument(tab, (document) => {
Debug.LogWarning($"dropzone 1: '{document}'");
doc = document;
StartCoroutine(document.querySelectorAll("[dropzone='copy']", (dropzones) => {
foreach (var dropzone in dropzones)
{
Debug.LogWarning($"dropzone 2: Node is Null?: '{dropzone.Node == null}'");
StartCoroutine(dropzone.getAttributes((attributes) =>
{
Debug.LogWarning($"dropzone 3 getAttributes: '{string.Join(", ", attributes.Values)}'");
}));
}
}));
});
Debug.LogWarning($"dropzone post: '{doc}'");
// alternative way to get the dropzone state
}
// Update is called once per frame
private void Update()
{
}
#region pointer event handlers
public void OnPointerDown(PointerEventData eventData)
{
Vector2Int pos = toBrowserCoordinates(eventData.position);
tab.OnPointerDown(pos, eventData);
}
public void OnPointerMove(PointerEventData eventData)
{
// TODO: transform eventData delta vector to browser coordinates
Vector2Int pos = toBrowserCoordinates(eventData.position);
tab.OnPointerMove(pos, eventData);
// On drag over
if (eventData.dragging)
{
Debug.LogWarning($"OnDragOver: {eventData.position}");
createDragEvent(DragEventType.dragOver, eventData);
}
}
public void OnPointerUp(PointerEventData eventData)
{
Vector2Int pos = toBrowserCoordinates(eventData.position);
tab.OnPointerUp(pos, eventData);
}
#endregion pointer event handlers
#region drag event handlers
public void OnPointerEnter(PointerEventData eventData)
{
if (eventData.dragging)
{
Debug.LogWarning($"OnDragEnter: {eventData.position}");
createDragEvent(DragEventType.dragEnter, eventData);
}
}
public void OnDrop(PointerEventData eventData)
{
Debug.LogWarning($"OnDrop: {eventData.position}");
createDragEvent(DragEventType.drop, eventData);
// TODO: remove debug code
StartCoroutine(getDropzoneState());
}
public void OnPointerExit(PointerEventData eventData)
{
if (eventData.dragging)
{
Debug.LogWarning($"OnDragLeave: {eventData.position}");
//createDragEvent(DragEventType.dragCancel, eventData);
tab.CancelDragging();
// TODO: drag cancel seems to be ignored by the browser
}
}
private void createDragEvent(DragEventType dragEventType, PointerEventData eventData)
{
if (eventData.pointerDrag.TryGetComponent(out BrowserDropable dropable))
{
var position = toBrowserCoordinates(eventData.position);
var dragEvent = new dispatchDragEvent
{
type = dragEventType,
data = new DragData
{
items = new DragDataItem[]
{
new DragDataItem
{
mimeType = "application/json",
data = JsonConvert.SerializeObject(dropable, serializerSettings)
}
},
dragOperationsMask = DragOperationsMask.Copy
},
x = position.x,
y = position.y,
};
Debug.LogWarning($"DragEvent: {dragEvent.type}, {eventData.position}, '{dragEvent.data.items[0].data}'");
// send the DragEvent as drag event to the browser
tab.OnDragNDrop(dragEvent);
}
}
#endregion drag event handlers
private Vector2Int toBrowserCoordinates(Vector2 eventPos)
{
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventPos, null, out localPoint);
// invert y because the browser has y=0 on the top
Vector2 invertedLocalPos = new Vector2(localPoint.x, rectTransform.rect.size.y - localPoint.y);
Vector2 browserCoorinate = tab.size / rectTransform.rect.size * invertedLocalPos;
Debug.Log($"eventPos: {eventPos}, invertedLocalPos: {invertedLocalPos}, browserCoordinate: {browserCoorinate}");
return new Vector2Int((int) browserCoorinate.x, (int) browserCoorinate.y);
}
private void OnDisable()
{
// TODO: do we want to close the browser when not in use?
// close browser when recompiling
tab.Close();
browser.Close();
}
private void OnDestroy()
{
tab.Close();
browser.Close();
}
/**
* Close all browser windows.
*/
private void OnApplicationQuit()
{
tab.Close();
browser.Close();
}
}
public interface BrowserDropable { }
}