// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: SetDigitalOutResponse.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "SetDigitalOutResponse.pb.h"
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
namespace pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using Tango.Core;
using Tango.Core.Commands;
using Tango.PPC.Common;
using Tango.PPC.Common.Modules;
using Tango.PPC.Common.Navigation;
using Tango.PPC.Common.Notifications;
using Tango.PPC.Common.Threading;
using Tango.PPC.UI.Views;
using Tango.SharedUI.Controls;
namespace Tango.PPC.UI.Navigation
{
/// <summary>
/// Represents the default PPC navigation manager.
/// </summary>
/// <seealso cref="Tango.PPC.Common.Navigation.INavigationManager" />
public class DefaultNavigationManager : ExtendedObject, INavigationManager
{
//private event Action<Object, Object> NavigationCycleCompleted;
//private event Action<Object, Object> BeforeNavigationCycleCompleted;
private class AwaitingVMResult
{
public PPCViewModel FromVM { get; set; }
public PPCViewModel ToVM { get; set; }
public Action Action { get; set; }
}
private List<AwaitingVMResult> _awaitingVMResults;
private IDispatcherProvider _dispatcherProvider;
private IPPCModuleLoader _moduleLoader;
private INotificationProvider _notificationProvider;
private Object _currentVM;
private String _lastFullPath;
private bool _preventHistory;
private bool _navigating_back;
private Stack<String> _navigationHistory;
/// <summary>
/// Gets the current view model.
/// </summary>
public PPCViewModel CurrentVM
{
get { return _currentVM as PPCViewModel; }
}
private IPPCModule _currentModule;
/// <summary>
/// Gets or sets the current module.
/// </summary>
public IPPCModule CurrentModule
{
get { return _currentModule; }
private set { _currentModule = value; RaisePropertyChangedAuto(); }
}
/// <summary>
/// Navigates to the previous view.
/// </summary>
public RelayCommand NavigateBackCommand { get; private set; }
/// <summary>
/// Navigates to the specified full path in command parameter.
/// </summary>
public RelayCommand<String> NavigateToCommand { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class.
/// </summary>
/// <param name="moduleLoader">The module loader.</param>
public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider)
{
IsBackEnabled = true;
_awaitingVMResults = new List<AwaitingVMResult>();
_navigationHistory = new Stack<String>();
_moduleLoader = moduleLoader;
_notificationProvider = notificationProvider;
NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x));
NavigateBackCommand = new RelayCommand(async () => await NavigateBack());
_dispatcherProvider = dispatcherProvider;
}
/// <summary>
/// Navigates to the specified PPC view.
/// </summary>
/// <param name="view">The view.</param>
public Task<bool> NavigateTo(NavigationView view, bool pushToHistory = true)
{
if (view == NavigationView.HomeModule)
{
_navigationHistory.Clear();
_lastFullPath = null;
var firstModule = _moduleLoader.UserModules.FirstOrDefault();
if (firstModule != null)
{
var moduleAtt = firstModule.GetType().GetCustomAttribute<PPCModuleAttribute>();
if (moduleAtt != null)
{
return NavigateTo(firstModule.GetType(), pushToHistory, moduleAtt.HomeViewName);
}
else
{
return NavigateTo(firstModule.GetType(), pushToHistory);
}
}
else
{
return NavigateTo(NavigationView.NoPermissionsView);
}
}
else
{
LogManager.Log($"Navigating to: {view.ToString()}...");
var fromView = MainView.Instance.NavigationControl.SelectedElement;
FrameworkElement toView = null;
toView = MainView.Instance.NavigationControl.NavigateTo(view.ToString(), () =>
{
_currentVM = toView.DataContext;
NotifyOnNavigated(fromView.DataContext, toView.DataContext);
});
NotifyOnBeforeNavigated(fromView.DataContext, toView.DataContext);
return Task.FromResult(true);
}
}
/// <summary>
/// Navigates to the specified PPC view with the specified receive object.
/// </summary>
/// <param name="view">The view.</param>
/// <param name="obj"></param>
/// <param name="pushToHistory"></param>
/// <returns></returns>
public Task<bool> NavigateWithObject<TPass>(NavigationView view, TPass obj, bool pushToHistory = true)
{
LogManager.Log($"Navigating to: {view.ToString()}, with object {typeof(TPass).Name}...");
MainView.Instance.NavigationControl.NavigateTo(view.ToString());
INavigationObjectReceiver<TPass> receiver = MainView.Instance.NavigationControl.Elements.FirstOrDefault(x => (x.GetType().Name == view.ToString() || NavigationControl.GetNavigationName(x) == view.ToString()) && x.DataContext is INavigationObjectReceiver<TPass>).DataContext as INavigationObjectReceiver<TPass>;
if (receiver != null)
{
receiver.OnNavigatedToWithObject(obj);
}
return Task.FromResult(true);
}
/// <summary>
/// Navigates to the specified module.
/// </summary>
/// <typeparam name="T"></typeparam>
public Task<bool> NavigateTo<T>(bool pushToHistory = true) where T : IPPCModule
{
return NavigateTo(typeof(T));
}
/// <summary>
/// Navigates to the specified module using the view path (e.g MainView.JobsView).
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="viewPath">The view path.</param>
public Task<bool> NavigateTo<T>(string viewPath, bool pushToHistory = true) where T : IPPCModule
{
return NavigateTo<T>(pushToHistory, viewPath.Split('.'));
}
/// <summary>
/// Navigates to the specified module using the view path (e.g MainView,JobsView).
/// This method makes it easy to do stuff like NavigateTo(nameof(MainView),nameof(JobsView));
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="viewPath">The view path.</param>
public Task<bool> NavigateTo<T>(bool pushToHistory = true, params String[] viewPath) where T : IPPCModule
{
return NavigateTo(typeof(T), pushToHistory, viewPath);
}
/// <summary>
/// Navigates to the specified module and view by full path (e.g Jobs.JobsView).
/// </summary>
/// <param name="fullPath">The full path.</param>
public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<PPCViewModel, PPCViewModel> onNavigating = null, Action<PPCViewModel, PPCViewModel> onNavigated = null)
{
try
{
String[] path = fullPath.Split('.');
var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]);
if (module == null)
{
await _notificationProvider.ShowError("The specified module was not loaded.");
return false;
}
if (path.Length == 1 && path[0] == CurrentModule.Name) return true;
LogManager.Log($"Navigating to: {fullPath}...");
var fromVM = _currentVM;
if (_currentVM != null && _currentVM is INavigationBlocker)
{
if (_navigating_back)
{
if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest())
{
return false;
}
}
else
{
if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest())
{
return false;
}
}
}
if (pushToHistory && _lastFullPath != null && !_preventHistory)
{
_navigationHistory.Push(_lastFullPath);
RaisePropertyChanged(nameof(CanNavigateBack));
}
_lastFullPath = fullPath;
MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString());
var navigationControl = LayoutView.Instance.NavigationControl;
CurrentModule = module;
var moduleView = navigationControl.NavigateTo(module.Name);
_currentVM = moduleView.DataContext;
if (path.Length > 1)
{
var moduleNavigation = moduleView.FindChildOffline<NavigationControl>();
if (moduleNavigation != null)
{
moduleNavigation.RegisterForLoadedOrNow(async (x, e) =>
{
var lastView = moduleNavigation.GetElement(path.Last());
if (lastView != null)
{
onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel);
}
foreach (var view in path.Skip(1))
{
await Task.Delay(100);
FrameworkElement v = null;
v = moduleNavigation.NavigateTo(view, () =>
{
if (v != null)
{
NotifyOnNavigated(fromVM, v.DataContext);
onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel);
NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel);
}
});
NotifyOnBeforeNavigated(fromVM, v.DataContext);
if (v != null)
{
_currentVM = v.DataContext;
if (view != path.Last())
{
moduleNavigation = v.FindChildOffline<NavigationControl>();
}
}
else
{
throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath));
}
}
});
}
else
{
onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel);
NotifyOnBeforeNavigated(fromVM, _currentVM);
await Task.Delay(navigationControl.TransitionDuration.TimeSpan);
NotifyOnNavigated(fromVM, _currentVM);
onNavigated?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel);
NotifyAwaitingVMResults(fromVM as PPCViewModel, _currentVM as PPCViewModel);
}
}
else
{
NotifyOnBeforeNavigated(fromVM, _currentVM);
onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel);
await Task.Delay(navigationControl.TransitionDuration.TimeSpan);
NotifyOnNavigated(fromVM, _currentVM);
onNavigated?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel);
NotifyAwaitingVMResults(fromVM as PPCViewModel, _currentVM as PPCViewModel);
}
return true;
}
catch (Exception ex)
{
await _notificationProvider.ShowError($"Error navigating to '{fullPath}'.");
return false;
}
}
/// <summary>
/// Navigates for result.
/// </summary>
/// <typeparam name="TModule">The type of the module.</typeparam>
/// <typeparam name="TView">The type of the view.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
/// <returns></returns>
public async Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true)
where TModule : IPPCModule
{
TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>();
var fromVM = _currentVM;
await NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (from, to) =>
{
_awaitingVMResults.Add(new AwaitingVMResult()
{
FromVM = fromVM as PPCViewModel,
ToVM = to as PPCViewModel,
Action = () =>
{
if (to is INavigationResultProvider<TResult, TObject>)
{
source.SetResult((to as INavigationResultProvider<TResult, TObject>).GetNavigationResult());
}
}
});
if (to is INavigationResultProvider<TResult, TObject>)
{
(to as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj);
}
});
return await source.Task;
}
/// <summary>
/// Navigates to the specified module and view with the specified object.
/// </summary>
/// <typeparam name="TModule">The type of the module.</typeparam>
/// <typeparam name="TView">The type of the view.</typeparam>
/// <typeparam name="TPass">The type of the pass.</typeparam>
/// <param name="obj">The object.</param>
/// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
/// <returns></returns>
public Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true) where TModule : IPPCModule
{
return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) =>
{
if (toVM is INavigationObjectReceiver<TPass>)
{
(toVM as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj);
}
});
}
private Task<bool> NavigateTo(Type moduleType, bool pushToHistory = true, params String[] viewPath)
{
if (viewPath != null && viewPath.Length > 0)
{
return NavigateTo(moduleType.Name + "." + String.Join(".", viewPath), pushToHistory);
}
else
{
return NavigateTo(moduleType.Name, pushToHistory);
}
}
/// <summary>
/// Gets a value indicating whether the navigation system is able to navigate to the previous view.
/// </summary>
public bool CanNavigateBack
{
get { return _navigationHistory.Count > 0; }
}
private bool _isBackEnabled;
/// <summary>
/// Gets a value indicating whether the back should be enabled.
/// </summary>
public bool IsBackEnabled
{
get { return _isBackEnabled; }
set { _isBackEnabled = value; RaisePropertyChangedAuto(); }
}
/// <summary>
/// Navigates to the previous view if <see cref="P:Tango.PPC.Common.Navigation.INavigationManager.CanNavigateBack" /> is true.
/// </summary>
public async Task<bool> NavigateBack()
{
LogManager.Log("Navigating back...");
_navigating_back = true;
if (_navigationHistory.Count > 0)
{
String first = _navigationHistory.Pop();
_preventHistory = true;
if (await NavigateTo(first))
{
RaisePropertyChanged(nameof(CanNavigateBack));
_preventHistory = false;
_navigating_back = false;
return true;
}
else
{
_navigationHistory.Push(first);
_preventHistory = false;
_navigating_back = false;
RaisePropertyChanged(nameof(CanNavigateBack));
return false;
}
}
else
{
await NavigateTo(NavigationView.HomeModule);
RaisePropertyChanged(nameof(CanNavigateBack));
_preventHistory = false;
_navigating_back = false;
return true;
}
}
/// <summary>
/// Clears the navigation back history.
/// </summary>
public void ClearHistory()
{
LogManager.Log("Navigation history cleared.");
_navigationHistory.Clear();
RaisePropertyChanged(nameof(CanNavigateBack));
}
/// <summary>
/// Clears the navigation back history except the specified view type.
/// </summary>
/// <typeparam name="T"></typeparam>
public void ClearHistoryExcept<T>()
{
LogManager.Log($"Navigation history cleared except for {typeof(T).Name}.");
var history_list = _navigationHistory.ToList();
history_list = history_list.Where(x => x.Contains(typeof(T).Name)).Distinct().ToList();
_navigationHistory.Clear();
foreach (var item in history_list)
{
_navigationHistory.Push(item);
}
RaisePropertyChanged(nameof(CanNavigateBack));
}
private void NotifyOnBeforeNavigated(object fromVM, object toVM)
{
if (fromVM is PPCViewModel)
{
(fromVM as PPCViewModel)?.OnBeforeNavigatedFrom();
}
if (toVM is PPCViewModel)
{
(toVM as PPCViewModel)?.OnBeforeNavigatedTo();
}
}
private void NotifyOnNavigated(object fromVM, object toVM)
{
if (fromVM is PPCViewModel)
{
(fromVM as PPCViewModel)?.OnNavigatedFrom();
}
if (toVM is PPCViewModel)
{
(toVM as PPCViewModel)?.OnNavigatedTo();
(toVM as PPCViewModel)?.OnNavigatedTo(fromVM as PPCViewModel);
}
}
private void NotifyAwaitingVMResults(PPCViewModel fromVM, PPCViewModel toVM)
{
var awaiter = _awaitingVMResults.SingleOrDefault(x => x.FromVM == toVM && x.ToVM == fromVM);
if (awaiter != null)
{
_awaitingVMResults.Remove(awaiter);
awaiter.Action();
}
}
}
}