2023-05-13 15:17:57 +02:00
|
|
|
using System;
|
2023-06-29 09:42:02 +02:00
|
|
|
using Quik.CommandMachine;
|
2023-05-13 15:17:57 +02:00
|
|
|
|
|
|
|
namespace Quik.Controls
|
|
|
|
{
|
|
|
|
public class Control
|
|
|
|
{
|
|
|
|
public string Name { get; set; } = null;
|
|
|
|
|
|
|
|
public Control Parent { get; set; } = null;
|
|
|
|
|
|
|
|
protected RootControl Root { get; set; } = null;
|
|
|
|
|
2023-06-29 09:42:02 +02:00
|
|
|
public QRectangle Bounds { get; set; }
|
2023-05-13 15:17:57 +02:00
|
|
|
|
|
|
|
public bool Focused { get => Root.FocusedControl == this; }
|
|
|
|
|
2023-06-29 09:42:02 +02:00
|
|
|
public QRectangle AbsoluteBounds
|
2023-05-13 15:17:57 +02:00
|
|
|
{
|
|
|
|
get => Parent is null
|
|
|
|
? Bounds
|
2023-06-29 09:42:02 +02:00
|
|
|
: new QRectangle(Parent.Bounds.Min + Bounds.Max, Parent.Bounds.Min + Bounds.Min);
|
2023-05-13 15:17:57 +02:00
|
|
|
set => Bounds = Parent is null
|
|
|
|
? value
|
2023-06-29 09:42:02 +02:00
|
|
|
: new QRectangle(value.Min - Parent.Bounds.Min, value.Max - Parent.Bounds.Min);
|
2023-05-13 15:17:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private MouseButton DownButtons;
|
|
|
|
|
|
|
|
// Hierarchy events.
|
|
|
|
|
|
|
|
public event EventHandler Update;
|
2023-06-29 09:42:02 +02:00
|
|
|
public event EventHandler<CommandQueue> Paint;
|
2023-05-13 15:17:57 +02:00
|
|
|
public event EventHandler<RootChangedEventArgs> RootChanging;
|
|
|
|
public event EventHandler<ParentChangedEventArgs> ParentChanging;
|
|
|
|
public event EventHandler<FocusChangedEventArgs> FocusLost;
|
|
|
|
public event EventHandler<FocusChangedEventArgs> FocusAcquired;
|
|
|
|
|
|
|
|
// Mouse events.
|
|
|
|
|
|
|
|
public event EventHandler<MouseButtonEventArgs> Clicked;
|
|
|
|
public event EventHandler<MouseButtonEventArgs> MouseDown;
|
|
|
|
public event EventHandler<MouseButtonEventArgs> MouseUp;
|
|
|
|
public event EventHandler<MouseMoveEventArgs> MouseEnter;
|
|
|
|
public event EventHandler<MouseMoveEventArgs> MouseMove;
|
|
|
|
// public event EventHandler<MouseMoveEventArgs> MouseHover;
|
|
|
|
public event EventHandler<MouseMoveEventArgs> MouseLeave;
|
|
|
|
|
|
|
|
protected virtual void OnUpdate() => Update?.Invoke(this, EventArgs.Empty);
|
2023-06-29 09:42:02 +02:00
|
|
|
protected virtual void OnPaint(CommandQueue draw) => Paint?.Invoke(this, draw);
|
2023-05-13 15:17:57 +02:00
|
|
|
protected virtual void OnParentChanging(ParentChangedEventArgs args) => ParentChanging?.Invoke(this, args);
|
|
|
|
protected virtual void OnRootChanging(RootChangedEventArgs args) => RootChanging?.Invoke(this, args);
|
|
|
|
protected virtual void OnFocusLost(FocusChangedEventArgs args) => FocusLost?.Invoke(this, args);
|
|
|
|
protected virtual void OnFocusAcquired(FocusChangedEventArgs args) => FocusAcquired?.Invoke(this, args);
|
|
|
|
|
|
|
|
protected virtual void OnClicked(MouseButtonEventArgs args) => Clicked?.Invoke(this, args);
|
|
|
|
protected virtual void OnMouseDown(MouseButtonEventArgs args) => MouseDown?.Invoke(this, args);
|
|
|
|
protected virtual void OnMouseUp(MouseButtonEventArgs args) => MouseUp?.Invoke(this, args);
|
|
|
|
protected virtual void OnMouseEnter(MouseMoveEventArgs args) => MouseEnter?.Invoke(this, args);
|
|
|
|
protected virtual void OnMouseMove(MouseMoveEventArgs args) => MouseMove?.Invoke(this, args);
|
|
|
|
// protected virtual void OnMouseHover(MouseMoveEventArgs args) => MouseHover?.Invoke(this, args);
|
|
|
|
protected virtual void OnMouseLeave(MouseMoveEventArgs args) => MouseLeave?.Invoke(this, args);
|
|
|
|
|
|
|
|
public void Focus()
|
|
|
|
{
|
|
|
|
Root?.Focus(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyUpdate()
|
|
|
|
{
|
|
|
|
OnUpdate();
|
|
|
|
}
|
|
|
|
|
2023-06-29 09:42:02 +02:00
|
|
|
internal virtual void NotifyPaint(CommandQueue draw)
|
2023-05-13 15:17:57 +02:00
|
|
|
{
|
|
|
|
OnPaint(draw);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void NotifyFocusChanged(FocusChangedEventArgs args)
|
|
|
|
{
|
|
|
|
if (args.Focused == this)
|
|
|
|
{
|
|
|
|
OnFocusAcquired(args);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OnFocusLost(args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyParentChanged(ParentChangedEventArgs args)
|
|
|
|
{
|
|
|
|
OnParentChanging(args);
|
|
|
|
Parent = args.NewParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyRootChanged(RootChangedEventArgs args)
|
|
|
|
{
|
|
|
|
OnRootChanging(args);
|
|
|
|
Root = args.NewRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyMouseMove(MouseMoveEventArgs args)
|
|
|
|
{
|
2023-06-29 09:42:02 +02:00
|
|
|
QRectangle bounds = AbsoluteBounds;
|
2023-05-13 15:17:57 +02:00
|
|
|
|
|
|
|
if (bounds.Contains(args.AbsolutePosition))
|
|
|
|
{
|
|
|
|
if (!bounds.Contains(args.AbsolutePosition - args.Motion))
|
|
|
|
{
|
|
|
|
OnMouseEnter(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
OnMouseMove(args);
|
|
|
|
}
|
|
|
|
else if (bounds.Contains(args.AbsolutePosition - args.Motion))
|
|
|
|
{
|
|
|
|
OnMouseLeave(args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyMouseDown(MouseButtonEventArgs args)
|
|
|
|
{
|
|
|
|
if (AbsoluteBounds.Contains(args.AbsolutePosition))
|
|
|
|
{
|
|
|
|
OnMouseDown(args);
|
|
|
|
DownButtons = args.Buttons;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void NotifyMouseUp(MouseButtonEventArgs args)
|
|
|
|
{
|
|
|
|
if (AbsoluteBounds.Contains(args.AbsolutePosition))
|
|
|
|
{
|
|
|
|
MouseButton mask;
|
|
|
|
|
|
|
|
OnMouseUp(args);
|
|
|
|
|
|
|
|
if ((mask = DownButtons & args.Buttons) > 0)
|
|
|
|
{
|
|
|
|
MouseButtonEventArgs nargs = new MouseButtonEventArgs(args.AbsolutePosition, mask);
|
|
|
|
Focus();
|
|
|
|
OnClicked(nargs);
|
|
|
|
}
|
|
|
|
|
|
|
|
DownButtons &= ~mask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DownButtons = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|