/* TODO: Refactor as popup, detach from the window renderer */ using System.Windows.Controls; using WPFluent.Input; // ReSharper disable once CheckNamespace namespace WPFluent.Controls; /// /// Snackbar inform user of a process that an app has performed or will perform. It appears temporarily, towards the /// bottom of the window. /// public class Snackbar : ContentControl, IAppearanceControl, IIconControl { /// /// Identifies the dependency property. /// public static readonly DependencyProperty AppearanceProperty = DependencyProperty.Register( nameof(Appearance), typeof(ControlAppearance), typeof(Snackbar), new PropertyMetadata(ControlAppearance.Secondary)); /// /// Identifies the routed event. /// public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent( nameof(Closed), RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(Snackbar)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty ContentForegroundProperty = DependencyProperty.Register( nameof(ContentForeground), typeof(Brush), typeof(Snackbar), new FrameworkPropertyMetadata(SystemColors.ControlTextBrush, FrameworkPropertyMetadataOptions.Inherits)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), typeof(Snackbar), new PropertyMetadata(null, null, IconElement.Coerce)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty IsCloseButtonEnabledProperty = DependencyProperty.Register( nameof(IsCloseButtonEnabled), typeof(bool), typeof(Snackbar), new PropertyMetadata(true)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty IsShownProperty = DependencyProperty.Register( nameof(IsShown), typeof(bool), typeof(Snackbar), new PropertyMetadata(false, (d, e) => (d as Snackbar)?.OnIsShownChanged(e))); /// /// Identifies the routed event. /// public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent( nameof(Opened), RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(Snackbar)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty SlideTransformProperty = DependencyProperty.Register( nameof(SlideTransform), typeof(TranslateTransform), typeof(Snackbar), new PropertyMetadata(null)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(IRelayCommand), typeof(Snackbar), new PropertyMetadata(null)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty TimeoutProperty = DependencyProperty.Register( nameof(Timeout), typeof(TimeSpan), typeof(Snackbar), new PropertyMetadata(TimeSpan.FromSeconds(2))); /// /// Identifies the dependency property. /// public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( nameof(Title), typeof(object), typeof(Snackbar), new PropertyMetadata(null)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register( nameof(TitleTemplate), typeof(DataTemplate), typeof(Snackbar), new PropertyMetadata(null)); /// /// Initializes a new instance of the class with a specified presenter. /// /// The to manage the snackbar's display and interactions. public Snackbar(SnackbarPresenter presenter) { Presenter = presenter; SetValue(TemplateButtonCommandProperty, new RelayCommand(_ => Hide())); } /// /// Occurs when the snackbar is about to close. /// public event TypedEventHandler Closed { add => AddHandler(ClosedEvent, value); remove => RemoveHandler(ClosedEvent, value); } /// /// Occurs when the snackbar is about to open. /// public event TypedEventHandler Opened { add => AddHandler(OpenedEvent, value); remove => RemoveHandler(OpenedEvent, value); } /// /// Hides the /// protected virtual void Hide() { Presenter.HideCurrent(); } /// /// This virtual method is called when is closing and it raises the . /// protected virtual void OnClosed() { RaiseEvent(new RoutedEventArgs(ClosedEvent, this)); } protected void OnIsShownChanged(DependencyPropertyChangedEventArgs e) { bool newValue = (bool)e.NewValue; if (newValue) { OnOpened(); } else { OnClosed(); } } /// /// This virtual method is called when is opening and it raises the . /// protected virtual void OnOpened() { RaiseEvent(new RoutedEventArgs(OpenedEvent, this)); } protected SnackbarPresenter Presenter { get; } /// /// Shows the /// public virtual void Show() { Show(false); } /// /// Shows the /// public virtual void Show(bool immediately) { if (immediately) { Presenter.ImmediatelyDisplay(this); } else { Presenter.AddToQue(this); } } /// /// Shows the . /// public virtual Task ShowAsync() { return ShowAsync(false); } /// /// Shows the . /// public virtual async Task ShowAsync(bool immediately) { if (immediately) { await Presenter.ImmediatelyDisplay(this); } else { Presenter.AddToQue(this); } } /// [Bindable(true)] [Category("Appearance")] public ControlAppearance Appearance { get => (ControlAppearance)GetValue(AppearanceProperty); set => SetValue(AppearanceProperty, value); } /// /// Gets or sets the foreground of the . /// [Bindable(true)] [Category("Appearance")] public Brush ContentForeground { get => (Brush)GetValue(ContentForegroundProperty); set => SetValue(ContentForegroundProperty, value); } /// /// Gets or sets the icon /// [Bindable(true)] [Category("Appearance")] public IconElement? Icon { get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } /// /// Gets or sets a value indicating whether the close button should be visible. /// public bool IsCloseButtonEnabled { get => (bool)GetValue(IsCloseButtonEnabledProperty); set => SetValue(IsCloseButtonEnabledProperty, value); } /// /// Gets or sets a value indicating whether the is visible. /// public bool IsShown { get => (bool)GetValue(IsShownProperty); set => SetValue(IsShownProperty, value); } /// /// Gets or sets the transform. /// public TranslateTransform? SlideTransform { get => (TranslateTransform?)GetValue(SlideTransformProperty); set => SetValue(SlideTransformProperty, value); } /// /// Gets the command triggered after clicking the button in the template. /// internal IRelayCommand TemplateButtonCommand => (IRelayCommand)GetValue(TemplateButtonCommandProperty); /// /// Gets or sets a time for which the should be visible. /// public TimeSpan Timeout { get => (TimeSpan)GetValue(TimeoutProperty); set => SetValue(TimeoutProperty, value); } /// /// Gets or sets the title of the . /// public object? Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); } /// /// Gets or sets the title template of the . /// public DataTemplate? TitleTemplate { get => (DataTemplate?)GetValue(TitleTemplateProperty); set => SetValue(TitleTemplateProperty, value); } }