123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Windows;
- using System.Windows.Controls;
- using InABox.Configuration;
- using InABox.Core;
- namespace InABox.Wpf;
- public interface IPanelActionItem
- {
- }
- public interface IPanelActionEntry
- {
- object? Data { get; set; }
- string? Caption { get; set; }
- Bitmap? Image { get; set; }
- void Execute();
- }
- public class PanelActionEntry<T> : DependencyObject, IPanelActionEntry
- {
-
- public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
- nameof(Data),
- typeof(T),
- typeof(PanelActionEntry<T>)
- );
- public T? Data { get; set; }
- object? IPanelActionEntry.Data
- {
- get => this.Data;
- set => this.Data = value == null ? default(T) : (T)value;
- }
-
- public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
- nameof(Caption),
- typeof(string),
- typeof(PanelActionEntry<T>),
- new PropertyMetadata("")
- );
- public string? Caption { get; set; }
-
- public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
- nameof(Image),
- typeof(Bitmap),
- typeof(PanelActionEntry<T>)
- );
- public Bitmap? Image
- {
- get => GetValue(ImageProperty) as Bitmap;
- set => SetValue(ImageProperty, value);
- }
-
- public Action<PanelActionEntry<T>>? OnExecute { get; set; }
- public PanelActionEntry()
- {
-
- }
-
- public PanelActionEntry(string? caption, Bitmap? image, T? data, Action<PanelActionEntry<T>>? onExecute)
- {
- Data = data;
- Caption = caption;
- Image = image;
- OnExecute = onExecute;
- }
- public void Execute()
- {
- OnExecute?.Invoke(this);
- }
-
- }
- public class PanelAction : DependencyObject, IPanelActionItem
- {
- public Func<PanelAction,IPanelActionEntry[]>? OnPopulate { get; set; }
- public Action<PanelAction>? OnExecute { get; set; }
-
-
- public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register(
- nameof(IsEnabled),
- typeof(bool),
- typeof(PanelAction),
- new PropertyMetadata(true)
- );
-
- public bool IsEnabled
- {
- get => (bool)GetValue(IsEnabledProperty);
- set => SetValue(IsEnabledProperty, value);
- }
-
-
- public static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register(
- nameof(Visibility),
- typeof(Visibility),
- typeof(PanelAction),
- new PropertyMetadata(Visibility.Visible)
- );
-
- public Visibility Visibility
- {
- get => (Visibility)GetValue(VisibilityProperty);
- set => SetValue(VisibilityProperty, value);
- }
- public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
- nameof(Caption),
- typeof(string),
- typeof(PanelAction),
- new PropertyMetadata("")
- );
-
- public string Caption
- {
- get => (string)GetValue(CaptionProperty);
- set => SetValue(CaptionProperty, value);
- }
- public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
- nameof(Image),
- typeof(Bitmap),
- typeof(PanelAction)
- );
- public Bitmap? Image
- {
- get => GetValue(ImageProperty) as Bitmap;
- set => SetValue(ImageProperty, value);
- }
-
- public static readonly DependencyProperty MenuProperty = DependencyProperty.Register(
- nameof(Menu),
- typeof(ContextMenu),
- typeof(PanelAction)
- );
-
- public ContextMenu? Menu
- {
- get => GetValue(MenuProperty) as ContextMenu;
- set => SetValue(MenuProperty, value);
- }
- public PanelAction()
- {
- }
- public PanelAction(string caption, Bitmap? image, Action<PanelAction>? onExecute,
- Func<PanelAction, IPanelActionEntry[]>? onPopulate = null)
- {
- Caption = caption;
- Image = image;
- OnPopulate = onPopulate;
- OnExecute = onExecute;
- }
-
- public void Execute()
- {
- OnExecute?.Invoke(this);
- }
- public IPanelActionEntry[]? Populate()
- {
- return OnPopulate?.Invoke(this);
- }
-
- }
- public class PanelActionSeparator : IPanelActionItem
- {
- }
- public interface ICorePanel
- {
- void Setup();
- /// <summary>
- /// Shutdown the panel.
- /// </summary>
- /// <param name="cancel">If the operation can be cancelled, this is not <see langword="null"/></param>
- void Shutdown(CancelEventArgs? cancel);
- void Refresh();
- }
- public interface IBasePanel : ICorePanel, IDataModelSource
- {
- bool IsReady { get; set; }
- void CreateToolbarButtons(IPanelHost host);
- Dictionary<string, object[]> Selected();
- void Heartbeat(TimeSpan time);
- }
- public interface IPanel<T> : IBasePanel
- {
- }
- public interface IPropertiesPanel<TProperties>
- where TProperties : BaseObject, IGlobalConfigurationSettings, new()
- {
- public TProperties Properties { get; set; }
- }
- public interface IPropertiesPanel<TProperties, TSecurity> : IPropertiesPanel<TProperties>
- where TProperties : BaseObject, IGlobalConfigurationSettings, new()
- where TSecurity : ISecurityDescriptor, new()
- {
- }
- public interface IPanelHost
- {
- void CreatePanelAction(PanelAction action);
- void CreateReport(PanelAction action);
- void CreateSetupAction(PanelAction action);
- void CreateSetupSeparator();
- }
- public static class IPanelHostExtensions
- {
- public static void CreateSetupAction(this IPanelHost host, string caption, Bitmap image, Action<PanelAction> onExecute, ContextMenu? menu = null)
- {
- host.CreateSetupAction(new PanelAction(caption, image, onExecute) { Menu = menu });
- }
- public static void CreateSetupActionIf(this IPanelHost host, string caption, Bitmap image, Action<PanelAction> onExecute, bool canView, ContextMenu? menu = null)
- {
- if (canView)
- {
- host.CreateSetupAction(new PanelAction(caption, image, onExecute) { Menu = menu });
- }
- }
- public static void CreateSetupActionIf<TSecurity>(this IPanelHost host, string caption, Bitmap image, Action<PanelAction> onExecute, ContextMenu? menu = null)
- where TSecurity : ISecurityDescriptor, new()
- {
- host.CreateSetupActionIf(caption, image, onExecute, Security.IsAllowed<TSecurity>(), menu);
- }
- public static void CreateSetupActionIfCanView<T>(this IPanelHost host, string caption, Bitmap image, Action<PanelAction> onExecute, ContextMenu? menu = null)
- where T : Entity, new()
- {
- host.CreateSetupActionIf(caption, image, onExecute, Security.CanView<T>(), menu);
- }
- }
- /// <summary>
- /// Implement this interface to cause a class to act as a host of <see cref="ISubPanel"/>. Then, you can use the extension functions
- /// <see cref="ISubPanelHostExtensions.ShutdownSubPanels(ISubPanelHost, CancelEventArgs?)"/> and
- /// <see cref="ISubPanelHostExtensions.AddSubPanel(ISubPanelHost, ISubPanel)"/> to interact with it.
- /// </summary>
- /// <remarks>
- /// If you mark an <see cref="IPanel{T}"/> as an <see cref="ISubPanelHost"/>, then the shutdown method is called automatically by <see cref="IPanelHost"/>.
- /// </remarks>
- public interface ISubPanelHost
- {
- List<ISubPanel> SubPanels { get; }
- static ISubPanelHost Global = new GlobalSubPanelHost();
- private class GlobalSubPanelHost : ISubPanelHost
- {
- public List<ISubPanel> SubPanels { get; set; } = new();
- }
- }
- public static class ISubPanelHostExtensions
- {
- public static void ShutdownSubPanels(this ISubPanelHost host, CancelEventArgs? cancel)
- {
- ISubPanel[] panels;
- lock (host.SubPanels)
- {
- panels = host.SubPanels.ToArray();
- host.SubPanels.Clear();
- var isCancelled = false;
- foreach(var panel in panels)
- {
- if (isCancelled)
- {
- host.SubPanels.Add(panel);
- }
- else
- {
- panel.Shutdown(cancel);
- if (cancel?.Cancel == true)
- {
- isCancelled = true;
- host.SubPanels.Add(panel);
- }
- }
- }
- }
- }
- public static void AddSubPanel(this ISubPanelHost host, ISubPanel panel)
- {
- host.SubPanels.Add(panel);
- panel.SubPanelClosed += p =>
- {
- lock (host.SubPanels)
- {
- host.SubPanels.Remove(p);
- }
- };
- }
- }
- /// <summary>
- /// An <see cref="ISubPanel"/> is a non-modal window, which is tied to a parent
- /// </summary>
- public interface ISubPanel
- {
- public delegate void ClosedEvent(ISubPanel panel);
- /// <summary>
- /// Event to be called when a sub-panel closes itself; in this case, <see cref="Shutdown(CancelEventArgs?)"/> will not be called. This allows
- /// the host to get rid of the sub-panel, instead of keeping it forever.
- /// </summary>
- /// <remarks>
- /// You may call this after <see cref="Shutdown(CancelEventArgs?)"/> has been called.
- /// </remarks>
- public event ClosedEvent? SubPanelClosed;
- /// <summary>
- /// Shutdown the panel.
- /// </summary>
- /// <param name="cancel">If the operation can be cancelled, this is not <see langword="null"/></param>
- void Shutdown(CancelEventArgs? cancel);
- }
|