Dashboard/Quik/Controls/Control.cs

154 lines
5.3 KiB
C#
Raw Normal View History

using System;
using Quik.CommandMachine;
namespace Quik.Controls
{
public class Control
{
public string Name { get; set; } = null;
public Control Parent { get; set; } = null;
protected RootControl Root { get; set; } = null;
public QRectangle Bounds { get; set; }
public bool Focused { get => Root.FocusedControl == this; }
public QRectangle AbsoluteBounds
{
get => Parent is null
? Bounds
: new QRectangle(Parent.Bounds.Min + Bounds.Max, Parent.Bounds.Min + Bounds.Min);
set => Bounds = Parent is null
? value
: new QRectangle(value.Min - Parent.Bounds.Min, value.Max - Parent.Bounds.Min);
}
private MouseButton DownButtons;
// Hierarchy events.
public event EventHandler Update;
public event EventHandler<CommandQueue> Paint;
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);
protected virtual void OnPaint(CommandQueue draw) => Paint?.Invoke(this, draw);
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();
}
internal virtual void NotifyPaint(CommandQueue draw)
{
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)
{
QRectangle bounds = AbsoluteBounds;
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;
}
}
}
}