using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using MaterialDesignThemes.Wpf; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.UI.Windows; using System.Windows.Media; using Tango.Core; using System.Collections.ObjectModel; using Tango.SharedUI; using System.Collections.Concurrent; namespace Tango.MachineStudio.UI.Notifications { /// /// Represents the default Machine Studio Notification Provider. /// /// /// public class DefaultNotificationProvider : ExtendedObject, INotificationProvider { private int _message_count = 0; /// /// The view types /// private static List viewTypes; /// /// Gets the collection of active task items. /// public ObservableCollection TaskItems { get; private set; } /// /// Gets the collection of active bar items. /// public ObservableCollection BarItems { get; private set; } /// /// Gets a value indicating whether there are any queued task items. /// public bool HasTaskItems { get { return TaskItems.Count > 0; } } /// /// The current task item /// private TaskItem _currentTaskItem; /// /// Gets the current displayed task item. /// public TaskItem CurrentTaskItem { get { return _currentTaskItem; } set { _currentTaskItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasTaskItems)); } } /// /// Initializes a new instance of the class. /// public DefaultNotificationProvider() { TaskItems = new ObservableCollection(); BarItems = new ObservableCollection(); } /// /// Display a message box. /// /// The icon. /// Color of the icon. /// The message. /// if set to true displays the cancel button. /// public bool? ShowMessageBox(PackIconKind icon, Brush iconColor, string message, bool hasCancel) { MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; _message_count++; var result = new MessageBoxWindow() { Owner = Application.Current.MainWindow, Message = message, IconKind = icon, IconColor = iconColor, HasCancel = hasCancel }.ShowDialog(); _message_count--; if (_message_count == 0) { MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } return result; } /// /// Shows the specified view with the specified view model as it's data context. /// /// The type of the mm. /// The type of the view. /// The view model. /// The view. /// The accept action. /// The cancel action. public void ShowModalDialog(VM vm, View view, Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM { try { DialogWindow dialog = new DialogWindow(); dialog.Owner = Application.Current.MainWindow; dialog.InnerContent = view; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; view.Loaded += (x, y) => { try { VM context = vm; dialog.DataContext = context; Action onAcceptAction = null; Action onCancelAction = null; onAcceptAction = new Action(() => { dialog.Close(); onAccept(context); context.Accepted -= onAcceptAction; context.Canceled -= onCancelAction; }); onCancelAction = new Action(() => { dialog.Close(); if (onCancel != null) { onCancel(); } context.Canceled -= onCancelAction; context.Accepted -= onAcceptAction; }); context.Accepted += onAcceptAction; context.Canceled += onCancelAction; context.OnShow(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } }; dialog.ShowDialog(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } finally { MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } } /// /// Creates a new instance of the specified View type and displays it as a modal dialog. /// /// The type of the view. /// The type of the view model. /// Accept button callback. /// Cancel button callback. public void ShowModalDialog(Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM { try { var view = Activator.CreateInstance(); DialogWindow dialog = new DialogWindow(); dialog.Owner = Application.Current.MainWindow; dialog.InnerContent = view; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; view.Loaded += (x, y) => { try { VM context = view.DataContext as VM; dialog.DataContext = context; Action onAcceptAction = null; Action onCancelAction = null; onAcceptAction = new Action(() => { dialog.Close(); onAccept(context); context.Accepted -= onAcceptAction; context.Canceled -= onCancelAction; }); onCancelAction = new Action(() => { dialog.Close(); if (onCancel != null) { onCancel(); } context.Accepted -= onAcceptAction; context.Canceled -= onCancelAction; }); context.Accepted += onAcceptAction; context.Canceled += onCancelAction; context.OnShow(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } }; dialog.ShowDialog(); MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } finally { MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } } /// /// Shows the specified view with the specified view model as it's data context. /// /// The type of the mm. /// The type of the view. /// The view model. /// The view. /// The accept action. /// The cancel action. public void ShowModalDialog(VM vm, Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM { try { var view = Activator.CreateInstance(); DialogWindow dialog = new DialogWindow(); dialog.Owner = Application.Current.MainWindow; dialog.InnerContent = view; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; view.Loaded += (x, y) => { try { VM context = vm; dialog.DataContext = context; Action onAcceptAction = null; Action onCancelAction = null; onAcceptAction = new Action(() => { dialog.Close(); onAccept(context); context.Accepted -= onAcceptAction; context.Canceled -= onCancelAction; }); onCancelAction = new Action(() => { dialog.Close(); if (onCancel != null) { onCancel(); } context.Accepted -= onAcceptAction; context.Canceled -= onCancelAction; }); context.Accepted += onAcceptAction; context.Canceled += onCancelAction; context.OnShow(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } }; dialog.ShowDialog(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } finally { MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } } /// /// Creates a new view by a naming convention of the specified view model type. /// /// The type of the view model. /// Accept button callback. /// Cancel button callback. /// Could not locate view " + viewName public void ShowModalDialog(Action onAccept, Action onCancel) where VM : DialogViewVM { try { String viewName = typeof(VM).Name.Replace("VM", ""); if (viewTypes == null) { viewTypes = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.Contains("MachineStudio")).SelectMany(x => x.GetTypes()).ToList(); } var viewType = viewTypes.SingleOrDefault(x => x.Name == viewName); if (viewType == null) { throw new NullReferenceException("Could not locate view " + viewName); } var view = Activator.CreateInstance(viewType) as FrameworkElement; DialogWindow dialog = new DialogWindow(); dialog.Owner = Application.Current.MainWindow; dialog.InnerContent = view; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; view.Loaded += (x, y) => { try { VM context = view.DataContext as VM; if (context == null) { context = Activator.CreateInstance(); } dialog.DataContext = context; Action onCancelAction = null; Action onAcceptAction = null; onAcceptAction = new Action(() => { dialog.Close(); onAccept(context); context.Canceled -= onCancelAction; context.Accepted -= onAcceptAction; }); onCancelAction = new Action(() => { dialog.Close(); if (onCancel != null) { onCancel(); } context.Canceled -= onCancelAction; context.Accepted -= onAcceptAction; }); context.Accepted += onAcceptAction; context.Canceled += onCancelAction; context.OnShow(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); return; } }; dialog.ShowDialog(); } catch (Exception ex) { LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}"); onCancel?.Invoke(); } finally { MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; } } /// /// Creates a new view by a naming convention of the specified view model type. /// /// The type of the view model. /// Accept button callback. public void ShowModalDialog(Action onAccept) where VM : DialogViewVM { ShowModalDialog(onAccept, null); } /// /// Shows an error message box. /// /// The message. public void ShowError(string message) { ShowMessageBox(PackIconKind.AlertOctagon, (SolidColorBrush)Application.Current.Resources["RedBrush100"], message, false); } /// /// Shows an information message box. /// /// The message. public void ShowInfo(string message) { ShowMessageBox(PackIconKind.CommentAlertOutline, (SolidColorBrush)Application.Current.Resources["Dialog.Foreground"], message, false); } /// /// Shows a question message box. /// /// The message. /// public bool ShowQuestion(string message) { return ShowMessageBox(PackIconKind.CommentQuestionOutline, (SolidColorBrush)Application.Current.Resources["Dialog.Foreground"], message, true).Value; } /// /// Shows warning message box. /// /// The message. public void ShowWarning(string message) { ShowMessageBox(PackIconKind.AlertOutline, (SolidColorBrush)Application.Current.Resources["OrangeUploadBrush"], message, false); } /// /// Shows a question message box with an error icon. /// /// The message. /// public bool ShowErrorQuestion(string message) { return ShowMessageBox(PackIconKind.CommentAlertOutline, (SolidColorBrush)Application.Current.Resources["OrangeUploadBrush"], message, true).Value; } /// /// Pushes the specified task item to the queue. /// /// The task item. public void PushTaskItem(TaskItem taskItem) { InvokeUI(() => { TaskItems.Add(taskItem); CurrentTaskItem = taskItem; }); } /// /// Create and push a new task item from the specified message. /// /// The message. /// public TaskItem PushTaskItem(string message) { TaskItem item = new TaskItem(this); item.Message = message; PushTaskItem(item); return item; } /// /// Removed the specified task item from the queue. /// /// The task item. public void PopTaskItem(TaskItem taskItem) { Task.Delay(1000).ContinueWith((x) => { InvokeUI(() => { TaskItems.Remove(taskItem); if (TaskItems.Count > 0) { CurrentTaskItem = TaskItems.Last(); } RaisePropertyChanged(nameof(HasTaskItems)); }); }); } /// /// Pushes the specified bar item. /// /// The bar item. /// public BarItem PushBarItem(BarItem barItem) { BarItems.Add(barItem); return barItem; } /// /// Creates and push a new bar item from the specified framework element. /// /// The element. /// public BarItem PushBarItem(FrameworkElement element) { BarItem item = new BarItem(this); item.Element = element; PushBarItem(item); return item; } /// /// Removed the specified bar item. /// /// The bar item. public void PopBarItem(BarItem barItem) { BarItems.Remove(barItem); } /// /// Shows a dialog with a text input field and returns the response. /// /// The message. /// Text field hint. /// Optional default response. /// public string ShowTextInput(string message, string hint, string defaultResponse = null) { MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; TextInputBoxWindow dlg = new TextInputBoxWindow() { Owner = Application.Current.MainWindow, Message = message, IconKind = PackIconKind.Pencil, IconColor = (SolidColorBrush)Application.Current.Resources["DimGrayBrush"], Hint = hint, Response = defaultResponse }; var result = dlg.ShowDialog(); MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; return (result.Value ? dlg.Response : null); } } }