csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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.
275 lines
7.6 KiB
275 lines
7.6 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reactive;
|
|
using System.Reactive.Disposables;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Gpu;
|
|
using Avalonia.Input;
|
|
using Avalonia.Input.Raw;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Rendering;
|
|
using Avalonia.Threading;
|
|
using Avalonia.Windowing.Bindings;
|
|
|
|
namespace Avalonia.Windowing
|
|
{
|
|
public class WindowImpl : IWindowImpl
|
|
{
|
|
IWindowWrapper _windowWrapper;
|
|
private LogicalPosition _lastPosition;
|
|
|
|
const int FramesPerSecond = 60;
|
|
|
|
public WindowImpl(IWindowWrapper wrapper)
|
|
{
|
|
_windowWrapper = wrapper;
|
|
|
|
// TODO: This is only necessary when using ImmediateRenderer
|
|
Observable.Repeat(Observable.Timer(TimeSpan.FromMilliseconds(1000 / FramesPerSecond)))
|
|
.SubscribeOn(AvaloniaScheduler.Instance)
|
|
.Subscribe((x) =>
|
|
{
|
|
// Dont schedule a paint for empty invalidations.
|
|
if (coalescedRect != Rect.Empty) {
|
|
Dispatcher.UIThread.Post(() => Paint(coalescedRect), DispatcherPriority.Render);
|
|
coalescedRect = Rect.Empty;
|
|
}
|
|
});
|
|
}
|
|
|
|
public WindowState WindowState { get; set; }
|
|
public Action<WindowState> WindowStateChanged { get; set; }
|
|
public Func<bool> Closing { get; set; }
|
|
public Point Position
|
|
{
|
|
get
|
|
{
|
|
var (x, y) = _windowWrapper.GetPosition();
|
|
return new Point(x, y);
|
|
}
|
|
set
|
|
{
|
|
// TODO: SetPosition
|
|
var x = value;
|
|
}
|
|
}
|
|
|
|
public bool timeToPaint = false;
|
|
|
|
public void Test() {
|
|
timeToPaint = true;
|
|
}
|
|
|
|
public Action<Point> PositionChanged { get; set; }
|
|
public Action Deactivated { get; set; }
|
|
public Action Activated { get; set; }
|
|
|
|
public IPlatformHandle Handle => new DummyPlatformHandle();
|
|
|
|
public Size MaxClientSize => Size.Empty;
|
|
|
|
public IScreenImpl Screen => new Monitors();
|
|
|
|
public Size ClientSize
|
|
{
|
|
get
|
|
{
|
|
var (width, height) = _windowWrapper.GetSize();
|
|
return new Size(width, height);
|
|
}
|
|
}
|
|
|
|
public double Scaling => _windowWrapper.GetScaleFactor();
|
|
|
|
public IEnumerable<object> Surfaces => new List<object>() { _windowWrapper };
|
|
|
|
public Action<RawInputEventArgs> Input { get; set; }
|
|
public Action<Rect> Paint { get; set; }
|
|
public Action<Size> Resized { get; set; }
|
|
public Action<double> ScalingChanged { get; set; }
|
|
public Action Closed { get; set; }
|
|
|
|
public IMouseDevice MouseDevice => AvaloniaLocator.Current.GetService<IMouseDevice>();
|
|
public IKeyboardDevice KeyboardDevice => AvaloniaLocator.Current.GetService<IKeyboardDevice>();
|
|
|
|
public void Activate()
|
|
{
|
|
}
|
|
|
|
public void BeginMoveDrag()
|
|
{
|
|
}
|
|
|
|
public void BeginResizeDrag(WindowEdge edge)
|
|
{
|
|
}
|
|
|
|
public void CanResize(bool value)
|
|
{
|
|
}
|
|
|
|
public IRenderer CreateRenderer(IRenderRoot root)
|
|
{
|
|
return new ImmediateRenderer(root);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_windowWrapper.Dispose();
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
_windowWrapper.Hide();
|
|
}
|
|
|
|
private Rect coalescedRect = Rect.Empty;
|
|
public void Invalidate(Rect rect)
|
|
{
|
|
coalescedRect = coalescedRect.Union(rect);
|
|
}
|
|
|
|
public Point PointToClient(Point point)
|
|
{
|
|
var position = Position;
|
|
return new Point(point.X + position.X, point.Y + position.Y);
|
|
}
|
|
|
|
public Point PointToScreen(Point point)
|
|
{
|
|
var position = Position;
|
|
return new Point(point.X - position.X, point.Y - position.Y); ;
|
|
}
|
|
|
|
public void Resize(Size clientSize)
|
|
{
|
|
if (clientSize == ClientSize)
|
|
return;
|
|
|
|
_windowWrapper.SetSize(clientSize.Width, clientSize.Height);
|
|
}
|
|
|
|
public void SetCursor(IPlatformHandle cursor)
|
|
{
|
|
}
|
|
|
|
public void SetIcon(IWindowIconImpl icon)
|
|
{
|
|
}
|
|
|
|
private IInputRoot _inputRoot;
|
|
public void SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot;
|
|
|
|
public void SetMinMaxSize(Size minSize, Size maxSize)
|
|
{
|
|
}
|
|
|
|
public void SetSystemDecorations(bool enabled)
|
|
{
|
|
_windowWrapper.ToggleDecorations(enabled);
|
|
}
|
|
|
|
public void SetTitle(string title)
|
|
{
|
|
_windowWrapper.SetTitle(title);
|
|
}
|
|
|
|
public void SetTopmost(bool value)
|
|
{
|
|
}
|
|
|
|
public void Show()
|
|
{
|
|
_windowWrapper.Show();
|
|
}
|
|
|
|
public IDisposable ShowDialog()
|
|
{
|
|
return Disposable.Create(() => {});
|
|
}
|
|
|
|
public void ShowTaskbarIcon(bool value)
|
|
{
|
|
}
|
|
|
|
public void OnCharacterEvent(CharacterEvent evt)
|
|
{
|
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
|
|
var timeStamp = (uint)Environment.TickCount;
|
|
|
|
Input
|
|
(
|
|
new RawTextInputEventArgs
|
|
(
|
|
KeyboardDevice,
|
|
timeStamp,
|
|
evt.Character.ToString()
|
|
)
|
|
);
|
|
}
|
|
|
|
public void OnKeyboardEvent (KeyboardEvent evt)
|
|
{
|
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
|
|
var eventType = evt.Pressed == 1 ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp;
|
|
var timeStamp = (uint)Environment.TickCount;
|
|
|
|
Input
|
|
(
|
|
new RawKeyEventArgs
|
|
(
|
|
KeyboardDevice,
|
|
timeStamp,
|
|
eventType,
|
|
KeyTransform.TransformKeyCode(evt.VirtualKeyCode).Value,
|
|
InputModifiers.None
|
|
)
|
|
);
|
|
}
|
|
|
|
public void OnMouseEvent(MouseEvent evt)
|
|
{
|
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
|
|
var eventType = (RawMouseEventType)evt.EventType;
|
|
var timeStamp = (uint)Environment.TickCount;
|
|
|
|
if (evt.EventType == MouseEventType.Move)
|
|
_lastPosition = evt.Position;
|
|
|
|
Input
|
|
(
|
|
eventType != RawMouseEventType.Wheel ?
|
|
new RawMouseEventArgs
|
|
(
|
|
MouseDevice,
|
|
timeStamp,
|
|
_inputRoot,
|
|
eventType,
|
|
new Point(_lastPosition.X, _lastPosition.Y),
|
|
InputModifiers.None
|
|
)
|
|
:
|
|
new RawMouseWheelEventArgs
|
|
(
|
|
MouseDevice,
|
|
timeStamp,
|
|
_inputRoot,
|
|
new Point(_lastPosition.X, _lastPosition.Y),
|
|
new Point(evt.Position.X, evt.Position.Y),
|
|
InputModifiers.None
|
|
)
|
|
);
|
|
}
|
|
|
|
public void OnResizeEvent(ResizeEvent evt)
|
|
{
|
|
Resized?.Invoke(ClientSize);
|
|
if (_windowWrapper is IGpuContext gpuCtx) {
|
|
gpuCtx.ResizeContext(ClientSize.Width, ClientSize.Height);
|
|
}
|
|
}
|
|
}
|
|
}
|