// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine.GUI;
namespace FlaxEngine
{
partial class Window
{
///
/// Window closing delegate.
///
/// The closing reason.
/// If set to true operation will be cancelled, otherwise window will be closed.
public delegate void ClosingDelegate(ClosingReason reason, ref bool cancel);
///
/// Perform window hit test delegate.
///
/// The mouse position. The coordinate is relative to the upper-left corner of the screen. Use to convert position into client space coordinates.
/// Hit result.
public delegate WindowHitCodes HitTestDelegate(ref Float2 mouse);
///
/// Perform mouse buttons action.
///
/// The mouse position.
/// The mouse buttons state.
/// The flag that indicated that event has been handled by the custom code and should not be passed further. By default it is set to false.
public delegate void MouseButtonDelegate(ref Float2 mouse, MouseButton button, ref bool handled);
///
/// Perform mouse move action.
///
/// The mouse position.
public delegate void MouseMoveDelegate(ref Float2 mouse);
///
/// Perform mouse wheel action.
///
/// The mouse position.
/// The mouse wheel move delta (can be positive or negative; normalized to [-1;1] range).
/// The flag that indicated that event has been handled by the custom code and should not be passed further. By default it is set to false.
public delegate void MouseWheelDelegate(ref Float2 mouse, float delta, ref bool handled);
///
/// Perform touch action.
///
/// The touch pointer position.
/// The touch pointer identifier. Stable for the whole touch gesture/interaction.
/// The flag that indicated that event has been handled by the custom code and should not be passed further. By default it is set to false.
public delegate void TouchDelegate(ref Float2 pointerPosition, int pointerId, ref bool handled);
///
/// Perform input character action.
///
/// The input character.
public delegate void CharDelegate(char c);
///
/// Perform keyboard action.
///
/// The key.
public delegate void KeyboardDelegate(KeyboardKeys key);
///
/// Event fired on character input.
///
public event CharDelegate OnCharInput;
///
/// Event fired on key pressed.
///
public event KeyboardDelegate KeyDown;
///
/// Event fired on key released.
///
public event KeyboardDelegate KeyUp;
///
/// Event fired when mouse goes down.
///
public event MouseButtonDelegate MouseDown;
///
/// Event fired when mouse goes up.
///
public event MouseButtonDelegate MouseUp;
///
/// Event fired when mouse double clicks.
///
public event MouseButtonDelegate MouseDoubleClick;
///
/// Event fired when mouse wheel is scrolling.
///
public event MouseWheelDelegate MouseWheel;
///
/// Event fired when mouse moves
///
public event MouseMoveDelegate MouseMove;
///
/// Event fired when mouse leaves window.
///
public event Action MouseLeave;
///
/// Event fired when touch begins.
///
public event TouchDelegate TouchDown;
///
/// Event fired when touch moves.
///
public event TouchDelegate TouchMove;
///
/// Event fired when touch ends.
///
public event TouchDelegate TouchUp;
///
/// Event fired when window gets focus.
///
public event Action GotFocus;
///
/// Event fired when window lost focus.
///
public event Action LostFocus;
///
/// Event fired when window performs hit test, parameter is a mouse position
///
public HitTestDelegate HitTest;
///
/// Event fired when left mouse button goes down (hit test performed etc.).
/// Returns true if event has been processed and further actions should be canceled, otherwise false.
///
public Func LeftButtonHit;
///
/// Event fired when windows wants to be closed. Should return true if suspend window closing, otherwise returns false
///
public event ClosingDelegate Closing;
///
/// Event fired when gets closed and deleted, all references to the window object should be removed at this point.
///
public event Action Closed;
///
/// The window GUI root object.
///
public readonly WindowRootControl GUI;
///
/// Starts the drag and drop operation.
///
/// The data.
public void DoDragDrop(DragData data)
{
if (data is DragDataText text)
DoDragDrop(text.Text);
else
throw new NotImplementedException("Only DragDataText drag and drop is supported.");
}
private Window()
{
GUI = new WindowRootControl(this);
}
internal void Internal_OnShow()
{
GUI.UnlockChildrenRecursive();
GUI.PerformLayout();
}
internal void Internal_OnUpdate(float dt)
{
GUI.Update(dt);
}
internal void Internal_OnDraw()
{
Matrix3x3.Scaling(DpiScale, out var scale);
Render2D.PushTransform(ref scale);
GUI.Draw();
Render2D.PopTransform();
}
internal void Internal_OnResize(int width, int height)
{
GUI.Size = new Float2(width / DpiScale, height / DpiScale);
}
internal void Internal_OnCharInput(char c)
{
OnCharInput?.Invoke(c);
GUI.OnCharInput(c);
}
internal void Internal_OnKeyDown(KeyboardKeys key)
{
KeyDown?.Invoke(key);
GUI.OnKeyDown(key);
}
internal void Internal_OnKeyUp(KeyboardKeys key)
{
KeyUp?.Invoke(key);
GUI.OnKeyUp(key);
}
internal void Internal_OnMouseDown(ref Float2 mousePos, MouseButton button)
{
var pos = mousePos / DpiScale;
bool handled = false;
MouseDown?.Invoke(ref pos, button, ref handled);
if (handled)
return;
GUI.OnMouseDown(pos, button);
}
internal void Internal_OnMouseUp(ref Float2 mousePos, MouseButton button)
{
var pos = mousePos / DpiScale;
bool handled = false;
MouseUp?.Invoke(ref pos, button, ref handled);
if (handled)
return;
GUI.OnMouseUp(pos, button);
}
internal void Internal_OnMouseDoubleClick(ref Float2 mousePos, MouseButton button)
{
var pos = mousePos / DpiScale;
bool handled = false;
MouseDoubleClick?.Invoke(ref pos, button, ref handled);
if (handled)
return;
GUI.OnMouseDoubleClick(pos, button);
}
internal void Internal_OnMouseWheel(ref Float2 mousePos, float delta)
{
var pos = mousePos / DpiScale;
bool handled = false;
MouseWheel?.Invoke(ref pos, delta, ref handled);
if (handled)
return;
GUI.OnMouseWheel(pos, delta);
}
internal void Internal_OnMouseMove(ref Float2 mousePos)
{
var pos = mousePos / DpiScale;
MouseMove?.Invoke(ref pos);
GUI.OnMouseMove(pos);
}
internal void Internal_OnMouseLeave()
{
MouseLeave?.Invoke();
GUI.OnMouseLeave();
}
internal void Internal_OnTouchDown(ref Float2 pointerPosition, int pointerId)
{
var pos = pointerPosition / DpiScale;
bool handled = false;
TouchDown?.Invoke(ref pos, pointerId, ref handled);
if (handled)
return;
GUI.OnTouchDown(pos, pointerId);
}
internal void Internal_OnTouchMove(ref Float2 pointerPosition, int pointerId)
{
var pos = pointerPosition / DpiScale;
bool handled = false;
TouchMove?.Invoke(ref pos, pointerId, ref handled);
if (handled)
return;
GUI.OnTouchMove(pos, pointerId);
}
internal void Internal_OnTouchUp(ref Float2 pointerPosition, int pointerId)
{
var pos = pointerPosition / DpiScale;
bool handled = false;
TouchUp?.Invoke(ref pos, pointerId, ref handled);
if (handled)
return;
GUI.OnTouchUp(pos, pointerId);
}
internal void Internal_OnGotFocus()
{
GotFocus?.Invoke();
GUI.OnGotFocus();
}
internal void Internal_OnLostFocus()
{
LostFocus?.Invoke();
GUI.OnLostFocus();
}
internal void Internal_OnHitTest(ref Float2 mousePos, ref WindowHitCodes result, ref bool handled)
{
if (HitTest != null)
{
var pos = mousePos / DpiScale;
result = HitTest(ref pos);
handled = true;
}
}
internal void Internal_OnLeftButtonHit(WindowHitCodes hit, ref bool result)
{
if (LeftButtonHit != null)
{
result = LeftButtonHit(hit);
}
}
internal DragDropEffect Internal_OnDragEnter(ref Float2 mousePos, bool isText, string[] data)
{
DragData dragData;
if (isText)
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
var pos = mousePos / DpiScale;
return GUI.OnDragEnter(ref pos, dragData);
}
internal DragDropEffect Internal_OnDragOver(ref Float2 mousePos, bool isText, string[] data)
{
DragData dragData;
if (isText)
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
var pos = mousePos / DpiScale;
return GUI.OnDragMove(ref pos, dragData);
}
internal DragDropEffect Internal_OnDragDrop(ref Float2 mousePos, bool isText, string[] data)
{
DragData dragData;
if (isText)
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
var pos = mousePos / DpiScale;
return GUI.OnDragDrop(ref pos, dragData);
}
internal void Internal_OnDragLeave()
{
GUI.OnDragLeave();
}
internal void Internal_OnClosing(ClosingReason reason, ref bool cancel)
{
Closing?.Invoke(reason, ref cancel);
}
internal void Internal_OnClosed()
{
Closed?.Invoke();
GUI.Dispose();
// Force clear all events (we cannot use window after close)
KeyDown = null;
KeyUp = null;
MouseLeave = null;
MouseDown = null;
MouseUp = null;
MouseDoubleClick = null;
MouseWheel = null;
MouseMove = null;
TouchDown = null;
TouchMove = null;
TouchUp = null;
GotFocus = null;
LostFocus = null;
LeftButtonHit = null;
HitTest = null;
Closing = null;
Closed = null;
}
}
}