Files
Dashboard/Dashboard/Controls/Control.cs
T

182 lines
4.9 KiB
C#

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Numerics;
using Dashboard.Drawing;
using Dashboard.Events;
using Dashboard.Layout;
using Dashboard.Pal;
using Dashboard.Windowing;
namespace Dashboard.Controls
{
public class Control : IEventListener, ILayoutItem, IDisposable
{
private Form? _owner = null;
public string? Id { get; set; }
public Form Owner
{
get => _owner ?? throw NoOwnerException;
protected set
{
_owner = value;
OnOwnerChanged(value);
}
}
public Control? Parent { get; private set; } = null;
public bool Disposed { get; private set; }
public virtual Box2d ClientArea { get; set; }
public bool IsFocused => _owner?.FocusedControl == this;
public Brush Background { get; set; } = new SolidColorBrush(Color.Transparent);
public Brush BorderBrush { get; set; } = new SolidColorBrush(Color.Black);
public LayoutInfo Layout { get; } = new LayoutInfo();
public bool IsLayoutEnabled { get; private set; } = true;
protected bool IsLayoutValid { get; set; } = false;
public event EventHandler<DeviceContext>? Painting;
public event EventHandler<TickEventArgs>? AnimationTick;
public event EventHandler? OwnerChanged;
public event EventHandler? ParentChanged;
public event EventHandler? FocusGained;
public event EventHandler? FocusLost;
public event EventHandler? Disposing;
public event EventHandler? Resized;
public virtual Vector2 CalculateIntrinsicSize()
{
return Vector2.Zero;
// return Vector2.Max(Vector2.Zero, Vector2.Max(Layout.Size, Layout.MinimumSize));
}
public Vector2 CalculateSize(Vector2 limits)
{
return CalculateIntrinsicSize();
}
public virtual void OnPaint(DeviceContext dc)
{
Painting?.Invoke(this, dc);
}
public virtual void OnAnimationTick(TickEventArgs tick)
{
AnimationTick?.Invoke(this, tick);
}
protected void InvokeDispose(bool disposing)
{
if (Disposed)
return;
Disposed = true;
Dispose(disposing);
if (disposing)
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing) Disposing?.Invoke(this, EventArgs.Empty);
}
public void Dispose() => InvokeDispose(true);
public event EventHandler? EventRaised;
protected virtual void OnEventRaised(object? sender, EventArgs args)
{
switch (args)
{
case PaintEventArgs paint:
OnPaint(paint.DeviceContext);
break;
}
EventRaised?.Invoke(this, TransformEvent(sender, args));
}
protected virtual EventArgs TransformEvent(object? sender, EventArgs args)
{
return args;
}
public void SendEvent(object? sender, EventArgs args)
{
OnEventRaised(sender, args);
}
internal static void SetParent(Container parent, Control child)
{
child.Parent = parent;
child.ParentChanged?.Invoke(child, EventArgs.Empty);
}
public virtual void Focus()
{
(Owner ?? throw NoOwnerException).Focus(this);
}
protected virtual void OnFocusGained(object sender)
{
FocusGained?.Invoke(sender, EventArgs.Empty);
}
protected virtual void OnFocusLost(object sender)
{
FocusLost?.Invoke(sender, EventArgs.Empty);
}
internal static void InvokeFocusGained(Form form, Control control)
{
control.OnFocusGained(form);
}
internal static void InvokeFocusLost(Form form, Control control)
{
control.OnFocusLost(form);
}
protected virtual void OnResize()
{
Resized?.Invoke(this, EventArgs.Empty);
InvalidateLayout();
}
private void OnOwnerChanged(Form value)
{
OwnerChanged?.Invoke(this, EventArgs.Empty);
}
public void InvalidateLayout()
{
IsLayoutValid = false;
}
protected virtual void ValidateLayout()
{
IsLayoutValid = true;
}
public void ResumeLayout()
{
IsLayoutEnabled = true;
}
public void SuspendLayout()
{
IsLayoutEnabled = false;
IsLayoutValid = false;
}
protected static Exception NoOwnerException => new Exception("No form owns this control");
public event PropertyChangedEventHandler? PropertyChanged;
}
}