diff --git a/AdamBlocklyLibrary/Properties/AssemblyInfo.cs b/AdamBlocklyLibrary/Properties/AssemblyInfo.cs deleted file mode 100644 index ca2c197..0000000 --- a/AdamBlocklyLibrary/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Resources; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Общие сведения об этой сборке предоставляются следующим набором -// набора атрибутов. Измените значения этих атрибутов для изменения сведений, -// связанные со сборкой. -[assembly: AssemblyTitle("AdamBlocklyLibrary")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("AdamBlocklyLibrary")] -[assembly: AssemblyCopyright("Copyright © 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми -// для компонентов COM. Если необходимо обратиться к типу в этой сборке через -// COM, задайте атрибуту ComVisible значение TRUE для этого типа. -[assembly: ComVisible(false)] - -// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM -[assembly: Guid("ccb5a70b-3f85-4d11-b774-365df8a220f6")] - -// Сведения о версии сборки состоят из указанных ниже четырех значений: -// -// Основной номер версии -// Дополнительный номер версии -// Номер сборки -// Редакция -// -// Можно задать все значения или принять номера сборки и редакции по умолчанию -// используя "*", как показано ниже: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: NeutralResourcesLanguage("en")] diff --git a/AdamController.Controls/AdamController.Controls.csproj b/AdamController.Controls/AdamController.Controls.csproj new file mode 100644 index 0000000..75c197e --- /dev/null +++ b/AdamController.Controls/AdamController.Controls.csproj @@ -0,0 +1,14 @@ + + + + net7.0-windows + enable + true + enable + + + + + + + diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutAction.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutAction.cs new file mode 100644 index 0000000..267ebbd --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutAction.cs @@ -0,0 +1,51 @@ +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// Represents the ongoing direction of change of a Flyout + /// + public class FlyoutAction + { + private const string mOpening = "Opening"; + private const string mClosing = "Closing"; + + private readonly string mThisAction; + + protected FlyoutAction(string action) + { + mThisAction = action; + } + + public static FlyoutAction Opening + { + get { return new FlyoutAction(mOpening); } + } + + public static FlyoutAction Closing + { + get { return new FlyoutAction(mClosing); } + } + + public string Action + { + get { return mThisAction; } + } + + public override bool Equals(object obj) + { + if (obj is not FlyoutAction other) + return false; + + return this.Action == other.Action; + } + + public override int GetHashCode() + { + return mThisAction.GetHashCode(); + } + + public override string ToString() + { + return mThisAction; + } + } +} diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutBase.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutBase.cs new file mode 100644 index 0000000..30cef2f --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutBase.cs @@ -0,0 +1,250 @@ +using MahApps.Metro.Controls; +using Prism.Mvvm; +using System.Drawing; +using System.Windows; +using System.Windows.Input; + +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// Base class that provides and implementation of IFlyout. + /// Inherits from BindableBase to allow property binding. + /// Recommended to perform the majority of ViewModel initialization within an override of OnOpening to prevent memory leaks, + /// and clean up as many resources as possible within OnClosing as the instance of the ViewModel will remain in memory from the + /// moment of registration with the FlyoutManager until the moment of unregistration, or program exit. + /// + public abstract class FlyoutBase : BindableBase, IFlyout + { + public event EventHandler OnClosed; + public event EventHandler OnOpened; + public event EventHandler OnOpenChanged; + + private bool mIsOpen; + private bool mIsModal = true; + private bool mAreAnimationsEnabled = true; + private bool mAnimateOpacity = true; + private bool mCloseButtonIsCancel; + private bool mIsPinned; + + private string mPosition = FlyoutPosition.Right; + private string mHeader = string.Empty; + private string mTheme = FlyoutTheme.Adapt; + + private double mBorderThickness = 1.0; + private string mBorderBrush = "White"; + + private ICommand mCloseCommand; + private MouseButton mExternalCloseButton; + + + public double BorderThickness + { + get => mBorderThickness; + set => SetProperty(ref mBorderThickness, value); + } + + public string BorderBrush + { + get => mBorderBrush; + set => SetProperty(ref mBorderBrush, value); + } + + + /// + /// Bindable property to determine open/closed staus of flyout, based on private field isOpen. + /// Generally set by FlyoutManager calling Open or Close method. + /// Initial value can be set by concrete child class. + /// + public bool IsOpen + { + get { return mIsOpen; } + set + { + OnChanging(value); + SetProperty(ref mIsOpen, value); + } + } + + + /// + /// Bindable property to determine position of flyout in window. + /// Possible values are stored in FlyoutPosition class and can be used to set property in the concrete class. + /// + public string Position + { + get { return mPosition; } + set { SetProperty(ref mPosition, value); } + } + + /// + /// Bindable property to determine theme of flyout. + /// Possible values are stored in FlyoutTheme class and can be used to set property in concrete class. + /// + public string Theme + { + get { return mTheme; } + set { SetProperty(ref mTheme, value); } + } + + /// + /// Bindable property to determine whether the Flyout is modal or not + /// + public bool IsModal + { + get { return mIsModal; } + set { SetProperty(ref mIsModal, value); } + } + + /// + /// Bindable property to determine whether flyout animations are enabled + /// + public bool AreAnimationsEnabled + { + get { return mAreAnimationsEnabled; } + set { SetProperty(ref mAreAnimationsEnabled, value); } + } + + /// + /// Command to execute when the close button is pressed + /// + public ICommand CloseCommand + { + get { return mCloseCommand; } + set { SetProperty(ref mCloseCommand, value); } + } + + /// + /// Designate a mousebutton that will close the flyout when pressed outside of its bounds. + /// + public MouseButton ExternalCloseButton + { + get { return mExternalCloseButton; } + set { SetProperty(ref mExternalCloseButton, value); } + } + + /// + /// Does the close button act as a cancel button. + /// + public bool CloseButtonIsCancel + { + get { return mCloseButtonIsCancel; } + set { SetProperty(ref mCloseButtonIsCancel, value); } + } + + /// + /// Is the flyout pinned. + /// + public bool IsPinned + { + get { return mIsPinned; } + set { SetProperty(ref mIsPinned, value); } + } + + /// + /// Whether the flyout is currently able to open. + /// Default: returns true + /// Override in concrete child class to implement custom logic. + /// + /// Instance of containing information on current Open request. + /// True if flyout can open, false if not. + public virtual bool CanOpen(FlyoutParameters flyoutParameters) + { + return true; + } + + + /// + /// Is opacity animated. + /// + public bool AnimateOpacity + { + get { return mAnimateOpacity; } + set { SetProperty(ref mAnimateOpacity, value); } + } + + /// + /// Whether the flyout is currently able to close. + /// Default: returns true. + /// Override in concrete child class to implement custom logic. + /// + /// Instance of containing information on current Close request. + /// True if flyout can close, false if not. + public virtual bool CanClose(FlyoutParameters flyoutParameters) + { + return true; + } + + /// + /// Event delegate called on flyout closing with FlyoutEventArgs. + /// + /// Instance of containing information on current Close request. + protected virtual void OnClosing(FlyoutParameters flyoutParameters) { } + + /// + /// Event delegate called on flyout closing, with FlyoutEventArgs. + /// + /// Instance of containing information on current Close request. + protected virtual void OnOpening(FlyoutParameters flyoutParameters) { } + + /// + /// Bindable property to determine header of flyout. + /// Value set by concrete child class. + /// + public string Header + { + get { return mHeader; } + set { SetProperty(ref mHeader, value); } + } + + /// + /// Event delegate called on flyout open status changed, with FlyoutEventArgs containing open/close direction. + /// + /// + protected virtual void OnChanging(bool isOpening) + { + var flyoutAction = isOpening ? FlyoutAction.Opening : FlyoutAction.Closing; + + var flyoutEventArgs = new FlyoutEventArgs(flyoutAction); + + OnOpenChanged?.Invoke(this, flyoutEventArgs); + + if (flyoutAction == FlyoutAction.Opening) + OnOpened?.Invoke(this, flyoutEventArgs); + + if (flyoutAction == FlyoutAction.Closing) + OnClosed?.Invoke(this, flyoutEventArgs); + } + + /// + /// Close the flyout. + /// + /// + public void Close(FlyoutParameters flyoutParameters) + { + OnClosing(flyoutParameters); + IsOpen = false; + } + + public void Close() + { + Close(new FlyoutParameters()); + } + + + /// + /// Open the flyout. + /// + /// + public void Open(FlyoutParameters flyoutParameters) + { + OnOpening(flyoutParameters); + IsOpen = true; + } + + public void Open() + { + Open(new FlyoutParameters()); + } + } +} + diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutEventArgs.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutEventArgs.cs new file mode 100644 index 0000000..23b3b15 --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutEventArgs.cs @@ -0,0 +1,17 @@ +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// Event arguments passed with the OnOpened, OnClosed and OnOpenChanged event delegates. + /// Flyout action is a required parameter to the constructor. + /// Additional FlyoutParameters can also be attached. + /// + public class FlyoutEventArgs : EventArgs + { + public FlyoutAction FlyoutAction { get; set; } + + public FlyoutEventArgs(FlyoutAction flyoutAction) + { + FlyoutAction = flyoutAction; + } + } +} diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutParameters.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutParameters.cs new file mode 100644 index 0000000..aaa66ac --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutParameters.cs @@ -0,0 +1,40 @@ +using System.Collections; + +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// A collection of parameters that are passed from objects requesting the Flyout to open to the IFlyout ViewModel that controls + /// the specific Flyout. + /// These parameters can also (optionally) be attached to FlyoutEventArgs when notifying subscribers of a change in the Flyout status. + /// + public class FlyoutParameters : IEnumerable + { + private readonly IDictionary parameters; + + public FlyoutParameters() + { + parameters = new Dictionary(); + } + + public void AddParameter(string name, object payload) + { + parameters.Add(name, payload); + } + + public object this[string key] + { + get { return parameters[key]; } + set { parameters[key] = value; } + } + + public bool ContainsKey(string key) + { + return parameters.ContainsKey(key); + } + + public IEnumerator GetEnumerator() + { + return parameters.GetEnumerator(); + } + } +} diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutPosition.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutPosition.cs new file mode 100644 index 0000000..d257c41 --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutPosition.cs @@ -0,0 +1,14 @@ +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// Represents the Position of the Flyout within the (Metro) Window + /// Usually set in the constructor of the IFlyout ViewModel + /// + public class FlyoutPosition + { + public const string Right = "Right"; + public const string Left = "Left"; + public const string Top = "Top"; + public const string Bottom = "Bottom"; + } +} diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutTheme.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutTheme.cs new file mode 100644 index 0000000..0552932 --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/FlyoutTheme.cs @@ -0,0 +1,15 @@ +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + /// + /// Represents the possible values for the Flyouts Theme + /// Usually set in the constructor of the individual IFlyout ViewModel + /// + public class FlyoutTheme + { + public const string Adapt = "Adapt"; + public const string Inverse = "Inverse"; + public const string Dark = "Dark"; + public const string Light = "Light"; + public const string Accent = "Accent"; + } +} diff --git a/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/IFlyout.cs b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/IFlyout.cs new file mode 100644 index 0000000..4162a90 --- /dev/null +++ b/AdamController.Controls/CustomControls.Mvvm/FlyoutContainer/IFlyout.cs @@ -0,0 +1,50 @@ +using System.Drawing; +using System.Windows.Input; + +namespace AdamController.Controls.CustomControls.Mvvm.FlyoutContainer +{ + public interface IFlyout + { + public event EventHandler OnClosed; + + public event EventHandler OnOpened; + + public event EventHandler OnOpenChanged; + + public double BorderThickness { get; set; } + + public string BorderBrush { get; set; } + + public string Position { get; set; } + + public string Header { get; set; } + + public string Theme { get; set; } + + public bool IsModal { get; set; } + + public bool AreAnimationsEnabled { get; set; } + + public bool AnimateOpacity { get; set; } + + public ICommand CloseCommand { get; set; } + + public MouseButton ExternalCloseButton { get; set; } + + public bool CloseButtonIsCancel { get; set; } + + public bool IsPinned { get; set; } + + public bool CanClose(FlyoutParameters flyoutParameters); + + public void Close(FlyoutParameters flyoutParameters); + + public void Close(); + + public bool CanOpen(FlyoutParameters flyoutParameters); + + public void Open(FlyoutParameters flyoutParameters); + + public void Open(); + } +} diff --git a/AdamController.Controls/CustomControls.RegionAdapters/FlyoutsControlRegionAdapter.cs b/AdamController.Controls/CustomControls.RegionAdapters/FlyoutsControlRegionAdapter.cs new file mode 100644 index 0000000..5534b0e --- /dev/null +++ b/AdamController.Controls/CustomControls.RegionAdapters/FlyoutsControlRegionAdapter.cs @@ -0,0 +1,45 @@ +using MahApps.Metro.Controls; +using Prism.Regions; +using System.Collections.Specialized; +using System.Windows; + +namespace AdamController.Controls.CustomControls.RegionAdapters +{ + public class FlyoutsControlRegionAdapter : RegionAdapterBase + { + public FlyoutsControlRegionAdapter(IRegionBehaviorFactory factory) : base(factory) { } + + protected override void Adapt(IRegion region, FlyoutsControl regionTarget) + { + region.ActiveViews.CollectionChanged += (s, e) => + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + foreach (FrameworkElement element in e?.NewItems) + { + Flyout flyout = new() + { + Content = element, + DataContext = element.DataContext + }; + + regionTarget.Items.Add(flyout); + } + } + + if (e.Action == NotifyCollectionChangedAction.Remove) + { + foreach (FrameworkElement element in e?.OldItems) + { + regionTarget.Items.Remove(element); + } + } + }; + } + + protected override IRegion CreateRegion() + { + return new AllActiveRegion(); + } + } +} diff --git a/AdamController.Controls/CustomControls.Services/ControlHelper.cs b/AdamController.Controls/CustomControls.Services/ControlHelper.cs new file mode 100644 index 0000000..9c21f18 --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/ControlHelper.cs @@ -0,0 +1,108 @@ +using AdamController.Controls.Enums; +using Prism.Mvvm; + +namespace AdamController.Controls.CustomControls.Services +{ + public class ControlHelper : BindableBase, IControlHelper + { + public event BlocklyColumnWidthChangeEventHandler RaiseBlocklyColumnWidthChangeEvent; + + public ControlHelper() {} + + private double mainGridActualWidth = double.NaN; + public double MainGridActualWidth + { + get => mainGridActualWidth; + set => SetProperty(ref mainGridActualWidth, value); + } + + private double blocklyColumnActualWidth = double.NaN; + public double BlocklyColumnActualWidth + { + get { return blocklyColumnActualWidth;} + set + { + bool isNewValue = SetProperty(ref blocklyColumnActualWidth, value); + + if (isNewValue) + { + UpdateCurrentBlocklyViewMode(); + } + } + } + + private double blocklyColumnWidth = double.NaN; + public double BlocklyColumnWidth + { + get { return blocklyColumnWidth; } + set + { + bool isNewValue = SetProperty(ref blocklyColumnWidth, value); + + if (isNewValue) + { + OnRaiseBlocklyColumnWidthChangeEvent(); + } + } + } + + private BlocklyViewMode currentBlocklyViewMode; + + public BlocklyViewMode CurrentBlocklyViewMode + { + get => currentBlocklyViewMode; + set + { + bool isNewValue = SetProperty(ref currentBlocklyViewMode, value); + + if (isNewValue) + UpdateBlocklyColumnWidth(); + } + } + + private void UpdateBlocklyColumnWidth() + { + var dividedScreen = MainGridActualWidth/2; + + switch (CurrentBlocklyViewMode) + { + case BlocklyViewMode.Hidden: + BlocklyColumnWidth = 0; + break; + case BlocklyViewMode.MiddleScreen: + BlocklyColumnWidth = dividedScreen; + break; + case BlocklyViewMode.FullScreen: + BlocklyColumnWidth = MainGridActualWidth; + break; + } + } + + private void UpdateCurrentBlocklyViewMode() + { + if (BlocklyColumnActualWidth >= MainGridActualWidth - 10) + { + CurrentBlocklyViewMode = BlocklyViewMode.FullScreen; + return; + } + + if (BlocklyColumnActualWidth == 0) + { + CurrentBlocklyViewMode = BlocklyViewMode.Hidden; + return; + } + + CurrentBlocklyViewMode = BlocklyViewMode.MiddleScreen; + } + + public void Dispose() + { + } + + protected virtual void OnRaiseBlocklyColumnWidthChangeEvent() + { + BlocklyColumnWidthChangeEventHandler raiseEvent = RaiseBlocklyColumnWidthChangeEvent; + raiseEvent?.Invoke(this); + } + } +} diff --git a/AdamController.Controls/CustomControls.Services/FlyoutManager.cs b/AdamController.Controls/CustomControls.Services/FlyoutManager.cs new file mode 100644 index 0000000..425cabc --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/FlyoutManager.cs @@ -0,0 +1,256 @@ +using AdamController.Controls.CustomControls.Mvvm.FlyoutContainer; +using DryIoc; +using Prism.Regions; +using System.Windows; + +namespace AdamController.Controls.CustomControls.Services +{ + /// + /// Manages a collection of Flyouts, registering them with specified regions and creating their views and viewmodels. + /// Flyouts that are managed must have viewmodels that implement IFlyout. + /// + public class FlyoutManager : IFlyoutManager + { + private readonly IDictionary mFlyouts; + + private readonly IContainer mDryIocContainer; + + private string mDefaultFlyoutRegion = string.Empty; + + /// + /// The region manager controlling the region where the Flyouts are to be displayed. + /// Made public to allow use of sub-region managers. + /// + public IRegionManager RegionManager { get; } + + /// + /// Default constructor + /// + /// DryIoc container, generally passed by dependency injection. + /// Region manager, generally passed by dependency injection. + public FlyoutManager(IContainer container, IRegionManager regionManager) + { + mDryIocContainer = container; + RegionManager = regionManager; + + mFlyouts = new Dictionary(); + } + + + public void RegisterFlyoutWithDefaultRegion(string flyoutKey) where TView : FrameworkElement + { + if (string.IsNullOrEmpty(mDefaultFlyoutRegion)) + throw new NullReferenceException("Default region not set."); + + RegisterFlyout(flyoutKey, mDefaultFlyoutRegion); + } + + + public void RegisterFlyoutWithDefaultRegion(string flyoutKey, IFlyout viewModel) where TView : FrameworkElement + { + if (string.IsNullOrEmpty(mDefaultFlyoutRegion)) + throw new NullReferenceException("Default region not set."); + + RegisterFlyout(flyoutKey, mDefaultFlyoutRegion, viewModel); + } + + /// + /// Register Flyout with FlyoutManager. The viewmodel will be obtained from the view, so a view-first approach must + /// be used. This method is compatible with autowireviewmodel. The viewmodel produced must derive from IFlyout. + /// + /// Type of the view used for the flyout. + /// A key to identify the flyout. + /// The region name in which to display the flyout. + public void RegisterFlyout(string flyoutKey, string flyoutRegion) where TView : FrameworkElement + { + var flyoutView = ResolveFlyoutView(); + + var flyoutViewModel = GetFlyoutViewModelFromView(flyoutView); + + AddFlyoutToCollection(flyoutKey, flyoutRegion, flyoutViewModel, flyoutView); + } + + /// + /// Register Flyout with FlyoutManager, a viewmodel must be supplied that derives from IFlyout. + /// + /// Type of the view used for the flyout. + /// /// A key to identify the flyout. + /// The region name in which to display the flyout. + /// + public void RegisterFlyout(string flyoutKey, string flyoutRegion, IFlyout flyoutViewModel) where TView : FrameworkElement + { + var flyoutView = ResolveFlyoutView(); + + AddFlyoutToCollection(flyoutKey, flyoutRegion, flyoutViewModel, flyoutView); + } + + /// + /// Remove the specified Flyout from this FlyoutManager. + /// + /// The key that identifies the flyout. + public void UnRegisterFlyout(string key) + { + mFlyouts.Remove(key); + } + + /// + /// Remove the specified Flyout from this FlyoutManager + /// + /// The flyout to remove. + public void UnRegisterFlyout(IFlyout flyout) + { + var items = mFlyouts.Where(kvp => kvp.Value == flyout).ToList(); + items.ForEach(item => UnRegisterFlyout(item.Key)); + } + + /// + /// Attempt to open the identified flyout, passing default flyoutparameters to the flyout's CanOpen method. + /// + /// Identifies the flyout to open. + /// True if opened, false if CanOpen prevented opening. + public bool OpenFlyout(string key) + { + return OpenFlyout(key, new FlyoutParameters()); + } + + /// + /// Attempt to open the identified flyout, passing the specified flyoutparameters to the flyout's CanOpen method. + /// + /// Identifies the flyout to open. + /// Passed to the flyouts CanOpen method, and indirectly to OnOpening. + /// True if opened, false if CanOpen prevented opening. + public bool OpenFlyout(string key, FlyoutParameters flyoutParameters) + { + return OpenFlyout(key, flyoutParameters, false); + } + + /// + /// Attempts to open the identified flyout + /// Default flyoutparameters are passed to the flyout's CanOpen method and the result returned, + /// but if forceOpen is true, the flyout is opened even if CanOpen returns false. + /// + /// Identifies the flyout to open. + /// Whether to force open the flyout. + /// The result of the identified flyout's CanOpen method. + public bool OpenFlyout(string key, bool forceOpen) + { + return OpenFlyout(key, new FlyoutParameters(), forceOpen); + } + + /// + /// Attempts to open the identified flyout + /// The specified flyoutparameters are passed to the flyout's CanOpen method and the result returned, + /// but if forceOpen is true, the flyout is opened even if CanOpen returns false. + /// + /// Identifies the flyout to open. + /// Passed to the flyouts CanOpen method, and indirectly to OnOpening. + /// Whether to force open the flyout. + /// The result of the identified flyout's CanOpen method. + public bool OpenFlyout(string key, FlyoutParameters flyoutParameters, bool forceOpen) + { + var flyoutToActivate = mFlyouts[key]; + bool canOpen = flyoutToActivate.CanOpen(flyoutParameters); + + if (!forceOpen && !canOpen) + return false; + + flyoutToActivate.Open(flyoutParameters); + + return canOpen; + } + + public void SetDefaultFlyoutRegion(string regionName) + { + mDefaultFlyoutRegion = regionName; + } + + /// + /// Attempt to close the identified flyout, passing default flyoutparameters to the flyout's CanClose method. + /// + /// Identifies the flyout to close. + /// Passed to the flyouts CanClose method, and indirectly to OnClosing. + /// True if closed, false if CanClose prevented closing. + public bool CloseFlyout(string key) + { + return CloseFlyout(key, new FlyoutParameters()); + } + + /// + /// Attempt to close the identified flyout, passing the provided flyoutparameters to the flyout's CanClose method. + /// + /// Identifies the flyout to close. + /// Passed to the flyouts CanClose method, and indirectly to OnClosing. + /// True if closed, false if CanClose prevented closing. + public bool CloseFlyout(string key, FlyoutParameters flyoutParameters) + { + return CloseFlyout(key, flyoutParameters, false); + } + + /// + /// Closes the identified flyout, passing default flyoutparameters to the flyout's CanClose method. + /// If forceClose is true, the flyout will be closed even if CanClose returns false. The result of CanClose + /// will be returned by this method even if closure is forced. + /// + /// Identifies the flyout to close. + /// Force flyout closure even if CanClose returns false. + /// The results of the indentified flyouts CanClose method. + public bool CloseFlyout(string key, bool forceClose) + { + return CloseFlyout(key, new FlyoutParameters(), forceClose); + } + + /// + /// Closes the identified flyout, passing the provided flyoutparameters to the flyout's CanClose method. + /// If forceClose is true, the flyout will be closed even if CanClose returns false. The result of CanClose + /// will be returned by this method even if closure is forced. + /// + /// Identifies the flyout to close. + /// Passed to the flyouts CanClose method, and indirectly to OnClosing. + /// Force flyout closure even if CanClose returns false. + /// The results of the indentified flyouts CanClose method. + public bool CloseFlyout(string key, FlyoutParameters flyoutParameters, bool forceClose) + { + var flyoutToClose = mFlyouts[key]; + bool canClose = flyoutToClose.CanClose(flyoutParameters); + + if (!forceClose && !canClose) + return false; + + flyoutToClose.Open(flyoutParameters); + + return canClose; + } + + private IFlyout GetFlyoutViewModelFromView(FrameworkElement flyoutView) + { + IFlyout flyoutViewModel = flyoutView.DataContext as IFlyout; + + if (flyoutViewModel == null) + throw new ArgumentException(@"Type passed must have an auto-wired view model that implements IFlyout. + If auto-wiring is not used then pass the viewmodel instance to the overloaded + RegisterFlyout method."); + + return flyoutViewModel; + } + + private FrameworkElement ResolveFlyoutView() + { + return mDryIocContainer.Resolve() as FrameworkElement; + } + + private void RegisterFlyoutWithRegion(FrameworkElement flyoutView, string flyoutRegion) + { + RegionManager.RegisterViewWithRegion(flyoutRegion, () => + { + return flyoutView; + }); + } + + private void AddFlyoutToCollection(string flyoutKey, string flyoutRegion, IFlyout flyoutViewModel, FrameworkElement flyoutView) + { + RegisterFlyoutWithRegion(flyoutView, flyoutRegion); + + mFlyouts.Add(flyoutKey, flyoutViewModel); + } + } +} diff --git a/AdamController.Controls/CustomControls.Services/FlyoutStateChecker.cs b/AdamController.Controls/CustomControls.Services/FlyoutStateChecker.cs new file mode 100644 index 0000000..e98240c --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/FlyoutStateChecker.cs @@ -0,0 +1,28 @@ + +namespace AdamController.Controls.CustomControls.Services +{ + public class FlyoutStateChecker : IFlyoutStateChecker + { + public event IsNotificationFlyoutOpenedStateChangeEventHandler IsNotificationFlyoutOpenedStateChangeEvent; + + private bool isNotificationFlyoutOpened; + public bool IsNotificationFlyoutOpened + { + get { return isNotificationFlyoutOpened; } + set + { + if (isNotificationFlyoutOpened == value) + return; + + isNotificationFlyoutOpened = value; + OnNotificationFlyoutOpenedStateChangeEvent(); + } + } + + protected void OnNotificationFlyoutOpenedStateChangeEvent() + { + IsNotificationFlyoutOpenedStateChangeEventHandler raiseEvent = IsNotificationFlyoutOpenedStateChangeEvent; + raiseEvent?.Invoke(this); + } + } +} diff --git a/AdamController.Controls/CustomControls.Services/IControlHelper.cs b/AdamController.Controls/CustomControls.Services/IControlHelper.cs new file mode 100644 index 0000000..81ad806 --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/IControlHelper.cs @@ -0,0 +1,24 @@ +using AdamController.Controls.Enums; + +namespace AdamController.Controls.CustomControls.Services +{ + #region Delegates + + public delegate void BlocklyColumnWidthChangeEventHandler(object sender); + + #endregion + + public interface IControlHelper : IDisposable + { + #region Events + + public event BlocklyColumnWidthChangeEventHandler RaiseBlocklyColumnWidthChangeEvent; + + #endregion + + public double MainGridActualWidth { get; set; } + public double BlocklyColumnActualWidth { get; set; } + public double BlocklyColumnWidth { get; set; } + public BlocklyViewMode CurrentBlocklyViewMode { get; set; } + } +} diff --git a/AdamController.Controls/CustomControls.Services/IFlyoutManager.cs b/AdamController.Controls/CustomControls.Services/IFlyoutManager.cs new file mode 100644 index 0000000..618487a --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/IFlyoutManager.cs @@ -0,0 +1,41 @@ +using AdamController.Controls.CustomControls.Mvvm.FlyoutContainer; +using Prism.Regions; +using System.Windows; + +namespace AdamController.Controls.CustomControls.Services +{ + public interface IFlyoutManager + { + public IRegionManager RegionManager { get; } + + public void SetDefaultFlyoutRegion(string regionName); + + public void RegisterFlyoutWithDefaultRegion(string flyoutKey) where TView : FrameworkElement; + + public void RegisterFlyoutWithDefaultRegion(string flyoutKey, IFlyout viewModel) where TView : FrameworkElement; + + public void RegisterFlyout(string flyoutKey, string regionName) where T : FrameworkElement; + + public void RegisterFlyout(string flyoutKey, string regionName, IFlyout flyoutViewModel) where T : FrameworkElement; + + public void UnRegisterFlyout(string key); + + public void UnRegisterFlyout(IFlyout flyout); + + public bool OpenFlyout(string key); + + public bool OpenFlyout(string key, FlyoutParameters flyoutParameters); + + public bool OpenFlyout(string key, bool forceOpen); + + public bool OpenFlyout(string key, FlyoutParameters flyoutParameters, bool forceOpen); + + public bool CloseFlyout(string key); + + public bool CloseFlyout(string key, FlyoutParameters flyoutParameters); + + public bool CloseFlyout(string key, bool forceClose); + + public bool CloseFlyout(string key, FlyoutParameters flyoutParameters, bool forceClose); + } +} diff --git a/AdamController.Controls/CustomControls.Services/IFlyoutStateChecker.cs b/AdamController.Controls/CustomControls.Services/IFlyoutStateChecker.cs new file mode 100644 index 0000000..04bff2e --- /dev/null +++ b/AdamController.Controls/CustomControls.Services/IFlyoutStateChecker.cs @@ -0,0 +1,11 @@ +namespace AdamController.Controls.CustomControls.Services +{ + public delegate void IsNotificationFlyoutOpenedStateChangeEventHandler(object sender); + + public interface IFlyoutStateChecker + { + public event IsNotificationFlyoutOpenedStateChangeEventHandler IsNotificationFlyoutOpenedStateChangeEvent; + + public bool IsNotificationFlyoutOpened { get; set; } + } +} diff --git a/AdamController.Controls/CustomControls/FlyoutContainer.xaml b/AdamController.Controls/CustomControls/FlyoutContainer.xaml new file mode 100644 index 0000000..befa621 --- /dev/null +++ b/AdamController.Controls/CustomControls/FlyoutContainer.xaml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/AdamController.Controls/CustomControls/FlyoutContainer.xaml.cs b/AdamController.Controls/CustomControls/FlyoutContainer.xaml.cs new file mode 100644 index 0000000..0106a6c --- /dev/null +++ b/AdamController.Controls/CustomControls/FlyoutContainer.xaml.cs @@ -0,0 +1,12 @@ +using MahApps.Metro.Controls; + +namespace AdamController.Controls.CustomControls +{ + public partial class FlyoutContainer : FlyoutsControl + { + public FlyoutContainer() + { + InitializeComponent(); + } + } +} diff --git a/AdamController.Controls/Enums/BlocklyViewMode.cs b/AdamController.Controls/Enums/BlocklyViewMode.cs new file mode 100644 index 0000000..e8a1570 --- /dev/null +++ b/AdamController.Controls/Enums/BlocklyViewMode.cs @@ -0,0 +1,9 @@ +namespace AdamController.Controls.Enums +{ + public enum BlocklyViewMode + { + Hidden = 0, + MiddleScreen = 1, + FullScreen = 2 + } +} diff --git a/AdamController.Core/AdamController.Core.csproj b/AdamController.Core/AdamController.Core.csproj new file mode 100644 index 0000000..2234d09 --- /dev/null +++ b/AdamController.Core/AdamController.Core.csproj @@ -0,0 +1,77 @@ + + + net7.0-windows + true + MIT-Modern-Variant + + + bin\x64\Debug\ + + + bin\x64\Release\ + + + + + + + + + + + + + + Always + + + + + + + + + + + + True + True + Resource.resx + + + True + Settings.settings + True + + + + + PublicResXFileCodeGenerator + Resource.Designer.cs + + + + + Settings.Designer.cs + PublicSettingsSingleFileGenerator + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + MSBuild:Compile + + + + + + \ No newline at end of file diff --git a/AdamController/App.config b/AdamController.Core/App.config similarity index 51% rename from AdamController/App.config rename to AdamController.Core/App.config index 0d6b677..b3fa840 100644 --- a/AdamController/App.config +++ b/AdamController.Core/App.config @@ -2,6 +2,7 @@ +
@@ -9,6 +10,277 @@ + + + 18000 + + + 15005 + + + 192.168.50.10 + + + Light + + + Blue + + + 0 + + + False + + + 20 + + + 0 + + + + + + True + + + True + + + ru + + + True + + + True + + + True + + + True + + + True + + + True + + + False + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + False + + + False + + + False + + + 854 + + + 512 + + + True + + + + + + + + + + + + + + + + + + True + + + True + + + 15000 + + + 32 + + + 192.168.50.10 + + + 15000 + + + 1 + + + 1000 + + + 10 + + + 10 + + + 16001 + + + 16002 + + + 32 + + + 1000 + + + 1 + + + 16000 + + + False + + + + + + 3 + + + 0 + + + 5 + + + 0 + + + True + + + False + + + True + + + 1 + + + True + + + False + + + + + + + + + True + + + + + + False + + + + + + adam + + + adam1234 + + + 5147 + + + True + + + 7071 + + + False + + + True + + + 8000 + + + + + + True + + + False + + + True + + + 10 + + + 0.7 + + 18000 diff --git a/AdamController/Behaviors/AvalonEditBehaviour.cs b/AdamController.Core/Behaviors/AvalonEditBehaviour.cs similarity index 93% rename from AdamController/Behaviors/AvalonEditBehaviour.cs rename to AdamController.Core/Behaviors/AvalonEditBehaviour.cs index 7cc9994..6e4d7be 100644 --- a/AdamController/Behaviors/AvalonEditBehaviour.cs +++ b/AdamController.Core/Behaviors/AvalonEditBehaviour.cs @@ -3,7 +3,7 @@ using System; using System.Windows; -namespace AdamController.Behaviors +namespace AdamController.Core.Behaviors { public class AvalonEditBehaviour : Behavior { @@ -41,8 +41,7 @@ private void AssociatedObjectOnTextChanged(object sender, EventArgs eventArgs) } } - private static void PropertyChangedCallback(DependencyObject dependencyObject, - DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) + private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { AvalonEditBehaviour behavior = dependencyObject as AvalonEditBehaviour; if (behavior.AssociatedObject != null) diff --git a/AdamController/Converters/BoolToVisibilityConverter.cs b/AdamController.Core/Converters/BoolToVisibilityConverter.cs similarity index 95% rename from AdamController/Converters/BoolToVisibilityConverter.cs rename to AdamController.Core/Converters/BoolToVisibilityConverter.cs index e598979..b05d282 100644 --- a/AdamController/Converters/BoolToVisibilityConverter.cs +++ b/AdamController.Core/Converters/BoolToVisibilityConverter.cs @@ -3,7 +3,7 @@ using System.Windows; using System.Windows.Data; -namespace AdamController.Converters +namespace AdamController.Core.Converters { [ValueConversion(typeof(bool?), typeof(Visibility))] public class BoolToVisibilityConverter : IValueConverter diff --git a/AdamController/Converters/GridLengthConverter.cs b/AdamController.Core/Converters/GridLengthConverter.cs similarity index 93% rename from AdamController/Converters/GridLengthConverter.cs rename to AdamController.Core/Converters/GridLengthConverter.cs index 653acaf..ab44f5f 100644 --- a/AdamController/Converters/GridLengthConverter.cs +++ b/AdamController.Core/Converters/GridLengthConverter.cs @@ -3,7 +3,7 @@ using System.Windows; using System.Windows.Data; -namespace AdamController.Converters +namespace AdamController.Core.Converters { public class GridLengthConverter : IValueConverter { diff --git a/AdamController/Converters/InverseBooleanConverter.cs b/AdamController.Core/Converters/InverseBooleanConverter.cs similarity index 93% rename from AdamController/Converters/InverseBooleanConverter.cs rename to AdamController.Core/Converters/InverseBooleanConverter.cs index 26713c4..45f3ef5 100644 --- a/AdamController/Converters/InverseBooleanConverter.cs +++ b/AdamController.Core/Converters/InverseBooleanConverter.cs @@ -2,7 +2,7 @@ using System.Globalization; using System.Windows.Data; -namespace AdamController.Converters +namespace AdamController.Core.Converters { [ValueConversion(typeof(bool), typeof(bool))] public class InverseBooleanConverter : IValueConverter diff --git a/AdamController/Converters/MultiConverter.cs b/AdamController.Core/Converters/MultiConverter.cs similarity index 94% rename from AdamController/Converters/MultiConverter.cs rename to AdamController.Core/Converters/MultiConverter.cs index 410ef30..6a9ab33 100644 --- a/AdamController/Converters/MultiConverter.cs +++ b/AdamController.Core/Converters/MultiConverter.cs @@ -2,7 +2,7 @@ using System.Globalization; using System.Windows.Data; -namespace AdamController.Converters +namespace AdamController.Core.Converters { public class MultiConverter : IMultiValueConverter { @@ -17,6 +17,7 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur } return true; } + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException("BooleanAndConverter is a OneWay converter."); diff --git a/AdamController/Converters/SelectedItemToContentConverter.cs b/AdamController.Core/Converters/SelectedItemToContentConverter.cs similarity index 94% rename from AdamController/Converters/SelectedItemToContentConverter.cs rename to AdamController.Core/Converters/SelectedItemToContentConverter.cs index a58e115..0f37800 100644 --- a/AdamController/Converters/SelectedItemToContentConverter.cs +++ b/AdamController.Core/Converters/SelectedItemToContentConverter.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Windows.Data; -namespace AdamController.Converters +namespace AdamController.Core.Converters { public class SelectedItemToContentConverter : IMultiValueConverter { diff --git a/AdamController/DataSource/ThemesCollection.cs b/AdamController.Core/DataSource/ThemesCollection.cs similarity index 84% rename from AdamController/DataSource/ThemesCollection.cs rename to AdamController.Core/DataSource/ThemesCollection.cs index 1db5fb8..1df0449 100644 --- a/AdamController/DataSource/ThemesCollection.cs +++ b/AdamController.Core/DataSource/ThemesCollection.cs @@ -1,10 +1,6 @@ -using AdamBlocklyLibrary.Enum; -using AdamController.Model; -using System.Collections.ObjectModel; - -namespace AdamController.DataSource +namespace AdamController.Core.DataSource { - public class ThemesCollection + /*public class ThemesCollection { public static ObservableCollection BlocklyThemes { get; private set; } = new() { @@ -16,5 +12,5 @@ public class ThemesCollection new BlocklyThemeModel() { BlocklyTheme = BlocklyTheme.Tritanopia, BlocklyThemeName = "Tritanopia" }, new BlocklyThemeModel() { BlocklyTheme = BlocklyTheme.Zelos, BlocklyThemeName = "Zelos" }, }; - } + }*/ } diff --git a/AdamController.Core/Dialog.ViewModels/SettingsViewModel.cs b/AdamController.Core/Dialog.ViewModels/SettingsViewModel.cs new file mode 100644 index 0000000..7d85abc --- /dev/null +++ b/AdamController.Core/Dialog.ViewModels/SettingsViewModel.cs @@ -0,0 +1,52 @@ +using AdamController.Core.Mvvm; + +namespace AdamController.Core.Dialog.ViewModels +{ + /// + /// The template for calling a dialog box through a service + /// + public class SettingsViewModel : DialogViewModelBase + { + /* For Calling from MenuRegion: + * + * MenuRegionViewModel: + * public DelegateCommand ShowDialogCommand { get; } + * ShowDialogCommand = new DelegateCommand(ShowDialog); + * + * private void ShowDialog(string dialogNames) + * { + * switch (dialogNames) + * { + * case DialogNames.SettingsDialog: + * DialogService.ShowSettingsDialog(); + * break; + * } + * } + * + * MenuRegionView: + * + * + * + * + * + * + * In DialogNames: + * public const string SettingsDialog = nameof(SettingsView); + * + * In DialogServiceExtensions + * public static class DialogServiceExtensions + * { + * public static void ShowSettingsDialog(this IDialogService dialogService) + * { + * dialogService.ShowDialog(nameof(SettingsView)); + * } + * } + * + * + */ + } +} diff --git a/AdamController.Core/Dialog.Views/SettingsView.xaml b/AdamController.Core/Dialog.Views/SettingsView.xaml new file mode 100644 index 0000000..cbcd6f5 --- /dev/null +++ b/AdamController.Core/Dialog.Views/SettingsView.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/AdamController.Core/Dialog.Views/SettingsView.xaml.cs b/AdamController.Core/Dialog.Views/SettingsView.xaml.cs new file mode 100644 index 0000000..e30aafa --- /dev/null +++ b/AdamController.Core/Dialog.Views/SettingsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace AdamController.Core.Dialog.Views +{ + /// + /// Логика взаимодействия для SettingsView.xaml + /// + public partial class SettingsView : UserControl + { + public SettingsView() + { + InitializeComponent(); + } + } +} diff --git a/AdamController/Views/Window/SettingsWindow.xaml b/AdamController.Core/Dialog.Views/SettingsViewOld.xaml similarity index 91% rename from AdamController/Views/Window/SettingsWindow.xaml rename to AdamController.Core/Dialog.Views/SettingsViewOld.xaml index f513542..06048cd 100644 --- a/AdamController/Views/Window/SettingsWindow.xaml +++ b/AdamController.Core/Dialog.Views/SettingsViewOld.xaml @@ -1,28 +1,45 @@ - - - + + + + + + + + + + - + + + + + + + + + @@ -56,7 +73,7 @@ - + + endregion--> - + + endregion--> - + + #endregion--> - + + endregion--> - + IsOn="{Binding CheckServerVersion, Mode=TwoWay, Source={x:Static properties:Settings.Default}}"/>--> @@ -210,7 +227,7 @@ - + + #endregion--> - + + #endregion--> - + + #endregion--> - + + endregion--> - + + #endregion--> - + + endregion--> - + + endregion--> - + + endregion--> @@ -381,7 +398,7 @@ - + + #endregion--> - + + endregion--> - + + endregion--> - + + endregion--> @@ -512,7 +529,7 @@ - + + endregion--> - + + endregion--> - + + + endregion--> @@ -615,7 +632,7 @@ - + + endregion--> @@ -700,7 +717,7 @@ - + + #endregion--> @@ -750,7 +767,7 @@ - + + #endregion--> @@ -825,8 +842,8 @@ Width="80" VerticalAlignment="Center" HorizontalAlignment="Right" - Command="{Binding CloseWindowCommand}" - CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" + Command="{Binding CloseDialogCommand}" + CommandParameter="true" Style="{DynamicResource MahApps.Styles.Button}" HorizontalContentAlignment="Center"/> @@ -836,4 +853,4 @@ - + diff --git a/AdamController.Core/Dialog.Views/SettingsViewOld.xaml.cs b/AdamController.Core/Dialog.Views/SettingsViewOld.xaml.cs new file mode 100644 index 0000000..c1cac0d --- /dev/null +++ b/AdamController.Core/Dialog.Views/SettingsViewOld.xaml.cs @@ -0,0 +1,12 @@ +using System.Windows.Controls; + +namespace AdamController.Core.Dialog.Views +{ + public partial class SettingsViewOld : UserControl + { + public SettingsViewOld() + { + InitializeComponent(); + } + } +} diff --git a/AdamController.Core/DialogNames.cs b/AdamController.Core/DialogNames.cs new file mode 100644 index 0000000..f29c39b --- /dev/null +++ b/AdamController.Core/DialogNames.cs @@ -0,0 +1,7 @@ +namespace AdamController.Core +{ + public class DialogNames + { + //Dialog boxes are not used, but implemented + } +} diff --git a/AdamController.Core/Extensions/ColorExtensions.cs b/AdamController.Core/Extensions/ColorExtensions.cs new file mode 100644 index 0000000..653e06e --- /dev/null +++ b/AdamController.Core/Extensions/ColorExtensions.cs @@ -0,0 +1,23 @@ +using System; + +namespace AdamController.Core.Extensions +{ + public static class ColorExtensions + { + public static string HexToRbgColor(this string hexColorString) + { + if (string.IsNullOrEmpty(hexColorString)) + { + return ""; + } + + byte R = Convert.ToByte(hexColorString.Substring(3, 2), 16); + byte G = Convert.ToByte(hexColorString.Substring(5, 2), 16); + byte B = Convert.ToByte(hexColorString.Substring(7, 2), 16); + + return $"rgb({R}, {G}, {B})"; + } + + //TODO To HUE COLOR + } +} diff --git a/AdamController.Core/Extensions/DialogServiceExtensions.cs b/AdamController.Core/Extensions/DialogServiceExtensions.cs new file mode 100644 index 0000000..2430d13 --- /dev/null +++ b/AdamController.Core/Extensions/DialogServiceExtensions.cs @@ -0,0 +1,10 @@ +namespace AdamController.Core.Extensions +{ + /*public static class DialogServiceExtensions + { + public static void ShowSettingsDialog(this IDialogService dialogService) + { + dialogService.ShowDialog(nameof(SettingsView)); + } + }*/ +} diff --git a/AdamController/Helpers/SyslogParseMessage.cs b/AdamController.Core/Extensions/SyslogParseMessageExtension.cs similarity index 83% rename from AdamController/Helpers/SyslogParseMessage.cs rename to AdamController.Core/Extensions/SyslogParseMessageExtension.cs index 8453704..969be47 100644 --- a/AdamController/Helpers/SyslogParseMessage.cs +++ b/AdamController.Core/Extensions/SyslogParseMessageExtension.cs @@ -1,10 +1,10 @@ -using AdamController.Model; +using AdamController.Core.Model; using System; using System.Text.RegularExpressions; -namespace AdamController.Helpers +namespace AdamController.Core.Extensions { - public class SyslogParseMessage + public static class SyslogParseMessageExtension { private static readonly string mSyslogMsgHeaderPattern = @"\<(?\d{1,3})\>(?[1-9]{0,2}) (?(\S|\w)+) (?-|(\S|\w){1,255}) (?-|(\S|\w){1,48}) (?-|(\S|\w){1,128}) (?-|(\S|\w){1,32})"; private static readonly string mSyslogMsgStructuredDataPattern = @"(?-|\[[^\[\=\x22\]\x20]{1,32}( ([^\[\=\x22\]\x20]{1,32}=\x22.+\x22))?\])"; @@ -18,14 +18,15 @@ public class SyslogParseMessage /// /// /// - public static SyslogMessage Parse(string rawMessage) + public static SyslogMessageModel Parse(this string rawMessage) { - if (string.IsNullOrWhiteSpace(rawMessage)) { throw new ArgumentNullException(nameof(rawMessage)); } + if (string.IsNullOrWhiteSpace(rawMessage)) + { throw new ArgumentNullException(nameof(rawMessage)); } var match = mExpression.Match(rawMessage); if (match.Success) { - return new SyslogMessage + return new SyslogMessageModel { Prival = Convert.ToInt32(match.Groups["PRIVAL"].Value), Version = Convert.ToInt32(match.Groups["VERSION"].Value), @@ -39,9 +40,9 @@ public static SyslogMessage Parse(string rawMessage) RawMessage = rawMessage }; } - else - { - throw new InvalidOperationException("Invalid message."); + else + { + throw new InvalidOperationException("Invalid message."); } } } diff --git a/AdamController.Core/FlyoutNames.cs b/AdamController.Core/FlyoutNames.cs new file mode 100644 index 0000000..adf9841 --- /dev/null +++ b/AdamController.Core/FlyoutNames.cs @@ -0,0 +1,15 @@ +namespace AdamController.Core +{ + /// + /// The flyout name must match the view + /// Binding to the viewmodel must be enabled in the view (prism:ViewModelLocator.AutoWireViewModel="True") + /// + public class FlyoutNames + { + public const string FlyoutNotification = "NotificationView"; + public const string FlyoutPortSettings = "PortSettingsView"; + public const string FlyoutUserFoldersSettings = "UserFoldersSettingsView"; + public const string FlyoutWebApiSettings = "WebApiSettingsView"; + + } +} diff --git a/AdamController.Core/HighlightingName.cs b/AdamController.Core/HighlightingName.cs new file mode 100644 index 0000000..a866f53 --- /dev/null +++ b/AdamController.Core/HighlightingName.cs @@ -0,0 +1,9 @@ +using AdamController.Core.Properties; + +namespace AdamController.Core +{ + public class HighlightingName + { + public const string AdamPython = nameof(Resource.AdamPython); + } +} diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.en.xaml new file mode 100644 index 0000000..c220b4a --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.en.xaml @@ -0,0 +1,8 @@ + + + Management + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.ru.xaml new file mode 100644 index 0000000..affbef7 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ComputerVisionControlView.ru.xaml @@ -0,0 +1,8 @@ + + + Управление + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.en.xaml new file mode 100644 index 0000000..9162619 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.en.xaml @@ -0,0 +1,16 @@ + + + + The debugging session has started + The debugging session is over + + + The program has been completed + Further output of the result will be hidden. + The program continues to run interactively. + To stop the program, press "Stop" or wait for the completion. + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.ru.xaml new file mode 100644 index 0000000..44f588e --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/DebuggerMessages.ru.xaml @@ -0,0 +1,16 @@ + + + + Сеанс отладки начат + Сеанс отладки закончен + + + Выполнение программы завершено + Дальнейший вывод результата, будет скрыт. + Программа продолжает выполняться в неинтерактивном режиме. + Для остановки нажмите "Stop" или дождитесь завершения. + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.en.xaml new file mode 100644 index 0000000..26efb45 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.en.xaml @@ -0,0 +1,20 @@ + + + No new messages + Robot Adam disconnect! + Check the connection and click reconnect + + Reconnect + + Clear notifications + + + Notification center + + Connect + Disconnect + Wait + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.ru.xaml new file mode 100644 index 0000000..8996d37 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/NotificationView.ru.xaml @@ -0,0 +1,21 @@ + + + Новых уведомлений нет + Робот Адам отключен! + Проверьте связь и нажмите переподключить + + Переподключить + + Очистить уведомления + + + + Центр уведомлений + + Подключить + Отключить + Подождите + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.en.xaml new file mode 100644 index 0000000..7adf1fb --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.en.xaml @@ -0,0 +1,13 @@ + + + Video stream + Server socket port + Debugger port + Log server port + Connection control port + + Port settings + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.ru.xaml new file mode 100644 index 0000000..dca8e4e --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/PortSettingsView.ru.xaml @@ -0,0 +1,13 @@ + + + Видео стрим + Порт сокет сервера + Порт отладчика + Порт сервера логов + Порт контроля подключения + + Настройки портов + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.en.xaml new file mode 100644 index 0000000..1aa9a18 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.en.xaml @@ -0,0 +1,13 @@ + + + Scripts + Workspace + + User folder location settings + + Select a directory to save workspaces to + Select the directory to save the scripts to + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.ru.xaml new file mode 100644 index 0000000..47e8c7a --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/UserFoldersSettingsView.ru.xaml @@ -0,0 +1,13 @@ + + + Скрипты + Рабочие области + + Настройки расположения папок пользователя + + Выберите директорию для сохранения рабочих областей + Выберите директорию для сохранения скриптов + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.en.xaml new file mode 100644 index 0000000..2842e74 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.en.xaml @@ -0,0 +1,11 @@ + + + Login + Password + Port + + WebApi Settings + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.ru.xaml new file mode 100644 index 0000000..baed90e --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/Flyout/WebApiSettingsView.ru.xaml @@ -0,0 +1,10 @@ + + + Логин + Пароль + Порт + + Настройки WebApi + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.en.xaml new file mode 100644 index 0000000..2bcab40 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.en.xaml @@ -0,0 +1,10 @@ + + + + Scratch editor + Computer vision + Settings + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.ru.xaml new file mode 100644 index 0000000..f782687 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/HamburgerMenu.ru.xaml @@ -0,0 +1,10 @@ + + + + Скретч редактор + Компьютерное зрение + Настройки + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.en.xaml new file mode 100644 index 0000000..6ea5913 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.en.xaml @@ -0,0 +1,17 @@ + + + + File + View + + + Close + + + Scratch editor + Computer vision + Settings + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.ru.xaml new file mode 100644 index 0000000..de8fbfd --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/MainMenu.ru.xaml @@ -0,0 +1,18 @@ + + + + + Файл + Вид + + + Закрыть + + + Скретч редактор + Компьютерное зрение + Настройки + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.en.xaml new file mode 100644 index 0000000..569aef8 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.en.xaml @@ -0,0 +1,11 @@ + + + Output data + + Result + Execution time + Initialization time + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.ru.xaml new file mode 100644 index 0000000..da9aae3 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlView.ru.xaml @@ -0,0 +1,11 @@ + + + Выходные данные + + Результат + Время выполнения + Время инициализации + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.en.xaml new file mode 100644 index 0000000..494e881 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.en.xaml @@ -0,0 +1,19 @@ + + + Save workspace + Save the program file + PythonScript file (.py)|*.py|All files|*.* + + + Select a saved workspace + + The file is saved. Path + The file has not been saved + The workspace file is not selected + + Scretch loaded complete + Scretch loaded error + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.ru.xaml new file mode 100644 index 0000000..fda3797 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/ScratchControlViewModel.ru.xaml @@ -0,0 +1,20 @@ + + + Сохранить рабочую область + Сохранить файл программы + PythonScript file (.py)|*.py|Все файлы|*.* + + + Выберите сохранененную рабочую область + + Файл сохранен. Путь + Файл не сохранен + Файл рабочей области не выбран + + Загрузка скретч редактора завершена + Загрузка скретч внезапно прервана + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.en.xaml new file mode 100644 index 0000000..4f05669 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.en.xaml @@ -0,0 +1,58 @@ + + + + Language and theme + Scratch editor settings + Connection and notification settings + Environment settings + + + App theme + App language + Displayed sets of blocks + + + Logical + Colors + Lists + Loops + Mathematical + Procedures + Text + Variables + Blocks Adam v.2.6 + Blocks Adam v.2.7 + + + Connect at startup + Notify robot disconnection + Create user folders + + + The size of the grid cell + + + Custom + + + By default + + + Show grid + Show the trash can + Align blocks + Load latest + Do not show the browser menu + Shadow on debug + + + Robot IP + + + WebApi settings + Port settings + Configuring user folders + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.ru.xaml new file mode 100644 index 0000000..05e709d --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/SettingsControlView.ru.xaml @@ -0,0 +1,58 @@ + + + + Язык и тема + Настройки скретч редактора + Настройки подключений и уведомлений + Настройки окружения + + + Тема приложения + Язык приложения + Отображаемые наборы блоков + + + Логические + Цвета + Списки + Циклы + Математические + Процедуры + Текстовые + Переменные + Блоки Adam v.2.6 + Блоки Adam v.2.7 + + + Подключаться при запуске + Уведомлять об отключении от робота + Создавать папки пользователя + + + Размер ячейки сетки + + + Пользовательский + + + По умолчанию + + + Показывать сетку + Показывать корзину + Выравнивать блоки + Загружать последние + Не показывать меню браузера + Затемнять при отладке + + + Адрес робота + + + Настройки WebApi + Настройки портов + Настройка папок пользователя + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.en.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.en.xaml new file mode 100644 index 0000000..1812319 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.en.xaml @@ -0,0 +1,14 @@ + + + Adam: disconnect + Adam: connect + Adam: reconnect + + Robot log + App log + + The application language has been changed + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.ru.xaml b/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.ru.xaml new file mode 100644 index 0000000..8bf05fc --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/DictonaryCollection/StatusBarViewModel.ru.xaml @@ -0,0 +1,14 @@ + + + Адам: отключен + Адам: подключен + Адам: переподключение + + Лог робота + Лог приложения + + Язык приложения изменен + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/en.xaml b/AdamController.Core/LocalizationDictionary/en.xaml new file mode 100644 index 0000000..c5065f3 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/en.xaml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AdamController.Core/LocalizationDictionary/ru.xaml b/AdamController.Core/LocalizationDictionary/ru.xaml new file mode 100644 index 0000000..f0f0cd0 --- /dev/null +++ b/AdamController.Core/LocalizationDictionary/ru.xaml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AdamController/Model/BlocklyThemeModel.cs b/AdamController.Core/Model/BlocklyThemeModel.cs similarity index 52% rename from AdamController/Model/BlocklyThemeModel.cs rename to AdamController.Core/Model/BlocklyThemeModel.cs index a770db7..b81cc21 100644 --- a/AdamController/Model/BlocklyThemeModel.cs +++ b/AdamController.Core/Model/BlocklyThemeModel.cs @@ -1,10 +1,8 @@ -using AdamBlocklyLibrary.Enum; - -namespace AdamController.Model +namespace AdamController.Core.Model { - public class BlocklyThemeModel + /*public class BlocklyThemeModel { public BlocklyTheme BlocklyTheme { get; set; } public string BlocklyThemeName { get; set; } - } + }*/ } diff --git a/AdamController/Model/SyslogMessage.cs b/AdamController.Core/Model/SyslogMessageModel.cs similarity index 81% rename from AdamController/Model/SyslogMessage.cs rename to AdamController.Core/Model/SyslogMessageModel.cs index 592671e..4272ee1 100644 --- a/AdamController/Model/SyslogMessage.cs +++ b/AdamController.Core/Model/SyslogMessageModel.cs @@ -2,9 +2,9 @@ using System; using System.Text; -namespace AdamController.Model +namespace AdamController.Core.Model { - public class SyslogMessage + public class SyslogMessageModel { public int Prival { get; set; } public int Version { get; set; } @@ -19,7 +19,7 @@ public class SyslogMessage public override string ToString() { - var message = new StringBuilder($@"<{Prival:###}>{Version:##} {TimeStamp.ToString("yyyy-MM-ddTHH:mm:ss.fffK")} {HostName} {AppName} {ProcId} {MessageId} {StructuredData}"); + var message = new StringBuilder($@"<{Prival:###}>{Version:##} {TimeStamp:yyyy-MM-ddTHH:mm:ss.fffK} {HostName} {AppName} {ProcId} {MessageId} {StructuredData}"); if (!string.IsNullOrWhiteSpace(Message)) { diff --git a/AdamController/Model/VectorModel.cs b/AdamController.Core/Model/VectorModel.cs similarity index 91% rename from AdamController/Model/VectorModel.cs rename to AdamController.Core/Model/VectorModel.cs index 8eebee9..fde0ef9 100644 --- a/AdamController/Model/VectorModel.cs +++ b/AdamController.Core/Model/VectorModel.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace AdamController.Model +namespace AdamController.Core.Model { public class VectorModel diff --git a/AdamController.Core/Mvvm/DialogViewModelBase.cs b/AdamController.Core/Mvvm/DialogViewModelBase.cs new file mode 100644 index 0000000..4f7b396 --- /dev/null +++ b/AdamController.Core/Mvvm/DialogViewModelBase.cs @@ -0,0 +1,59 @@ +using Prism.Commands; +using Prism.Mvvm; +using Prism.Services.Dialogs; +using System; + +namespace AdamController.Core.Mvvm +{ + public class DialogViewModelBase : BindableBase, IDialogAware + { + public string Title { get; protected set; } = "Title"; + + #region Command + + private DelegateCommand mCloseDialogCommand; + public DelegateCommand CloseDialogCommand => mCloseDialogCommand ??= new DelegateCommand(CloseDialog); + + #endregion + + #region Navigation + + + public event Action RequestClose; + + public virtual void RaiseRequestClose(IDialogResult dialogResult) + { + RequestClose?.Invoke(dialogResult); + } + + public virtual bool CanCloseDialog() + { + return true; + } + + public virtual void OnDialogClosed() + { + + } + + public virtual void OnDialogOpened(IDialogParameters parameters) + { + + } + + public virtual void CloseDialog(string parameter) + { + ButtonResult result = ButtonResult.None; + + if (parameter?.ToLower() == "true") + result = ButtonResult.OK; + else if (parameter?.ToLower() == "false") + result = ButtonResult.Cancel; + + RaiseRequestClose(new DialogResult(result)); + } + + #endregion + + } +} diff --git a/AdamController.Core/Mvvm/RegionViewModelBase.cs b/AdamController.Core/Mvvm/RegionViewModelBase.cs new file mode 100644 index 0000000..0c0ac31 --- /dev/null +++ b/AdamController.Core/Mvvm/RegionViewModelBase.cs @@ -0,0 +1,54 @@ +using Prism.Regions; +using System; + + +namespace AdamController.Core.Mvvm +{ + public class RegionViewModelBase : ViewModelBase, INavigationAware, IConfirmNavigationRequest + { + + #region private service + + protected IRegionManager RegionManager { get; } + + #endregion + + #region ~ + + public RegionViewModelBase(IRegionManager regionManager) + { + RegionManager = regionManager; + } + + #endregion + + /// + /// Occurs when the navigation area is called + /// + public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) + { + continuationCallback?.Invoke(true); + } + + + public virtual bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + /// + /// On close region + /// + public virtual void OnNavigatedFrom(NavigationContext navigationContext) + { + } + + /// + /// On load region + /// + public virtual void OnNavigatedTo(NavigationContext navigationContext) + { + + } + } +} diff --git a/AdamController.Core/Mvvm/ViewModelBase.cs b/AdamController.Core/Mvvm/ViewModelBase.cs new file mode 100644 index 0000000..29681c2 --- /dev/null +++ b/AdamController.Core/Mvvm/ViewModelBase.cs @@ -0,0 +1,12 @@ +using Prism.Mvvm; +using Prism.Navigation; + +namespace AdamController.Core.Mvvm +{ + public class ViewModelBase : BindableBase, IDestructible + { + protected ViewModelBase() {} + + public virtual void Destroy() {} + } +} diff --git a/AdamController.Core/NavigationParametersKey.cs b/AdamController.Core/NavigationParametersKey.cs new file mode 100644 index 0000000..e424c4e --- /dev/null +++ b/AdamController.Core/NavigationParametersKey.cs @@ -0,0 +1,7 @@ +namespace AdamController.Core +{ + public class NavigationParametersKey + { + public const string SourceCode = nameof(SourceCode); + } +} diff --git a/AdamController/Properties/AdamPython.xshd b/AdamController.Core/Properties/AdamPython.xshd similarity index 100% rename from AdamController/Properties/AdamPython.xshd rename to AdamController.Core/Properties/AdamPython.xshd diff --git a/AdamController/Images/Icons/AdamIconAndRGBPageIcon.ico b/AdamController.Core/Properties/Icons/main_app_icon.ico similarity index 100% rename from AdamController/Images/Icons/AdamIconAndRGBPageIcon.ico rename to AdamController.Core/Properties/Icons/main_app_icon.ico diff --git a/AdamController/Properties/Resources.Designer.cs b/AdamController.Core/Properties/Resource.Designer.cs similarity index 85% rename from AdamController/Properties/Resources.Designer.cs rename to AdamController.Core/Properties/Resource.Designer.cs index 1f8e8d2..d2dbece 100644 --- a/AdamController/Properties/Resources.Designer.cs +++ b/AdamController.Core/Properties/Resource.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace AdamController.Properties { +namespace AdamController.Core.Properties { using System; @@ -22,14 +22,14 @@ namespace AdamController.Properties { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class Resources { + public class Resource { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { + internal Resource() { } /// @@ -39,7 +39,7 @@ internal Resources() { public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AdamController.Properties.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AdamController.Core.Properties.Resource", typeof(Resource).Assembly); resourceMan = temp; } return resourceMan; @@ -69,5 +69,15 @@ public static byte[] AdamPython { return ((byte[])(obj)); } } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Icon, аналогичного (Значок). + /// + public static System.Drawing.Icon main_app_icon { + get { + object obj = ResourceManager.GetObject("main_app_icon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } } } diff --git a/AdamController/Properties/Resources.resx b/AdamController.Core/Properties/Resource.resx similarity index 93% rename from AdamController/Properties/Resources.resx rename to AdamController.Core/Properties/Resource.resx index 9ad5cd9..572b121 100644 --- a/AdamController/Properties/Resources.resx +++ b/AdamController.Core/Properties/Resource.resx @@ -112,13 +112,16 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + AdamPython.xshd;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\main_app_icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/AdamController/Properties/Settings.Designer.cs b/AdamController.Core/Properties/Settings.Designer.cs similarity index 93% rename from AdamController/Properties/Settings.Designer.cs rename to AdamController.Core/Properties/Settings.Designer.cs index 283bb7b..2b71097 100644 --- a/AdamController/Properties/Settings.Designer.cs +++ b/AdamController.Core/Properties/Settings.Designer.cs @@ -8,12 +8,12 @@ // //------------------------------------------------------------------------------ -namespace AdamController.Properties { +namespace AdamController.Core.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.6.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] + public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -1054,5 +1054,77 @@ public int SoketServerPort { this["SoketServerPort"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string AppThemeName { + get { + return ((string)(this["AppThemeName"])); + } + set { + this["AppThemeName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool CreateUserDirrectory { + get { + return ((bool)(this["CreateUserDirrectory"])); + } + set { + this["CreateUserDirrectory"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool ShowLineNumber { + get { + return ((bool)(this["ShowLineNumber"])); + } + set { + this["ShowLineNumber"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool EditorIsReadOnly { + get { + return ((bool)(this["EditorIsReadOnly"])); + } + set { + this["EditorIsReadOnly"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("10")] + public double SourceEditorLength { + get { + return ((double)(this["SourceEditorLength"])); + } + set { + this["SourceEditorLength"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0.7")] + public double WebViewZoomFactor { + get { + return ((double)(this["WebViewZoomFactor"])); + } + set { + this["WebViewZoomFactor"] = value; + } + } } } diff --git a/AdamController/Properties/Settings.settings b/AdamController.Core/Properties/Settings.settings similarity index 93% rename from AdamController/Properties/Settings.settings rename to AdamController.Core/Properties/Settings.settings index 6e6d614..7201d65 100644 --- a/AdamController/Properties/Settings.settings +++ b/AdamController.Core/Properties/Settings.settings @@ -1,5 +1,5 @@  - + @@ -260,5 +260,23 @@ 8000 + + + + + True + + + False + + + True + + + 10 + + + 0.7 + \ No newline at end of file diff --git a/AdamController.Core/RegionNames.cs b/AdamController.Core/RegionNames.cs new file mode 100644 index 0000000..f64b2e8 --- /dev/null +++ b/AdamController.Core/RegionNames.cs @@ -0,0 +1,10 @@ +namespace AdamController.Core +{ + public class RegionNames + { + public const string MenuRegion = $"{nameof(MenuRegion)}"; + public const string ContentRegion = $"{nameof(ContentRegion)}"; + public const string FlayoutsRegion = $"{nameof(FlayoutsRegion)}"; + public const string StatusBarRegion = $"{nameof(StatusBarRegion)}"; + } +} diff --git a/AdamController.Core/SubRegionNames.cs b/AdamController.Core/SubRegionNames.cs new file mode 100644 index 0000000..09c3e3f --- /dev/null +++ b/AdamController.Core/SubRegionNames.cs @@ -0,0 +1,16 @@ +namespace AdamController.Core +{ + public class SubRegionNames + { + /// + /// region to switch SubRegionView inside ContentRegion + /// + public const string InsideConentRegion = $"{nameof(InsideConentRegion)}"; + + public const string SubRegionScratch = $"{nameof(SubRegionScratch)}"; + + public const string SubRegionComputerVisionControl = $"{nameof(SubRegionComputerVisionControl)}"; + + public const string SubRegionVisualSettings = $"{nameof(SubRegionVisualSettings)}"; + } +} diff --git a/AdamController.Services/AdamController.Services.csproj b/AdamController.Services/AdamController.Services.csproj new file mode 100644 index 0000000..9a0f9ae --- /dev/null +++ b/AdamController.Services/AdamController.Services.csproj @@ -0,0 +1,30 @@ + + + + net7.0-windows + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdamController.Services/AvalonEditService.cs b/AdamController.Services/AvalonEditService.cs new file mode 100644 index 0000000..91f12fa --- /dev/null +++ b/AdamController.Services/AvalonEditService.cs @@ -0,0 +1,62 @@ +using AdamBlocklyLibrary.Properties; +using AdamController.Services.Interfaces; +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.AvalonEdit.Highlighting.Xshd; +using System; +using System.Collections.ObjectModel; + +namespace AdamController.Services +{ + public class AvalonEditService : IAvalonEditService + { + #region Var + + private readonly IFileManagmentService mFileManagmentService; + private readonly HighlightingManager mHighlightingManager; + + #endregion + + #region ~ + + public AvalonEditService(IFileManagmentService fileManagmentService) + { + mFileManagmentService = fileManagmentService; + mHighlightingManager = HighlightingManager.Instance; + } + + #endregion + + #region Public field + + public ReadOnlyCollection HighlightingDefinitions + { + get => mHighlightingManager.HighlightingDefinitions; + } + + #endregion + + #region Public methods + + public void RegisterHighlighting(string highlightingName, byte[] xmlByteArray) + { + var xml = mFileManagmentService.ReadTextAsXml(xmlByteArray); + var definition = HighlightingLoader.Load(xml, mHighlightingManager); + mHighlightingManager.RegisterHighlighting(highlightingName, Array.Empty(), definition); + + } + + public IHighlightingDefinition GetDefinition(string name) + { + IHighlightingDefinition definition = mHighlightingManager.GetDefinition(name); + return definition; + } + + public void Dispose() + { + + } + + #endregion + + } +} diff --git a/AdamController.Services/CommunicationProviderService.cs b/AdamController.Services/CommunicationProviderService.cs new file mode 100644 index 0000000..468f266 --- /dev/null +++ b/AdamController.Services/CommunicationProviderService.cs @@ -0,0 +1,215 @@ +using AdamController.Services.Interfaces; +using AdamController.Services.UdpClientServiceDependency; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace AdamController.Services +{ + public class CommunicationProviderService : ICommunicationProviderService + { + #region Events + + public event TcpServiceCientConnectedEventHandler RaiseTcpServiceCientConnectedEvent; + public event TcpServiceClientDisconnectEventHandler RaiseTcpServiceClientDisconnectEvent; + public event TcpServiceClientReconnectedEventHandler RaiseTcpServiceClientReconnectedEvent; + public event UdpServiceServerReceivedEventHandler RaiseUdpServiceServerReceivedEvent; + public event UdpServiceClientMessageEnqueueEvent RaiseUdpServiceClientMessageEnqueueEvent; + + #endregion + + #region Services + + private readonly ITcpClientService mTcpClientService; + private readonly IUdpClientService mUdpClientService; + private readonly IUdpServerService mUdpServerService; + private readonly IWebSocketClientService mWebSocketClientService; + + #endregion + + #region var + + private bool mIsDisconnectByUserRequest = false; + + #endregion + + #region ~ + + public CommunicationProviderService(ITcpClientService adamTcpClientService, IUdpClientService adamUdpClientService, + IUdpServerService adamUdpServerService, IWebSocketClientService adamWebSocketClientService) + { + mTcpClientService = adamTcpClientService; + mUdpClientService = adamUdpClientService; + mUdpServerService = adamUdpServerService; + mWebSocketClientService = adamWebSocketClientService; + + Subscribe(); + } + + #endregion + + #region Public fields + + public bool IsTcpClientConnected { get; private set; } + + #endregion + + #region Public methods + + public void ConnectAllAsync() + { + _ = Task.Run(mTcpClientService.ConnectAsync); + _ = Task.Run(mUdpClientService.Start); + _ = Task.Run(mUdpServerService.Start); + _ = Task.Run(mWebSocketClientService.ConnectAsync); + } + + public void DisconnectAllAsync() + { + mIsDisconnectByUserRequest = false; + + _ = Task.Run(mTcpClientService.DisconnectAndStop); + _ = Task.Run(mUdpClientService.Stop); + _ = Task.Run(mUdpServerService.Stop); + _ = Task.Run(mWebSocketClientService.DisconnectAsync); + } + + public void DisconnectAllAsync(bool isUserRequest) + { + mIsDisconnectByUserRequest = isUserRequest; + + _ = Task.Run(mTcpClientService.DisconnectAndStop); + _ = Task.Run(mUdpClientService.Stop); + _ = Task.Run(mUdpServerService.Stop); + _ = Task.Run(mWebSocketClientService.DisconnectAsync); + } + + public void WebSocketSendTextMessage(string message) + { + Task.Run(() => mWebSocketClientService.SendTextAsync(message)); + } + + public void Dispose() + { + DisconnectAllAsync(); + Unsubscribe(); + + mTcpClientService.Dispose(); + mUdpClientService.Dispose(); + mUdpServerService.Dispose(); + mWebSocketClientService.Dispose(); + } + + #endregion + + + #region Private methods + + #endregion + + #region Subscriptions + + private void Subscribe() + { + mTcpClientService.RaiseTcpClientReconnectedEvent += RaiseServiceTcpClientReconnected; + mTcpClientService.RaiseTcpCientConnectedEvent += RaiseServiceTcpCientConnected; + mTcpClientService.RaiseTcpClientDisconnectedEvent += RaiseTcpClientDisconnected; + + mUdpClientService.RaiseUdpClientMessageEnqueueEvent += RaiseUdpClientMessageEnqueueEvent; + + mUdpServerService.RaiseUdpServerReceivedEvent += RaiseServiceUdpServerReceived; + } + + + private void Unsubscribe() + { + mTcpClientService.RaiseTcpClientReconnectedEvent -= RaiseServiceTcpClientReconnected; + mTcpClientService.RaiseTcpCientConnectedEvent -= RaiseServiceTcpCientConnected; + mTcpClientService.RaiseTcpClientDisconnectedEvent -= RaiseTcpClientDisconnected; + + mUdpClientService.RaiseUdpClientMessageEnqueueEvent -= RaiseUdpClientMessageEnqueueEvent; + + mUdpServerService.RaiseUdpServerReceivedEvent -= RaiseServiceUdpServerReceived; + } + + #endregion + + #region Event methods + + private void RaiseServiceTcpCientConnected(object sender) + { + IsTcpClientConnected = true; + + OnRaiseTcpServiceCientConnectedEvent(); + + mUdpClientService.Start(); + mUdpServerService.Start(); + mWebSocketClientService.ConnectAsync(); + } + + private void RaiseTcpClientDisconnected(object sender) + { + IsTcpClientConnected = false; + + OnRaiseTcpServiceClientDisconnectEvent(); + + mUdpClientService.Stop(); + mUdpServerService.Stop(); + mWebSocketClientService.DisconnectAsync(); + } + + private void RaiseServiceTcpClientReconnected(object sender, int reconnectCount) + { + OnRaiseTcpServiceClientReconnectedEvent(reconnectCount); + } + + private void RaiseUdpClientMessageEnqueueEvent(object sender, ReceivedData data) + { + OnRaiseUdpServiceClientMessageEnqueueEvent(data); + } + + private void RaiseServiceUdpServerReceived(object sender, EndPoint endpoint, byte[] buffer, long offset, long size) + { + string encodedMessage = Encoding.UTF8.GetString(buffer, (int)offset, (int)size); + OnRaiseUdpServiceServerReceivedEvent(encodedMessage); + } + + #endregion + + #region OnRaise events + + protected virtual void OnRaiseTcpServiceCientConnectedEvent() + { + TcpServiceCientConnectedEventHandler raiseEvent = RaiseTcpServiceCientConnectedEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaiseTcpServiceClientDisconnectEvent() + { + TcpServiceClientDisconnectEventHandler raiseEvent = RaiseTcpServiceClientDisconnectEvent; + raiseEvent?.Invoke(this, mIsDisconnectByUserRequest); + + mIsDisconnectByUserRequest = false; + } + + public virtual void OnRaiseTcpServiceClientReconnectedEvent(int reconnectCounter) + { + TcpServiceClientReconnectedEventHandler raiseEvent = RaiseTcpServiceClientReconnectedEvent; + raiseEvent?.Invoke(this, reconnectCounter); + } + + protected virtual void OnRaiseUdpServiceServerReceivedEvent(string message) + { + UdpServiceServerReceivedEventHandler raiseEvent = RaiseUdpServiceServerReceivedEvent; + raiseEvent?.Invoke(this, message); + } + + protected virtual void OnRaiseUdpServiceClientMessageEnqueueEvent(ReceivedData data) + { + UdpServiceClientMessageEnqueueEvent raiseEvent = RaiseUdpServiceClientMessageEnqueueEvent; + raiseEvent?.Invoke(this, data); + } + + #endregion + } +} diff --git a/AdamController.Services/CultureProvider.cs b/AdamController.Services/CultureProvider.cs new file mode 100644 index 0000000..97586db --- /dev/null +++ b/AdamController.Services/CultureProvider.cs @@ -0,0 +1,142 @@ +using AdamController.Services.Interfaces; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Windows; + +namespace AdamController.Services +{ + public class CultureProvider : BindableBase, ICultureProvider + { + #region Events + + public event CurrentAppCultureLoadOrChangeEventHandler RaiseCurrentAppCultureLoadOrChangeEvent; + + #endregion + + #region Const + + private const string cEnString = "en-EN"; + private const string cRuString = "ru-RU"; + + #endregion + + #region Var + + private readonly Application mCurrentApp = Application.Current; + + #endregion + + #region ~ + + public CultureProvider() {} + + #endregion + + #region Public fields + + public List SupportAppCultures { get { return GetSupportAppCultures(); } } + + private CultureInfo currentAppCulture; + public CultureInfo CurrentAppCulture + { + get => currentAppCulture; + private set + { + bool isNewValue = SetProperty(ref currentAppCulture, value); + + if (isNewValue) + OnRaiseCurrentAppCultureLoadOrChangeEvent(); + } + + } + + #endregion + + #region Public methods + + public void ChangeAppCulture(CultureInfo culture) + { + string resourceName = $"pack://application:,,,/AdamController.Core;component/LocalizationDictionary/{culture.TwoLetterISOLanguageName}.xaml"; + Uri uri = new(resourceName); + ResourceDictionary resources = new() + { + Source = uri + }; + + RemoveLoadedDictonary(); + + mCurrentApp.Resources.MergedDictionaries.Add(resources); + UpdateCurrentCulture(culture); + } + + + public void Dispose() + { + + } + + public string FindResource(string resource) + { + var @string = mCurrentApp.TryFindResource(resource) as string; + return @string; + } + + #endregion + + #region Private method + + private void UpdateCurrentCulture(CultureInfo culture) + { + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = culture; + CurrentAppCulture = culture; + } + + private void RemoveLoadedDictonary() + { + List supportedCultures = SupportAppCultures; + ResourceDictionary currentResourceDictionary = null; + + foreach (var culture in supportedCultures) + { + string resourceName = $"pack://application:,,,/AdamController.Core;component/LocalizationDictionary/{culture.TwoLetterISOLanguageName}.xaml"; + currentResourceDictionary = mCurrentApp.Resources.MergedDictionaries.FirstOrDefault(x => x?.Source?.OriginalString == resourceName); + } + + if (currentResourceDictionary == null || currentResourceDictionary?.MergedDictionaries.Count == 0) + return; + + foreach (ResourceDictionary dictionary in currentResourceDictionary.MergedDictionaries) + mCurrentApp.Resources.MergedDictionaries.Remove(dictionary); + } + + private static List GetSupportAppCultures() + { + CultureInfo en = new(cEnString); + CultureInfo ru = new(cRuString); + + List cultureInfos = new() + { + ru, en + }; + + return cultureInfos; + } + + #endregion + + #region OnRaise events + + protected virtual void OnRaiseCurrentAppCultureLoadOrChangeEvent() + { + CurrentAppCultureLoadOrChangeEventHandler raiseEvent = RaiseCurrentAppCultureLoadOrChangeEvent; + raiseEvent?.Invoke(this); + } + + #endregion + } +} diff --git a/AdamController.Services/DialogManager.cs b/AdamController.Services/DialogManager.cs new file mode 100644 index 0000000..e0109b6 --- /dev/null +++ b/AdamController.Services/DialogManager.cs @@ -0,0 +1,13 @@ +using AdamController.Services.Interfaces; +using MessageDialogManagerLib; +using System.Windows; + +namespace AdamController.Services +{ + public class DialogManager : MessageDialogManagerMahapps, IDialogManagerService + { + public DialogManager(Application app) : base(app) {} + + public void Dispose(){} + } +} diff --git a/AdamController.Services/FileManagmentService.cs b/AdamController.Services/FileManagmentService.cs new file mode 100644 index 0000000..fd83e42 --- /dev/null +++ b/AdamController.Services/FileManagmentService.cs @@ -0,0 +1,84 @@ +using AdamController.Services.Interfaces; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace AdamController.Services +{ + public class FileManagmentService : IFileManagmentService + { + #region Const + + private const int cBufferSize = 0x4096; + + #endregion + + #region ~ + + public FileManagmentService() { } + + #endregion + + #region Public methods + + public XmlTextReader ReadTextAsXml(byte[] xmlByteArray) + { + MemoryStream stream = new(xmlByteArray); + XmlTextReader reader = new(stream); + + return reader; + } + + public async Task ReadTextAsByteArray(string path) + { + using var fs = OpenFileStreamAsync(path); + + var buffer = new byte[fs.Length]; + _ = await fs.ReadAsync(buffer.AsMemory(0, (int)fs.Length)); + return buffer; + } + + public async Task ReadTextAsStringAsync(string path) + { + using FileStream sourceStream = OpenFileStreamAsync(path); + + StringBuilder sb = new(); + + byte[] buffer = new byte[0x1000]; + int numRead; + + while ((numRead = await sourceStream.ReadAsync(buffer)) != 0) + { + string text = Encoding.UTF8.GetString(buffer, 0, numRead); + _ = sb.Append(text); + } + + return sb.ToString(); + } + + public async Task WriteAsync(string path, string file) + { + using StreamWriter writer = File.CreateText(path); + await writer.WriteAsync(file); + } + + public void Dispose() + { + + } + + #endregion + + #region Private mehods + + private static FileStream OpenFileStreamAsync(string path) + { + return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: cBufferSize, useAsync: true); + } + + #endregion + + } +} diff --git a/AdamController.Services/FolderManagmentService.cs b/AdamController.Services/FolderManagmentService.cs new file mode 100644 index 0000000..3214357 --- /dev/null +++ b/AdamController.Services/FolderManagmentService.cs @@ -0,0 +1,99 @@ +using AdamController.Services.Interfaces; +using System; +using System.Globalization; +using System.IO; +using System.Reflection; + +namespace AdamController.Services +{ + public class FolderManagmentService : IFolderManagmentService + { + #region Var + + private readonly string mAssemblyTitle = Assembly.GetEntryAssembly().GetName().Name; + + #endregion + + #region ~ + + public FolderManagmentService() + { + } + + #endregion + + #region Public fields + + public string MyDocumentsUserDir => Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + + public string SpecialProgramDocumentsDir => MyDocumentsUserDir + Path.DirectorySeparatorChar + "AdamStudio"; + + public string SavedWorkspaceDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyWorkspaces"; + + //public string SavedToolboxDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyToolboxes"; + + //public string SavedUserCustomBlocksDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyBlocks"; + + public string SavedUserScriptsDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyScripts"; + + //public string SavedResultsNetworkTestsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "NetworkResultsTests"; + + public string DirAppData => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + mAssemblyTitle; + + public string DirFileAppSessionData => Path.Combine(DirAppData, string.Format(CultureInfo.InvariantCulture, "{0}.App.session", mAssemblyTitle)); + + public string CommonDirAppData => Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + Path.DirectorySeparatorChar + Assembly.GetEntryAssembly().GetName().Name; + + #endregion + + #region Public methods + + public bool CreateAppDataFolder() + { + try + { + if (!Directory.Exists(DirAppData)) + { + _ = Directory.CreateDirectory(DirAppData); + } + + if (!Directory.Exists(SpecialProgramDocumentsDir)) + { + _ = Directory.CreateDirectory(SpecialProgramDocumentsDir); + } + + if (!Directory.Exists(SavedWorkspaceDocumentsDir)) + { + _ = Directory.CreateDirectory(SavedWorkspaceDocumentsDir); + } + + //if (!Directory.Exists(SavedToolboxDocumentsDir)) + //{ + // _ = Directory.CreateDirectory(SavedToolboxDocumentsDir); + //} + //if (!Directory.Exists(SavedUserCustomBlocksDocumentsDir)) + //{ + // _ = Directory.CreateDirectory(SavedUserCustomBlocksDocumentsDir); + //} + if (!Directory.Exists(SavedUserScriptsDocumentsDir)) + { + _ = Directory.CreateDirectory(SavedUserScriptsDocumentsDir); + } + //if (!Directory.Exists(SavedResultsNetworkTestsDir)) + //{ + // _ = Directory.CreateDirectory(SavedResultsNetworkTestsDir); + //} + } + catch + { + return false; + } + + return true; + } + + public void Dispose(){} + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IAvalonEditService.cs b/AdamController.Services/Interfaces/IAvalonEditService.cs new file mode 100644 index 0000000..f71cc99 --- /dev/null +++ b/AdamController.Services/Interfaces/IAvalonEditService.cs @@ -0,0 +1,16 @@ +using ICSharpCode.AvalonEdit.Highlighting; +using System; +using System.Collections.ObjectModel; + +namespace AdamController.Services.Interfaces +{ + public interface IAvalonEditService : IDisposable + { + /// + /// Register highlighting for AvalonEdit. You need to call before loading the regions + /// + public void RegisterHighlighting(string highlightingName, byte[] xmlByteArray); + public ReadOnlyCollection HighlightingDefinitions { get; } + public IHighlightingDefinition GetDefinition(string name); + } +} diff --git a/AdamController.Services/Interfaces/ICommunicationProviderService.cs b/AdamController.Services/Interfaces/ICommunicationProviderService.cs new file mode 100644 index 0000000..b891f2a --- /dev/null +++ b/AdamController.Services/Interfaces/ICommunicationProviderService.cs @@ -0,0 +1,45 @@ +using AdamController.Services.UdpClientServiceDependency; +using System; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + public delegate void TcpServiceCientConnectedEventHandler(object sender); + public delegate void TcpServiceClientDisconnectEventHandler(object sender, bool isUserRequest); + public delegate void TcpServiceClientReconnectedEventHandler(object sender, int reconnectCounter); + public delegate void UdpServiceServerReceivedEventHandler(object sender, string message); + public delegate void UdpServiceClientMessageEnqueueEvent(object sender, ReceivedData data); + + #endregion + + /// + /// ComunicateHeleper functional + /// + public interface ICommunicationProviderService : IDisposable + { + #region Events + + public event TcpServiceCientConnectedEventHandler RaiseTcpServiceCientConnectedEvent; + public event TcpServiceClientDisconnectEventHandler RaiseTcpServiceClientDisconnectEvent; + public event TcpServiceClientReconnectedEventHandler RaiseTcpServiceClientReconnectedEvent; + public event UdpServiceServerReceivedEventHandler RaiseUdpServiceServerReceivedEvent; + public event UdpServiceClientMessageEnqueueEvent RaiseUdpServiceClientMessageEnqueueEvent; + + #endregion + + #region Public fields + public bool IsTcpClientConnected { get; } + + #endregion + + #region Public methods + + public void ConnectAllAsync(); + public void DisconnectAllAsync(); + public void DisconnectAllAsync(bool isUserRequest); + public void WebSocketSendTextMessage(string message); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/ICultureProvider.cs b/AdamController.Services/Interfaces/ICultureProvider.cs new file mode 100644 index 0000000..ef28e4e --- /dev/null +++ b/AdamController.Services/Interfaces/ICultureProvider.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace AdamController.Services.Interfaces +{ + #region Delegates + + public delegate void CurrentAppCultureLoadOrChangeEventHandler(object sender); + + #endregion + + public interface ICultureProvider : IDisposable + { + #region Events + + public event CurrentAppCultureLoadOrChangeEventHandler RaiseCurrentAppCultureLoadOrChangeEvent; + + #endregion + + #region Public fields + + public List SupportAppCultures { get; } + public CultureInfo CurrentAppCulture { get; } + + #endregion + + #region Public methods + + public string FindResource(string resourcePath); + public void ChangeAppCulture(CultureInfo culture); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IDialogManagerService.cs b/AdamController.Services/Interfaces/IDialogManagerService.cs new file mode 100644 index 0000000..8b1a471 --- /dev/null +++ b/AdamController.Services/Interfaces/IDialogManagerService.cs @@ -0,0 +1,11 @@ +using MessageDialogManagerLib; +using System; + +namespace AdamController.Services.Interfaces +{ + /// + /// The old dialog call type integrated into the service + /// + public interface IDialogManagerService : IMessageDialogManager, IDisposable + {} +} diff --git a/AdamController.Services/Interfaces/IFileManagmentService.cs b/AdamController.Services/Interfaces/IFileManagmentService.cs new file mode 100644 index 0000000..97fce96 --- /dev/null +++ b/AdamController.Services/Interfaces/IFileManagmentService.cs @@ -0,0 +1,21 @@ +using System; +using System.Threading.Tasks; +using System.Xml; + +namespace AdamController.Services.Interfaces +{ + public interface IFileManagmentService : IDisposable + { + #region Public methods + + public Task WriteAsync(string path, string file); + + public Task ReadTextAsStringAsync(string path); + + public Task ReadTextAsByteArray(string path); + + public XmlTextReader ReadTextAsXml(byte[] xml); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IFolderManagmentService.cs b/AdamController.Services/Interfaces/IFolderManagmentService.cs new file mode 100644 index 0000000..8ee768a --- /dev/null +++ b/AdamController.Services/Interfaces/IFolderManagmentService.cs @@ -0,0 +1,31 @@ + + +using System; + +namespace AdamController.Services.Interfaces +{ + public interface IFolderManagmentService : IDisposable + { + public string MyDocumentsUserDir { get; } + + public string SpecialProgramDocumentsDir { get; } + + public string SavedWorkspaceDocumentsDir { get; } + + //public string SavedToolboxDocumentsDir { get; } + + //public string SavedUserCustomBlocksDocumentsDir { get; } + + public string SavedUserScriptsDocumentsDir { get; } + + //public string SavedResultsNetworkTestsDir { get; } + + public string DirAppData { get; } + + public string DirFileAppSessionData { get; } + + public string CommonDirAppData { get; } + + public bool CreateAppDataFolder(); + } +} diff --git a/AdamController.Services/Interfaces/IPythonRemoteRunnerService.cs b/AdamController.Services/Interfaces/IPythonRemoteRunnerService.cs new file mode 100644 index 0000000..53acd50 --- /dev/null +++ b/AdamController.Services/Interfaces/IPythonRemoteRunnerService.cs @@ -0,0 +1,24 @@ +using AdamController.WebApi.Client.v1.ResponseModel; +using System; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + public delegate void PythonStandartOutputEventHandler(object sender, string message); + public delegate void PythonScriptExecuteStartEventHandler(object sender); + public delegate void PythonScriptExecuteFinishEventHandler(object sender, ExtendedCommandExecuteResult remoteCommandExecuteResult); + + #endregion + + public interface IPythonRemoteRunnerService : IDisposable + { + #region Events + + public event PythonStandartOutputEventHandler RaisePythonStandartOutputEvent; + public event PythonScriptExecuteStartEventHandler RaisePythonScriptExecuteStartEvent; + public event PythonScriptExecuteFinishEventHandler RaisePythonScriptExecuteFinishEvent; + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IStatusBarNotificationDeliveryService.cs b/AdamController.Services/Interfaces/IStatusBarNotificationDeliveryService.cs new file mode 100644 index 0000000..62cb2dc --- /dev/null +++ b/AdamController.Services/Interfaces/IStatusBarNotificationDeliveryService.cs @@ -0,0 +1,40 @@ +using System; + +namespace AdamController.Services.Interfaces +{ + #region Delegates + + public delegate void ChangeProgressRingStateEventHandler(object sender, bool newState); + public delegate void NewCompileLogMessageEventHandler(object sender, string message); + public delegate void NewAppLogMessageEventHandler(object sender, string message); + public delegate void UpdateNotificationCounterEventHandler(object sender, int counter); + + #endregion + + public interface IStatusBarNotificationDeliveryService : IDisposable + { + #region Event + + public event ChangeProgressRingStateEventHandler RaiseChangeProgressRingStateEvent; + public event NewCompileLogMessageEventHandler RaiseNewCompileLogMessageEvent; + public event NewAppLogMessageEventHandler RaiseNewAppLogMessageEvent; + public event UpdateNotificationCounterEventHandler RaiseUpdateNotificationCounterEvent; + + #endregion + + #region Public fields + + public bool ProgressRingStart { get; set; } + public string CompileLogMessage { get; set; } + public string AppLogMessage { get; set; } + public int NotificationCounter { get; set; } + + #endregion + + #region Public fields + + public void ResetNotificationCounter(); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/ISubRegionChangeAwareService.cs b/AdamController.Services/Interfaces/ISubRegionChangeAwareService.cs new file mode 100644 index 0000000..a71d8fb --- /dev/null +++ b/AdamController.Services/Interfaces/ISubRegionChangeAwareService.cs @@ -0,0 +1,25 @@ +using System; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + public delegate void SubRegionChangeEventHandler(object sender); + + #endregion + + public interface ISubRegionChangeAwareService : IDisposable + { + #region Events + + public event SubRegionChangeEventHandler RaiseSubRegionChangeEvent; + + #endregion + + #region Public fields + + public string InsideRegionNavigationRequestName { get; set; } + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/ITcpClientService.cs b/AdamController.Services/Interfaces/ITcpClientService.cs new file mode 100644 index 0000000..9afc450 --- /dev/null +++ b/AdamController.Services/Interfaces/ITcpClientService.cs @@ -0,0 +1,48 @@ +using System; +using System.Net.Sockets; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + public delegate void TcpCientConnectedEventHandler(object sender); + public delegate void TcpCientSentEventHandler(object sender, long sent, long pending); + public delegate void TcpClientDisconnectEventHandler(object sender); + public delegate void TcpClientErrorEventHandler(object sender, SocketError error); + public delegate void TcpClientReceivedEventHandler(object sender, byte[] buffer, long offset, long size); + public delegate void TcpClientReconnectedEventHandler(object sender, int reconnectCount); + + #endregion + + public interface ITcpClientService : IDisposable + { + + #region Events + + public event TcpCientConnectedEventHandler RaiseTcpCientConnectedEvent; + public event TcpCientSentEventHandler RaiseTcpCientSentEvent; + public event TcpClientDisconnectEventHandler RaiseTcpClientDisconnectedEvent; + public event TcpClientErrorEventHandler RaiseTcpClientErrorEvent; + public event TcpClientReceivedEventHandler RaiseTcpClientReceivedEvent; + public event TcpClientReconnectedEventHandler RaiseTcpClientReconnectedEvent; + + #endregion + + /// + /// The number of reconnections when the connection is lost + /// + public int ReconnectCount { get; } + + /// + /// Reconnection timeout + /// + public int ReconnectTimeout { get; } + + public void DisconnectAndStop(); + + /// + /// This method is implemented in NetCoreServer.TcpClient + /// + public bool ConnectAsync(); + } +} diff --git a/AdamController.Services/Interfaces/IThemeManagerService.cs b/AdamController.Services/Interfaces/IThemeManagerService.cs new file mode 100644 index 0000000..3139da2 --- /dev/null +++ b/AdamController.Services/Interfaces/IThemeManagerService.cs @@ -0,0 +1,22 @@ +using ControlzEx.Theming; +using System; +using System.Collections.ObjectModel; + +namespace AdamController.Services.Interfaces +{ + public interface IThemeManagerService : IDisposable + { + #region Public fields + public ReadOnlyObservableCollection AppThemesCollection { get; } + + #endregion + + #region Public methods + + public Theme GetCurrentAppTheme(); + public Theme ChangeAppTheme(string themeName); + public Theme ChangeAppTheme(Theme themeName); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IUdpClientService.cs b/AdamController.Services/Interfaces/IUdpClientService.cs new file mode 100644 index 0000000..7a39e74 --- /dev/null +++ b/AdamController.Services/Interfaces/IUdpClientService.cs @@ -0,0 +1,33 @@ +using AdamController.Services.UdpClientServiceDependency; +using System; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + public delegate void UdpClientMessageEnqueueEventHandler(object sender, ReceivedData data); + + #endregion + + public interface IUdpClientService : IDisposable + { + #region Events + + public event UdpClientMessageEnqueueEventHandler RaiseUdpClientMessageEnqueueEvent; + + #endregion + + #region Public fields + public bool IsStarted { get; } + + #endregion + + #region Public methods + + public bool Stop(); + + public bool Start(); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IUdpServerService.cs b/AdamController.Services/Interfaces/IUdpServerService.cs new file mode 100644 index 0000000..3fc7793 --- /dev/null +++ b/AdamController.Services/Interfaces/IUdpServerService.cs @@ -0,0 +1,37 @@ + +using System; +using System.Net; + +namespace AdamController.Services.Interfaces +{ + + #region Delegate + + public delegate void UdpServerReceivedEventHandler(object sender, EndPoint endpoint, byte[] buffer, long offset, long size); + + #endregion + + public interface IUdpServerService : IDisposable + { + #region Events + + public event UdpServerReceivedEventHandler RaiseUdpServerReceivedEvent; + + #endregion + + #region Public fields + + public bool IsStarted { get; } + + #endregion + + #region Public methods + + public bool Start(); + + public bool Stop(); + + #endregion + + } +} diff --git a/AdamController.Services/Interfaces/IWebApiService.cs b/AdamController.Services/Interfaces/IWebApiService.cs new file mode 100644 index 0000000..87f45ba --- /dev/null +++ b/AdamController.Services/Interfaces/IWebApiService.cs @@ -0,0 +1,18 @@ +using AdamController.WebApi.Client.v1.RequestModel; +using AdamController.WebApi.Client.v1.ResponseModel; +using System; +using System.Threading.Tasks; + +namespace AdamController.Services.Interfaces +{ + public interface IWebApiService : IDisposable + { + public Task StopPythonExecute(); + public Task GetPythonVersion(); + public Task GetPythonBinDir(); + public Task GetPythonWorkDir(); + public Task PythonExecuteAsync(PythonCommandModel command); + public Task MoveToZeroPosition(); + + } +} diff --git a/AdamController.Services/Interfaces/IWebSocketClientService.cs b/AdamController.Services/Interfaces/IWebSocketClientService.cs new file mode 100644 index 0000000..4e3ce37 --- /dev/null +++ b/AdamController.Services/Interfaces/IWebSocketClientService.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; + +namespace AdamController.Services.Interfaces +{ + + #region Delegate + + public delegate void WebSocketClientReceivedEventHandler(object sender, string text); + public delegate void WebSocketConnectedEventHandler(object sender); + public delegate void WebSocketClientDisconnectEventHandler(object sender); + + #endregion + + public interface IWebSocketClientService : IDisposable + { + #region Events + + public event WebSocketClientReceivedEventHandler RaiseWebSocketClientReceivedEvent; + public event WebSocketConnectedEventHandler RaiseWebSocketConnectedEvent; + public event WebSocketClientDisconnectEventHandler RaiseWebSocketClientDisconnectEvent; + + #endregion + + #region Public field + + public bool IsStarted { get; } + + public bool IsRunning { get; } + + #endregion + + #region Public method + + public Task ConnectAsync(); + + public Task DisconnectAsync(); + + public Task SendTextAsync(string text); + + #endregion + } +} diff --git a/AdamController.Services/Interfaces/IWebViewProvider.cs b/AdamController.Services/Interfaces/IWebViewProvider.cs new file mode 100644 index 0000000..e6e2e6c --- /dev/null +++ b/AdamController.Services/Interfaces/IWebViewProvider.cs @@ -0,0 +1,41 @@ +using AdamController.Services.WebViewProviderDependency; +using System; +using System.Threading.Tasks; + +namespace AdamController.Services.Interfaces +{ + #region Delegate + + /*event in view model*/ + public delegate void WebViewNavigationCompleteEventHandler(object sender); + public delegate void WebViewbMessageReceivedEventHandler(object sender, WebMessageJsonReceived webMessageReceived); + + /*event in view */ + public delegate Task ExecuteJavaScriptEventHandler(object sender, string script, bool deserializeResultToString = false); + public delegate void ExecuteReloadWebViewEventHandler(object sender); + + #endregion + + public interface IWebViewProvider : IDisposable + { + /*event in view model*/ + public event WebViewNavigationCompleteEventHandler RaiseWebViewNavigationCompleteEvent; + public event WebViewbMessageReceivedEventHandler RaiseWebViewMessageReceivedEvent; + + /*event in view */ + public event ExecuteJavaScriptEventHandler RaiseExecuteJavaScriptEvent; + public event ExecuteReloadWebViewEventHandler RaiseExecuteReloadWebViewEvent; + + + /// + /// Execute JS script + /// + /// Json objects as string if deserializeResultToString false, deserialize object as string otherwise + public Task ExecuteJavaScript(string script, bool deserializeResultToString = false); + + /* in view model */ + public void ReloadWebView(); + public void NavigationComplete(); + public void WebViewMessageReceived(WebMessageJsonReceived receivedResult); + } +} diff --git a/AdamController.Services/PythonRemoteRunnerService.cs b/AdamController.Services/PythonRemoteRunnerService.cs new file mode 100644 index 0000000..1eec389 --- /dev/null +++ b/AdamController.Services/PythonRemoteRunnerService.cs @@ -0,0 +1,158 @@ +using AdamController.Services.Interfaces; +using AdamController.Services.UdpClientServiceDependency; +using AdamController.WebApi.Client.v1.ResponseModel; +using AdamController.WebApi.Client.Common; +using System.Linq; +using System.Text.RegularExpressions; + + +namespace AdamController.Services +{ + public partial class PythonRemoteRunnerService : IPythonRemoteRunnerService + { + #region Events + + public event PythonStandartOutputEventHandler RaisePythonStandartOutputEvent; + public event PythonScriptExecuteStartEventHandler RaisePythonScriptExecuteStartEvent; + public event PythonScriptExecuteFinishEventHandler RaisePythonScriptExecuteFinishEvent; + + #endregion + + #region Services + + private readonly IUdpClientService mUdpClientService; + + #endregion + + #region Const + + private const string cStartMessage = "start"; + private const string cErrorMessage = "error"; + private const string cFinishMessage = "finish"; + private const string cPattern = $"{cStartMessage}|{cErrorMessage}|{cFinishMessage}"; + + #endregion + + #region var + + private readonly Regex mRegex; + + [GeneratedRegex($"{cPattern}", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.NonBacktracking)] + private static partial Regex MyRegex(); + + #endregion + + #region ~ + + public PythonRemoteRunnerService(IUdpClientService udpClientService) + { + mUdpClientService = udpClientService; + + Subscribe(); + + mRegex = MyRegex(); + } + + + #endregion + + + #region Public method + + public void Dispose() + { + Unsubscribe(); + } + + #endregion + + #region Private methods + + private void ParseEvents(Match match, string message) + { + switch (match.Value) + { + case cStartMessage: + OnRaisePythonScriptExecuteStartEvent(); + break; + + case cErrorMessage: + break; + + case cFinishMessage: + { + string cleanMessage = message.Remove(0, 6); + + ExtendedCommandExecuteResult executeResult = cleanMessage.ToExtendedCommandResult(); + OnRaisePythonScriptExecuteFinishEvent(executeResult); + break; + } + } + } + + private void ParseMessage(string message) + { + MatchCollection matches = mRegex.Matches(message); + + if(matches.Count > 0) + { + foreach(Match match in matches.Cast()) + { + ParseEvents(match, message); + } + + return; + } + + OnRaisePythonStandartOutputEvent($"{message}\n"); + + } + + #endregion + + #region Subscribses + + private void Subscribe() + { + mUdpClientService.RaiseUdpClientMessageEnqueueEvent += RaiseUdpClientMessageEnqueueEvent; + } + + private void Unsubscribe() + { + mUdpClientService.RaiseUdpClientMessageEnqueueEvent -= RaiseUdpClientMessageEnqueueEvent; + } + + #endregion + + #region Event methods + + private void RaiseUdpClientMessageEnqueueEvent(object sender, ReceivedData data) + { + ParseMessage(data.ToString()); + } + + #endregion + + #region OnRaise events + + protected virtual void OnRaisePythonStandartOutputEvent(string message) + { + PythonStandartOutputEventHandler raiseEvent = RaisePythonStandartOutputEvent; + raiseEvent?.Invoke(this, message); + } + + protected virtual void OnRaisePythonScriptExecuteStartEvent() + { + PythonScriptExecuteStartEventHandler raiseEvent = RaisePythonScriptExecuteStartEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaisePythonScriptExecuteFinishEvent(ExtendedCommandExecuteResult remoteCommandExecuteResult) + { + PythonScriptExecuteFinishEventHandler raiseEvent = RaisePythonScriptExecuteFinishEvent; + raiseEvent?.Invoke(this, remoteCommandExecuteResult); + } + + #endregion + } +} diff --git a/AdamController.Services/StatusBarNotificationDeliveryService.cs b/AdamController.Services/StatusBarNotificationDeliveryService.cs new file mode 100644 index 0000000..9931092 --- /dev/null +++ b/AdamController.Services/StatusBarNotificationDeliveryService.cs @@ -0,0 +1,124 @@ +using AdamController.Services.Interfaces; +using Prism.Mvvm; + + +namespace AdamController.Services +{ + public class StatusBarNotificationDeliveryService : BindableBase, IStatusBarNotificationDeliveryService + { + + #region Events + + public event ChangeProgressRingStateEventHandler RaiseChangeProgressRingStateEvent; + public event NewCompileLogMessageEventHandler RaiseNewCompileLogMessageEvent; + public event NewAppLogMessageEventHandler RaiseNewAppLogMessageEvent; + public event UpdateNotificationCounterEventHandler RaiseUpdateNotificationCounterEvent; + + #endregion + + #region ~ + + public StatusBarNotificationDeliveryService() { } + + #endregion + + #region Public fields + + private bool progressRingStart; + public bool ProgressRingStart + { + get => progressRingStart; + set + { + bool isNewValue = SetProperty(ref progressRingStart, value); + + if (isNewValue) + OnRaiseChangeProgressRingStateEvent(ProgressRingStart); + + } + } + + private string compileLogMessage = string.Empty; + public string CompileLogMessage + { + get => compileLogMessage; + set + { + bool isNewValue = SetProperty(ref compileLogMessage, value); + + if (isNewValue) + OnRaiseNewCompileLogMessageEvent(CompileLogMessage); + } + } + + private string appLogMessage = string.Empty; + public string AppLogMessage + { + get => appLogMessage; + set + { + bool isNewValue = SetProperty(ref appLogMessage, value); + + if (isNewValue) + OnRaiseNewAppLogMessageEvent(AppLogMessage); + } + } + + private int notificationCounter; + public int NotificationCounter + { + get => notificationCounter; + set + { + bool isNewValue = SetProperty(ref notificationCounter, value); + + if (isNewValue) + OnRaiseUpdateNotificationCounterEvent(NotificationCounter); + } + } + + #endregion + + #region Public methode + + public void ResetNotificationCounter() + { + NotificationCounter = 0; + } + + public void Dispose() + { + + } + + #endregion + + #region OnRaise methods + + protected virtual void OnRaiseChangeProgressRingStateEvent(bool newState) + { + ChangeProgressRingStateEventHandler raiseEvent = RaiseChangeProgressRingStateEvent; + raiseEvent?.Invoke(this, newState); + } + + protected virtual void OnRaiseNewCompileLogMessageEvent(string message) + { + NewCompileLogMessageEventHandler raiseEvent = RaiseNewCompileLogMessageEvent; + raiseEvent?.Invoke(this, message); + } + + protected virtual void OnRaiseNewAppLogMessageEvent(string message) + { + NewAppLogMessageEventHandler raiseEvent = RaiseNewAppLogMessageEvent; + raiseEvent?.Invoke(this, message); + } + + protected virtual void OnRaiseUpdateNotificationCounterEvent(int counter) + { + UpdateNotificationCounterEventHandler raiseEvent = RaiseUpdateNotificationCounterEvent; + raiseEvent?.Invoke(this, counter); + } + + #endregion + } +} diff --git a/AdamController.Services/SubRegionChangeAwareService.cs b/AdamController.Services/SubRegionChangeAwareService.cs new file mode 100644 index 0000000..dd84ea5 --- /dev/null +++ b/AdamController.Services/SubRegionChangeAwareService.cs @@ -0,0 +1,50 @@ +using AdamController.Services.Interfaces; +using Prism.Mvvm; + +namespace AdamController.Services +{ + public class SubRegionChangeAwareService : BindableBase, ISubRegionChangeAwareService + { + #region Events + + public event SubRegionChangeEventHandler RaiseSubRegionChangeEvent; + + #endregion + + #region ~ + + public SubRegionChangeAwareService() { } + + #endregion + + #region Public fields + + private string insideRegionNavigationRequestName; + public string InsideRegionNavigationRequestName + { + get { return insideRegionNavigationRequestName; } + set + { + bool isNewValue = SetProperty(ref insideRegionNavigationRequestName, value); + + if (isNewValue) + OnRaiseRegionChangeEvent(); + } + } + + public void Dispose() { } + + #endregion + + #region OnRaise events + + protected virtual void OnRaiseRegionChangeEvent() + { + SubRegionChangeEventHandler raiseEvent = RaiseSubRegionChangeEvent; + raiseEvent?.Invoke(this); + } + + #endregion + + } +} diff --git a/AdamControllerLibrary/AdamComunicate/AdamTcpClientOption.cs b/AdamController.Services/TcpClientDependency/TcpClientOption.cs similarity index 77% rename from AdamControllerLibrary/AdamComunicate/AdamTcpClientOption.cs rename to AdamController.Services/TcpClientDependency/TcpClientOption.cs index ce5f4fe..04d1199 100644 --- a/AdamControllerLibrary/AdamComunicate/AdamTcpClientOption.cs +++ b/AdamController.Services/TcpClientDependency/TcpClientOption.cs @@ -1,6 +1,6 @@ -namespace AdamControllerLibrary.AdamComunicate +namespace AdamController.Services.TcpClientDependency { - public class AdamTcpClientOption + public class TcpClientOption { /// /// The number of reconnections when the connection is lost diff --git a/AdamControllerLibrary/AdamComunicate/AdamTcpClient.cs b/AdamController.Services/TcpClientService.cs similarity index 55% rename from AdamControllerLibrary/AdamComunicate/AdamTcpClient.cs rename to AdamController.Services/TcpClientService.cs index 80dd96a..db0e575 100644 --- a/AdamControllerLibrary/AdamComunicate/AdamTcpClient.cs +++ b/AdamController.Services/TcpClientService.cs @@ -1,44 +1,22 @@ -using System; +using AdamController.Services.Interfaces; +using AdamController.Services.TcpClientDependency; +using System; using System.Net.Sockets; using System.Threading; -namespace AdamControllerLibrary.AdamComunicate +namespace AdamController.Services { - public class AdamTcpClient : NetCoreServer.TcpClient - { - #region DelegateAndEvent - - public delegate void OnTcpCientConnected(); - public event OnTcpCientConnected TcpCientConnected; - - public delegate void OnTcpCientSent(long sent, long pending); - public event OnTcpCientSent TcpCientSent; - - public delegate void OnTcpClientDisconnect(); - public event OnTcpClientDisconnect TcpClientDisconnected; - public delegate void OnTcpClientError(SocketError error); - public event OnTcpClientError TcpClientError; - - public delegate void OnTcpClientReceived(byte[] buffer, long offset, long size); - public event OnTcpClientReceived TcpClientReceived; + public class TcpClientService : NetCoreServer.TcpClient, ITcpClientService + { + #region Events - public delegate void OnTcpClientReconnected(int reconnectCount); - public event OnTcpClientReconnected TcpClientReconnected; - - #endregion - - #region Public field - - /// - /// The number of reconnections when the connection is lost - /// - public int ReconnectCount { get; private set; } - - /// - /// Reconnection timeout - /// - public int ReconnectTimeout { get; private set; } + public event TcpCientConnectedEventHandler RaiseTcpCientConnectedEvent; + public event TcpCientSentEventHandler RaiseTcpCientSentEvent; + public event TcpClientDisconnectEventHandler RaiseTcpClientDisconnectedEvent; + public event TcpClientErrorEventHandler RaiseTcpClientErrorEvent; + public event TcpClientReceivedEventHandler RaiseTcpClientReceivedEvent; + public event TcpClientReconnectedEventHandler RaiseTcpClientReconnectedEvent; #endregion @@ -54,7 +32,7 @@ public class AdamTcpClient : NetCoreServer.TcpClient #region ~ - public AdamTcpClient(string address, int port, AdamTcpClientOption option) : base(address, port) + public TcpClientService(string address, int port, TcpClientOption option) : base(address, port) { ReconnectCount = option.ReconnectCount; ReconnectTimeout = option.ReconnectTimeout; @@ -66,6 +44,22 @@ public AdamTcpClient(string address, int port, AdamTcpClientOption option) : bas #endregion + #region Public field + + /// + /// The number of reconnections when the connection is lost + /// + public int ReconnectCount { get; } + + /// + /// Reconnection timeout + /// + public int ReconnectTimeout { get; } + + #endregion + + #region Public methods + public void DisconnectAndStop() { mTokenSource.Cancel(); @@ -82,6 +76,10 @@ public void DisconnectAndStop() } } + #endregion + + #region Private methods + /// /// Need update varible on connected because clients in helper class static /// @@ -96,7 +94,6 @@ private void RenewVariable(bool updateReconnect) if (!updateReconnect) return; //it must be in renew variable in all method, but this called while connecting create inifinity update variable on reconnecting mReconnectCount = ReconnectCount; - } protected override void OnDisconnected() @@ -106,7 +103,7 @@ protected override void OnDisconnected() if (!mDisconnectAlreadyInvoke) { mDisconnectAlreadyInvoke = true; - TcpClientDisconnected?.Invoke(); + OnRaiseTcpClientDisconnectedEvent(); } return; @@ -119,7 +116,7 @@ protected override void OnDisconnected() if (!mDisconnectAlreadyInvoke) { mDisconnectAlreadyInvoke = true; - TcpClientDisconnected?.Invoke(); + OnRaiseTcpClientDisconnectedEvent(); } RenewVariable(true); @@ -138,7 +135,8 @@ private void Reconnect(CancellationTokenSource tokenSource) { if (!tokenSource.IsCancellationRequested) { - TcpClientReconnected?.Invoke(mReconnectCount--); + OnRaiseTcpClientReconnectedEvent(mReconnectCount--); + _ = tokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(mReconnectTimeout)); _ = ConnectAsync(); } @@ -150,7 +148,7 @@ private void Reconnect(CancellationTokenSource tokenSource) protected override void OnConnected() { - TcpCientConnected?.Invoke(); + OnRaiseTcpCientConnectedEvent(); RenewVariable(false); base.OnConnected(); @@ -158,17 +156,59 @@ protected override void OnConnected() protected override void OnSent(long sent, long pending) { - TcpCientSent?.Invoke(sent, pending); + OnRaiseTcpCientSentEvent(sent, pending); } protected override void OnError(SocketError error) { - TcpClientError?.Invoke(error); + OnRaiseTcpClientErrorEvent(error); } protected override void OnReceived(byte[] buffer, long offset, long size) { - TcpClientReceived?.Invoke(buffer, offset, size); + OnRaiseTcpClientReceivedEvent(buffer, offset, size); } + + #endregion + + #region OnRaiseEvents + + protected virtual void OnRaiseTcpCientConnectedEvent() + { + TcpCientConnectedEventHandler raiseEvent = RaiseTcpCientConnectedEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaiseTcpCientSentEvent(long sent, long pending) + { + TcpCientSentEventHandler raiseEvent = RaiseTcpCientSentEvent; + raiseEvent?.Invoke(this, sent, pending); + } + + protected virtual void OnRaiseTcpClientDisconnectedEvent() + { + TcpClientDisconnectEventHandler raiseEvent = RaiseTcpClientDisconnectedEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaiseTcpClientErrorEvent(SocketError socketError) + { + TcpClientErrorEventHandler raiseEvent = RaiseTcpClientErrorEvent; + raiseEvent?.Invoke(this, socketError); + } + + protected virtual void OnRaiseTcpClientReceivedEvent(byte[] buffer, long offset, long size) + { + TcpClientReceivedEventHandler raiseEvent = RaiseTcpClientReceivedEvent; + raiseEvent?.Invoke(this, buffer, offset, size); + } + + protected virtual void OnRaiseTcpClientReconnectedEvent(int reconnectCount) + { + TcpClientReconnectedEventHandler raiseEvent = RaiseTcpClientReconnectedEvent; + raiseEvent?.Invoke(this, reconnectCount); + } + + #endregion } } diff --git a/AdamController.Services/ThemeManagerService.cs b/AdamController.Services/ThemeManagerService.cs new file mode 100644 index 0000000..c95a395 --- /dev/null +++ b/AdamController.Services/ThemeManagerService.cs @@ -0,0 +1,61 @@ +using AdamController.Services.Interfaces; +using ControlzEx.Theming; +using System.Collections.ObjectModel; +using System.Windows; + +namespace AdamController.Services +{ + public class ThemeManagerService : IThemeManagerService + { + private readonly Application mCurrentApplication; + private readonly ThemeManager mCurrentThemeManager; + + #region ~ + + public ThemeManagerService() + { + mCurrentApplication = Application.Current; + mCurrentThemeManager = ThemeManager.Current; + AppThemesCollection = mCurrentThemeManager.Themes; + } + + #endregion + + #region Public filelds + + public ReadOnlyObservableCollection AppThemesCollection { get; private set; } + + #endregion + + #region Public methods + + public Theme ChangeAppTheme(string themeName) + { + var isThemeExist = mCurrentThemeManager.GetTheme(themeName) != null; + + if (isThemeExist) + return mCurrentThemeManager.ChangeTheme(mCurrentApplication, themeName, false); + + return null; + } + + public Theme ChangeAppTheme(Theme theme) + { + return mCurrentThemeManager.ChangeTheme(mCurrentApplication, theme.Name, false); + } + + public Theme GetCurrentAppTheme() + { + return mCurrentThemeManager.DetectTheme(); + } + + + + public void Dispose() + { + + } + + #endregion + } +} diff --git a/AdamController.Services/UdpClientService.cs b/AdamController.Services/UdpClientService.cs new file mode 100644 index 0000000..cd89b4b --- /dev/null +++ b/AdamController.Services/UdpClientService.cs @@ -0,0 +1,51 @@ +using AdamController.Services.Interfaces; +using AdamController.Services.UdpClientServiceDependency; +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace AdamController.Services +{ + public class UdpClientService : NetCoreServer.UdpServer, IUdpClientService + { + public event UdpClientMessageEnqueueEventHandler RaiseUdpClientMessageEnqueueEvent; + + private readonly QueueWithEvent mMessageQueue = new(); + public UdpClientService(IPAddress address, int port) : base(address, port) + { + mMessageQueue.RaiseEnqueueEvent += RaiseEnqueueEvent; + } + + private void RaiseEnqueueEvent(object sender, System.EventArgs e) + { + var messages = mMessageQueue.Dequeue(); + + OnRaiseUdpClientMessageEnqueueEvent(messages); + } + + protected override void OnReceived(EndPoint endpoint, byte[] buffer, long offset, long size) + { + Task.Run(() => + { + mMessageQueue.Enqueue(new(endpoint, buffer, offset, size)); + ReceiveAsync(); + }); + } + + protected override void OnStarted() + { + ReceiveAsync(); + } + + #region OnRaiseEvents + + protected virtual void OnRaiseUdpClientMessageEnqueueEvent(ReceivedData data) + { + UdpClientMessageEnqueueEventHandler raiseEvent = RaiseUdpClientMessageEnqueueEvent; + raiseEvent?.Invoke(this, data); + } + + #endregion + } +} diff --git a/AdamController.Services/UdpClientServiceDependency/QueueWithEvent.cs b/AdamController.Services/UdpClientServiceDependency/QueueWithEvent.cs new file mode 100644 index 0000000..ae65e33 --- /dev/null +++ b/AdamController.Services/UdpClientServiceDependency/QueueWithEvent.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace AdamController.Services.UdpClientServiceDependency +{ + public class QueueWithEvent + { + public event EventHandler RaiseEnqueueEvent; + + private readonly Queue queue = new(); + + public int Count { get { return queue.Count; } } + + public virtual void Enqueue(T item) + { + queue.Enqueue(item); + OnRaiseEnqueueEvent(); + } + + + public virtual T Dequeue() + { + T item = queue.Dequeue(); + return item; + } + + protected virtual void OnRaiseEnqueueEvent() + { + EventHandler raiseEvent = RaiseEnqueueEvent; + raiseEvent?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/AdamController.Services/UdpClientServiceDependency/ReceivedData.cs b/AdamController.Services/UdpClientServiceDependency/ReceivedData.cs new file mode 100644 index 0000000..0f69ca1 --- /dev/null +++ b/AdamController.Services/UdpClientServiceDependency/ReceivedData.cs @@ -0,0 +1,28 @@ +using System; +using System.Net; +using System.Text; + +namespace AdamController.Services.UdpClientServiceDependency +{ + public class ReceivedData : EventArgs + { + public ReceivedData(EndPoint endpoint, byte[] buffer, long offset, long size) + { + Endpoint = endpoint; + Buffer = buffer; + Offset = offset; + Size = size; + } + + public EndPoint Endpoint { get; } + public byte[] Buffer { get; } + public long Offset { get; } + public long Size { get; } + + public override string ToString() + { + string @string = Encoding.UTF8.GetString(Buffer, (int) Offset, (int) Size); + return @string; + } + } +} diff --git a/AdamController.Services/UdpServerService.cs b/AdamController.Services/UdpServerService.cs new file mode 100644 index 0000000..1a4dceb --- /dev/null +++ b/AdamController.Services/UdpServerService.cs @@ -0,0 +1,51 @@ +using AdamController.Services.Interfaces; +using NetCoreServer; +using System.Net; + +namespace AdamController.Services +{ + public class UdpServerService : UdpServer, IUdpServerService + { + #region Events + + public event UdpServerReceivedEventHandler RaiseUdpServerReceivedEvent; + + #endregion + + #region ~ + + public UdpServerService(IPAddress address, int port) : base(address, port){} + + #endregion + + #region Private methods + + protected override void OnStarted() + { + ReceiveAsync(); + } + + protected override void OnReceived(EndPoint endpoint, byte[] buffer, long offset, long size) + { + OnRaiseUdpServerReceivedEvent(endpoint, buffer, offset, size); + ReceiveAsync(); + } + + protected override void OnSent(EndPoint endpoint, long sent) + { + ReceiveAsync(); + } + + #endregion + + #region OnRaiseEvents + + protected virtual void OnRaiseUdpServerReceivedEvent(EndPoint endpoint, byte[] buffer, long offset, long size) + { + UdpServerReceivedEventHandler raiseEvent = RaiseUdpServerReceivedEvent; + raiseEvent?.Invoke(this, endpoint, buffer, offset, size); + } + + #endregion + } +} diff --git a/AdamController.Services/WebApiService.cs b/AdamController.Services/WebApiService.cs new file mode 100644 index 0000000..1216655 --- /dev/null +++ b/AdamController.Services/WebApiService.cs @@ -0,0 +1,72 @@ +using AdamController.Services.Interfaces; +using AdamController.WebApi.Client; +using AdamController.WebApi.Client.v1.RequestModel; +using AdamController.WebApi.Client.v1.ResponseModel; +using System; +using System.Threading.Tasks; + +namespace AdamController.Services +{ + public class WebApiService : IWebApiService + { + + #region Var + + private readonly BaseApi mBaseApi; + + #endregion + + #region ~ + + public WebApiService(string ip, int port, string login, string password) + { + Uri defaultUri = new($"http://{ip}:{port}"); + mBaseApi = new BaseApi(defaultUri, login, password); + + } + + #endregion + + #region Public methods + + public Task GetPythonBinDir() + { + return mBaseApi.PythonCommand.GetPythonBinDir(); + } + + public Task GetPythonVersion() + { + return mBaseApi.PythonCommand.GetVersion(); + } + + public Task GetPythonWorkDir() + { + return mBaseApi.PythonCommand.GetPythonWorkDir(); + } + + public Task PythonExecuteAsync(PythonCommandModel command) + { + return mBaseApi.PythonCommand.ExecuteAsync(command); + } + + + public Task StopPythonExecute() + { + return mBaseApi.PythonCommand.StopExecuteAsync(); + } + + public Task MoveToZeroPosition() + { + return mBaseApi.AdamSdk.MoveToZeroPosition(); + } + + public void Dispose() + { + mBaseApi.Dispose(); + } + + #endregion + } + + +} diff --git a/AdamController.Services/WebSocketClientService.cs b/AdamController.Services/WebSocketClientService.cs new file mode 100644 index 0000000..785e29c --- /dev/null +++ b/AdamController.Services/WebSocketClientService.cs @@ -0,0 +1,124 @@ +using AdamController.Services.Interfaces; +using System; +using System.Threading.Tasks; +using Websocket.Client; + +namespace AdamController.Services +{ + public class WebSocketClientService : IWebSocketClientService + { + #region Events + + public event WebSocketClientReceivedEventHandler RaiseWebSocketClientReceivedEvent; + public event WebSocketConnectedEventHandler RaiseWebSocketConnectedEvent; + public event WebSocketClientDisconnectEventHandler RaiseWebSocketClientDisconnectEvent; + + #endregion + + #region var + + private readonly WebsocketClient mWebsocketClient; + + #endregion + + #region ~ + + public WebSocketClientService(Uri url) + { + mWebsocketClient = new(url) + { + ReconnectTimeout = null + }; + + Subscribe(); + } + + #endregion + + #region Public field + + public bool IsStarted => mWebsocketClient.IsStarted; + + public bool IsRunning => mWebsocketClient.IsRunning; + + #endregion + + #region Public method + + public Task ConnectAsync() + { + return mWebsocketClient.StartOrFail(); + } + + public Task DisconnectAsync() + { + return mWebsocketClient.StopOrFail(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "Nomal close"); + } + + public Task SendTextAsync(string text) + { + if(!string.IsNullOrEmpty(text)) + { + Task task = mWebsocketClient.SendInstant(text); + return task; + } + + return Task.CompletedTask; + } + + public void Dispose() + { + mWebsocketClient.Dispose(); + } + + #endregion + + #region Subscriptions + + private void Subscribe() + { + mWebsocketClient.MessageReceived.Subscribe(message => + { + OnRaiseWebSocketClientReceivedEvent(message.Text); + }); + + mWebsocketClient.DisconnectionHappened.Subscribe(eventHappened => + { + OnRaiseWebSocketClientDisconnectEvent(); + }); + + mWebsocketClient.ReconnectionHappened.Subscribe(eventHappened => + { + OnRaiseWebSocketConnectedEvent(); + }); + } + + #endregion + + #region OnRaiseEvents + + protected virtual void OnRaiseWebSocketClientReceivedEvent(string text) + { + WebSocketClientReceivedEventHandler raiseEvent = RaiseWebSocketClientReceivedEvent; + raiseEvent?.Invoke(this, text); + } + + protected virtual void OnRaiseWebSocketConnectedEvent() + { + WebSocketConnectedEventHandler raiseEvent = RaiseWebSocketConnectedEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaiseWebSocketClientDisconnectEvent() + { + WebSocketClientDisconnectEventHandler raiseEvent = RaiseWebSocketClientDisconnectEvent; + raiseEvent?.Invoke(this); + } + + #endregion + } +} + + + + diff --git a/AdamController.Services/WebViewProvider.cs b/AdamController.Services/WebViewProvider.cs new file mode 100644 index 0000000..7e91d5f --- /dev/null +++ b/AdamController.Services/WebViewProvider.cs @@ -0,0 +1,81 @@ +using AdamController.Services.Interfaces; +using AdamController.Services.WebViewProviderDependency; +using System.Threading.Tasks; + +namespace AdamController.Services +{ + public class WebViewProvider : IWebViewProvider + { + #region Events + + /*event in view model*/ + public event WebViewNavigationCompleteEventHandler RaiseWebViewNavigationCompleteEvent; + public event WebViewbMessageReceivedEventHandler RaiseWebViewMessageReceivedEvent; + + /*event in view */ + public event ExecuteJavaScriptEventHandler RaiseExecuteJavaScriptEvent; + public event ExecuteReloadWebViewEventHandler RaiseExecuteReloadWebViewEvent; + + #endregion + + #region ~ + + public WebViewProvider(){} + + #endregion + + #region Public methods + + public void WebViewMessageReceived(WebMessageJsonReceived receivedResult) + { + OnRaiseWebViewbMessageReceivedEvent(receivedResult); + } + + public Task ExecuteJavaScript(string script, bool deserializeResultToString = false) + { + return OnRaiseExecuteJavaScriptEvent(script, deserializeResultToString); + } + + public void NavigationComplete() + { + OnRaiseWebViewNavigationCompleteEvent(); + } + + public virtual void ReloadWebView() + { + OnRaiseExecuteReloadWebViewEvent(); + } + + public void Dispose(){} + + #endregion + + #region OnRaise methods + + protected virtual void OnRaiseWebViewNavigationCompleteEvent() + { + WebViewNavigationCompleteEventHandler raiseEvent = RaiseWebViewNavigationCompleteEvent; + raiseEvent?.Invoke(this); + } + + protected virtual void OnRaiseWebViewbMessageReceivedEvent(WebMessageJsonReceived result) + { + WebViewbMessageReceivedEventHandler raiseEvent = RaiseWebViewMessageReceivedEvent; + raiseEvent?.Invoke(this, result); + } + + protected virtual Task OnRaiseExecuteJavaScriptEvent(string script, bool deserializeResultToString) + { + ExecuteJavaScriptEventHandler raiseEvent = RaiseExecuteJavaScriptEvent; + return raiseEvent?.Invoke(this, script, deserializeResultToString); + } + + protected virtual void OnRaiseExecuteReloadWebViewEvent() + { + ExecuteReloadWebViewEventHandler raiseEvent = RaiseExecuteReloadWebViewEvent; + raiseEvent?.Invoke(this); + } + + #endregion + } +} diff --git a/AdamController.Services/WebViewProviderDependency/WebMessageJsonReceived.cs b/AdamController.Services/WebViewProviderDependency/WebMessageJsonReceived.cs new file mode 100644 index 0000000..44516d5 --- /dev/null +++ b/AdamController.Services/WebViewProviderDependency/WebMessageJsonReceived.cs @@ -0,0 +1,14 @@ +using System; +using System.Text.Json.Serialization; + +namespace AdamController.Services.WebViewProviderDependency +{ + public class WebMessageJsonReceived : EventArgs + { + [JsonPropertyName("action")] + public string Action { get; set; } + + [JsonPropertyName("data")] + public string Data { get; set; } + } +} diff --git a/AdamController.WebApi.Client/ApiClient.cs b/AdamController.WebApi.Client/ApiClient.cs deleted file mode 100644 index bec04a2..0000000 --- a/AdamController.WebApi.Client/ApiClient.cs +++ /dev/null @@ -1,86 +0,0 @@ -using AdamController.WebApi.Client.v1; -using System.Net.Http.Headers; -using System.Text; - -namespace AdamController.WebApi.Client -{ - public class ApiClient - { - private static readonly HttpClient mClient = new(); - private static readonly MediaTypeWithQualityHeaderValue mMediaTypeHeader = new("application/json"); - private const string cDefaultApiPath = "api/"; - - static ApiClient() - { - mClient.DefaultRequestHeaders.Accept.Clear(); - mClient.DefaultRequestHeaders.Add("X-Version", "1"); - mClient.DefaultRequestHeaders.Accept.Add(mMediaTypeHeader); - } - - internal static void SetAuthenticationHeaderValue(string login, string password) - { - AuthenticationHeaderValue defaultAutentificationHeader = new("Basic", - Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}:{password}"))); - - mClient.DefaultRequestHeaders.Authorization = defaultAutentificationHeader; - } - - internal static void SetUri(Uri uri) - { - mClient.BaseAddress = uri; - } - - internal static void SetUri(string uri) - { - mClient.BaseAddress = new($"{uri}"); - } - - internal static void SetUri(string ip, int port) - { - mClient.BaseAddress = new($"http://{ip}:{port}"); - } - - internal static async Task Put(string path) - { - HttpResponseMessage? responseMessage = await mClient.PutAsync($"{cDefaultApiPath}{path}", null); - responseMessage.EnsureSuccessStatusCode(); - - return responseMessage; - } - - internal static async Task Get(string path) - { - HttpResponseMessage? responseMessage = await mClient.GetAsync($"{cDefaultApiPath}{path}"); - responseMessage.EnsureSuccessStatusCode(); - - return responseMessage; - } - - internal static async Task Post(string path, string command) - { - StringContent content = new(command); - var result = await mClient.PostAsync($"{cDefaultApiPath}{path}", content); - return result; - } - - internal static async Task Post(string path, v1.RequestModel.PythonCommand command) - { - var result = await mClient.PostAsJsonAsync($"{cDefaultApiPath}{path}", command); - return result; - } - - internal static async Task Post(string path, string filePath, string name, string fileName) - { - - using (var content = new MultipartFormDataContent("Upload--------------------" + DateTime.Now.ToString())) - { - var fileStreamContent = new StreamContent(File.OpenRead(filePath)); - content.Add(fileStreamContent, name, fileName); - var result = await mClient.PostAsync($"{cDefaultApiPath}{path}", content); - - return result; - } - - } - } -} \ No newline at end of file diff --git a/AdamController.WebApi.Client/Common/Extension.cs b/AdamController.WebApi.Client/Common/Extension.cs deleted file mode 100644 index e0fdb9b..0000000 --- a/AdamController.WebApi.Client/Common/Extension.cs +++ /dev/null @@ -1,115 +0,0 @@ -using AdamController.WebApi.Client.v1.ResponseModel; -using Newtonsoft.Json; -using System.Text; -using System.Text.Encodings.Web; -using System.Web; - -namespace AdamController.WebApi.Client.Common -{ - public static class Extension - { - #region public extensions - - /// - /// Deserealize jsonString to CommandExecuteResult - /// - /// JSON string with CommandExecuteResult object - /// Returns the CommandExecuteResult object with the result, if deserialization is successful, or a new CommandExecuteResult object otherwise - public static CommandExecuteResult ToCommandResult(this string jsonString) - { - if (jsonString == null) - return new CommandExecuteResult(); - - CommandExecuteResult executeResult = new(); - - try - { - executeResult = JsonConvert.DeserializeObject(jsonString); - } - catch - { - - } - - return executeResult; - } - - /// - /// Deserealize jsonString to ExtendedCommandExecuteResult - /// - /// JSON string with ExtendedCommandExecuteResult object - /// Returns the ExtendedCommandExecuteResult object with the result, if deserialization is successful, or a new ExtendedCommandExecuteResult object otherwise - public static ExtendedCommandExecuteResult ToExtendedCommandResult(this string jsonString) - { - if (jsonString == null) - return new ExtendedCommandExecuteResult(); - - ExtendedCommandExecuteResult executeResult = new(); - - try - { - executeResult = JsonConvert.DeserializeObject(jsonString); - } - catch - { - - } - - return executeResult; - } - - #endregion - - #region internal extension - - internal static string FromBase64ToString(this string base64string) - { - byte[] base64EncodedBytes = Convert.FromBase64String(base64string); - string decodedString = Encoding.UTF8.GetString(base64EncodedBytes); - - return decodedString; - } - - internal static string FromStringToBase64String(this string @string) - { - byte[] plainTextBytes = Encoding.UTF8.GetBytes(@string); - string encodedToBase64String = Convert.ToBase64String(plainTextBytes); - - return encodedToBase64String; - } - - internal static string FromStringToUrlEncodeString(this string @string) - { - string encodedToUrlEncodeString = HttpUtility.UrlEncode(@string); - return encodedToUrlEncodeString; - } - - internal static string FromUrlEncodeToString(this string @string) - { - string encodedToUrlEncodeString = HttpUtility.UrlDecode(@string); - return encodedToUrlEncodeString; - } - - internal async static Task ToExtendedCommandResult(this HttpResponseMessage? response) - { - if(response == null) - return new ExtendedCommandExecuteResult(); - - var jsonString = await response.Content.ReadAsStringAsync(); - ExtendedCommandExecuteResult result = JsonConvert.DeserializeObject(jsonString); - return result; - } - - internal async static Task ToCommandResult(this HttpResponseMessage? response) - { - if(response == null) - return new CommandExecuteResult(); - - var jsonString = await response.Content.ReadAsStringAsync(); - CommandExecuteResult result = JsonConvert.DeserializeObject(jsonString); - return result; - } - - #endregion - } -} diff --git a/AdamController.WebApi.Client/v1/AdamSdk.cs b/AdamController.WebApi.Client/v1/AdamSdk.cs deleted file mode 100644 index f455826..0000000 --- a/AdamController.WebApi.Client/v1/AdamSdk.cs +++ /dev/null @@ -1,17 +0,0 @@ -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class AdamSdk - { - private const string cApiPath = "AdamSdk"; - - internal static async Task MoveToZeroPosition() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/MoveToZeroPosition"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - } -} diff --git a/AdamController.WebApi.Client/v1/BaseApi.cs b/AdamController.WebApi.Client/v1/BaseApi.cs deleted file mode 100644 index ded8d89..0000000 --- a/AdamController.WebApi.Client/v1/BaseApi.cs +++ /dev/null @@ -1,209 +0,0 @@ -using AdamController.WebApi.Client.v1.RequestModel; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - public static class BaseApi - { - #region Api Client Settings (is not api call) - - public static void SetApiClientUri(Uri uri) => ApiClient.SetUri(uri); - public static void SetApiClientUri(string uri) => ApiClient.SetUri(uri); - public static void SetApiClientUri(string ip, int port) => ApiClient.SetUri(ip, port); - public static void SetAuthenticationHeader(string login, string password) => ApiClient.SetAuthenticationHeaderValue(login, password); - - #endregion - - - #region AdamSdk - - public static async Task MoveToZeroPosition() => await AdamSdk.MoveToZeroPosition(); - - #endregion - - #region BashCommand - - /// - /// Execute with waiting and return json result to http api. - /// Command canceled after 30 second automatic. - /// - /// Bash command or programm - /// JSON object ExtendedShellCommandExecuteResult - public static async Task BashExecute(string command) => await BashCommand.Execute(command); - - /// - /// Execute with waiting and return json result to http api - /// - /// Bash command or programm - /// Command canceled after 30 second automatic if null - /// JSON object ExtendedShellCommandExecuteResult as http response - public static async Task BashExecute(string command, int cancelAfterSeconds) => await BashCommand.Execute(command, cancelAfterSeconds); - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// Python command or programm - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - public static async Task BashExecuteAsync(string command) => await BashCommand.ExecuteAsync(command); - - /// - /// Execute without waiting. With cancelation timer. Return execute result in udp stream. - /// - /// Bash command or programm - /// Task canceled after this time in seconds - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - public static async Task BashExecuteAsyncWithCancelTimer(string command, int cancelAfterSeconds) => await BashCommand.ExecuteAsyncWithCancelTimer(command, cancelAfterSeconds); - - /// - /// Stopped running process - /// - public static async Task BashPythonExecute() => await BashCommand.StopExecuteAsync(); - - /// - /// Returned bash version - /// - /// ExtendedShellCommandExecuteResult with bash version in standart output - public static async Task GetBashVersion() => await BashCommand.GetVersion(); - - #endregion - - #region ComunicationManagment - - public static Task GetServersStatus() => ComunicationManagment.GetServersStatus(); - public static Task GetServerStatus(string serverName) => ComunicationManagment.GetServerStatus(serverName); - public static Task SendCommand(ServerCommand command, string serverName) => ComunicationManagment.SendCommand(command, serverName); - - #endregion - - #region FileManager - - /// - /// Listing dirrectory - /// - public static Task GetFileList() => FileManager.GetFileList(); - - /// - /// Listing dirrectory - /// - /// Exiting dirrectory path - public static Task GetFileList(string path) => FileManager.GetFileList(path); - - /// - /// Extended listing dirrectory - /// - public static Task GetExtendedFileList() => FileManager.GetExtendedFileList(); - - /// - /// Extended listing dirrectory - /// - /// Exiting dirrectory path - public static Task GetExtendedFileList(string path) => FileManager.GetExtendedFileList(path); - - /// - /// Cat file - /// - /// Exiting file path - public static Task GetFileContent(string path) => FileManager.GetFileContent(path); - - /// - /// Calculate the checksum for file - /// - /// Exiting file path - public static Task GetCheckSum(string path) => FileManager.GetCheckSum(path); - - /// - /// Calculate the SHA-1 checksum for file - /// - /// Exiting file path - public static Task GetSha1Sum(string path) => FileManager.GetSha1Sum(path); - - /// - /// Calculate the SHA-256 checksum for file - /// - /// Exiting file path - public static Task GetSha256Sum(string path) => FileManager.GetSha256Sum(path); - - /// - /// Simple file uploaded - /// - /// sha1sum in standart output field is success upload - public static Task UploadFile(string filePath, string name, string fileName) => FileManager.UploadFile(filePath, name, fileName); - - /// - /// Simple file uploaded - /// - /// sha1sum in standart output field is success upload - //public static Task UploadFile(string file, string name, string fileName) => FileManager.UploadFile(file, name, fileName); - - - #endregion - - #region LoggerConfiguration - - public static Task DisableUdpSyslog() => LoggerConfiguration.DisableUdpSyslog(); - public static Task EnableUdpSyslog(string ip) => LoggerConfiguration.EnableUdpSyslog(ip); - - #endregion - - #region PythonCommand - - /// - /// Execute with waiting and return json result to http api. - /// Command canceled after 30 second automatic. - /// - /// Python command or programm - /// JSON object ExtendedShellCommandExecuteResult - public static async Task PythonExecute(RequestModel.PythonCommand command) => await PythonCommand.Execute(command); - - /// - /// Execute with waiting and return json result to http api - /// - /// Python command or programm - /// Command canceled after 30 second automatic if null - /// JSON object ExtendedShellCommandExecuteResult as http response - //public static async Task PythonExecute(string command, int cancelAfterSeconds) => await PythonCommand.Execute(command, cancelAfterSeconds); - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// Python command or programm in JSON structure - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - public static async Task PythonExecuteAsync(RequestModel.PythonCommand command) => await PythonCommand.ExecuteAsync(command); - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// Python command or programm - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - public static async Task PythonExecuteAsync(string command) => await PythonCommand.ExecuteAsync(command); - - /// - /// Stopped running process - /// - public static async Task StopPythonExecute() => await PythonCommand.StopExecuteAsync(); - - /// - /// Returned python version - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - public static async Task GetPythonVersion() => await PythonCommand.GetVersion(); - - /// - /// Returned python bin dirrectory - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - public static async Task GetPythonBinDir() => await PythonCommand.GetPythonBinDir(); - - /// - /// Returned python work dirrectory - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - public static async Task GetPythonWorkDir() => await PythonCommand.GetPythonWorkDir(); - - #endregion - } -} diff --git a/AdamController.WebApi.Client/v1/BashCommand.cs b/AdamController.WebApi.Client/v1/BashCommand.cs deleted file mode 100644 index edec82a..0000000 --- a/AdamController.WebApi.Client/v1/BashCommand.cs +++ /dev/null @@ -1,83 +0,0 @@ -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class BashCommand - { - private const string cApiPath = "BashCommand"; - - /// - /// Execute with waiting and return json result to http api. - /// Command canceled after 30 second automatic. - /// - /// Bash command or programm - /// JSON object ExtendedShellCommandExecuteResult - internal static async Task Execute(string command) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/Execute/{command.FromStringToUrlEncodeString()}/cancelAfter?cancelAfterSeconds=-1"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Execute with waiting and return json result to http api - /// - /// Bash command or programm - /// Command canceled after 30 second automatic if null - /// JSON object ExtendedShellCommandExecuteResult as http response - internal static async Task Execute(string command, int cancelAfterSeconds) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/Execute/{command.FromStringToUrlEncodeString()}/cancelAfter?cancelAfterSeconds={cancelAfterSeconds}"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// Bash command or programm - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - internal static async Task ExecuteAsync(string command) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/ExecuteAsync/{command.FromStringToUrlEncodeString()}"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Execute without waiting. With cancelation timer. Return execute result in udp stream. - /// - /// Bash command or programm - /// Task canceled after this time in seconds - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - internal static async Task ExecuteAsyncWithCancelTimer(string command, int cancelAfterSeconds) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/ExecuteAsyncWithCancelTimer/{command.FromStringToUrlEncodeString()}/{cancelAfterSeconds}"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Stopped running process - /// - internal static async Task StopExecuteAsync() - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/StopExecuteAsync"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Returned bash version - /// - /// ExtendedShellCommandExecuteResult with bash version in standart output - internal static async Task GetVersion() - { - ExtendedCommandExecuteResult? responseValue = await Execute("bash --version"); - return responseValue; - } - } -} \ No newline at end of file diff --git a/AdamController.WebApi.Client/v1/ComunicationManagment.cs b/AdamController.WebApi.Client/v1/ComunicationManagment.cs deleted file mode 100644 index b924849..0000000 --- a/AdamController.WebApi.Client/v1/ComunicationManagment.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AdamController.WebApi.Client.v1.RequestModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class ComunicationManagment - { - private const string cApiPath = "ComunicationManagment"; - - internal static async Task GetServersStatus() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetServersStatus"); - - ComunicationStatus responseValue = await responseMessage.Content.ReadAsAsync(); - return responseValue; - } - - internal static async Task GetServerStatus(string serverName) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetServerStatus/{serverName}"); - - string responseValue = await responseMessage.Content.ReadAsAsync(); - return responseValue; - } - - internal static async Task SendCommand(ServerCommand command, string serverName) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/SendCommand/{serverName}/{command}"); - - bool responseValue = await responseMessage.Content.ReadAsAsync(); - return responseValue; - } - - } -} diff --git a/AdamController.WebApi.Client/v1/FileManager.cs b/AdamController.WebApi.Client/v1/FileManager.cs deleted file mode 100644 index c4d52d8..0000000 --- a/AdamController.WebApi.Client/v1/FileManager.cs +++ /dev/null @@ -1,171 +0,0 @@ -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class FileManager - { - private const string cApiPath = "FileManager"; - - #region Listing dirrectory - - /// - /// Listing dirrectory - /// - internal static async Task GetFileList() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetFileList"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Listing dirrectory - /// - /// Exiting dirrectory path - /// - internal static async Task GetFileList(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetFileList/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region Extended listing dirrectory - - /// - /// Extended listing dirrectory - /// - internal static async Task GetExtendedFileList() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetExtendedFileList"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Extended listing dirrectory - /// - /// Exiting dirrectory path - /// - internal static async Task GetExtendedFileList(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetExtendedFileList/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region GetFileContent - - /// - /// Cat file - /// - /// Exiting file path - internal static async Task GetFileContent(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetFileContent/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region CheckSum - - /// - /// Calculate the checksum for file - /// - internal static async Task GetCheckSum(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetCheckSum/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Calculate the SHA-1 checksum for file - /// - internal static async Task GetSha1Sum(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetSha1Sum/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Calculate the SHA-256 checksum for file - /// - internal static async Task GetSha256Sum(string path) - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetSha256Sum/{path.FromStringToBase64String()}"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region Upload File - - /// - /// Simple file uploaded - /// - /// sha1sum in standart output field is success upload - internal static async Task UploadFile(string filePath, string name, string fileName) - { - HttpResponseMessage? responseMessage = await ApiClient.Post($"{cApiPath}/UploadFile", filePath, name, fileName); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Simple file uploaded - /// - /// sha1sum in standart output field is success upload - /*internal static async Task UploadFile(string filePath, string name, string fileName) - { - byte[] file; - DateTime startTime = DateTime.Now; - - try - { - file = File.ReadAllBytes(filePath); - } - catch(Exception ex) - { - DateTime endTime = DateTime.Now; - - return new ExtendedCommandExecuteResult() - { - StartTime = startTime, - EndTime = endTime, - RunTime = endTime - startTime, - - StandardOutput = "", - StandardError = ex.Message, - - ExitCode = -1, - Succeesed = false - }; - } - - HttpResponseMessage? responseMessage = await ApiClient.Post($"{cApiPath}/UploadFile", file, name, fileName); - ExtendedCommandExecuteResult responseValue = await responseMessage?.Content.ReadAsAsync(); - - return responseValue; - }*/ - - #endregion - } -} \ No newline at end of file diff --git a/AdamController.WebApi.Client/v1/LoggerConfiguration.cs b/AdamController.WebApi.Client/v1/LoggerConfiguration.cs deleted file mode 100644 index ad584d9..0000000 --- a/AdamController.WebApi.Client/v1/LoggerConfiguration.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace AdamController.WebApi.Client.v1 -{ - internal static class LoggerConfiguration - { - private const string cApiPath = "LoggerConfiguration"; - - internal static async Task DisableUdpSyslog() - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/DisableUdpSyslog"); - - bool responseValue = await responseMessage.Content.ReadAsAsync(); - return responseValue; - - } - - internal static async Task EnableUdpSyslog(string ip) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/EnableUdpSyslog/{ip}"); - - bool responseValue = await responseMessage.Content.ReadAsAsync(); - return responseValue; - } - } -} diff --git a/AdamController.WebApi.Client/v1/PythonCommand.cs b/AdamController.WebApi.Client/v1/PythonCommand.cs deleted file mode 100644 index a500c02..0000000 --- a/AdamController.WebApi.Client/v1/PythonCommand.cs +++ /dev/null @@ -1,90 +0,0 @@ -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class PythonCommand - { - private const string cApiPath = "PythonCommand"; - - /// - /// Execute with waiting and return json result to http api - /// - /// - /// - internal static async Task Execute(RequestModel.PythonCommand command) - { - HttpResponseMessage? responseMessage = await ApiClient.Post($"{cApiPath}/Execute/", command); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// - /// - internal static async Task ExecuteAsync(RequestModel.PythonCommand command) - { - HttpResponseMessage? responseMessage = await ApiClient.Post($"{cApiPath}/ExecuteAsync/", command); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Execute without waiting. Return execute result in udp stream - /// - /// Python command or programm - /// ExtendedShellCommandExecuteResult as http-response with report about running process - /// and UDP stream by message client with result running process - internal static async Task ExecuteAsync(string command) - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/ExecuteAsync/{command.FromStringToUrlEncodeString()}"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Stopped running process - /// - internal static async Task StopExecuteAsync() - { - HttpResponseMessage? responseMessage = await ApiClient.Put($"{cApiPath}/StopExecuteAsync"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Returned python version - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - internal static async Task GetVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetVersion"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Returned python work dir - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - internal static async Task GetPythonWorkDir() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetPythonWorkDir"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - /// - /// Returned python bin dir - /// - /// ExtendedShellCommandExecuteResult with python version in standart output - internal static async Task GetPythonBinDir() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetPythonBinDir"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - } -} diff --git a/AdamController.WebApi.Client/v1/RequestModel/CameraResolution.cs b/AdamController.WebApi.Client/v1/RequestModel/CameraResolution.cs deleted file mode 100644 index 99472b5..0000000 --- a/AdamController.WebApi.Client/v1/RequestModel/CameraResolution.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AdamController.WebApi.Client.v1.RequestModel -{ - public enum CameraResolution - { - FullRes, - MiddleRes, - LowRes, - LowestRes - } -} diff --git a/AdamController.WebApi.Client/v1/RequestModel/ComunicationStatus.cs b/AdamController.WebApi.Client/v1/RequestModel/ComunicationStatus.cs deleted file mode 100644 index 59dcfb2..0000000 --- a/AdamController.WebApi.Client/v1/RequestModel/ComunicationStatus.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AdamController.WebApi.Client.v1.RequestModel -{ - public class ComunicationStatus - { - internal string ServerName { get; set; } = string.Empty; - internal string ServerStatus { get; set; } = string.Empty; - } -} diff --git a/AdamController.WebApi.Client/v1/RequestModel/ServerCommand.cs b/AdamController.WebApi.Client/v1/RequestModel/ServerCommand.cs deleted file mode 100644 index 81fa1e1..0000000 --- a/AdamController.WebApi.Client/v1/RequestModel/ServerCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AdamController.WebApi.Client.v1.RequestModel -{ - public enum ServerCommand - { - Stop, - Start, - Restart - } -} diff --git a/AdamController.WebApi.Client/v1/ResponseModel/CommandExecuteResult.cs b/AdamController.WebApi.Client/v1/ResponseModel/CommandExecuteResult.cs deleted file mode 100644 index 4b4b7d8..0000000 --- a/AdamController.WebApi.Client/v1/ResponseModel/CommandExecuteResult.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace AdamController.WebApi.Client.v1.ResponseModel -{ - public class CommandExecuteResult - { - /// - /// The succeeded status of an executable. - /// - public bool Succeeded { get; set; } - - /// - /// The exit code of an executable. - /// - public int ExitCode { get; set; } - - /// - /// The standard error of an executable. - /// - public string StandardError { get; set; } = string.Empty; - - /// - /// The start time of an executable. - /// - public DateTime StartTime { get; set; } - - /// - /// The end time of an executable. - /// - public DateTime EndTime { get; set; } - - /// - /// The run time of an executable. - /// - public TimeSpan RunTime { get; set; } - } -} diff --git a/AdamController.WebApi.Client/v1/SystemInfo.cs b/AdamController.WebApi.Client/v1/SystemInfo.cs deleted file mode 100644 index 27dfb43..0000000 --- a/AdamController.WebApi.Client/v1/SystemInfo.cs +++ /dev/null @@ -1,134 +0,0 @@ - - -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.WebApi.Client.v1 -{ - internal class SystemInfo - { - private const string cApiPath = "SystemInfo"; - - #region System average - - internal static async Task GetExtendedUptimeAndLoadAverage() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetExtendedUptimeAndLoadAverage"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetUptimeAndLoadAverage() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetUptimeAndLoadAverage"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetLoadAverage() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetLoadAverage"); - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region OS version - - internal static async Task GetOsReleaseVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetOsReleaseVersion"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetDebianOsVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetDebianOsVersion"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetArchitectureOsVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetArchitectureOsVersion"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetKernelVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetKernelVersion"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region CPU/GPU temperature - - internal static async Task GetGpuTemp() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetGpuTemp"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetCpuTemp() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetCpuTemp"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region Network info - - internal static async Task GetNetworkInfo() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetNetworkInfo"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetIpInfo() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetIpInfo"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - internal static async Task GetWiFiSsids() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetWiFiSsids"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - - #region AdamServer info - - internal static async Task GetAdamServerVersion() - { - HttpResponseMessage? responseMessage = await ApiClient.Get($"{cApiPath}/GetAdamServerVersion"); - - var result = await responseMessage.ToExtendedCommandResult(); - return result; - } - - #endregion - } - -} diff --git a/AdamController.sln b/AdamController.sln index 9c36a7d..5b251e1 100644 --- a/AdamController.sln +++ b/AdamController.sln @@ -4,24 +4,28 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController", "AdamController\AdamController.csproj", "{0D918664-5F27-4525-ABE4-0D1A1FB22761}" - ProjectSection(ProjectDependencies) = postProject - {CCB5A70B-3F85-4D11-B774-365DF8A220F6} = {CCB5A70B-3F85-4D11-B774-365DF8A220F6} - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1} = {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1} - EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamControllerLibrary", "AdamControllerLibrary\AdamControllerLibrary.csproj", "{1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{BF38E868-9FEB-4645-9B2B-15AC47844075}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0A650D34-3B1C-4EA6-8F8B-F5B6B21025E6}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Modules.ContentRegion", "Modules\AdamController.Modules.ContentRegion\AdamController.Modules.ContentRegion.csproj", "{8EF23718-8FE0-4711-BB00-04411C6B4787}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamBlocklyLibrary", "AdamBlocklyLibrary\AdamBlocklyLibrary.csproj", "{CCB5A70B-3F85-4D11-B774-365DF8A220F6}" - ProjectSection(ProjectDependencies) = postProject - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1} = {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1} - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Modules.MenuRegion", "Modules\AdamController.Modules.MenuRegion\AdamController.Modules.MenuRegion.csproj", "{6F12ECFD-3891-40AE-A18D-B3362C6A2946}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.WebApi.Client", "AdamController.WebApi.Client\AdamController.WebApi.Client.csproj", "{157FE150-54A5-4D10-A052-580A5B4895DA}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Legacy", "Legacy", "{511F4919-C2FC-4775-92A4-C446E51B49DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Modules.StatusBarRegion", "Modules\AdamController.Modules.StatusBar\AdamController.Modules.StatusBarRegion.csproj", "{05913116-D1EA-49C3-92C4-B4316E7C0A9C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Services", "AdamController.Services\AdamController.Services.csproj", "{C6EEA5FC-E4F2-4334-B134-C4A9B7D2A49A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Modules.FlayoutsRegion", "Modules\AdamController.Modules.FlayoutsRegion\AdamController.Modules.FlayoutsRegion.csproj", "{D17BE826-5C86-4EAC-8424-534F9CF3DFE0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.Core", "AdamController.Core\AdamController.Core.csproj", "{F6817FD0-DE3E-4636-8443-A26F46507A6F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamBlocklyLibrary", "Legacy\AdamBlocklyLibrary\AdamBlocklyLibrary.csproj", "{941A4E7D-6A53-44F8-876C-6B33AAEDDA89}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdamController.WebApi.Client", "Legacy\AdamController.WebApi.Client\AdamController.WebApi.Client.csproj", "{771220FE-2F25-441B-815E-7DD63918BA95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdamController.Controls", "AdamController.Controls\AdamController.Controls.csproj", "{1BADFDB1-D66E-4580-8EAF-CAEE37761640}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -33,22 +37,54 @@ Global {0D918664-5F27-4525-ABE4-0D1A1FB22761}.Debug|Any CPU.Build.0 = Debug|Any CPU {0D918664-5F27-4525-ABE4-0D1A1FB22761}.Release|Any CPU.ActiveCfg = Release|Any CPU {0D918664-5F27-4525-ABE4-0D1A1FB22761}.Release|Any CPU.Build.0 = Release|Any CPU - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1FCB70D5-1BBC-414D-8DFB-4AEA7D45B1D1}.Release|Any CPU.Build.0 = Release|Any CPU - {CCB5A70B-3F85-4D11-B774-365DF8A220F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CCB5A70B-3F85-4D11-B774-365DF8A220F6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CCB5A70B-3F85-4D11-B774-365DF8A220F6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CCB5A70B-3F85-4D11-B774-365DF8A220F6}.Release|Any CPU.Build.0 = Release|Any CPU - {157FE150-54A5-4D10-A052-580A5B4895DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {157FE150-54A5-4D10-A052-580A5B4895DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {157FE150-54A5-4D10-A052-580A5B4895DA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {157FE150-54A5-4D10-A052-580A5B4895DA}.Release|Any CPU.Build.0 = Release|Any CPU + {8EF23718-8FE0-4711-BB00-04411C6B4787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8EF23718-8FE0-4711-BB00-04411C6B4787}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8EF23718-8FE0-4711-BB00-04411C6B4787}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8EF23718-8FE0-4711-BB00-04411C6B4787}.Release|Any CPU.Build.0 = Release|Any CPU + {6F12ECFD-3891-40AE-A18D-B3362C6A2946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F12ECFD-3891-40AE-A18D-B3362C6A2946}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F12ECFD-3891-40AE-A18D-B3362C6A2946}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F12ECFD-3891-40AE-A18D-B3362C6A2946}.Release|Any CPU.Build.0 = Release|Any CPU + {05913116-D1EA-49C3-92C4-B4316E7C0A9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05913116-D1EA-49C3-92C4-B4316E7C0A9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05913116-D1EA-49C3-92C4-B4316E7C0A9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05913116-D1EA-49C3-92C4-B4316E7C0A9C}.Release|Any CPU.Build.0 = Release|Any CPU + {C6EEA5FC-E4F2-4334-B134-C4A9B7D2A49A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6EEA5FC-E4F2-4334-B134-C4A9B7D2A49A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6EEA5FC-E4F2-4334-B134-C4A9B7D2A49A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6EEA5FC-E4F2-4334-B134-C4A9B7D2A49A}.Release|Any CPU.Build.0 = Release|Any CPU + {D17BE826-5C86-4EAC-8424-534F9CF3DFE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D17BE826-5C86-4EAC-8424-534F9CF3DFE0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D17BE826-5C86-4EAC-8424-534F9CF3DFE0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D17BE826-5C86-4EAC-8424-534F9CF3DFE0}.Release|Any CPU.Build.0 = Release|Any CPU + {F6817FD0-DE3E-4636-8443-A26F46507A6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6817FD0-DE3E-4636-8443-A26F46507A6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6817FD0-DE3E-4636-8443-A26F46507A6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6817FD0-DE3E-4636-8443-A26F46507A6F}.Release|Any CPU.Build.0 = Release|Any CPU + {941A4E7D-6A53-44F8-876C-6B33AAEDDA89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {941A4E7D-6A53-44F8-876C-6B33AAEDDA89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {941A4E7D-6A53-44F8-876C-6B33AAEDDA89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {941A4E7D-6A53-44F8-876C-6B33AAEDDA89}.Release|Any CPU.Build.0 = Release|Any CPU + {771220FE-2F25-441B-815E-7DD63918BA95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {771220FE-2F25-441B-815E-7DD63918BA95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {771220FE-2F25-441B-815E-7DD63918BA95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {771220FE-2F25-441B-815E-7DD63918BA95}.Release|Any CPU.Build.0 = Release|Any CPU + {1BADFDB1-D66E-4580-8EAF-CAEE37761640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1BADFDB1-D66E-4580-8EAF-CAEE37761640}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1BADFDB1-D66E-4580-8EAF-CAEE37761640}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1BADFDB1-D66E-4580-8EAF-CAEE37761640}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {8EF23718-8FE0-4711-BB00-04411C6B4787} = {BF38E868-9FEB-4645-9B2B-15AC47844075} + {6F12ECFD-3891-40AE-A18D-B3362C6A2946} = {BF38E868-9FEB-4645-9B2B-15AC47844075} + {05913116-D1EA-49C3-92C4-B4316E7C0A9C} = {BF38E868-9FEB-4645-9B2B-15AC47844075} + {D17BE826-5C86-4EAC-8424-534F9CF3DFE0} = {BF38E868-9FEB-4645-9B2B-15AC47844075} + {941A4E7D-6A53-44F8-876C-6B33AAEDDA89} = {511F4919-C2FC-4775-92A4-C446E51B49DB} + {771220FE-2F25-441B-815E-7DD63918BA95} = {511F4919-C2FC-4775-92A4-C446E51B49DB} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D00A029C-930D-44A8-8257-721FCA9202F6} EndGlobalSection diff --git a/AdamController/AdamController.csproj b/AdamController/AdamController.csproj index 6182832..8d6999a 100644 --- a/AdamController/AdamController.csproj +++ b/AdamController/AdamController.csproj @@ -2,50 +2,25 @@ Dynamic False + MIT-Modern-Variant + 2.0.0.0 + 2.0.0.0 net7.0-windows WinExe - 9.0 - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - false - False true - true - MinimumRecommendedRules.ruleset bin\x64\Debug\ - 9.0 MinimumRecommendedRules.ruleset bin\x64\Release\ - 9.0 - MinimumRecommendedRules.ruleset AdamController.App - - - Images\Icons\AdamIconAndRGBPageIcon.ico - MIT-Modern-Variant - 1.0.2.4 - 1.0.2.4 + ..\AdamController.Core\Properties\Icons\main_app_icon.ico 1701;1702;CA1416 @@ -54,69 +29,16 @@ 1701;1702;CA1416 - - - - - - - - - - - Always - + + + + + - - - False - Microsoft .NET Framework 4.8 %28x86 и x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - - - - - - - - - - - True - True - Resources.resx - - - True - True - Settings.settings - - - - - PublicResXFileCodeGenerator - Resources.Designer.cs - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - \ No newline at end of file diff --git a/AdamController/App.xaml b/AdamController/App.xaml index db91ed2..d4ec1bc 100644 --- a/AdamController/App.xaml +++ b/AdamController/App.xaml @@ -1,21 +1,60 @@ - - - + + - + + + - - - + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/AdamController/App.xaml.cs b/AdamController/App.xaml.cs index a99262e..76126cf 100644 --- a/AdamController/App.xaml.cs +++ b/AdamController/App.xaml.cs @@ -1,71 +1,358 @@ -using AdamController.Helpers; -using AdamController.Properties; -using AdamController.ViewModels.HamburgerMenu; -using AdamController.Views; -using ControlzEx.Theming; -using ICSharpCode.AvalonEdit.Highlighting; +#region system + using System; -using System.IO; using System.Windows; -using System.Xml; + +#endregion + +#region prism + +using Prism.Ioc; +using Prism.DryIoc; +using Prism.Modularity; +using Prism.Regions; +using DryIoc; + +#endregion + +#region innerhit + +using AdamController.Views; +using AdamController.Modules.MenuRegion; +using AdamController.Modules.ContentRegion; +using AdamController.Services; +using AdamController.Modules.StatusBarRegion; +using AdamController.Modules.FlayoutsRegion; +using AdamController.Services.Interfaces; +using AdamController.Controls.CustomControls.Services; +using AdamController.Controls.CustomControls.RegionAdapters; + +#endregion + +#region mahapps + +using MahApps.Metro.Controls; + +#endregion + +#region other + +using AdamController.Core.Properties; +using System.Diagnostics; +using System.Threading.Tasks; +using System.Net; +using AdamController.Services.TcpClientDependency; +using System.ComponentModel; + +#endregion namespace AdamController { - public partial class App : Application + public partial class App : PrismApplication { - protected override void OnStartup(StartupEventArgs e) + #region ~ + + public App() { - LoadHighlighting(); + Subscribe(); + } + + #endregion + + protected override Window CreateShell() + { + MainWindow window = Container.Resolve(); + return window; + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + //#15 test + containerRegistry.RegisterSingleton(); + + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + + containerRegistry.RegisterSingleton(containerRegistry => + { + IFileManagmentService fileManagment = containerRegistry.Resolve(); + AvalonEditService avalonService = new(fileManagment); + return avalonService; + }); + + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + + containerRegistry.RegisterSingleton(containerRegistry => + { + DryIoc.IContainer container = containerRegistry.GetContainer(); + IRegionManager regionManager = containerRegistry.Resolve(); + + return new FlyoutManager(container, regionManager); + }); + + containerRegistry.RegisterSingleton(() => + { + TcpClientOption option = new() + { + ReconnectCount = Settings.Default.ReconnectQtyComunicateTcpClient, + ReconnectTimeout = Settings.Default.ReconnectTimeoutComunicateTcpClient + }; + + string ip = Settings.Default.ServerIP; + int port = Settings.Default.TcpConnectStatePort; + + TcpClientService client; + + if (!string.IsNullOrEmpty(ip)) + { + client = new(ip, port, option); + } + else + { + client = new("127.0.0.1", port, option); + } + + + return client; + }); + + containerRegistry.RegisterSingleton(() => + { + IPAddress ip = IPAddress.Any; + int port = int.Parse(Settings.Default.MessageDataExchangePort); + + UdpClientService client = new(ip, port) + { + OptionDualMode = true, + OptionReuseAddress = true + }; - // side menu context, MUST inherit from MainViewModel - // HamburgerMenuView : MainWindowView - // and MainWindowView MUST inherit from BaseViewModel - // MainWindowView : BaseViewModel - new WindowShowerHelpers(new MainWindow(), new HamburgerMenuView()).Show(); + return client; + }); - _ = FolderHelper.CreateAppDataFolder(); + containerRegistry.RegisterSingleton(() => + { + IPAddress ip = IPAddress.Any; + int port = Settings.Default.LogServerPort; + + UdpServerService server = new(ip, port) + { + OptionDualMode = true, + OptionReuseAddress = true + }; + + return server; + }); + + containerRegistry.RegisterSingleton(() => + { + string ip = Settings.Default.ServerIP; + int port = Settings.Default.SoketServerPort; + Uri uri; + + if (!string.IsNullOrEmpty(ip)) + { + uri = new($"ws://{Settings.Default.ServerIP}:9001/adam-2.7/movement"); + } + else + { + uri = new($"ws://127.0.0.1:9001/adam-2.7/movement"); + } + + // debug, use only with debug server, which runs separately, not as a service + //Uri uri = new($"ws://{Settings.Default.ServerIP}:9001/adam-2.7/movement"); - //TODO check theme before ChangeTheme - _ = ThemeManager.Current.ChangeTheme(this, $"{Settings.Default.BaseTheme}.{Settings.Default.ThemeColorScheme}", false); + // work in production, connect to socket-server run as service + // Uri uri = new($"ws://{ip}:{port}/adam-2.7/movement"); - string ip = Settings.Default.ServerIP; - int port = Settings.Default.ApiPort; + WebSocketClientService client = new(uri); + return client; + }); + + containerRegistry.RegisterSingleton(() => + { + string ip = Settings.Default.ServerIP; + int port = Settings.Default.ApiPort; + string login = Settings.Default.ApiLogin; + string password = Settings.Default.ApiPassword; + + if (string.IsNullOrEmpty(ip)) + { + ip = "127.0.0.1"; + } + + WebApiService client = new(ip, port, login, password); + return client; + + }); + + containerRegistry.RegisterSingleton(containerRegistry => + { + ITcpClientService tcpClientService = containerRegistry.Resolve(); + IUdpClientService udpClientService = containerRegistry.Resolve(); + IUdpServerService udpServerService = containerRegistry.Resolve(); + IWebSocketClientService socketClientService = containerRegistry.Resolve(); + + CommunicationProviderService communicationProvider = new(tcpClientService, udpClientService, udpServerService, socketClientService); - Uri DefaultUri = new($"http://{ip}:{port}"); - WebApi.Client.v1.BaseApi.SetApiClientUri(DefaultUri); + return communicationProvider; + }); - string login = Settings.Default.ApiLogin; - string password = Settings.Default.ApiPassword; + containerRegistry.RegisterSingleton(containerRegistry => + { + IUdpClientService udpClient = containerRegistry.Resolve(); - WebApi.Client.v1.BaseApi.SetAuthenticationHeader(login, password); + PythonRemoteRunnerService remoteRunnerService = new(udpClient); + return remoteRunnerService; + }); - + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); - base.OnStartup(e); + RegisterDialogs(containerRegistry); } - private static void LoadHighlighting() + private static void RegisterDialogs(IContainerRegistry containerRegistry) { - try - { - using var stream = new MemoryStream(AdamController.Properties.Resources.AdamPython); - using var reader = new XmlTextReader(stream); - HighlightingManager.Instance.RegisterHighlighting("AdamPython", Array.Empty(), - ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader.Load(reader, HighlightingManager.Instance)); - } - catch + //Dialog boxes are not used, but implemented + //containerRegistry.RegisterDialog(); + + //The old dialog call type integrated into the service + containerRegistry.RegisterSingleton(containerRegistry => { + var app = Current; + return new DialogManager(app); + }); + } - } + protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings) + { + base.ConfigureRegionAdapterMappings(regionAdapterMappings); + + regionAdapterMappings.RegisterMapping(typeof(FlyoutsControl), Container.Resolve()); + } + + protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) + { + moduleCatalog.AddModule(); + moduleCatalog.AddModule(); + moduleCatalog.AddModule(); + moduleCatalog.AddModule(); } protected override void OnExit(ExitEventArgs e) { - Settings.Default.BaseTheme = ThemeManager.Current.DetectTheme(Current).BaseColorScheme; - Settings.Default.ThemeColorScheme = ThemeManager.Current.DetectTheme(Current).ColorScheme; - Settings.Default.Save(); + OnAppCrashOrExit(); base.OnExit(e); } + + private void OnAppCrashOrExit() + { + Unsubscribe(); + DisposeServices(); + Current.Shutdown(); + } + + /// + /// The priority of resource release is important! + /// FirstRun/LastStop + /// + private void DisposeServices() + { + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + Container.Resolve().Dispose(); + + Container.Resolve().Dispose(); + } + + #region Subscribes + + private void Subscribe() + { + SubscribeUnhandledExceptionHandling(); + Settings.Default.PropertyChanged += OnPropertyChange; + } + + private void Unsubscribe() + { + Settings.Default.PropertyChanged -= OnPropertyChange; + } + + #endregion + + #region On raise event + private void OnPropertyChange(object sender, PropertyChangedEventArgs e) + { + Settings.Default.Save(); + } + #endregion + + #region Intercepting Unhandled Exception + + private void SubscribeUnhandledExceptionHandling() + { + // Catch exceptions from all threads in the AppDomain. + AppDomain.CurrentDomain.UnhandledException += (sender, args) => + ShowUnhandledException(args.ExceptionObject as Exception, "AppDomain.CurrentDomain.UnhandledException", false); + + // Catch exceptions from each AppDomain that uses a task scheduler for async operations. + TaskScheduler.UnobservedTaskException += (sender, args) => + ShowUnhandledException(args.Exception, "TaskScheduler.UnobservedTaskException", false); + + // Catch exceptions from a single specific UI dispatcher thread. + Dispatcher.UnhandledException += (sender, args) => + { + // If we are debugging, let Visual Studio handle the exception and take us to the code that threw it. + if (!Debugger.IsAttached) + { + args.Handled = true; + ShowUnhandledException(args.Exception, "Dispatcher.UnhandledException", true); + } + }; + } + + private void ShowUnhandledException(Exception e, string unhandledExceptionType, bool promptUserForShutdown) + { + if (e.HResult == -2146233088) + { + // This message disables an error about the inability to connect to the websocket server. + // As a temporary measure. Service errors should be handled in the services themselves + if (e.InnerException.Source == "Websocket.Client") + return; + } + var messageBoxTitle = $"An unexpected error has occurred: {unhandledExceptionType}"; + var messageBoxMessage = $"The following exception occurred:\n\n{e}"; + var messageBoxButtons = MessageBoxButton.OK; + + if (promptUserForShutdown) + { + messageBoxMessage += "\n\nTo continue working, you need to exit the application. Can I do it now?"; + messageBoxButtons = MessageBoxButton.YesNo; + } + + // Let the user decide if the app should die or not (if applicable). + if (MessageBox.Show(messageBoxMessage, messageBoxTitle, messageBoxButtons) == MessageBoxResult.Yes) + { + OnAppCrashOrExit(); + } + } + + #endregion } } diff --git a/AdamController/Behaviors/ActivateBehavior.cs b/AdamController/Behaviors/ActivateBehavior.cs deleted file mode 100644 index fbd6d11..0000000 --- a/AdamController/Behaviors/ActivateBehavior.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.Xaml.Behaviors; -using System; -using System.Windows; - -namespace AdamController.Behaviors -{ - public class ActivateBehavior : Behavior - { - private bool isActivated; - - public static readonly DependencyProperty ActivatedProperty = DependencyProperty.Register("Activated", - typeof(bool), - typeof(ActivateBehavior), - new PropertyMetadata(OnActivatedChanged) - ); - - public bool Activated - { - get => (bool)GetValue(ActivatedProperty); - set => SetValue(ActivatedProperty, value); - } - - static void OnActivatedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) - { - ActivateBehavior behavior = (ActivateBehavior)dependencyObject; - if (!behavior.Activated || behavior.isActivated) return; - - // The Activated property is set to true but the Activated event (tracked by the - // isActivated field) hasn't been fired. Go ahead and activate the window. - if (behavior.AssociatedObject.WindowState == WindowState.Minimized) - behavior.AssociatedObject.WindowState = WindowState.Normal; - _ = behavior.AssociatedObject.Activate(); - } - - protected override void OnAttached() - { - AssociatedObject.Activated += OnActivated; - AssociatedObject.Deactivated += OnDeactivated; - } - - protected override void OnDetaching() - { - AssociatedObject.Activated -= OnActivated; - AssociatedObject.Deactivated -= OnDeactivated; - } - - private void OnActivated(object sender, EventArgs eventArgs) - { - isActivated = true; - Activated = true; - } - - private void OnDeactivated(object sender, EventArgs eventArgs) - { - isActivated = false; - Activated = false; - } - - } -} diff --git a/AdamController/Behaviors/PutCursorAtEndTextBoxBehavior.cs b/AdamController/Behaviors/PutCursorAtEndTextBoxBehavior.cs deleted file mode 100644 index 10221f3..0000000 --- a/AdamController/Behaviors/PutCursorAtEndTextBoxBehavior.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Xaml.Behaviors; -using System.Windows.Controls; - - -namespace AdamController.Behaviors -{ - public class PutCursorAtEndTextBoxBehavior : Behavior - { - protected override void OnAttached() - { - AssociatedObject.TextChanged += AssociatedObject_TextChanged; - } - - protected override void OnDetaching() - { - AssociatedObject.TextChanged -= AssociatedObject_TextChanged; - } - - void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e) - { - AssociatedObject.ScrollToEnd(); - } - } -} diff --git a/AdamController/Behaviors/SelectionChangedBehavior.cs b/AdamController/Behaviors/SelectionChangedBehavior.cs deleted file mode 100644 index 228110f..0000000 --- a/AdamController/Behaviors/SelectionChangedBehavior.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; - -//TODO refactor this -namespace AdamController.Behaviors -{ - /// - /// Attached behaviour to implement a selection changed command on a Selector (combobox). - /// The Selector (combobox) generates a SelectionChanged event which in turn generates a - /// Command (in this behavior), which in turn is, when bound, invoked on the viewmodel. - /// - [Obsolete("Remove if dont`t need")] - public static class SelectionChangedCommand - { - // Field of attached ICommand property - private static readonly DependencyProperty ChangedCommandProperty = DependencyProperty.RegisterAttached("ChangedCommand", - typeof(ICommand), - typeof(SelectionChangedCommand), - new PropertyMetadata(null, OnSelectionChangedCommandChange)); - - /// - /// Setter method of the attached DropCommand property - /// - /// - /// - public static void SetChangedCommand(DependencyObject source, ICommand value) - { - source.SetValue(ChangedCommandProperty, value); - } - - /// - /// Getter method of the attached DropCommand property - /// - /// - /// - public static ICommand GetChangedCommand(DependencyObject source) - { - return (ICommand)source.GetValue(ChangedCommandProperty); - } - - /// - /// This method is hooked in the definition of the . - /// It is called whenever the attached property changes - in our case the event of binding - /// and unbinding the property to a sink is what we are looking for. - /// - /// - /// - private static void OnSelectionChangedCommandChange(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - Selector uiElement = d as Selector; // Remove the handler if it exist to avoid memory leaks - - if (uiElement != null) - { - uiElement.SelectionChanged -= Selection_Changed; - uiElement.KeyUp -= uiElement_KeyUp; - - if (e.NewValue is ICommand command) - { - // the property is attached so we attach the Drop event handler - uiElement.SelectionChanged += Selection_Changed; - uiElement.KeyUp += uiElement_KeyUp; - } - } - } - - private static void uiElement_KeyUp(object sender, KeyEventArgs e) - { - if (e == null) - return; - - // Forward key event only if user has hit the return, BackSlash, or Slash key - if (e.Key != Key.Return) - return; - - - // Sanity check just in case this was somehow send by something else - if (sender is not ComboBox uiElement) - return; - - ICommand changedCommand = GetChangedCommand(uiElement); - - // There may not be a command bound to this after all - if (changedCommand == null) - return; - - // Check whether this attached behaviour is bound to a RoutedCommand - if (changedCommand is RoutedCommand) - { - // Execute the routed command - (changedCommand as RoutedCommand).Execute(uiElement.Text, uiElement); - } - else - { - // Execute the Command as bound delegate - changedCommand.Execute(uiElement.Text); - } - } - - /// - /// This method is called when the selection changed event occurs. The sender should be the control - /// on which this behaviour is attached - so we convert the sender into a - /// and receive the Command through the getter listed above. - /// - /// This implementation supports binding of delegate commands and routed commands. - /// - /// - /// - private static void Selection_Changed(object sender, SelectionChangedEventArgs e) - { - // Sanity check just in case this was somehow send by something else - if (sender is not Selector uiElement) - return; - - ICommand changedCommand = GetChangedCommand(uiElement); - - // There may not be a command bound to this after all - if (changedCommand == null) - return; - - // Check whether this attached behaviour is bound to a RoutedCommand - if (changedCommand is RoutedCommand) - { - // Execute the routed command - (changedCommand as RoutedCommand).Execute(e.AddedItems, uiElement); - } - else - { - // Execute the Command as bound delegate - changedCommand.Execute(e.AddedItems); - } - } - } -} diff --git a/AdamController/Commands/EventToCommand.cs b/AdamController/Commands/EventToCommand.cs deleted file mode 100644 index 2dd8c73..0000000 --- a/AdamController/Commands/EventToCommand.cs +++ /dev/null @@ -1,415 +0,0 @@ -using Microsoft.Xaml.Behaviors; -using System; -using System.Windows; -using System.Windows.Input; - -namespace AdamController.Commands -{ - - /// - /// This can be - /// used to bind any event on any FrameworkElement to an . - /// Typically, this element is used in XAML to connect the attached element - /// to a command located in a ViewModel. This trigger can only be attached - /// to a FrameworkElement or a class deriving from FrameworkElement. - /// To access the EventArgs of the fired event, use a RelayCommand<EventArgs> - /// and leave the CommandParameter and CommandParameterValue empty! - /// - ////[ClassInfo(typeof(EventToCommand), - //// VersionString = "5.2.8", - //// DateString = "201504252130", - //// Description = "A Trigger used to bind any event to an ICommand.", - //// UrlContacts = "http://www.galasoft.ch/contact_en.html", - //// Email = "laurent@galasoft.ch")] - public class EventToCommand : TriggerAction - { - /// - /// Identifies the dependency property - /// - public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register( - "CommandParameter", - typeof(object), - typeof(EventToCommand), - new PropertyMetadata( - null, - (s, e) => - { - var sender = s as EventToCommand; - - if (sender?.AssociatedObject == null) - { - return; - } - - sender.EnableDisableElement(); - })); - - /// - /// Identifies the dependency property - /// - public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( - "Command", - typeof(ICommand), - typeof(EventToCommand), - new PropertyMetadata( - null, - (s, e) => OnCommandChanged(s as EventToCommand, e))); - - /// - /// Identifies the dependency property - /// - public static readonly DependencyProperty MustToggleIsEnabledProperty = DependencyProperty.Register( - "MustToggleIsEnabled", - typeof(bool), - typeof(EventToCommand), - new PropertyMetadata( - false, - (s, e) => - { - var sender = s as EventToCommand; - - if (sender?.AssociatedObject == null) - { - return; - } - - sender.EnableDisableElement(); - })); - - private object _commandParameterValue; - - private bool? _mustToggleValue; - - /// - /// Gets or sets the ICommand that this trigger is bound to. This - /// is a DependencyProperty. - /// - public ICommand Command - { - get - { - return (ICommand)GetValue(CommandProperty); - } - - set - { - SetValue(CommandProperty, value); - } - } - - /// - /// Gets or sets an object that will be passed to the - /// attached to this trigger. This is a DependencyProperty. - /// - public object CommandParameter - { - get - { - return GetValue(CommandParameterProperty); - } - - set - { - SetValue(CommandParameterProperty, value); - } - } - - /// - /// Gets or sets an object that will be passed to the - /// attached to this trigger. This property is here for compatibility - /// with the Silverlight version. This is NOT a DependencyProperty. - /// For databinding, use the property. - /// - public object CommandParameterValue - { - get - { - return _commandParameterValue ?? CommandParameter; - } - - set - { - _commandParameterValue = value; - EnableDisableElement(); - } - } - - /// - /// Gets or sets a value indicating whether the attached element must be - /// disabled when the property CanExecuteChanged - /// event fires. If this property is true, and the command CanExecute - /// method returns false, the element will be disabled. If this property - /// is false, the element will not be disabled when the command's - /// CanExecute method changes. This is a DependencyProperty. - /// - public bool MustToggleIsEnabled - { - get - { - return (bool)GetValue(MustToggleIsEnabledProperty); - } - - set - { - SetValue(MustToggleIsEnabledProperty, value); - } - } - - /// - /// Gets or sets a value indicating whether the attached element must be - /// disabled when the property CanExecuteChanged - /// event fires. If this property is true, and the command CanExecute - /// method returns false, the element will be disabled. This property is here for - /// compatibility with the Silverlight version. This is NOT a DependencyProperty. - /// For databinding, use the property. - /// - public bool MustToggleIsEnabledValue - { - get - { - return _mustToggleValue ?? MustToggleIsEnabled; - } - - set - { - _mustToggleValue = value; - EnableDisableElement(); - } - } - - /// - /// Called when this trigger is attached to a FrameworkElement. - /// - protected override void OnAttached() - { - base.OnAttached(); - EnableDisableElement(); - } - - /// - /// This method is here for compatibility - /// with the Silverlight version. - /// - /// The FrameworkElement to which this trigger - /// is attached. - private FrameworkElement GetAssociatedObject() - { - return AssociatedObject as FrameworkElement; - } - - /// - /// This method is here for compatibility - /// with the Silverlight 3 version. - /// - /// The command that must be executed when - /// this trigger is invoked. - private ICommand GetCommand() - { - return Command; - } - - /// - /// Specifies whether the EventArgs of the event that triggered this - /// action should be passed to the bound RelayCommand. If this is true, - /// the command should accept arguments of the corresponding - /// type (for example RelayCommand<MouseButtonEventArgs>). - /// - public bool PassEventArgsToCommand - { - get; - set; - } - - /// - /// Gets or sets a converter used to convert the EventArgs when using - /// . If PassEventArgsToCommand is false, - /// this property is never used. - /// - public IEventArgsConverter EventArgsConverter - { - get; - set; - } - - /// - /// The dependency property name. - /// - public const string EventArgsConverterParameterPropertyName = "EventArgsConverterParameter"; - - /// - /// Gets or sets a parameters for the converter used to convert the EventArgs when using - /// . If PassEventArgsToCommand is false, - /// this property is never used. This is a dependency property. - /// - public object EventArgsConverterParameter - { - get - { - return GetValue(EventArgsConverterParameterProperty); - } - set - { - SetValue(EventArgsConverterParameterProperty, value); - } - } - - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty EventArgsConverterParameterProperty = DependencyProperty.Register( - EventArgsConverterParameterPropertyName, - typeof(object), - typeof(EventToCommand), - new PropertyMetadata(null)); - - /// - /// The dependency property name. - /// - public const string AlwaysInvokeCommandPropertyName = "AlwaysInvokeCommand"; - - /// - /// Gets or sets a value indicating if the command should be invoked even - /// if the attached control is disabled. This is a dependency property. - /// - public bool AlwaysInvokeCommand - { - get - { - return (bool)GetValue(AlwaysInvokeCommandProperty); - } - set - { - SetValue(AlwaysInvokeCommandProperty, value); - } - } - - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty AlwaysInvokeCommandProperty = DependencyProperty.Register( - AlwaysInvokeCommandPropertyName, - typeof(bool), - typeof(EventToCommand), - new PropertyMetadata(false)); - - - /// - /// Provides a simple way to invoke this trigger programatically - /// without any EventArgs. - /// - public void Invoke() - { - Invoke(null); - } - - /// - /// Executes the trigger. - /// To access the EventArgs of the fired event, use a RelayCommand<EventArgs> - /// and leave the CommandParameter and CommandParameterValue empty! - /// - /// The EventArgs of the fired event. - protected override void Invoke(object parameter) - { - if (AssociatedElementIsDisabled() - && !AlwaysInvokeCommand) - { - return; - } - - var command = GetCommand(); - var commandParameter = CommandParameterValue; - - if (commandParameter == null - && PassEventArgsToCommand) - { - commandParameter = EventArgsConverter == null - ? parameter - : EventArgsConverter.Convert(parameter, EventArgsConverterParameter); - } - - if (command != null - && command.CanExecute(commandParameter)) - { - command.Execute(commandParameter); - } - } - - private static void OnCommandChanged( - EventToCommand element, - DependencyPropertyChangedEventArgs e) - { - if (element == null) - { - return; - } - - if (e.OldValue != null) - { - ((ICommand)e.OldValue).CanExecuteChanged -= element.OnCommandCanExecuteChanged; - } - - var command = (ICommand)e.NewValue; - - if (command != null) - { - command.CanExecuteChanged += element.OnCommandCanExecuteChanged; - } - - element.EnableDisableElement(); - } - - private bool AssociatedElementIsDisabled() - { - var element = GetAssociatedObject(); - - return AssociatedObject == null - || (element != null - && !element.IsEnabled); - } - - private void EnableDisableElement() - { - var element = GetAssociatedObject(); - - if (element == null) - { - return; - } - - var command = GetCommand(); - - if (MustToggleIsEnabledValue - && command != null) - { - element.IsEnabled = command.CanExecute(CommandParameterValue); - } - } - - private void OnCommandCanExecuteChanged(object sender, EventArgs e) - { - EnableDisableElement(); - } - } - - /// - /// The definition of the converter used to convert an EventArgs - /// in the class, if the - /// property is true. - /// Set an instance of this class to the - /// property of the EventToCommand instance. - /// - ////[ClassInfo(typeof(EventToCommand))] - public interface IEventArgsConverter - { - /// - /// The method used to convert the EventArgs instance. - /// - /// An instance of EventArgs passed by the - /// event that the EventToCommand instance is handling. - /// An optional parameter used for the conversion. Use - /// the property - /// to set this value. This may be null. - /// The converted value. - object Convert(object value, object parameter); - } -} diff --git a/AdamController/Commands/RelayCommand.cs b/AdamController/Commands/RelayCommand.cs deleted file mode 100644 index ba680fd..0000000 --- a/AdamController/Commands/RelayCommand.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Windows.Input; - -namespace AdamController.Commands -{ - /// Provides an implementation of the interface. - public class RelayCommand : ICommand - { - private readonly Action mExecute; - private readonly Func mCanExecute; - - public RelayCommand(Action execute, Func canExecute = null) - { - mExecute = execute; - mCanExecute = canExecute; - } - - public event EventHandler CanExecuteChanged - { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } - } - - public bool CanExecute(object parameter) - { - return mCanExecute == null || mCanExecute(parameter); - } - - public void Execute(object parameter) - { - mExecute(parameter); - } - } - - public class RelayCommand : ICommand - { - #region Fields - - private readonly Action mExecute; - private readonly Predicate mCanExecute; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of DelegateCommand{T}/>. - /// - /// Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate. - /// will always return true. - public RelayCommand(Action execute) : this(execute, null){} - - /// - /// Creates a new command. - /// - /// The execution logic. - /// The execution status logic. - public RelayCommand(Action execute, Predicate canExecute) - { - mExecute = execute ?? throw new ArgumentNullException(nameof(execute)); - mCanExecute = canExecute; - } - - #endregion - - #region ICommand Members - - /// - /// - /// Defines the method that determines whether the command can execute in its current state. - /// - /// Data used by the command. If the command does not require data to be passed, this object can be set to null. - /// - /// true if this command can be executed; otherwise, false. - /// - public bool CanExecute(object parameter) => mCanExecute?.Invoke((T)parameter) ?? true; - - /// - /// - /// Occurs when changes occur that affect whether or not the command should execute. - /// - public event EventHandler CanExecuteChanged - { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } - } - - /// - /// - /// Defines the method to be called when the command is invoked. - /// - /// Data used by the command. If the command does not require data to be passed, this object can be set to . - public void Execute(object parameter) - { - mExecute((T)parameter); - } - - #endregion - } -} diff --git a/AdamController/DataSource/LanguagesCollection.cs b/AdamController/DataSource/LanguagesCollection.cs deleted file mode 100644 index fd4008b..0000000 --- a/AdamController/DataSource/LanguagesCollection.cs +++ /dev/null @@ -1,21 +0,0 @@ -using AdamBlocklyLibrary.Enum; -using AdamController.Model; -using System.Collections.ObjectModel; - -namespace AdamController.DataSource -{ - public class LanguagesCollection - { - public static ObservableCollection AppLanguageCollection { get; private set; } = new ObservableCollection - { - new AppLanguageModel { AppLanguage = "ru", LanguageName = "Русский" } - }; - - public static ObservableCollection BlocklyLanguageCollection { get; private set; } = new ObservableCollection - { - new BlocklyLanguageModel { BlocklyLanguage = BlocklyLanguage.ru, LanguageName = "Русский" }, - new BlocklyLanguageModel { BlocklyLanguage = BlocklyLanguage.zh, LanguageName = "Китайский" }, - new BlocklyLanguageModel { BlocklyLanguage = BlocklyLanguage.en, LanguageName = "Английский" } - }; - } -} diff --git a/AdamController/Helpers/ComunicateBenchmarkHelper.cs b/AdamController/Helpers/ComunicateBenchmarkHelper.cs deleted file mode 100644 index e084b54..0000000 --- a/AdamController/Helpers/ComunicateBenchmarkHelper.cs +++ /dev/null @@ -1,130 +0,0 @@ -using AdamController.Properties; -using AdamControllerLibrary.AdamComunicate; -using System.Threading; - -namespace AdamController.Helpers -{ - - public sealed class ComunicateBenchmarkHelper - { - #region Singelton - - private static readonly object @lock = new(); - private static ComunicateBenchmarkHelper instance = null; - - public static ComunicateBenchmarkHelper Instance - { - get - { - if (instance != null) - { - LazyInitializer(); - return instance; - } - - Monitor.Enter(@lock); - ComunicateBenchmarkHelper temp = new(); - - _ = Interlocked.Exchange(ref instance, temp); - Monitor.Exit(@lock); - return instance; - } - } - - #endregion - - #region Declaration delegates and events - - public delegate void OnTcpCientConnected(); - public static event OnTcpCientConnected OnTcpConnected; - - public delegate void OnTcpClientDisconnect(); - public static event OnTcpClientDisconnect OnTcpDisconnected; - - public delegate void OnTcpClientReconnected(int reconnectCount); - public static event OnTcpClientReconnected OnTcpReconnected; - - #endregion - - public bool TcpClientIsConnected => mAdamTcpClient != null && mAdamTcpClient.IsConnected; - - private static AdamTcpClient mAdamTcpClient; - - #region ~ - - static ComunicateBenchmarkHelper() - { - LazyInitializer(); - } - - private static void LazyInitializer() - { - if(mAdamTcpClient == null) - { - AdamTcpClientOption option = new() - { - ReconnectCount = Settings.Default.ReconnectQtyBenchmarkComunicateTcpClient, - ReconnectTimeout = Settings.Default.ReconnectTimeoutBenchmarkComunicateTcpClient - }; - - mAdamTcpClient = new(Settings.Default.BenchmarkTestServerIp, Settings.Default.BenchmarkTcpConnectStatePort, option); - } - - mAdamTcpClient.TcpCientConnected += TcpCientConnected; - mAdamTcpClient.TcpClientDisconnected += TcpClientDisconnected; - mAdamTcpClient.TcpClientReconnected += TcpClientReconnected; - } - - #endregion - - #region Client events - - private static void TcpClientDisconnected() - { - OnTcpDisconnected?.Invoke(); - } - - private static void TcpCientConnected() - { - OnTcpConnected?.Invoke(); - } - - private static void TcpClientReconnected(int reconnectCount) - { - OnTcpReconnected?.Invoke(reconnectCount); - } - - #endregion - - #region Tcp connect - - public void Connect() - { - _ = mAdamTcpClient?.ConnectAsync(); - } - - #endregion - - # region Tcp disconnect - - public void Disconnect() - { - mAdamTcpClient?.DisconnectAndStop(); - } - - public void DisconnectAndDestroy() - { - Disconnect(); - - if(mAdamTcpClient != null) - { - mAdamTcpClient.TcpCientConnected -= TcpCientConnected; - mAdamTcpClient.TcpClientDisconnected -= TcpClientDisconnected; - mAdamTcpClient.TcpClientReconnected -= TcpClientReconnected; - mAdamTcpClient = null; - } - } - - #endregion - } -} diff --git a/AdamController/Helpers/ComunicateHelper.cs b/AdamController/Helpers/ComunicateHelper.cs deleted file mode 100644 index 6657d3c..0000000 --- a/AdamController/Helpers/ComunicateHelper.cs +++ /dev/null @@ -1,248 +0,0 @@ -using AdamController.Properties; -using AdamControllerLibrary.AdamComunicate; -using System; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace AdamController.Helpers -{ - public sealed class ComunicateHelper - { - #region Declaration delegates and events - - public delegate void OnAdamTcpCientConnected(); - public static event OnAdamTcpCientConnected OnAdamTcpConnectedEvent; - - public delegate void OnAdamTcpClientDisconnect(); - public static event OnAdamTcpClientDisconnect OnAdamTcpDisconnectedEvent; - - public delegate void OnAdamTcpClientReconnected(int reconnectCount); - public static event OnAdamTcpClientReconnected OnAdamTcpReconnected; - - public delegate void OnAdamUdpServerReceived(string message); - public static event OnAdamUdpServerReceived OnAdamLogServerUdpReceivedEvent; - - public delegate void OnAdamUdpMessageReceived(string message); - public static event OnAdamUdpMessageReceived OnAdamMessageReceivedEvent; - - #endregion - - public static bool TcpClientIsConnected => mAdamTcpClient != null && mAdamTcpClient.IsConnected; - - private static AdamTcpClient mAdamTcpClient; - private static AdamUdpClient mAdamUdpMessageClient; - private static AdamUdpServer mAdamUdpLogServer; - private static AdamWebSocketClient mAdamWebSocketClient; - - #region ~ - - static ComunicateHelper() - { - LazyInitializer(); - } - - private static void LazyInitializer() - { - if(mAdamTcpClient == null) - { - AdamTcpClientOption option = new() - { - ReconnectCount = Settings.Default.ReconnectQtyComunicateTcpClient, - ReconnectTimeout = Settings.Default.ReconnectTimeoutComunicateTcpClient - }; - - mAdamTcpClient = new(Settings.Default.ServerIP, Settings.Default.TcpConnectStatePort, option); - } - - mAdamUdpMessageClient ??= new(IPAddress.Any, int.Parse(Settings.Default.MessageDataExchangePort)) - { - OptionDualMode = true, - OptionReuseAddress = true - }; - - mAdamUdpLogServer ??= new(IPAddress.Any, Settings.Default.LogServerPort) - { - OptionDualMode = true, - OptionReuseAddress = true - }; - -#if DEBUG - mAdamWebSocketClient ??= new AdamWebSocketClient(new Uri($"ws://{Settings.Default.ServerIP}:9001/adam-2.7/movement")); -#else - mAdamWebSocketClient ??= new AdamWebSocketClient(new Uri($"ws://{Settings.Default.ServerIP}:{Settings.Default.SoketServerPort}/adam-2.7/movement")); -#endif - - - mAdamTcpClient.TcpCientConnected += TcpCientConnected; - mAdamTcpClient.TcpClientDisconnected += TcpClientDisconnected; - mAdamTcpClient.TcpClientError += TcpClientError; - mAdamTcpClient.TcpClientReceived += TcpClientReceived; - mAdamTcpClient.TcpClientReconnected += TcpClientReconnected; - - mAdamWebSocketClient.WebSocketConnectedEvent += WebSocketConnectedEvent; - mAdamWebSocketClient.WebSocketClientReceivedEvent += WebSocketClientReceived; - mAdamWebSocketClient.WebSocketClientDisconnectedEvent += WebSocketClientDisconnectedEvent; - - mAdamUdpMessageClient.UdpClientReceived += MessageClientUdpReceived; - mAdamUdpLogServer.UdpServerReceived += UdpServerReceived; - } - - private static void WebSocketClientDisconnectedEvent() - { - //throw new System.NotImplementedException(); - } - - private static void WebSocketClientReceived(string text) - { - //throw new System.NotImplementedException(); - } - - private static void WebSocketConnectedEvent() - { - //throw new System.NotImplementedException(); - } - - private static void MessageClientUdpReceived(EndPoint endpoint, byte[] buffer, long offset, long size) - { - string encodedMessage = Encoding.UTF8.GetString(buffer, (int)offset, (int)size); - OnAdamMessageReceivedEvent?.Invoke(encodedMessage); - } - - #endregion - - #region Udp Server events - - private static void UdpServerReceived(EndPoint endpoint, byte[] buffer, long offset, long size) - { - string encodedMessage = Encoding.UTF8.GetString(buffer, (int)offset, (int)size); - OnAdamLogServerUdpReceivedEvent?.Invoke(encodedMessage); - } - - #endregion - - #region TCP Client events - - private static void TcpClientReceived(byte[] buffer, long offset, long size) {} - - private static void TcpClientError(SocketError error) {} - - private static void TcpClientDisconnected() - { - OnAdamTcpDisconnectedEvent?.Invoke(); - - if (mAdamUdpLogServer != null) - { - if (mAdamUdpLogServer.IsStarted) - mAdamUdpLogServer?.Stop(); - } - - if(mAdamWebSocketClient != null) - { - //if (mAdamWebSocketClient.IsRunning) - mAdamWebSocketClient.DisconnectAsync(); - } - } - - private static void TcpCientConnected() - { - OnAdamTcpConnectedEvent?.Invoke(); - - if(!mAdamUdpLogServer.IsStarted) - mAdamUdpLogServer?.Start(); - - //if (!mAdamWebSocketClient.IsStarted) - mAdamWebSocketClient.ConnectAsync(); - } - - private static void TcpClientReconnected(int reconnectCount) - { - OnAdamTcpReconnected?.Invoke(reconnectCount); - } - - #endregion - - #region Tcp/Udp connect - - private static void Connect() - { - _ = Task.Run(() => mAdamTcpClient?.ConnectAsync()); - _ = Task.Run(() => mAdamUdpMessageClient?.Start()); - _ = Task.Run(() => mAdamWebSocketClient?.ConnectAsync()); - } - - public static void ConnectAllAsync() - { - _ = Task.Run(() => Connect()); - } - - #endregion - - # region Tcp/Upd disconnect - - public static void DisconnectAll() - { - _ = Task.Run(()=> mAdamTcpClient?.DisconnectAndStop()); - _ = Task.Run(() => mAdamUdpMessageClient?.Stop()); - _ = Task.Run(() => mAdamWebSocketClient?.DisconnectAsync()); - } - - public static void DisconnectAllAndDestroy() - { - DisconnectAll(); - - if(mAdamTcpClient != null) - { - mAdamTcpClient.TcpCientConnected -= TcpCientConnected; - mAdamTcpClient.TcpClientDisconnected -= TcpClientDisconnected; - mAdamTcpClient.TcpClientError -= TcpClientError; - mAdamTcpClient.TcpClientReceived -= TcpClientReceived; - mAdamTcpClient.TcpClientReconnected -= TcpClientReconnected; - - mAdamTcpClient = null; - } - - if(mAdamUdpLogServer != null) - { - mAdamUdpLogServer.UdpServerReceived -= UdpServerReceived; - mAdamUdpLogServer = null; - } - - if(mAdamUdpMessageClient != null) - { - mAdamUdpMessageClient.UdpClientReceived -= MessageClientUdpReceived; - mAdamUdpLogServer = null; - } - - if(mAdamWebSocketClient != null) - { - mAdamWebSocketClient.WebSocketConnectedEvent -= WebSocketConnectedEvent; - mAdamWebSocketClient.WebSocketClientReceivedEvent -= WebSocketClientReceived; - mAdamWebSocketClient.WebSocketClientDisconnectedEvent -= WebSocketClientDisconnectedEvent; - //mAdamWebSocketClient.Dispose(); - } - } - - #endregion - - #region Tcp/Udp/WebSocket send message - - public static void SendTcpMessage(string message) - { - mAdamTcpClient.Send(message); - } - - public static void SendTcpMessageAsync(string message) - { - _ = Task.Run(() => SendTcpMessage(message)); - } - - public static void WebSocketSendTextMessage(string message) - { - Task.Run(() => mAdamWebSocketClient.SendTextAsync(message)); - } - - #endregion - } -} diff --git a/AdamController/Helpers/FileHelper.cs b/AdamController/Helpers/FileHelper.cs deleted file mode 100644 index da61fb1..0000000 --- a/AdamController/Helpers/FileHelper.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace AdamController.Helpers -{ - public class FileHelper - { - private const int cBufferSize = 0x4096; - public static async Task WriteAsync(string path, string file) - { - using StreamWriter writer = File.CreateText(path); - await writer.WriteAsync(file); - } - - public static Task ReadTextAsStringAsync(string path) => ReadTextToStringAsync(path); - public static Task ReadTextAsByteArray(string path) => ReadTextToByteArrayAsync(path); - - private static async Task ReadTextToStringAsync(string filePath) - { - using FileStream sourceStream = OpenRead(filePath); - - StringBuilder sb = new(); - - byte[] buffer = new byte[0x1000]; - int numRead; - - while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0) - { - string text = Encoding.UTF8.GetString(buffer, 0, numRead); - _ = sb.Append(text); - } - - return sb.ToString(); - } - - private static async Task ReadTextToByteArrayAsync(string filePath) - { - using var fs = OpenRead(filePath); - - var buff = new byte[fs.Length]; - _ = await fs.ReadAsync(buff.AsMemory(0, (int) fs.Length)); - return buff; - } - - /// - /// Opens an existing file for asynchronous reading. - /// - /// Full file path - /// A read-only FileStream on the specified path. - public static FileStream OpenRead(string path) - { - // Open a file stream for reading and that supports asynchronous I/O - return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: cBufferSize, useAsync: true); - } - } - - -} diff --git a/AdamController/Helpers/FolderHelper.cs b/AdamController/Helpers/FolderHelper.cs deleted file mode 100644 index 04af945..0000000 --- a/AdamController/Helpers/FolderHelper.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Globalization; -using System.Reflection; -using System.IO; -using AdamController.Properties; - -namespace AdamController.Helpers -{ - public static class FolderHelper - { - static FolderHelper() - { - SaveFolderPathToSettings(); - } - - /// - /// starts when the application is first launched - /// - private static void SaveFolderPathToSettings() - { - if (string.IsNullOrEmpty(Settings.Default.SavedUserWorkspaceFolderPath)) - { - Settings.Default.SavedUserWorkspaceFolderPath = SavedWorkspaceDocumentsDir; - } - - if (string.IsNullOrEmpty(Settings.Default.SavedUserToolboxFolderPath)) - { - Settings.Default.SavedUserToolboxFolderPath = SavedToolboxDocumentsDir; - } - - if (string.IsNullOrEmpty(Settings.Default.SavedUserCustomBlocksFolderPath)) - { - Settings.Default.SavedUserCustomBlocksFolderPath = SavedUserCustomBlocksDocumentsDir; - } - - if (string.IsNullOrEmpty(Settings.Default.SavedUserScriptsFolderPath)) - { - Settings.Default.SavedUserScriptsFolderPath = SavedUserScriptsDocumentsDir; - } - - if (string.IsNullOrEmpty(Settings.Default.SavedResultsNetworkTestsFolderPath)) - { - Settings.Default.SavedResultsNetworkTestsFolderPath = SavedResultsNetworkTestsDir; - } - } - - private static string AssemblyTitle => Assembly.GetEntryAssembly().GetName().Name; - - /// - /// Get a path to the directory where the user store his documents - /// - public static string MyDocumentsUserDir => Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - - /// - /// Главная дирректория для хранения файлов пользователя - /// Путь C:\Users\UserName\AdamStudio - /// - public static string SpecialProgramDocumentsDir => MyDocumentsUserDir + Path.DirectorySeparatorChar + "AdamStudio"; - - /// - /// Дирректория для сохранения рабочих областей - /// Путь C:\Users\UserName\AdamStudio\SavedWorkspace - /// - public static string SavedWorkspaceDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyWorkspaces"; - - /// - /// Дирректория для сохранения пользовательских панелей - /// Путь C:\Users\UserName\AdamStudio\MyToolbox - /// - public static string SavedToolboxDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyToolboxes"; - - /// - /// Дирректория для сохранения пользовательских блоков - /// Путь C:\Users\UserName\AdamStudio\MyBlocks - /// - public static string SavedUserCustomBlocksDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyBlocks"; - - /// - /// Дирректория для сохранения пользовательских скриптов - /// Путь C:\Users\UserName\AdamStudio\MyScripts - /// - public static string SavedUserScriptsDocumentsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "MyScripts"; - - /// - /// Дирректория для сохранения тестов сети - /// Путь C:\Users\UserName\AdamStudio\MyScripts - /// - /// SavedResultsNetworkTestsFolderPath - public static string SavedResultsNetworkTestsDir => SpecialProgramDocumentsDir + Path.DirectorySeparatorChar + "NetworkResultsTests"; - - /// - /// Get a path to the directory where the application - /// can persist/load user data on session exit and re-start. - /// - public static string DirAppData => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + AssemblyTitle; - - /// - /// Get path and file name to application specific session file - /// - public static string DirFileAppSessionData => Path.Combine(DirAppData, string.Format(CultureInfo.InvariantCulture, "{0}.App.session", AssemblyTitle)); - - /// - /// Return common application data folder - /// - public static string CommonDirAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + Path.DirectorySeparatorChar + Assembly.GetEntryAssembly().GetName().Name; - - /// - /// Create app folder in application data dirrectory - /// - /// - public static bool CreateAppDataFolder() - { - try - { - if (!Directory.Exists(DirAppData)) - { - _ = Directory.CreateDirectory(DirAppData); - } - - if (!Directory.Exists(SpecialProgramDocumentsDir)) - { - _ = Directory.CreateDirectory(SpecialProgramDocumentsDir); - } - - if (!Directory.Exists(SavedWorkspaceDocumentsDir)) - { - _ = Directory.CreateDirectory(SavedWorkspaceDocumentsDir); - } - - if (!Directory.Exists(SavedToolboxDocumentsDir)) - { - _ = Directory.CreateDirectory(SavedToolboxDocumentsDir); - } - if (!Directory.Exists(SavedUserCustomBlocksDocumentsDir)) - { - _ = Directory.CreateDirectory(SavedUserCustomBlocksDocumentsDir); - } - if (!Directory.Exists(SavedUserScriptsDocumentsDir)) - { - _ = Directory.CreateDirectory(SavedUserScriptsDocumentsDir); - } - if (!Directory.Exists(SavedResultsNetworkTestsDir)) - { - _ = Directory.CreateDirectory(SavedResultsNetworkTestsDir); - } - } - catch - { - return false; - } - - return true; - } - } -} diff --git a/AdamController/Helpers/PythonScriptExecuteHelper.cs b/AdamController/Helpers/PythonScriptExecuteHelper.cs deleted file mode 100644 index b7277ef..0000000 --- a/AdamController/Helpers/PythonScriptExecuteHelper.cs +++ /dev/null @@ -1,77 +0,0 @@ -using AdamController.WebApi.Client.Common; -using AdamController.WebApi.Client.v1.ResponseModel; - -namespace AdamController.Helpers -{ - public class PythonScriptExecuteHelper - { - #region Declaration delegates and events - - public delegate void OnStandartOutput(string message); - public static event OnStandartOutput OnStandartOutputEvent; - - public delegate void OnExecuteStart(string message); - public static event OnExecuteStart OnExecuteStartEvent; - - public delegate void OnExecuteFinish(string message); - public static event OnExecuteFinish OnExecuteFinishEvent; - - #endregion - - static PythonScriptExecuteHelper() - { - ComunicateHelper.OnAdamMessageReceivedEvent += OnAdamMessageReceivedAsync; - } - - private static void OnAdamMessageReceivedAsync(string message) - { - switch (message) - { - case "start": - OnExecuteStartEvent.Invoke(string.Empty); - break; - - case "error": - break; - - case string result when result.StartsWith("finish"): - OnExecuteFinishEvent.Invoke(FinishExecuteMessage(message.Remove(0, 6))); - break; - - default: - OnStandartOutputEvent.Invoke($"{message}\n"); - break; - } - } - - private static string FinishExecuteMessage(string resultJson = null) - { - string message = "\n======================\n<<Выполнение программы завершено>>"; - - if(string.IsNullOrEmpty(resultJson)) - return message; - - CommandExecuteResult executeResult = resultJson.ToCommandResult(); - - string messageWithResult = $"{message}\n" + - $"\n" + - $"Отчет о выполнении\n" + - $"======================\n" + - $"Начало выполнения: {executeResult.StartTime}\n" + - $"Завершение выполнения: {executeResult.EndTime}\n" + - $"Общее время выполнения: {executeResult.RunTime}\n" + - $"Код выхода: {executeResult.ExitCode}\n" + - $"Статус успешности завершения: {executeResult.Succeeded}" + - $"\n======================\n"; - - if (!string.IsNullOrEmpty(executeResult.StandardError)) - messageWithResult += $"Ошибка: {executeResult.StandardError}" + - $"\n======================\n"; - - return messageWithResult; - - } - - - } -} diff --git a/AdamController/Helpers/TcpTestRunHelper.cs b/AdamController/Helpers/TcpTestRunHelper.cs deleted file mode 100644 index b740bfd..0000000 --- a/AdamController/Helpers/TcpTestRunHelper.cs +++ /dev/null @@ -1,122 +0,0 @@ -using AdamControllerLibrary.AdamComunicate; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace AdamController.Helpers -{ - public class TcpTestRunHelper - { - public static string LastErrorMessage { get; internal set; } = string.Empty; - public static long TotalErrors { get; internal set; } = 0; - public static long TotalBytes { get; internal set; } = 0; - public static DateTime TimestampStop { get; internal set; } = DateTime.UtcNow; - public static DateTime TimestampStart { get; private set; } = DateTime.UtcNow; - public static long TotalMessages { get; private set; } = 0; - public static bool IsTestRun { get; private set; } - - private static byte[] mMessageToSend; - private static string mAddress; - private static int mPort; - private static int mClientsQty; - private static int mMessagesQty; - private static int mSize; - private static int mTestTime; - private static List mAdamClients; - - private static CancellationTokenSource mTokenSource; - - public static void Run() - { - IsTestRun = true; - mTokenSource = new CancellationTokenSource(); - - ClearResultField(); - InitTestParam(); - - mAdamClients = new(); - mMessageToSend = new byte[mSize]; - - for (int i = 0; i < mClientsQty; ++i) - { - AdamTestTcpClient client = new(mAddress, mPort, mMessagesQty, mMessageToSend); - - mAdamClients.Add(client); - } - - TimestampStart = DateTime.UtcNow; - - foreach (AdamTestTcpClient client in mAdamClients) - { - _ = client.ConnectAsync(); - } - - foreach (AdamTestTcpClient client in mAdamClients) - { - while (!client.IsConnected) - { - _ = Thread.Yield(); - } - } - - _ = mTokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(mTestTime)); - - Stop(); - } - - private static void Stop() - { - IsTestRun = false; - - if (mAdamClients == null) return; - - TimestampStop = DateTime.UtcNow; - - foreach (AdamTestTcpClient client in mAdamClients) - { - TotalBytes += client.TotalBytes; - LastErrorMessage += client.LastErrorMessage; - TotalErrors += client.TotalErrors; - - _ = client.DisconnectAsync(); - } - - foreach (AdamTestTcpClient client in mAdamClients) - { - while (client.IsConnected) - { - _ = Thread.Yield(); - } - } - - mTokenSource.Dispose(); - - TotalMessages = TotalBytes / mSize; - } - - public static void AbortTest() - { - mTokenSource.Cancel(); - } - - private static void InitTestParam() - { - mAddress = Properties.Settings.Default.BenchmarkTestServerIp; - mPort = Properties.Settings.Default.BenchmarkTcpTestPort; - mClientsQty = Properties.Settings.Default.BenchmarkTestTcpClientsQty; - mMessagesQty = Properties.Settings.Default.BenchmarkTestTcpMessageQty; - mSize = Properties.Settings.Default.BenchmarkTcpSizeByteArray; - mTestTime = Properties.Settings.Default.BenchmarkTestTcpTime; - } - - private static void ClearResultField() - { - LastErrorMessage = string.Empty; - TotalErrors = 0; - TotalBytes = 0; - TimestampStart = DateTime.UtcNow; - TimestampStop = DateTime.UtcNow; - TotalMessages = 0; - } - } -} diff --git a/AdamController/Helpers/UdpTestRunHelper.cs b/AdamController/Helpers/UdpTestRunHelper.cs deleted file mode 100644 index 755dcd4..0000000 --- a/AdamController/Helpers/UdpTestRunHelper.cs +++ /dev/null @@ -1,121 +0,0 @@ -using AdamControllerLibrary.AdamComunicate; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace AdamController.Helpers -{ - public class UdpTestRunHelper - { - public static string LastErrorMessage { get; internal set; } = string.Empty; - public static long TotalErrors { get; internal set; } = 0; - public static long TotalBytes { get; internal set; } = 0; - public static DateTime TimestampStop { get; internal set; } = DateTime.UtcNow; - public static DateTime TimestampStart { get; private set; } = DateTime.UtcNow; - public static long TotalMessages { get; set; } = 0; - public static bool IsTestRun { get; private set; } - - private static byte[] mMessageToSend; - private static string mAddress; - private static int mPort; - private static int mClientsQty; - private static int mMessagesQty; - private static int mSize; - private static int mSeconds; - private static List mAdamClients; - - private static CancellationTokenSource mTokenSource; - - public static void Run() - { - IsTestRun = true; - mTokenSource = new CancellationTokenSource(); - - ClearResultField(); - InitTestParam(); - - mAdamClients = new(); - mMessageToSend = new byte[mSize]; - - for (int i = 0; i < mClientsQty; ++i) - { - AdamUdpTestClient client = new (mAddress, mPort, mMessagesQty, mMessageToSend); - mAdamClients.Add(client); - } - - TimestampStart = DateTime.UtcNow; - - foreach (AdamUdpTestClient client in mAdamClients) - { - _ = client.Connect(); - } - - foreach (AdamUdpTestClient client in mAdamClients) - { - while (!client.IsConnected) - { - _ = Thread.Yield(); - } - } - - _ = mTokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(mSeconds)); - - Stop(); - } - - private static void Stop() - { - IsTestRun = false; - if (mAdamClients == null) return; - - TimestampStop = DateTime.UtcNow; - - foreach (AdamUdpTestClient client in mAdamClients) - { - TotalBytes += client.TotalBytes; - LastErrorMessage += client.LastErrorMessage; - TotalErrors += client.TotalErrors; - - _ = client.Disconnect(); - } - - foreach (AdamUdpTestClient client in mAdamClients) - { - while (client.IsConnected) - { - _ = Thread.Yield(); - } - } - - mTokenSource.Dispose(); - - //? - TotalMessages = TotalBytes / mSize; - } - - public static void AbortTest() - { - mTokenSource.Cancel(); - } - - private static void InitTestParam() - { - mAddress = Properties.Settings.Default.BenchmarkTestServerIp; - mPort = Properties.Settings.Default.BenchmarkUdpTestPort; - mClientsQty = Properties.Settings.Default.BenchmarkTestUdpClientsQty; - mMessagesQty = Properties.Settings.Default.BenchmarkTestUdpMessageQty; - mSize = Properties.Settings.Default.BenchmarkUdpSizeByteArray; - mSeconds = Properties.Settings.Default.BenchmarkTestUdpTime; - } - - private static void ClearResultField() - { - LastErrorMessage = string.Empty; - TotalErrors = 0; - TotalBytes = 0; - TimestampStart = DateTime.UtcNow; - TimestampStop = DateTime.UtcNow; - TotalMessages = 0; - } - } -} diff --git a/AdamController/Helpers/WindowShowerHelpers.cs b/AdamController/Helpers/WindowShowerHelpers.cs deleted file mode 100644 index df71d81..0000000 --- a/AdamController/Helpers/WindowShowerHelpers.cs +++ /dev/null @@ -1,135 +0,0 @@ -using AdamController.Interface; -using MahApps.Metro.Controls; -using System.Windows; -using System.Windows.Controls; - -namespace AdamController.Helpers -{ - public class WindowShowerHelpers - { - private readonly MetroWindow mWindow; - private readonly bool mIsModal; - - public WindowShowerHelpers(MetroWindow window, object dataContext) - { - IWindowParam param = dataContext as IWindowParam ?? new DefaultWindowParam(); - mIsModal = param.IsModal; - - mWindow = window; - mWindow.DataContext = dataContext; - mWindow.Title = param.WindowTitle; - mWindow.Height = param.Height; - mWindow.Width = param.Width; - mWindow.ResizeMode = param.ResizeMode; - mWindow.WindowStartupLocation = param.WindowStartupLocation; - mWindow.TitleCharacterCasing = param.TitleCharacterCasing; - mWindow.WindowState = param.WindowState; - - mWindow.Closed += (sender, e) => param.OnClosed(window); - } - - public WindowShowerHelpers(UserControl userControl, object dataContext) - { - IWindowParam param = dataContext as IWindowParam ?? new DefaultWindowParam(); - mIsModal = param.IsModal; - - MetroWindow window = new() - { - Content = userControl, - DataContext = dataContext, - Title = param.WindowTitle, - Width = param.Width, - Height = param.Height, - ResizeMode = param.ResizeMode, - WindowStartupLocation = param.WindowStartupLocation, - TitleCharacterCasing = param.TitleCharacterCasing, - WindowState = param.WindowState - - }; - - window.Closed += (sender, e) => param.OnClosed(window); - mWindow = window; - } - - public WindowShowerHelpers(UserControl userControl, params object[] dataContext) - { - IWindowParam param = dataContext[0] as IWindowParam ?? new DefaultWindowParam(); - mIsModal = param.IsModal; - - MetroWindow window = new() - { - Content = userControl, - DataContext = dataContext, - Title = param.WindowTitle, - Width = param.Width, - Height = param.Height, - ResizeMode = param.ResizeMode, - WindowStartupLocation = param.WindowStartupLocation, - TitleCharacterCasing = param.TitleCharacterCasing, - WindowState = param.WindowState - }; - - window.Closed += (sender, e) => param.OnClosed(window); - mWindow = window; - } - - #region Show - - public void Show() - { - if (mWindow == null) - { - return; - } - - if (mIsModal) - { - try - { - _ = mWindow.ShowDialog(); - } - catch - { - - } - - } - else - { - try - { - mWindow.Show(); - } - catch - { - - } - - } - } - - #endregion - } - - internal class DefaultWindowParam : IWindowParam - { - public string WindowTitle => @"Заголовок окна не переопределен"; - public bool IsModal => true; - public double Height => 800; - public double Width => 1200; - public ResizeMode ResizeMode => ResizeMode.CanResize; - public WindowStartupLocation WindowStartupLocation => WindowStartupLocation.CenterScreen; - public CharacterCasing TitleCharacterCasing => CharacterCasing.Normal; - public WindowState WindowState => WindowState.Normal; - - public void OnClosed(Window window) - { - if (window == null) - { - return; - } - - window.Close(); - } - } -} diff --git a/AdamController/Interface/IWindowParam.cs b/AdamController/Interface/IWindowParam.cs deleted file mode 100644 index 66fc1ee..0000000 --- a/AdamController/Interface/IWindowParam.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace AdamController.Interface -{ - public interface IWindowParam - { - double Height { get; } - - double Width { get; } - - string WindowTitle { get; } - - bool IsModal { get; } - - ResizeMode ResizeMode { get; } - - WindowStartupLocation WindowStartupLocation { get; } - - WindowState WindowState { get; } - /// - /// Title charster style - /// - CharacterCasing TitleCharacterCasing { get; } - - /// - /// This method is executed when the window is closed - /// - abstract void OnClosed(Window window); - } -} diff --git a/AdamController/Model/AppLanguageModel.cs b/AdamController/Model/AppLanguageModel.cs deleted file mode 100644 index b9489cd..0000000 --- a/AdamController/Model/AppLanguageModel.cs +++ /dev/null @@ -1,39 +0,0 @@ -using AdamController.Model.Common; - -namespace AdamController.Model -{ - public class AppLanguageModel : BaseModel - { - private string appLanguage; - public string AppLanguage - { - get => appLanguage; - set - { - if (value == appLanguage) - { - return; - } - - appLanguage = value; - OnPropertyChanged(nameof(AppLanguage)); - } - } - - private string languageName; - public string LanguageName - { - get => languageName; - set - { - if (value == languageName) - { - return; - } - - languageName = value; - OnPropertyChanged(nameof(LanguageName)); - } - } - } -} diff --git a/AdamController/Model/BlocklyLanguageModel.cs b/AdamController/Model/BlocklyLanguageModel.cs deleted file mode 100644 index ea0e0f5..0000000 --- a/AdamController/Model/BlocklyLanguageModel.cs +++ /dev/null @@ -1,40 +0,0 @@ -using AdamBlocklyLibrary.Enum; -using AdamController.Model.Common; - -namespace AdamController.Model -{ - public class BlocklyLanguageModel : BaseModel - { - private BlocklyLanguage blocklyLanguage; - public BlocklyLanguage BlocklyLanguage - { - get { return blocklyLanguage; } - set - { - if (value == blocklyLanguage) - { - return; - } - - blocklyLanguage = value; - OnPropertyChanged(nameof(BlocklyLanguage)); - } - } - - private string languageName; - public string LanguageName - { - get { return languageName; } - set - { - if (value == languageName) - { - return; - } - - languageName = value; - OnPropertyChanged(nameof(LanguageName)); - } - } - } -} diff --git a/AdamController/Model/Common/BaseModel.cs b/AdamController/Model/Common/BaseModel.cs deleted file mode 100644 index a127691..0000000 --- a/AdamController/Model/Common/BaseModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace AdamController.Model.Common -{ - public class BaseModel : INotifyPropertyChanged - { - #region Event - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - #endregion - } -} diff --git a/AdamController/Model/EditorModel.cs b/AdamController/Model/EditorModel.cs deleted file mode 100644 index 36e5777..0000000 --- a/AdamController/Model/EditorModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -using ICSharpCode.AvalonEdit.CodeCompletion; -using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Editing; -using System; - -namespace AdamController.Model -{ - //TODO Rename this (as Autocomplete or etc) - /*public class EditorModel : ICompletionData - { - public EditorModel(string text) - { - Text = text; - } - - public System.Windows.Media.ImageSource Image => null; - - public string Text { get; private set; } - - // Use this property if you want to show a fancy UIElement in the drop down list. - public object Content => Text; - - public object Description => "Description for " + Text; - - public double Priority { get { return 0; } } - - public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) - { - textArea.Document.Replace(completionSegment, Text); - } - }*/ -} diff --git a/AdamController/Model/WebMessageJsonReceived.cs b/AdamController/Model/WebMessageJsonReceived.cs deleted file mode 100644 index 1d4810a..0000000 --- a/AdamController/Model/WebMessageJsonReceived.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace AdamController.Model -{ - public class WebMessageJsonReceived - { - [JsonProperty("action")] - public string Action { get; set; } - - [JsonProperty("data")] - public string Data { get; set; } - } -} diff --git a/AdamController/Properties/AssemblyInfo.cs b/AdamController/Properties/AssemblyInfo.cs deleted file mode 100644 index 2a3e4b4..0000000 --- a/AdamController/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Resources; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("AdamController")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("AdamController")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.2.4")] -[assembly: AssemblyFileVersion("1.0.2.4")] -[assembly: NeutralResourcesLanguage("")] diff --git a/AdamController/ViewModels/Common/BaseViewModel.cs b/AdamController/ViewModels/Common/BaseViewModel.cs deleted file mode 100644 index 1826dbc..0000000 --- a/AdamController/ViewModels/Common/BaseViewModel.cs +++ /dev/null @@ -1,47 +0,0 @@ -using AdamController.Interface; -using System.Windows; -using System.Windows.Controls; - -namespace AdamController.ViewModels.Common -{ - public abstract class BaseViewModel : BindableBase, IWindowParam - { - #region IWindowParam interface - - /// - /// Window title. - /// - public abstract string WindowTitle { get; } - - /// - /// Default window is modal. Ovverride this to false if window main. - /// - public virtual bool IsModal => true; - - public virtual double Height => 1000; - public virtual double Width => 1400; - - /// - /// Determines whether the window can be resized - /// - public virtual ResizeMode ResizeMode => ResizeMode.CanResize; - public virtual WindowStartupLocation WindowStartupLocation => WindowStartupLocation.CenterScreen; - public virtual CharacterCasing TitleCharacterCasing => CharacterCasing.Normal; - public virtual WindowState WindowState => WindowState.Normal; - - /// - /// This method is executed when the window is closed - /// - public virtual void OnClosed(Window window) - { - if (window == null) - { - return; - } - - window.Close(); - } - - #endregion - } -} diff --git a/AdamController/ViewModels/Common/BindableBase.cs b/AdamController/ViewModels/Common/BindableBase.cs deleted file mode 100644 index 86af9f6..0000000 --- a/AdamController/ViewModels/Common/BindableBase.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq.Expressions; -using System.Runtime.CompilerServices; - -namespace AdamController.ViewModels.Common -{ - public class BindableBase : INotifyPropertyChanged - { - public event PropertyChangedEventHandler PropertyChanged; - - //TODO test how it works - /// - /// Tell bound controls (via WPF binding) to refresh their display. - /// - /// Sample call: this.NotifyPropertyChanged(() => this.IsSelected); - /// where 'this' is derived from - /// and IsSelected is a property. - /// - /// - /// - public void RaisePropertyChanged(Expression> property) - { - LambdaExpression lambda = property; - MemberExpression memberExpression; - - if (lambda.Body is UnaryExpression) - { - UnaryExpression unaryExpression = (UnaryExpression)lambda.Body; - memberExpression = (MemberExpression)unaryExpression.Operand; - } - else - { - memberExpression = (MemberExpression)lambda.Body; - } - - RaisePropertyChanged(memberExpression.Member.Name); - } - - //TODO test how it works - /// - /// Tell bound controls (via WPF binding) to refresh their display. - /// Standard implementation through . - /// - /// - protected virtual void RaisePropertyChanged(string propertyName) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - //TODO test how it works - protected bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) - { - if (EqualityComparer.Default.Equals(storage, value)) - { - return false; - } - - storage = value; - OnPropertyChanged(propertyName); - return true; - } - } -} diff --git a/AdamController/ViewModels/HamburgerMenu/HamburgerMenuItemView.cs b/AdamController/ViewModels/HamburgerMenu/HamburgerMenuItemView.cs deleted file mode 100644 index 50cc323..0000000 --- a/AdamController/ViewModels/HamburgerMenu/HamburgerMenuItemView.cs +++ /dev/null @@ -1,44 +0,0 @@ -using AdamController.ViewModels.Common; -using MahApps.Metro.Controls; - -namespace AdamController.ViewModels.HamburgerMenu -{ - public class HamburgerMenuItemView : BindableBase, IHamburgerMenuItemBase - { - private object _icon; - private object _label; - private object _toolTip; - private bool _isVisible = true; - - public HamburgerMenuItemView(HamburgerMenuView hamburgerMenuView) - { - HamburgerMenuView = hamburgerMenuView; - } - - public HamburgerMenuView HamburgerMenuView { get; } - - public object Icon - { - get => _icon; - set => SetProperty(ref _icon, value); - } - - public object Label - { - get => _label; - set => SetProperty(ref _label, value); - } - - public object ToolTip - { - get => _toolTip; - set => SetProperty(ref _toolTip, value); - } - - public bool IsVisible - { - get => _isVisible; - set => SetProperty(ref _isVisible, value); - } - } -} diff --git a/AdamController/ViewModels/HamburgerMenu/HamburgerMenuView.cs b/AdamController/ViewModels/HamburgerMenu/HamburgerMenuView.cs deleted file mode 100644 index 898d632..0000000 --- a/AdamController/ViewModels/HamburgerMenu/HamburgerMenuView.cs +++ /dev/null @@ -1,67 +0,0 @@ - -using MahApps.Metro.IconPacks; -using System.Collections.ObjectModel; - -namespace AdamController.ViewModels.HamburgerMenu -{ - - public class HamburgerMenuView : MainWindowView - { - private ObservableCollection mMenuItems; - private ObservableCollection mMenuOptionItems; - - public HamburgerMenuView() - { - CreateMenuItems(); - } - - - public void CreateMenuItems() - { - MenuItems = new ObservableCollection - { - new ScratchControlView(this) - { - Icon = new PackIconSimpleIcons() {Kind = PackIconSimpleIconsKind.Scratch }, - Label = "Cкретч", - ToolTip = "Скретч редактор" - }, - new ScriptEditorControlView(this) - { - Icon = new PackIconModern() {Kind = PackIconModernKind.PageEdit}, - Label = "Редактор", - ToolTip = "Редактор скриптов" - }, - new ComputerVisionControlView(this) - { - Icon = new PackIconModern() { Kind = PackIconModernKind.Video }, - Label = "Компьютерное зрение", - ToolTip = "Компьютерное зрение" - } - }; - - MenuOptionItems = new ObservableCollection - { - new VisualSettingsControlView(this) - { - Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.Cog}, - Label = "Настройки", - ToolTip = "Графические настройки приложения" - } - }; - } - - public ObservableCollection MenuItems - { - get => mMenuItems; - set => SetProperty(ref mMenuItems, value); - } - - public ObservableCollection MenuOptionItems - { - get => mMenuOptionItems; - set => SetProperty(ref mMenuOptionItems, value); - } - - } -} diff --git a/AdamController/ViewModels/MainMenuView.cs b/AdamController/ViewModels/MainMenuView.cs deleted file mode 100644 index ecf7035..0000000 --- a/AdamController/ViewModels/MainMenuView.cs +++ /dev/null @@ -1,32 +0,0 @@ -using AdamController.Commands; -using AdamController.Helpers; -using AdamController.Views; -using AdamController.Views.Window; -using System.Windows; - -namespace AdamController.ViewModels -{ - public class MainMenuView - { - - #region Show window - - public static RelayCommand ShowSettingsWindow => new(obj => - { - new WindowShowerHelpers(new SettingsWindow(), new SettingsWindowView()).Show(); - }); - - /*public static RelayCommand ShowNetworkTestWindow => new(obj => - { - new WindowShowerHelpers(new NetworkTestWindow(), new NetworkTestView()).Show(); - });*/ - - #endregion - - public static RelayCommand ExitAppCommand => new(obj => - { - Application.Current.Shutdown(); - }); - - } -} diff --git a/AdamController/ViewModels/MainWindowView.cs b/AdamController/ViewModels/MainWindowView.cs deleted file mode 100644 index cfa0e0a..0000000 --- a/AdamController/ViewModels/MainWindowView.cs +++ /dev/null @@ -1,678 +0,0 @@ -using AdamBlocklyLibrary.Enum; -using AdamController.Commands; -using AdamController.DataSource; -using AdamController.Helpers; -using AdamController.Model; -using AdamController.Properties; -using AdamController.ViewModels.Common; -using AdamController.WebApi.Client.v1; -using MahApps.Metro.IconPacks; -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Reflection; -using System.Windows; -using System.Windows.Media; -using System.Windows.Threading; - -namespace AdamController.ViewModels -{ - public class MainWindowView : BaseViewModel - { - #region Const - - private const string mToolbarStatusClientDisconnected = "Робот Адам: отключен"; - private const string mToolbarStatusClientConnected = "Робот Адам: подключен"; - private const string mToolbarStatusClientReconnected = "Робот Адам: переподключение"; - - private const string mConnectButtonStatusDisconnected = "Подключить"; - private const string mConnectButtonStatusConnected = "Отключить"; - private const string mConnectButtonStatusReconnected = "Подождите"; - - #endregion - - public MainWindowView() - { - ComunicateHelper.OnAdamTcpConnectedEvent += OnTcpConnected; - ComunicateHelper.OnAdamTcpDisconnectedEvent += OnTcpDisconnected; - ComunicateHelper.OnAdamTcpReconnected += OnTcpReconnected; - ComunicateHelper.OnAdamLogServerUdpReceivedEvent += ComunicateHelperOnAdamUdpReceived; - - - InitAction(); - - if (Settings.Default.AutoStartTcpConnect) - { - ConnectButtonComand.Execute(null); - } - else - { - //init fields if autorun off - TextOnConnectFlayotButton = mConnectButtonStatusDisconnected; - TextOnStatusConnectToolbar = mToolbarStatusClientDisconnected; - - ConnectIcon = PackIconModernKind.Connect; - IconOnConnectFlayoutButton = PackIconMaterialKind.RobotDead; - } - } - - private void ComunicateHelperOnAdamUdpReceived(string message) - { - try - { - SyslogMessage syslogMessage = SyslogParseMessage.Parse(message); - CompileLogStatusBar = $"{syslogMessage.TimeStamp:T} {syslogMessage.Message}"; - } - catch(Exception ex) - { - CompileLogStatusBar = $"Error reading udp log with exception {ex.Message}"; - } - } - - #region SelectedPageIndex - - private int selectedPageIndex = 0; - public int SelectedPageIndex - { - get => selectedPageIndex; - set - { - if(value == selectedPageIndex) - { - return; - } - - selectedPageIndex = value; - GetSelectedPageIndex = value; - - OnPropertyChanged(nameof(SelectedPageIndex)); - } - } - - - public static int GetSelectedPageIndex { get; private set; } - - #endregion - - #region Events TCP/IP clients - - private void OnTcpDisconnected() - { - //если центр уведомлений закрыт, обновляем счетчик уведомлений - if(!NotificationFlayoutsIsOpen && Settings.Default.IsMessageShowOnAbortMainConnection) - { - BadgeCounter++; - FailConnectMessageVisibility = Visibility.Visible; - } - - TextOnConnectFlayotButton = mConnectButtonStatusDisconnected; - TextOnStatusConnectToolbar = mToolbarStatusClientDisconnected; - - ConnectIcon = PackIconModernKind.Connect; - IconOnConnectFlayoutButton = PackIconMaterialKind.RobotDead; - } - - private void OnTcpConnected() - { - _ = BaseApi.StopPythonExecute(); - - TextOnConnectFlayotButton = mConnectButtonStatusConnected; - TextOnStatusConnectToolbar = mToolbarStatusClientConnected; - - ConnectIcon = PackIconModernKind.Disconnect; - IconOnConnectFlayoutButton = PackIconMaterialKind.Robot; - } - - private void OnTcpReconnected(int reconnectCount) - { - TextOnConnectFlayotButton = $"{mConnectButtonStatusReconnected} {reconnectCount}"; - TextOnStatusConnectToolbar = $"{mToolbarStatusClientReconnected} {reconnectCount}"; - - ConnectIcon = PackIconModernKind.TransitConnectionDeparture; - IconOnConnectFlayoutButton = PackIconMaterialKind.RobotConfused; - } - - #endregion - - #region InitAction - - private void InitAction() - { - //move to page with selected index - if(ScratchControlView.SetSelectedPageIndex == null) - { - ScratchControlView.SetSelectedPageIndex = new Action(index => SelectedPageIndex = index); - } - - //open flayout page - if (VisualSettingsControlView.OpenAdvancedBlocklySettings == null) - { - VisualSettingsControlView.OpenAdvancedBlocklySettings = new Action(open => AdvancedBlocklySettingsFlayoutsIsOpen = open); - } - - //change toolbox lang settings - if (VisualSettingsControlView.SetToolboxLanguage == null) - { - VisualSettingsControlView.SetToolboxLanguage = new Action(model => SelectedBlocklyToolboxLanguage = model); - } - - //settings blockly theme - if (VisualSettingsControlView.SetBlocklyThemeAndGridColor == null) - { - VisualSettingsControlView.SetBlocklyThemeAndGridColor = new Action - (theme => - { - SelectedBlocklyTheme = theme; - - if (Settings.Default.ChangeGridColorSwitchToggleSwitchState) return; - - SelectGridColorDependingSelectedTheme(theme.BlocklyTheme); - }); - } - - if (VisualSettingsControlView.ChangeNotificationOpacity == null) - { - VisualSettingsControlView.ChangeNotificationOpacity = new Action - (opacity => - { - Settings.Default.NotificationOpacity = opacity; - NotificationOpacity = opacity; - }); - } - - //send message to status app log - if (ScratchControlView.AppLogStatusBarAction == null) - { - ScratchControlView.AppLogStatusBarAction = new Action(log => AppLogStatusBar = log); - } - - //send message to status complile log - if (ScratchControlView.CompileLogStatusBarAction == null) - { - ScratchControlView.CompileLogStatusBarAction = new Action(log => CompileLogStatusBar = log); - } - - //start process ring - if (ScratchControlView.ProgressRingStartAction == null) - { - ScratchControlView.ProgressRingStartAction = new Action(start => ProgressRingStart = start); - } - - if(ScriptEditorControlView.AppLogStatusBarAction == null) - { - ScriptEditorControlView.AppLogStatusBarAction = new Action(log => AppLogStatusBar = log); - } - } - - #endregion - - #region AppStatusBar field - - private string appLogStatusBar = "Лог приложения"; - public string AppLogStatusBar - { - get => appLogStatusBar; - set - { - if(value == appLogStatusBar) - { - return; - } - - appLogStatusBar = value; - OnPropertyChanged(nameof(AppLogStatusBar)); - } - } - - #endregion - - #region CompileLogStatusBar field - - private string compileLogStatusBar = "Лог робота"; - public string CompileLogStatusBar - { - get => compileLogStatusBar; - set - { - if(value == compileLogStatusBar) - { - return; - } - - compileLogStatusBar = value; - OnPropertyChanged(nameof(CompileLogStatusBar)); - } - } - - #endregion - - #region ProgressRing field - - private bool progressRingStart = false; - public bool ProgressRingStart - { - get => progressRingStart; - set - { - if (value == progressRingStart) return; - - progressRingStart = value; - OnPropertyChanged(nameof(ProgressRingStart)); - } - } - - - #endregion - - #region BlocklyTheme Settings - - public static ObservableCollection BlocklyThemes { get; private set; } = ThemesCollection.BlocklyThemes; - - private BlocklyThemeModel selectedBlocklyTheme = BlocklyThemes.FirstOrDefault(x => x.BlocklyTheme == Properties.Settings.Default.BlocklyTheme); - public BlocklyThemeModel SelectedBlocklyTheme - { - get => selectedBlocklyTheme; - set - { - if (value == selectedBlocklyTheme) - { - return; - } - - selectedBlocklyTheme = value; - OnPropertyChanged(nameof(SelectedBlocklyTheme)); - - Settings.Default.BlocklyTheme = selectedBlocklyTheme.BlocklyTheme; - - if (Settings.Default.ChangeGridColorSwitchToggleSwitchState) return; - SelectGridColorDependingSelectedTheme(SelectedBlocklyTheme.BlocklyTheme); - } - } - - #endregion - - #region BlocklyToolboxLanguage Settings - - public static ObservableCollection BlocklyLanguageCollection { get; private set; } = LanguagesCollection.BlocklyLanguageCollection; - - private BlocklyLanguageModel selectedBlocklyToolboxLanguage = BlocklyLanguageCollection.FirstOrDefault(x => x.BlocklyLanguage == Properties.Settings.Default.BlocklyToolboxLanguage); - public BlocklyLanguageModel SelectedBlocklyToolboxLanguage - { - get => selectedBlocklyToolboxLanguage; - set - { - if (value == selectedBlocklyToolboxLanguage) - { - return; - } - - selectedBlocklyToolboxLanguage = value; - OnPropertyChanged(nameof(SelectedBlocklyToolboxLanguage)); - - Properties.Settings.Default.BlocklyToolboxLanguage = selectedBlocklyToolboxLanguage.BlocklyLanguage; - } - } - - #endregion - - #region BlocklyGridColour settings - - private Color? selectedBlocklyGridColour = MahApps.Metro.Controls.ColorHelper.ColorFromString(Properties.Settings.Default.BlocklyGridColour); - public Color? SelectedBlocklyGridColour - { - get => selectedBlocklyGridColour; - set - { - if (value == selectedBlocklyGridColour) - { - return; - } - - selectedBlocklyGridColour = value; - OnPropertyChanged(nameof(SelectedBlocklyGridColour)); - - Settings.Default.BlocklyGridColour = selectedBlocklyGridColour.ToString(); - } - } - - #endregion - - #region Opened flayout page - - #region Open BlocklySettingsFlayots - - private bool advancedBlocklySettingsFlayoutsIsOpen; - public bool AdvancedBlocklySettingsFlayoutsIsOpen - { - get { return advancedBlocklySettingsFlayoutsIsOpen; } - set - { - if (value == advancedBlocklySettingsFlayoutsIsOpen) return; - - advancedBlocklySettingsFlayoutsIsOpen = value; - OnPropertyChanged(nameof(AdvancedBlocklySettingsFlayoutsIsOpen)); - } - } - - #endregion - - #region Open NotificationFlayouts - - private bool notificationFlayoutsIsOpen; - public bool NotificationFlayoutsIsOpen - { - get { return notificationFlayoutsIsOpen; } - set - { - if (value == notificationFlayoutsIsOpen) return; - - notificationFlayoutsIsOpen = value; - OnPropertyChanged(nameof(NotificationFlayoutsIsOpen)); - } - } - - #endregion - - #endregion - - #region NotificationMessage Visiblity - - private Visibility noNewNotificationMessageVisibility = Visibility.Visible; - public Visibility NoNewNotificationMessageVisibility - { - get => noNewNotificationMessageVisibility; - set - { - if (value == noNewNotificationMessageVisibility) return; - - noNewNotificationMessageVisibility = value; - OnPropertyChanged(nameof(NoNewNotificationMessageVisibility)); - - } - } - - private Visibility failConnectMessageVisibility = Visibility.Collapsed; - public Visibility FailConnectMessageVisibility - { - get => failConnectMessageVisibility; - set - { - if (value == failConnectMessageVisibility) return; - - if (value == Visibility.Visible) - NoNewNotificationMessageVisibility = Visibility.Collapsed; - if (value == Visibility.Collapsed) - NoNewNotificationMessageVisibility = Visibility.Visible; - - failConnectMessageVisibility = value; - OnPropertyChanged(nameof(FailConnectMessageVisibility)); - } - } - - #endregion - - #region NotificationBadge - - private int badgeCounter = 0; - private int BadgeCounter - { - get => badgeCounter; - set - { - if (value == badgeCounter) return; - if (value == 0) - { - badgeCounter = value; - NotificationBadge = ""; - return; - } - - badgeCounter = value; - - NotificationBadge = $"{BadgeCounter}"; - } - } - - private string notificationBadge; - public string NotificationBadge - { - get => notificationBadge; - set - { - if (value == notificationBadge) return; - - notificationBadge = value; - OnPropertyChanged(nameof(NotificationBadge)); - } - } - - private void ClearNotification() - { - BadgeCounter = 0; - FailConnectMessageVisibility = Visibility.Collapsed; - } - - #endregion - - #region NotificationOpacity - - private double notificationOpacity = Settings.Default.NotificationOpacity; - public double NotificationOpacity - { - get => notificationOpacity; - set - { - if (value == notificationOpacity) return; - - notificationOpacity = value; - - OnPropertyChanged(nameof(NotificationOpacity)); - } - } - - #endregion - - #region Connect/Disconnect button (Flayouts) - - private string textOnConnectFlayotButton; - public string TextOnConnectFlayotButton - { - get => textOnConnectFlayotButton; - set - { - if (value == textOnConnectFlayotButton) return; - - textOnConnectFlayotButton = value; - OnPropertyChanged(nameof(TextOnConnectFlayotButton)); - } - } - - private PackIconMaterialKind iconOnConnectFlayoutButton; - public PackIconMaterialKind IconOnConnectFlayoutButton - { - get => iconOnConnectFlayoutButton; - set - { - if (value == iconOnConnectFlayoutButton) return; - - iconOnConnectFlayoutButton = value; - OnPropertyChanged(nameof(IconOnConnectFlayoutButton)); - } - } - - #endregion - - #region Connect/Disconnect toolbar - - private string textOnStatusConnectToolbar; - public string TextOnStatusConnectToolbar - { - get => textOnStatusConnectToolbar; - set - { - if (value == textOnStatusConnectToolbar) return; - - textOnStatusConnectToolbar = value; - OnPropertyChanged(nameof(TextOnStatusConnectToolbar)); - } - } - - private PackIconModernKind connectIcon; - public PackIconModernKind ConnectIcon - { - get => connectIcon; - set - { - if (value == connectIcon) return; - - connectIcon = value; - OnPropertyChanged(nameof(ConnectIcon)); - } - } - - private RelayCommand connectButtonComand; - public RelayCommand ConnectButtonComand => connectButtonComand ??= new RelayCommand(async obj => - { - bool isNotifyButton = (string)obj == "IsNotificationButtonCalling"; - if (isNotifyButton) - { - ClearNotification(); - NotificationFlayoutsIsOpen = false; - } - - await Dispatcher.Yield(DispatcherPriority.Normal); - - - if (ComunicateHelper.TcpClientIsConnected) - { - ComunicateHelper.DisconnectAll(); - return; - } - - if (!ComunicateHelper.TcpClientIsConnected) - { - ComunicateHelper.ConnectAllAsync(); - return; - } - }); - - #endregion - - #region SelectMainTheme - - private void SelectGridColorDependingSelectedTheme(BlocklyTheme theme) - { - switch (theme) - { - case BlocklyTheme.Dark: - { - SelectedBlocklyGridColour = Colors.White; - break; - } - case BlocklyTheme.Classic: - { - SelectedBlocklyGridColour = Colors.Black; - break; - } - default: - { - SelectedBlocklyGridColour = Colors.Black; - break; - } - } - } - - #endregion - - #region Commands - - private RelayCommand clearNotifications; - public RelayCommand ClearNotifications => clearNotifications ??= new RelayCommand(obj => - { - ClearNotification(); - }); - - private RelayCommand closeNotificationFlayots; - public RelayCommand CloseNotificationFlayots => closeNotificationFlayots ??= new RelayCommand(obj => - { - NotificationFlayoutsIsOpen = false; - }); - - private RelayCommand openNotificationPanel; - public RelayCommand OpenNotificationPanel => openNotificationPanel ??= new RelayCommand(obj => - { - NotificationFlayoutsIsOpen = !NotificationFlayoutsIsOpen; - }); - - private RelayCommand changeGridColorToggleSwitchCommand; - public RelayCommand ChangeGridColorToggleSwitchCommand => changeGridColorToggleSwitchCommand ??= new RelayCommand(obj => - { - bool toogleSwitchState = obj; - - if (toogleSwitchState) return; - - SelectGridColorDependingSelectedTheme(SelectedBlocklyTheme.BlocklyTheme); - }); - - private RelayCommand changeSpacingToggleSwitchCommand; - public RelayCommand ChangeSpacingToggleSwitchCommand => changeSpacingToggleSwitchCommand ??= new RelayCommand(obj => - { - bool toogleSwitchState = obj; - - if (toogleSwitchState) return; - - Settings.Default.BlocklyGridSpacing = 20; - }); - - private RelayCommand enableShowGridCommand; - public RelayCommand EnableShowGridCommand => enableShowGridCommand ??= new RelayCommand(obj => - { - Settings.Default.BlocklyShowGrid = true; - }); - - private RelayCommand changeBlocklyThemeToogleSwitchCommand; - public RelayCommand ChangeBlocklyThemeToogleSwitchCommand => changeBlocklyThemeToogleSwitchCommand ??= new RelayCommand(obj => - { - bool toogleSwitchState = obj; - - if (toogleSwitchState) return; - - if (Settings.Default.BaseTheme == "Dark") - { - SelectedBlocklyTheme = BlocklyThemes.FirstOrDefault(x => x.BlocklyTheme == BlocklyTheme.Dark); - } - else if (Settings.Default.BaseTheme == "Light") - { - SelectedBlocklyTheme = BlocklyThemes.FirstOrDefault(x => x.BlocklyTheme == BlocklyTheme.Classic); - } - }); - - private RelayCommand changeToolboxLanguageToggleSwitchCommand; - public RelayCommand ChangeToolboxLanguageToggleSwitchCommand => changeToolboxLanguageToggleSwitchCommand ??= new RelayCommand(obj => - { - bool toogleSwitchState = obj; - - if (toogleSwitchState) return; - - SelectedBlocklyToolboxLanguage = BlocklyLanguageCollection.FirstOrDefault(x => x.BlocklyLanguage == Settings.Default.BlocklyWorkspaceLanguage); - - }); - - #endregion - - #region IWindowParam - - public override string WindowTitle => $"Adam IDE {Assembly.GetExecutingAssembly().GetName().Version}"; - public override bool IsModal => false; - public override WindowState WindowState => WindowState.Maximized; - - public override void OnClosed(Window window) - { - ComunicateHelper.DisconnectAllAndDestroy(); - - base.OnClosed(window); - } - - #endregion - } -} diff --git a/AdamController/ViewModels/MainWindowViewModel.cs b/AdamController/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..ca485f7 --- /dev/null +++ b/AdamController/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,303 @@ +using AdamController.Controls.CustomControls.Services; +using AdamController.Controls.Enums; +using AdamController.Core; +using AdamController.Core.Extensions; +using AdamController.Core.Model; +using AdamController.Core.Mvvm; +using AdamController.Core.Properties; +using AdamController.Services.Interfaces; +using Prism.Commands; +using Prism.Regions; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Windows; + +namespace AdamController.ViewModels +{ + public class MainWindowViewModel : ViewModelBase + { + #region DelegateCommands + + public DelegateCommand ShowRegionCommand { get; private set; } + public DelegateCommand MoveSplitterDelegateCommand { get; private set; } + + #endregion + + #region Services + + public IRegionManager RegionManager { get; } + private readonly ISubRegionChangeAwareService mSubRegionChangeAwareService; + private readonly IStatusBarNotificationDeliveryService mStatusBarNotification; + private readonly ICommunicationProviderService mCommunicationProviderService; + private readonly IFolderManagmentService mFolderManagment; + private readonly IWebApiService mWebApiService; + private readonly IAvalonEditService mAvalonEditService; + private readonly IThemeManagerService mThemeManager; + private readonly ICultureProvider mCultureProvider; + private readonly IControlHelper mControlHelper; + #endregion + + #region ~ + + public MainWindowViewModel(IRegionManager regionManager, ISubRegionChangeAwareService subRegionChangeAwareService, IStatusBarNotificationDeliveryService statusBarNotification, + ICommunicationProviderService communicationProviderService, IFolderManagmentService folderManagment, IWebApiService webApiService, + IAvalonEditService avalonEditService, IThemeManagerService themeManager, ICultureProvider cultureProvider, IControlHelper controlHelper) + { + RegionManager = regionManager; + mWebApiService = webApiService; + mSubRegionChangeAwareService = subRegionChangeAwareService; + mStatusBarNotification = statusBarNotification; + mCommunicationProviderService = communicationProviderService; + mFolderManagment = folderManagment; + mAvalonEditService = avalonEditService; + mThemeManager = themeManager; + mCultureProvider = cultureProvider; + mControlHelper = controlHelper; + + ShowRegionCommand = new DelegateCommand(ShowRegion); + MoveSplitterDelegateCommand = new DelegateCommand(MoveSplitter, MoveSplitterCanExecute); + + Subscribe(); + } + + #endregion + + #region Public fields + + public string WindowTitle => $"Adam IDE {Assembly.GetExecutingAssembly().GetName().Version}"; + + /// + /// -1 is not selected + /// + private int hamburgerMenuSelectedIndex = -1; + public int HamburgerMenuSelectedIndex + { + get { return hamburgerMenuSelectedIndex; } + set + { + bool isNewValue = SetProperty(ref hamburgerMenuSelectedIndex, value); + + if(isNewValue) + MoveSplitterDelegateCommand.RaiseCanExecuteChanged(); + } + } + + /// + /// -1 is not selected + /// + private int hamburgerMenuSelectedOptionsIndex = -1; + + public int HamburgerMenuSelectedOptionsIndex + { + get { return hamburgerMenuSelectedOptionsIndex; } + + set + { + SetProperty(ref hamburgerMenuSelectedOptionsIndex, value); + } + } + + #endregion + + #region DelegateCommands methods + + private void MoveSplitter(string commandArg) + { + BlocklyViewMode currentViewMode = mControlHelper.CurrentBlocklyViewMode; + + if (commandArg == "Left") + { + if (currentViewMode == BlocklyViewMode.FullScreen) + mControlHelper.CurrentBlocklyViewMode = BlocklyViewMode.MiddleScreen; + + if (currentViewMode == BlocklyViewMode.MiddleScreen) + mControlHelper.CurrentBlocklyViewMode = BlocklyViewMode.Hidden; + } + + if (commandArg == "Right") + { + if (currentViewMode == BlocklyViewMode.Hidden) + mControlHelper.CurrentBlocklyViewMode = BlocklyViewMode.MiddleScreen; + + if (currentViewMode == BlocklyViewMode.MiddleScreen) + mControlHelper.CurrentBlocklyViewMode = BlocklyViewMode.FullScreen; + } + } + + private bool MoveSplitterCanExecute(string arg) + { + return HamburgerMenuSelectedIndex == 0; + //return true; + //bool isPythonCodeNotExecute = !IsPythonCodeExecute; + //return isPythonCodeNotExecute; + } + + #endregion + + #region Private methods + + private void ChangeSelectedIndexByRegionName(string subRegionName) + { + switch (subRegionName) + { + case SubRegionNames.SubRegionScratch: + HamburgerMenuSelectedIndex = 0; + break; + case SubRegionNames.SubRegionComputerVisionControl: + HamburgerMenuSelectedIndex = 1; + break; + case SubRegionNames.SubRegionVisualSettings: + HamburgerMenuSelectedOptionsIndex = 0; + break; + } + } + + private void ShowRegion(string subRegionName) + { + switch (subRegionName) + { + case SubRegionNames.SubRegionScratch: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionScratch); + break; + case SubRegionNames.SubRegionComputerVisionControl: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionComputerVisionControl); + break; + case SubRegionNames.SubRegionVisualSettings: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionVisualSettings); + break; + } + } + + /// + /// starts when the application is first launched + /// + private void SaveFolderPathToSettings() + { + if (string.IsNullOrEmpty(Settings.Default.SavedUserWorkspaceFolderPath)) + { + Settings.Default.SavedUserWorkspaceFolderPath = mFolderManagment.SavedWorkspaceDocumentsDir; + } + + if (string.IsNullOrEmpty(Settings.Default.SavedUserScriptsFolderPath)) + { + Settings.Default.SavedUserScriptsFolderPath = mFolderManagment.SavedUserScriptsDocumentsDir; + } + } + + private void ParseSyslogMessage(string message) + { + try + { + SyslogMessageModel syslogMessage = message.Parse(); + mStatusBarNotification.CompileLogMessage = $"{syslogMessage.TimeStamp:T} {syslogMessage.Message}"; + } + catch + { + // If you couldn't read the message, it's okay, no one needs to know about it. + } + } + + /// + /// Register highlighting for AvalonEdit. You need to call before loading the regions + /// + private void LoadCustomAvalonEditHighlighting() + { + mAvalonEditService.RegisterHighlighting(HighlightingName.AdamPython, Resource.AdamPython); + } + + private void LoadAppTheme() + { + var appThemeName = Settings.Default.AppThemeName; + mThemeManager.ChangeAppTheme(appThemeName); + } + + private void LoadDefaultCultureInfo() + { + CultureInfo lastLoadLanguage = mCultureProvider.SupportAppCultures.FirstOrDefault(x => x.Name == Settings.Default.AppLanguage); + lastLoadLanguage ??= mCultureProvider.SupportAppCultures.FirstOrDefault(); + + mCultureProvider.ChangeAppCulture(lastLoadLanguage); + } + + #endregion + + #region Subscriptions + + /// + /// #20 + /// + private void Subscribe() + { + mSubRegionChangeAwareService.RaiseSubRegionChangeEvent += RaiseSubRegionChangeEvent; + mCommunicationProviderService.RaiseTcpServiceCientConnectedEvent += RaiseTcpServiceCientConnectedEvent; + mCommunicationProviderService.RaiseUdpServiceServerReceivedEvent += RaiseUdpServiceServerReceivedEvent; + Application.Current.MainWindow.Loaded += MainWindowLoaded; + } + + /// + /// #20 + /// + private void Unsubscribe() + { + mSubRegionChangeAwareService.RaiseSubRegionChangeEvent -= RaiseSubRegionChangeEvent; + mCommunicationProviderService.RaiseTcpServiceCientConnectedEvent -= RaiseTcpServiceCientConnectedEvent; + mCommunicationProviderService.RaiseUdpServiceServerReceivedEvent -= RaiseUdpServiceServerReceivedEvent; + Application.Current.MainWindow.Loaded -= MainWindowLoaded; + } + + #endregion + + #region Event methods + + /// + /// Load default region at startup + /// Need to call it after loading the main window + /// + private void MainWindowLoaded(object sender, RoutedEventArgs e) + { + LoadDefaultCultureInfo(); + + if (Settings.Default.CreateUserDirrectory) + { + mFolderManagment.CreateAppDataFolder(); + SaveFolderPathToSettings(); + } + + + LoadCustomAvalonEditHighlighting(); + LoadAppTheme(); + + ShowRegionCommand.Execute(SubRegionNames.SubRegionScratch); + + if (Settings.Default.AutoStartTcpConnect) + mCommunicationProviderService.ConnectAllAsync(); + } + + /// + /// Changes the selected section in the hamburger menu + /// + private void RaiseSubRegionChangeEvent(object sender) + { + var changeRegionName = mSubRegionChangeAwareService.InsideRegionNavigationRequestName; + ChangeSelectedIndexByRegionName(changeRegionName); + } + + /// + /// It is not clear where to put this, so it will not get lost here. + /// + /// Stops a remotely executed script that may have been executing before the connection was lost. + /// + private void RaiseTcpServiceCientConnectedEvent(object sender) + { + mWebApiService.StopPythonExecute(); + } + + private void RaiseUdpServiceServerReceivedEvent(object sender, string message) + { + ParseSyslogMessage(message); + } + + #endregion + } +} diff --git a/AdamController/ViewModels/MetroDialogView.cs b/AdamController/ViewModels/MetroDialogView.cs deleted file mode 100644 index 98e128e..0000000 --- a/AdamController/ViewModels/MetroDialogView.cs +++ /dev/null @@ -1,148 +0,0 @@ -using AdamController.Commands; -using MessageDialogManagerLib; -using System; -using System.Threading.Tasks; - -namespace AdamController.ViewModels -{ - [Obsolete("Use it as example")] - public class MetroDialogView - { - private readonly IMessageDialogManager IDialogManager; - - public MetroDialogView(IMessageDialogManager messageDialogManager) - { - IDialogManager = messageDialogManager; - ShowFolderBrowserSingleCommand = new RelayCommand(obj => ShowFolderBrowserSingleCommandExecute(), obj => ShowFolderBrowserSingleCommandCanExecute()); - ShowFileBrowserSingleCommand = new RelayCommand(obj => ShowFileBrowserSingleCommandExecute(), obj => ShowFileBrowserSingleCommandCanExecute()); - ShowFolderBrowserMultipleCommand = new RelayCommand(obj => ShowFolderBrowserMultipleCommandExecute(), obj => ShowFolderBrowserMultipleCommandCanExecute()); - ShowFileBrowserMultipleCommand = new RelayCommand(obj => ShowFileBrowserMultipleCommandExecute(), obj => ShowFileBrowserMultipleCommandCanExecute()); - ShowInfoDialogCommand = new RelayCommand(obj => ShowInfoDialogCommandExecute(), obj => ShowInfoDialogCommandCanExecute()); - ShowProgressCommand = new RelayCommand(obj => ShowProgressCommandExecute(), obj => ShowProgressCommandCanExecute()); - ShowSaveFileDialogCommand = new RelayCommand(obj => ShowSaveFileDialogCommandExecute(), obj => ShowSaveFileDialogCommandCanExecute()); - - - } - - public static Action AppLogStatusBarAction { get; set; } - public RelayCommand ShowFolderBrowserSingleCommand { get; private set; } - public RelayCommand ShowFileBrowserSingleCommand { get; private set; } - public RelayCommand ShowFolderBrowserMultipleCommand { get; private set; } - public RelayCommand ShowFileBrowserMultipleCommand { get; private set; } - public RelayCommand ShowInfoDialogCommand { get; private set; } - public RelayCommand ShowProgressCommand { get; private set; } - public RelayCommand ShowSaveFileDialogCommand { get; private set; } - - private bool ShowFolderBrowserSingleCommandCanExecute() - { - return true; - } - private async void ShowFolderBrowserSingleCommandExecute() - { - if (IDialogManager.ShowFolderBrowser("Select a folder", "")) - await IDialogManager.ShowInfoDialogAsync("Folder Selected", IDialogManager.FolderPath); - else - await IDialogManager.ShowInfoDialogAsync("No folder has been selected", IDialogManager.FolderPath); - } - - private bool ShowFileBrowserSingleCommandCanExecute() - { - return true; - } - - private void ShowFileBrowserSingleCommandExecute() - { - if (IDialogManager.ShowFileBrowser("Select a file", "", "*.* | *.*")) - - AppLogStatusBarAction($"Файл сохранен {IDialogManager.FilePath}"); - else - AppLogStatusBarAction($"Файл не сохранен {IDialogManager.FilePath}"); - } - - private bool ShowFolderBrowserMultipleCommandCanExecute() - { - return true; - } - - private async void ShowFolderBrowserMultipleCommandExecute() - { - if (IDialogManager.ShowFolderBrowser("Select a folder", "", true)) - { - string selected = string.Empty; - foreach (var folder in IDialogManager.FolderPaths) - { - selected += $"{folder}\n"; - } - await IDialogManager.ShowInfoDialogAsync("Folders Selected", selected); - } - else - await IDialogManager.ShowInfoDialogAsync("No folder has been selected", IDialogManager.FolderPath); - } - - private bool ShowFileBrowserMultipleCommandCanExecute() - { - return true; - } - - private async void ShowFileBrowserMultipleCommandExecute() - { - if (IDialogManager.ShowFileBrowser("Select a file", "", "*.* | *.*", true)) - { - string selected = string.Empty; - foreach (string file in IDialogManager.FilePaths) - { - selected += $"{file}\n"; - } - await IDialogManager.ShowInfoDialogAsync("File Selected", selected); - } - else - await IDialogManager.ShowInfoDialogAsync("No file has been selected", IDialogManager.FilePath); - } - - private async void ShowInfoDialogCommandExecute() - { - await IDialogManager.ShowInfoDialogAsync("Info dialog", "This is a info dialog example"); - } - - private bool ShowInfoDialogCommandCanExecute() - { - return true; - } - - - private bool ShowProgressCommandCanExecute() - { - return true; - } - - private async void ShowProgressCommandExecute() - { - await IDialogManager.ShowProgress("Progress", "This is a progress dialog"); - await DoSomeWorkAsync(); - await IDialogManager.CloseProgress(); - } - - private async Task DoSomeWorkAsync() - { - for (int i = 0; i < 10; i++) - { - await Task.Delay(1000); - IDialogManager.UpdateProgress(i * 10); - IDialogManager.UpdateMessageProgress($"Step {i} done"); - } - } - - private bool ShowSaveFileDialogCommandCanExecute() - { - return true; - } - - private void ShowSaveFileDialogCommandExecute() - { - if (IDialogManager.ShowSaveFileDialog("Save a file", "", "fileName", ".txt", "Text documents (.txt)|*.txt")) - AppLogStatusBarAction("Файл сохранен"); - else - AppLogStatusBarAction("Файл не сохранен"); - } - } -} diff --git a/AdamController/ViewModels/NetworkTestView.cs b/AdamController/ViewModels/NetworkTestView.cs deleted file mode 100644 index fd11db7..0000000 --- a/AdamController/ViewModels/NetworkTestView.cs +++ /dev/null @@ -1,1306 +0,0 @@ -using AdamController.Commands; -using AdamController.Helpers; -using AdamController.ViewModels.Common; -using AdamController.WebApi.Client.v1; -using AdamController.WebApi.Client.v1.RequestModel; -using MahApps.Metro.IconPacks; -using MessageDialogManagerLib; -using NetCoreServer; -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Threading; - -namespace AdamController.ViewModels -{ - public class NetworkTestView : BaseViewModel - { - #region Const - - private const string mClientDisconnected = "Статус тестового сервера: отключен"; - private const string mClientConnected = "Статус тестового сервера: подключен"; - private const string mClientReconnected = "Статус тестового сервера: переподключение"; - - private const string mTcpTestClientStatusNotRunning = "TCP Round-Trip тест: не запущен"; - private const string mTcpTestClientStatusRunning = "TCP Round-Trip тест: запущен"; - private const string mUdpTestClientStatusNotRunning = "UDP Round-Trip тест: не запущен"; - private const string mUdpTestClientStatusRunning = "UDP Round-Trip тест: запущен"; - - #endregion - - private readonly ComunicateBenchmarkHelper mComunicateTestHelper; - private readonly IMessageDialogManager IDialogManager; - - #region ~ - - public NetworkTestView() - { - SendApiComunicateCommand(ServerCommand.Start); - - mComunicateTestHelper = ComunicateBenchmarkHelper.Instance; - IDialogManager = new MessageDialogManagerMahapps(Application.Current); - - ComunicateBenchmarkHelper.OnTcpConnected += OnTcpConnected; - ComunicateBenchmarkHelper.OnTcpDisconnected += OnTcpDisconnected; - ComunicateBenchmarkHelper.OnTcpReconnected += OnTcpReconnected; - - ClearTcpResultField(); - TcpStatusBarManager(false); - - ClearUdpResultField(); - UdpStatusBarManager(false); - - if (Properties.Settings.Default.AutoStartTestTcpConnect) - { - ConnectButtonComand.Execute(null); - } - else - { - //init fields if autorun off - OnTcpDisconnected(); - } - } - - #endregion - - #region UI behavior - - //added to activate the reset button, after publishing the results, but does not work - //activates the window when disconnect, reconnect, connect - //if you fix the background of the connect button when the window is out of focus, you can delete it - //can be removed during refactoring - private bool networkWindowActivated; - public bool NetworkWindowActivated - { - get => networkWindowActivated; - set - { - if (value == networkWindowActivated) return; - - networkWindowActivated = value; - OnPropertyChanged(nameof(NetworkWindowActivated)); - - } - } - - #endregion - - #region Tcp/ip event test client method - - private void OnTcpDisconnected() - { - IsTcpClientConnected = false; - TextOnStatusConnectButton = mClientDisconnected; - ReconnectProgressRing = false; - ConnectIcon = PackIconModernKind.Connect; - NetworkWindowActivated = true; - } - - private void OnTcpConnected() - { - IsTcpClientConnected = true; - TextOnStatusConnectButton = mClientConnected; - ReconnectProgressRing = false; - ConnectIcon = PackIconModernKind.Disconnect; - NetworkWindowActivated = true; - } - - private void OnTcpReconnected(int reconnectCount) - { - IsTcpClientConnected = null; - TextOnStatusConnectButton = $"{mClientReconnected} {reconnectCount}"; - ReconnectProgressRing = true; - ConnectIcon = PackIconModernKind.TransitConnectionDeparture; - NetworkWindowActivated = true; - } - - #endregion - - #region IsTcpClientConnected - - private bool? isTcpClientConnected; - /// - /// The field determines the existence of a connection to the test server - /// null - the state of the reconnect - /// true - connection - /// false - disconnection - /// - public bool? IsTcpClientConnected - { - get => isTcpClientConnected; - set - { - if (value == isTcpClientConnected) return; - - isTcpClientConnected = value; - OnPropertyChanged(nameof(IsTcpClientConnected)); - } - } - - #endregion - - #region Publish result counter - - #region TCP - - private int publishTcpResultCount; - public int PublishTcpResultCount - { - get => publishTcpResultCount; - set - { - if (value == publishTcpResultCount) return; - publishTcpResultCount = value; - - OnPropertyChanged(nameof(PublishTcpResultCount)); - } - } - - #endregion - - #region UDP - - private int publishUdpResultCount; - public int PublishUdpResultCount - { - get => publishUdpResultCount; - set - { - if (value == publishUdpResultCount) return; - publishUdpResultCount = value; - - OnPropertyChanged(nameof(PublishUdpResultCount)); - } - } - - #endregion - - #endregion - - #region Start test time field - - #region TCP - - private string startTcpTestTime; - public string StartTcpTestTime - { - get => startTcpTestTime; - set - { - if (value == startTcpTestTime) return; - - startTcpTestTime = value; - OnPropertyChanged(nameof(StartTcpTestTime)); - } - } - - #endregion - - #region UDP - - private string startUdpTestTime; - public string StartUdpTestTime - { - get => startUdpTestTime; - set - { - if (value == startUdpTestTime) return; - - startUdpTestTime = value; - OnPropertyChanged(nameof(StartUdpTestTime)); - } - } - - #endregion - - #endregion - - #region Finish test time field - - #region TCP - - private string finishTcpTestTime; - public string FinishTcpTestTime - { - get => finishTcpTestTime; - set - { - if (value == finishTcpTestTime) return; - - finishTcpTestTime = value; - OnPropertyChanged(nameof(FinishTcpTestTime)); - } - } - - #endregion - - #region UDP - - private string finishUdpTestTime; - public string FinishUdpTestTime - { - get => finishUdpTestTime; - set - { - if (value == finishUdpTestTime) return; - - finishUdpTestTime = value; - OnPropertyChanged(nameof(FinishUdpTestTime)); - } - } - - #endregion - - #region TotalTimeTest field - - #region TCP - - private string totalTimeTcpTest; - public string TotalTimeTcpTest - { - get => totalTimeTcpTest; - private set - { - if (value == totalTimeTcpTest) return; - - totalTimeTcpTest = value; - OnPropertyChanged(nameof(TotalTimeTcpTest)); - } - } - - #endregion - - #region UDP - - private string totalTimeUdpTest; - public string TotalTimeUdpTest - { - get => totalTimeUdpTest; - private set - { - if (value == totalTimeUdpTest) return; - - totalTimeUdpTest = value; - OnPropertyChanged(nameof(TotalTimeUdpTest)); - } - } - - #endregion - - #endregion - - #endregion - - #region DataCounter field - - #region TCP - - private string dataTcpCounter; - public string DataTcpCounter - { - get => dataTcpCounter; - set - { - if (value == dataTcpCounter) return; - dataTcpCounter = value; - - OnPropertyChanged(nameof(DataTcpCounter)); - } - } - - #endregion - - #region UDP - - private string dataUdpCounter; - public string DataUdpCounter - { - get => dataUdpCounter; - set - { - if (value == dataUdpCounter) return; - dataUdpCounter = value; - - OnPropertyChanged(nameof(DataUdpCounter)); - } - } - - #endregion - - #endregion - - #region MessageCounter field - - #region TCP - - private string messageTcpCounter; - public string MessageTcpCounter - { - get => messageTcpCounter; - set - { - if (value == messageTcpCounter) return; - - messageTcpCounter = value; - OnPropertyChanged(nameof(MessageTcpCounter)); - } - } - - #endregion - - #region UDP - - private string messageUdpCounter; - public string MessageUdpCounter - { - get => messageUdpCounter; - set - { - if (value == messageUdpCounter) return; - - messageUdpCounter = value; - OnPropertyChanged(nameof(MessageUdpCounter)); - } - } - - #endregion - - #endregion - - #region DataThroughput field - - #region TCP - - private string dataTcpThroughput; - public string DataTcpThroughput - { - get => dataTcpThroughput; - private set - { - if (value == dataTcpThroughput) return; - dataTcpThroughput = value; - - OnPropertyChanged(nameof(DataTcpThroughput)); - } - } - - #endregion - - #region UDP - - private string dataUdpThroughput; - public string DataUdpThroughput - { - get => dataUdpThroughput; - private set - { - if (value == dataUdpThroughput) return; - dataUdpThroughput = value; - - OnPropertyChanged(nameof(DataUdpThroughput)); - } - } - - #endregion - - #endregion - - #region MessageLatency field - - #region TCP - - private string messageTcpLatency; - public string MessageTcpLatency - { - get => messageTcpLatency; - private set - { - if (value == messageTcpLatency) return; - messageTcpLatency = value; - - OnPropertyChanged(nameof(MessageTcpLatency)); - } - } - - #endregion - - #region UDP - - private string messageUdpLatency; - public string MessageUdpLatency - { - get => messageUdpLatency; - private set - { - if (value == messageUdpLatency) return; - messageUdpLatency = value; - - OnPropertyChanged(nameof(MessageUdpLatency)); - } - } - - #endregion - - #endregion - - #region MessageThroughput field - - #region TCP - - private string messageTcpThroughput; - public string MessageTcpThroughput - { - get => messageTcpThroughput; - private set - { - if (value == messageTcpThroughput) return; - messageTcpThroughput = value; - - OnPropertyChanged(nameof(MessageTcpThroughput)); - } - } - - #endregion - - #region UDP - - private string messageUdpThroughput; - public string MessageUdpThroughput - { - get => messageUdpThroughput; - private set - { - if (value == messageUdpThroughput) return; - messageUdpThroughput = value; - - OnPropertyChanged(nameof(MessageUdpThroughput)); - } - } - - #endregion - - #endregion - - #region Error counter field - - #region TCP - - private string errorTcpCounter; - public string ErrorTcpCounter - { - get => errorTcpCounter; - set - { - if (value == errorTcpCounter) return; - errorTcpCounter = value; - - OnPropertyChanged(nameof(ErrorTcpCounter)); - } - } - - #endregion - - #region UDP - - private string errorUdpCounter; - public string ErrorUdpCounter - { - get => errorUdpCounter; - set - { - if (value == errorUdpCounter) return; - errorUdpCounter = value; - - OnPropertyChanged(nameof(ErrorUdpCounter)); - } - } - - #endregion - - #endregion - - #region Error message - - #region TCP - - private string errorTcpMessage; - public string ErrorTcpMessage - { - get => errorTcpMessage; - set - { - if (value == errorTcpMessage) return; - errorTcpMessage = value; - - OnPropertyChanged(nameof(ErrorTcpMessage)); - } - } - - #endregion - - #region UDP - - private string errorUdpMessage; - public string ErrorUdpMessage - { - get => errorUdpMessage; - set - { - if (value == errorUdpMessage) return; - errorUdpMessage = value; - - OnPropertyChanged(nameof(ErrorUdpMessage)); - } - } - - #endregion - - #endregion - - #region ProgressRing field - - #region TCP - - private bool progressRingTcp = false; - public bool ProgressRingTcp - { - get => progressRingTcp; - set - { - if (value == progressRingTcp) return; - - progressRingTcp = value; - OnPropertyChanged(nameof(ProgressRingTcp)); - } - } - - #endregion - - #region UDP - - private bool progressRingUdp = false; - public bool ProgressRingUdp - { - get => progressRingUdp; - set - { - if (value == progressRingUdp) return; - - progressRingUdp = value; - OnPropertyChanged(nameof(ProgressRingUdp)); - } - } - - #endregion - - #region ReconnectProgressRing - - private bool reconnectProgressRing; - public bool ReconnectProgressRing - { - get => reconnectProgressRing; - set - { - if (value == reconnectProgressRing) return; - - reconnectProgressRing = value; - OnPropertyChanged(nameof(ReconnectProgressRing)); - } - } - - #endregion - - #endregion - - #region SelectedTabIndex - - private int selectedTabIndex; - public int SelectedTabIndex - { - get => selectedTabIndex; - set - { - if (value == selectedTabIndex) - return; - - selectedTabIndex = value; - OnPropertyChanged(nameof(SelectedTabIndex)); - } - } - - #endregion - - #region Environment tabs fields - - public int ProcessorCount { get; } = Environment.ProcessorCount; - public bool Is64BitOperatingSystem { get; } = Environment.Is64BitOperatingSystem; - public bool Is64BitProcess { get; } = Environment.Is64BitProcess; - public string MachineName { get; } = Environment.MachineName; - public string OSVersion { get; } = Environment.OSVersion.ToString(); - public string OSDescription { get; } = RuntimeInformation.OSDescription; - public string UserName { get; } = Environment.UserName; - public int TickCount { get; } = Environment.TickCount; - public long WorkingSet { get; } = Environment.WorkingSet; - - - #endregion - - #region Main Connect/Disconnect client toolbar - - private string textOnStatusConnectButton = mClientDisconnected; - public string TextOnStatusConnectButton - { - get => textOnStatusConnectButton; - set - { - if (value == textOnStatusConnectButton) return; - - textOnStatusConnectButton = value; - OnPropertyChanged(nameof(TextOnStatusConnectButton)); - } - } - - private PackIconModernKind connectIcon = PackIconModernKind.Connect; - public PackIconModernKind ConnectIcon - { - get => connectIcon; - set - { - if (value == connectIcon) return; - - connectIcon = value; - OnPropertyChanged(nameof(ConnectIcon)); - } - } - - #endregion - - #region Status TCP test toolbar - - private string textOnTcpStatusTest = mTcpTestClientStatusRunning; - public string TextOnTcpStatusTest - { - get => textOnTcpStatusTest; - set - { - if (value == textOnTcpStatusTest) return; - - textOnTcpStatusTest = value; - OnPropertyChanged(nameof(TextOnTcpStatusTest)); - } - } - - private PackIconMaterialKind tcpTestIcon = PackIconMaterialKind.TestTubeOff; - public PackIconMaterialKind TcpTestIcon - { - get => tcpTestIcon; - set - { - if (value == tcpTestIcon) return; - - tcpTestIcon = value; - OnPropertyChanged(nameof(TcpTestIcon)); - } - } - - #endregion - - #region Status UDP test toolbar - - private string textOnUdpStatusTest = mUdpTestClientStatusNotRunning; - public string TextOnUdpStatusTest - { - get => textOnUdpStatusTest; - set - { - if (value == textOnUdpStatusTest) return; - - textOnUdpStatusTest = value; - OnPropertyChanged(nameof(TextOnUdpStatusTest)); - } - } - - private PackIconMaterialKind udpTestIcon = PackIconMaterialKind.TestTubeOff; - public PackIconMaterialKind UdpTestIcon - { - get => udpTestIcon; - set - { - if (value == udpTestIcon) return; - - udpTestIcon = value; - OnPropertyChanged(nameof(UdpTestIcon)); - } - } - - #endregion - - #region Param managment - - #region TCP - - private bool serverIpTcpBoxIsEnabled; - /// - /// The state of this element (on/off) depends on the state of other input fields (linked via Binding ElementName) - /// If true, then the test is running, false otherwise - /// - public bool ServerIpTcpBoxIsEnabled - { - get => serverIpTcpBoxIsEnabled; - set - { - if (value == serverIpTcpBoxIsEnabled) return; - serverIpTcpBoxIsEnabled = value; - - OnPropertyChanged(nameof(ServerIpTcpBoxIsEnabled)); - } - } - #endregion - - #region UDP - - private bool serverIpUdpBoxIsEnabled; - /// - /// The state of this element (on/off) depends on the state of other input fields (linked via Binding ElementName) - /// If true, then the test is running, false otherwise - /// - public bool ServerIpUdpBoxIsEnabled - { - get => serverIpUdpBoxIsEnabled; - set - { - if (value == serverIpUdpBoxIsEnabled) return; - serverIpUdpBoxIsEnabled = value; - - OnPropertyChanged(nameof(ServerIpUdpBoxIsEnabled)); - } - } - - #endregion - - #endregion - - #region StatusBar Icons and Text manage - - #region TCP - - private void TcpStatusBarManager(bool isTestRun) - { - if (isTestRun) - { - ServerIpTcpBoxIsEnabled = false; - ProgressRingTcp = true; - TextOnTcpStatusTest = mTcpTestClientStatusRunning; - TcpTestIcon = PackIconMaterialKind.TestTube; - return; - } - - ServerIpTcpBoxIsEnabled = true; - ProgressRingTcp = false; - TextOnTcpStatusTest = mTcpTestClientStatusNotRunning; - TcpTestIcon = PackIconMaterialKind.TestTubeOff; - } - - #endregion - - #region UDP - - private void UdpStatusBarManager(bool isTestRun) - { - if (isTestRun) - { - ServerIpUdpBoxIsEnabled = false; - ProgressRingUdp = true; - TextOnUdpStatusTest = mUdpTestClientStatusRunning; - UdpTestIcon = PackIconMaterialKind.TestTube; - return; - } - - ServerIpUdpBoxIsEnabled = true; - ProgressRingUdp = false; - TextOnUdpStatusTest = mUdpTestClientStatusNotRunning; - UdpTestIcon = PackIconMaterialKind.TestTubeOff; - } - - #endregion - - #endregion - - #region TCP methods - - private void ClearTcpResultField() - { - PublishTcpResultCount = 0; - - //time result - TotalTimeTcpTest = "--:--:--"; - StartTcpTestTime = "--:--:--"; - FinishTcpTestTime = "--:--:--"; - - //data result - DataTcpCounter = "------"; - DataTcpThroughput = "------"; - - //message result - MessageTcpCounter = "------"; - MessageTcpLatency = "------"; - MessageTcpThroughput = "------"; - - //error result - ErrorTcpCounter = "------"; - ErrorTcpMessage = "------"; - } - - private void PublishTcpResults() - { - PublishTcpResultCount++; - - //time result - TotalTimeTcpTest = Utilities.GenerateTimePeriod((TcpTestRunHelper.TimestampStop - TcpTestRunHelper.TimestampStart).TotalMilliseconds); - StartTcpTestTime = TcpTestRunHelper.TimestampStart.ToLocalTime().ToLongTimeString(); - FinishTcpTestTime = TcpTestRunHelper.TimestampStop.ToLocalTime().ToLongTimeString(); - - if (TcpTestRunHelper.TotalBytes == 0) return; - - //data result - DataTcpCounter = Utilities.GenerateDataSize(TcpTestRunHelper.TotalBytes); - DataTcpThroughput = $"{Utilities.GenerateDataSize(TcpTestRunHelper.TotalBytes / (TcpTestRunHelper.TimestampStop - TcpTestRunHelper.TimestampStart).TotalSeconds)}/s"; - - //message result - MessageTcpCounter = TcpTestRunHelper.TotalMessages.ToString(); - MessageTcpLatency = $"{Utilities.GenerateTimePeriod((TcpTestRunHelper.TimestampStop - TcpTestRunHelper.TimestampStart).TotalMilliseconds / TcpTestRunHelper.TotalMessages)}"; - MessageTcpThroughput = $"{(long)(TcpTestRunHelper.TotalMessages / (TcpTestRunHelper.TimestampStop - TcpTestRunHelper.TimestampStart).TotalSeconds)} msg/s"; - - //error result - ErrorTcpCounter = TcpTestRunHelper.TotalErrors.ToString(); - ErrorTcpMessage = TcpTestRunHelper.LastErrorMessage; - - if (string.IsNullOrEmpty(TcpTestRunHelper.LastErrorMessage)) - { - ErrorTcpMessage = "Нет ошибок"; - } - - TcpStatusBarManager(false); - NetworkWindowActivated = true; - } - - private List SaveTcpResultsToList() - { - List tcpResults = new() - { - $"Time results", - $"StartTcpTestTime {StartTcpTestTime}", - $"FinishTcpTestTime {FinishTcpTestTime}", - $"FactTotalTimeTcpTest {TotalTimeTcpTest}", - $"", - $"Data results", - $"DataTcpCounter {DataTcpCounter}", - $"MessageTcpCounter {MessageTcpCounter}", - $"DataTcpThroughput {DataTcpThroughput}", - $"MessageTcpLatency {MessageTcpLatency}", - $"MessageTcpThroughput {MessageTcpThroughput}", - $"ErrorTcpCounter {ErrorTcpCounter}", - $"LastErrorTcpMessage {ErrorTcpMessage}", - $"", - $"Test parameters", - $"BenchmarkTestServerIp {Properties.Settings.Default.BenchmarkTestServerIp}", - $"BenchmarkTcpTestPort {Properties.Settings.Default.BenchmarkTcpTestPort}", - $"BenchmarkTcpSizeByteArray {Properties.Settings.Default.BenchmarkTcpSizeByteArray}", - $"BenchmarkTestTcpTime {Properties.Settings.Default.BenchmarkTestTcpTime}", - $"BenchmarkTestTcpMessageQty {Properties.Settings.Default.BenchmarkTestTcpMessageQty}", - $"BenchmarkTestTcpClientsQty {Properties.Settings.Default.BenchmarkTestTcpClientsQty}" - }; - - return tcpResults; - } - - #endregion - - #region UDP methods - - private void ClearUdpResultField() - { - PublishUdpResultCount = 0; - //time result - TotalTimeUdpTest = "--:--:--"; - StartUdpTestTime = "--:--:--"; - FinishUdpTestTime = "--:--:--"; - - //data result - DataUdpCounter = "------"; - DataUdpThroughput = "------"; - - //message result - MessageUdpCounter = "------"; - MessageUdpLatency = "------"; - MessageUdpThroughput = "------"; - - //error result - ErrorUdpCounter = "------"; - ErrorUdpMessage = "------"; - } - - private void PublishUdpResults() - { - PublishUdpResultCount++; - - //time result - TotalTimeUdpTest = Utilities.GenerateTimePeriod((UdpTestRunHelper.TimestampStop - UdpTestRunHelper.TimestampStart).TotalMilliseconds); - StartUdpTestTime = UdpTestRunHelper.TimestampStart.ToLocalTime().ToLongTimeString(); - FinishUdpTestTime = UdpTestRunHelper.TimestampStop.ToLocalTime().ToLongTimeString(); - - if (UdpTestRunHelper.TotalBytes == 0) return; - - //data result - DataUdpCounter = Utilities.GenerateDataSize(UdpTestRunHelper.TotalBytes); - DataUdpThroughput = $"{Utilities.GenerateDataSize(UdpTestRunHelper.TotalBytes / (UdpTestRunHelper.TimestampStop - UdpTestRunHelper.TimestampStart).TotalSeconds)}/s"; - - //message result - MessageUdpCounter = UdpTestRunHelper.TotalMessages.ToString(); - MessageUdpLatency = $"{Utilities.GenerateTimePeriod((UdpTestRunHelper.TimestampStop - UdpTestRunHelper.TimestampStart).TotalMilliseconds / UdpTestRunHelper.TotalMessages)}"; - MessageUdpThroughput = $"{(long)(UdpTestRunHelper.TotalMessages / (UdpTestRunHelper.TimestampStop - UdpTestRunHelper.TimestampStart).TotalSeconds)} msg/s"; - - //error result - ErrorUdpCounter = UdpTestRunHelper.TotalErrors.ToString(); - ErrorUdpMessage = UdpTestRunHelper.LastErrorMessage; - - if (string.IsNullOrEmpty(UdpTestRunHelper.LastErrorMessage)) - { - ErrorUdpMessage = "Нет ошибок"; - } - - UdpStatusBarManager(false); - - NetworkWindowActivated = true; - } - - private List SaveUdpResultsToList() - { - List tcpResults = new() - { - $"Time results", - $"StartUdpTestTime {StartUdpTestTime}", - $"FinishTcpTestTime {FinishUdpTestTime}", - $"FactTotalTimeTcpTest {TotalTimeUdpTest}", - $"", - $"Data results", - $"DataTcpCounter {DataUdpCounter}", - $"MessageTcpCounter {MessageUdpCounter}", - $"DataTcpThroughput {DataUdpThroughput}", - $"MessageTcpLatency {MessageUdpLatency}", - $"MessageTcpThroughput {MessageUdpThroughput}", - $"ErrorTcpCounter {ErrorUdpCounter}", - $"LastErrorTcpMessage {ErrorUdpMessage}", - $"", - $"Test parameters", - $"BenchmarkTestServerIp {Properties.Settings.Default.BenchmarkTestServerIp}", - $"BenchmarkTcpTestPort {Properties.Settings.Default.BenchmarkUdpTestPort}", - $"BenchmarkTcpTestPort {Properties.Settings.Default.BenchmarkUdpSizeByteArray}", - $"BenchmarkTcpSizeByteArray {Properties.Settings.Default.BenchmarkUdpSizeByteArray}", - $"BenchmarkTestTcpTime {Properties.Settings.Default.BenchmarkTestUdpTime}", - $"BenchmarkTestTcpMessageQty {Properties.Settings.Default.BenchmarkTestUdpMessageQty}", - $"BenchmarkTestTcpClientsQty {Properties.Settings.Default.BenchmarkTestUdpClientsQty}" - }; - - return tcpResults; - } - - #endregion - - #region Common methods - - private static string ConvertListToString(IList results = null, IList envParams = null) - { - string tempResults = string.Empty; - - if(envParams != null) - { - foreach (string @string in envParams) - { - tempResults += $"{@string}\n"; - } - } - - if(results != null) - { - foreach (string @string in results) - { - tempResults += $"{@string}\n"; - } - } - - return tempResults; - } - - /// - /// Writes environment parameters to a string array - /// - /// Use the short format when you need to get basic information about the environment - private IList SaveEnvironmentParametersToList(bool shortFormat) - { - List envParams = shortFormat - ? (new() - { - $"Environment parameters", - $"MachineName {MachineName}", - $"OSVersion {OSVersion}", - $"OSDescription {OSDescription}", - $"" - }) - : (new() - { - $"ProcessorCount {ProcessorCount}", - $"Is64BitOperatingSystem {Is64BitOperatingSystem}", - $"Is64BitProcess {Is64BitProcess}", - $"MachineName {MachineName}", - $"OSVersion {OSVersion}", - $"OSDescription {OSDescription}", - $"UserName {UserName}", - $"TickCount {TickCount}", - $"WorkingSet {WorkingSet}", - $"" - }); - - return envParams; - } - - private void OnCloseWindow() - { - if (TcpTestRunHelper.IsTestRun) - { - TcpTestRunHelper.AbortTest(); - } - - if (UdpTestRunHelper.IsTestRun) - { - UdpTestRunHelper.AbortTest(); - } - - mComunicateTestHelper.DisconnectAndDestroy(); - - SendApiComunicateCommand(ServerCommand.Stop); - Properties.Settings.Default.Save(); - } - - #endregion - - #region Api Calls - - private void SendApiComunicateCommand(ServerCommand command) - { - BaseApi.SendCommand(command, "BenchmarkStateTcpServer"); - BaseApi.SendCommand(command, "BenchmarkTcpServer"); - BaseApi.SendCommand(command, "BenchmarkUdpServer"); - } - - #endregion - - #region Commands - - #region TCP commands - - private RelayCommand stopTcpBenchmarkTest; - public RelayCommand StopTcpBenchmarkTest => stopTcpBenchmarkTest ??= new RelayCommand(obj => - { - TcpTestRunHelper.AbortTest(); - }); - - private RelayCommand clearTcpTestResult; - public RelayCommand ClearTcpTestResult => clearTcpTestResult ??= new RelayCommand(obj => - { - ClearTcpResultField(); - }, canExecute => PublishTcpResultCount > 0); - - private RelayCommand startTcpBenchmarkTest; - public RelayCommand StartTcpBenchmarkTest => startTcpBenchmarkTest ??= new RelayCommand(async obj => - { - TcpStatusBarManager(true); - - await Dispatcher.Yield(DispatcherPriority.Normal); - await Task.Run (() => TcpTestRunHelper.Run()); - - PublishTcpResults(); - }, canExecute => IsTcpClientConnected == true); - - #endregion - - #region UDP commands - - private RelayCommand stopUdpBenchmarkTest; - public RelayCommand StopUdpBenchmarkTest => stopUdpBenchmarkTest ??= new RelayCommand(obj => - { - UdpTestRunHelper.AbortTest(); - }); - - private RelayCommand clearUdpTestResult; - public RelayCommand ClearUdpTestResult => clearUdpTestResult ??= new RelayCommand(obj => - { - ClearUdpResultField(); - }, canExecute => PublishUdpResultCount > 0); - - private RelayCommand startUdpBenchmarkTest; - public RelayCommand StartUdpBenchmarkTest => startUdpBenchmarkTest ??= new RelayCommand(async obj => - { - UdpStatusBarManager(true); - - await Dispatcher.Yield(DispatcherPriority.Normal); - await Task.Run(() => UdpTestRunHelper.Run()); - - PublishUdpResults(); - }, canExecute => IsTcpClientConnected == true); - - - #endregion - - #region Common comands - - private RelayCommand closeWindowCommand; - public RelayCommand CloseWindowCommand => closeWindowCommand ??= new RelayCommand(obj => - { - OnCloseWindow(); - - ((Window)obj).Close(); - }); - - #endregion - - #region Test client connect commands - - private RelayCommand connectButtonComand; - public RelayCommand ConnectButtonComand => connectButtonComand ??= new RelayCommand(async obj => - { - await Dispatcher.Yield(DispatcherPriority.Normal); - - if (mComunicateTestHelper.TcpClientIsConnected) - { - await Task.Run(() => mComunicateTestHelper.Disconnect()); - return; - } - - if (!mComunicateTestHelper.TcpClientIsConnected) - { - await Task.Run(() => mComunicateTestHelper.Connect()); - return; - } - }); - - #endregion - - #region Saved/Copy buttons commands - - private RelayCommand copyResults; - public RelayCommand CopyResults => copyResults ??= new RelayCommand(obj => - { - IList envParamsShort = null; - - if (Properties.Settings.Default.BenchmarkAddEnvironmentParametersToResult) - { - envParamsShort = SaveEnvironmentParametersToList(true); - } - - switch (SelectedTabIndex) - { - case 0: - { - IList envParamsFull = SaveEnvironmentParametersToList(false); - string results = ConvertListToString(envParams: envParamsFull); - Clipboard.SetText(results); - break; - } - case 1: - { - IList tcpResults = SaveTcpResultsToList(); - string results = ConvertListToString(tcpResults, envParamsShort); - Clipboard.SetText(results); - break; - } - case 2: - { - IList udpResults = SaveUdpResultsToList(); - string results = ConvertListToString(udpResults, envParamsShort); - Clipboard.SetText(results); - break; - } - - default: - break; - } - }); - - private RelayCommand saveResults; - public RelayCommand SaveResults => saveResults ??= new RelayCommand(obj => - { - IList envParamsShort = null; - - if (Properties.Settings.Default.BenchmarkAddEnvironmentParametersToResult) - { - envParamsShort = SaveEnvironmentParametersToList(true); - } - - switch (SelectedTabIndex) - { - case 0: - { - IList envParamsFull = SaveEnvironmentParametersToList(false); - string results = ConvertListToString(envParams: envParamsFull); - FileSaveDialog(results, "Сохранить параметры окружения", "EnvironmentParameters"); - break; - } - case 1: - { - IList tcpResults = SaveTcpResultsToList(); - string results = ConvertListToString(tcpResults, envParamsShort); - FileSaveDialog(results, "Сохранить результаты TCP RoundTrip теста", $"TCP benchmark results {DateTime.Now:HH-mm-ss.ff}"); - break; - } - case 2: - { - IList udpResults = SaveUdpResultsToList(); - string results = ConvertListToString(udpResults, envParamsShort); - FileSaveDialog(results, "Сохранить результаты UDP RoundTrip теста", $"UDP benchmark results {DateTime.Now:HH-mm-ss.ff}"); - break; - } - - default: - break; - } - - }); - - private async void FileSaveDialog(string file, string title, string fileName) - { - - if (IDialogManager.ShowSaveFileDialog(title, Properties.Settings.Default.SavedResultsNetworkTestsFolderPath, fileName, ".txt", "TXT documents (.txt)|*.txt")) - { - string path = IDialogManager.FilePathToSave; - await FileHelper.WriteAsync(path, file); - } - else - { - //AppLogStatusBarAction("Файл не сохранен"); - } - } - - #endregion - - #endregion - - #region IWindowParam - - public override string WindowTitle => @"Тест сети"; - public override double Width => 1000; - public override double Height => 550; - public override bool IsModal => false; - - public override void OnClosed(Window window) - { - OnCloseWindow(); - - base.OnClosed(window); - } - - #endregion - } -} diff --git a/AdamController/ViewModels/ScratchControlView.cs b/AdamController/ViewModels/ScratchControlView.cs deleted file mode 100644 index ca1bd57..0000000 --- a/AdamController/ViewModels/ScratchControlView.cs +++ /dev/null @@ -1,735 +0,0 @@ -using AdamBlocklyLibrary; -using AdamBlocklyLibrary.Enum; -using AdamBlocklyLibrary.Struct; -using AdamBlocklyLibrary.Toolbox; -using AdamBlocklyLibrary.ToolboxSets; -using AdamController.Commands; -using AdamController.Helpers; -using AdamController.Model; -using AdamController.Properties; -using AdamController.ViewModels.HamburgerMenu; -using AdamController.Views.HamburgerPage; -using AdamController.WebApi.Client.v1; -using AdamController.WebApi.Client.v1.ResponseModel; -using MessageDialogManagerLib; -using Microsoft.AspNetCore.Authorization.Infrastructure; -using Newtonsoft.Json; -using System; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Threading; - -namespace AdamController.ViewModels -{ - public class ScratchControlView : HamburgerMenuItemView - { - #region Action field - - public static Action SendSourceToScriptEditor { get; set; } - public static Action SetSelectedPageIndex { get; set; } - public static Action AppLogStatusBarAction { get; set; } - public static Action CompileLogStatusBarAction { get; set; } - public static Action ProgressRingStartAction { get; set; } - public static Action ReloadWebView { get; set; } - - #endregion - - private readonly IMessageDialogManager IDialogManager; - private bool mIsWarningStackOwerflowAlreadyShow; - - public ScratchControlView(HamburgerMenuView hamburgerMenuView) : base(hamburgerMenuView) - { - IDialogManager = new MessageDialogManagerMahapps(Application.Current); - - InitAction(); - PythonExecuteEvent(); - - ComunicateHelper.OnAdamTcpConnectedEvent += OnAdamTcpConnectedEvent; - ComunicateHelper.OnAdamTcpDisconnectedEvent += OnAdamTcpDisconnectedEvent; - - } - - private void OnAdamTcpDisconnectedEvent() - { - UpdatePythonInfo(); - } - - private async void OnAdamTcpConnectedEvent() - { - var pythonVersionResult = await BaseApi.GetPythonVersion(); - var pythonBinPathResult = await BaseApi.GetPythonBinDir(); - var pythonWorkDirResult = await BaseApi.GetPythonWorkDir(); - - string pythonVersion = pythonVersionResult?.StandardOutput?.Replace("\n", ""); - string pythonBinPath = pythonBinPathResult?.StandardOutput?.Replace("\n", ""); - string pythonWorkDir = pythonWorkDirResult?.StandardOutput?.Replace("\n", ""); - - UpdatePythonInfo(pythonVersion, pythonBinPath, pythonWorkDir); - } - - private void UpdatePythonInfo(string pythonVersion = "", string pythonBinPath = "", string pythonWorkDir = "") - { - if (string.IsNullOrEmpty(pythonVersion)) - { - PythonVersion = "Не подключена"; - PythonBinPath = string.Empty; - PythonWorkDir = string.Empty; - return; - } - - PythonVersion = pythonVersion; - PythonBinPath = $"[{pythonBinPath}]"; - PythonWorkDir = $"Рабочая дирректория {pythonWorkDir}"; - } - - #region Action initialize - - private void InitAction() - { - ScratchControl.NavigationComplete ??= new Action(() => NavigationComplete()); - - ScratchControl.WebMessageReceived ??= new Action((results) => WebMessageReceived(results)); - } - - #endregion - - #region Native python execute event - - private void PythonExecuteEvent() - { - PythonScriptExecuteHelper.OnExecuteStartEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 0) - return; - - mIsWarningStackOwerflowAlreadyShow = false; - - StartExecuteProgram(); - - ResultTextEditor += message; - }; - - PythonScriptExecuteHelper.OnStandartOutputEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 0) - return; - - if(ResultTextEditorLength > 10000) - { - if (!mIsWarningStackOwerflowAlreadyShow) - { - ResultTextEditor += "\nДальнейший вывод результата, будет скрыт."; - ResultTextEditor += "\nПрограмма продолжает выполняться в неинтерактивном режиме."; - ResultTextEditor += "\nДля остановки нажмите \"Stop\". Или дождитесь завершения."; - - mIsWarningStackOwerflowAlreadyShow = true; - } - - return; - } - - ResultTextEditor += message; - }; - - PythonScriptExecuteHelper.OnExecuteFinishEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 0) - return; - - FinishExecuteProgram(); - ResultTextEditor += message; - }; - } - - #endregion - - #region Execute program event - - private async void StartExecuteProgram() - { - CompileLogStatusBarAction("Сеанс отладки запущен"); - IsEnabledShowOpenDialogButton = false; - IsEnabledStopExecuteButton = true; - ResultTextEditor = string.Empty; - ProgressRingStartAction(true); - - if (!Properties.Settings.Default.ShadowWorkspaceInDebug) return; - - await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(async () => - { - await ScratchControl.ExecuteScript(Scripts.ShadowEnable); - })); - } - - private void FinishExecuteProgram() - { - OnStopExecuteProgram("Сеанс отладки закончен"); - } - - private async void OnStopExecuteProgram(string compileLogStatusBarAction) - { - await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(async () => - { - await ScratchControl.ExecuteScript(Scripts.ShadowDisable); - })); - - CompileLogStatusBarAction(compileLogStatusBarAction); - ProgressRingStartAction(false); - IsEnabledShowOpenDialogButton = true; - IsEnabledStopExecuteButton = false; - } - - #endregion - - private void WebMessageReceived(WebMessageJsonReceived results) - { - if (results.Action == "sendSourceCode") - { - SourceTextEditor = results.Data; - } - } - - #region IsEnabled buttons field - - private bool isEnabledStopExecuteButton = false; - public bool IsEnabledStopExecuteButton - { - get => isEnabledStopExecuteButton; - set - { - if (value == isEnabledStopExecuteButton) return; - - isEnabledStopExecuteButton = value; - OnPropertyChanged(nameof(IsEnabledStopExecuteButton)); - } - } - - private bool isEnabledShowOpenDialogButton = true; - public bool IsEnabledShowOpenDialogButton - { - get => isEnabledShowOpenDialogButton; - set - { - if (value == isEnabledShowOpenDialogButton) return; - - isEnabledShowOpenDialogButton = value; - OnPropertyChanged(nameof(IsEnabledShowOpenDialogButton)); - } - } - - #endregion - - #region Initialize Blockly - - /// - /// Run js-script after web view navigation complete - /// - private void NavigationComplete() - { - InitBlockly(); - } - - private async void InitBlockly() - { - BlocklyLanguage language = Settings.Default.BlocklyWorkspaceLanguage; - - try - { - await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(async () => - { - await LoadBlocklySrc(); - await LoadBlocklyBlockLocalLangSrc(language); - _ = await ScratchControl.ExecuteScript(InitWorkspace()); - _ = await ScratchControl.ExecuteScript(Scripts.ListenerCreatePythonCode); - _ = await ScratchControl.ExecuteScript(Scripts.ListenerSavedBlocks); - - if (Settings.Default.BlocklyRestoreBlockOnLoad) - { - _ = await ScratchControl.ExecuteScript(Scripts.RestoreSavedBlocks); - } - - - })); - - AppLogStatusBarAction("Загрузка скретч-редактора закончена"); - } - catch - { - //the error occurs when switching to another tab before blockly is fully loaded - AppLogStatusBarAction("Загрузка скретч-редактора внезапно прервана"); - } - } - - private string InitWorkspace() - { - Toolbox toolbox = InitDefaultToolbox(Settings.Default.BlocklyToolboxLanguage); - BlocklyGrid blocklyGrid = InitGrid(); - - Workspace workspace = new() - { - Toolbox = toolbox, - BlocklyGrid = blocklyGrid, - Theme = Settings.Default.BlocklyTheme, - ShowTrashcan = Settings.Default.BlocklyShowTrashcan, - Render = Render.thrasos, - Collapse = true - }; - - string workspaceString = Scripts.SerealizeObjectToJsonString("init", new object[] { workspace }); - return workspaceString; - } - - private BlocklyGrid InitGrid() - { - BlocklyGrid blocklyGrid = new(); - - if (Settings.Default.BlocklyShowGrid) - { - blocklyGrid.Length = Settings.Default.BlocklyGridSpacing; - blocklyGrid.Spacing = Settings.Default.BlocklyGridSpacing; - } - else - { - blocklyGrid.Length = 0; - blocklyGrid.Spacing = 0; - } - - blocklyGrid.Colour = Settings.Default.BlocklyGridColour.ToRbgColor(); - blocklyGrid.Snap = Settings.Default.BlocklySnapToGridNodes; - - return blocklyGrid; - } - - private Toolbox InitDefaultToolbox(BlocklyLanguage language) - { - Toolbox toolbox = new DefaultSimpleCategoryToolbox(language) - { - LogicCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyLogicCategoryState, - AlternateName = Settings.Default.BlocklyLogicCategoryAlternateName - }, - ColourCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyColorCategoryState, - AlternateName = Settings.Default.BlocklyColourCategoryAlternateName - }, - ListsCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyListsCategoryState, - AlternateName = Settings.Default.BlocklyListsCategoryAlternateName - }, - LoopsCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyLoopCategoryState, - AlternateName = Settings.Default.BlocklyLoopCategoryAlternateName - }, - MathCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyMathCategoryState, - AlternateName = Settings.Default.BlocklyMathCategoryAlternateName - }, - TextCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyTextCategoryState, - AlternateName = Settings.Default.BlocklyTextCategoryAlternateName - }, - ProcedureCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyProcedureCategoryState, - AlternateName = Settings.Default.BlocklyProcedureCategoryAlternateName - }, - VariableDynamicCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyDynamicVariableCategoryState, - AlternateName = Settings.Default.BlocklyDynamicVariableCategoryAlternateName - }, - VariableCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyVariableCategoryState, - AlternateName = Settings.Default.BlocklyVariableCategoryAlternateName - }, - DateTimeCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyDateTimeCategoryState, - AlternateName = Settings.Default.BlocklyDateTimeCategoryAlternateName - }, - AdamCommonCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyAdamCommonCategoryState, - AlternateName = Settings.Default.BlocklyAdamCommonCategoryAlternateName - }, - AdamTwoCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyAdamTwoCategoryState, - AlternateName = Settings.Default.BlocklyAdamTwoCategoryAlternateName - }, - AdamThreeCategoryParam = new ToolboxParam - { - Hidden = !Settings.Default.BlocklyAdamThreeCategoryState, - AlternateName = Settings.Default.BlocklyAdamThreeCategoryAlternateName - } - }.Toolbox; - - return toolbox; - } - - #endregion - - #region Blockly method - - private async Task LoadBlocklySrc() - { - string loadLocalSrc = Scripts.SerealizeObject("loadSrcs", new object[] - { - Scripts.BlocksCompressedSrc, - Scripts.JavascriptCompressedSrc, - Scripts.PythonCompressedSrc, - }); - - string loadLocalAdamBlockSrc = Scripts.SerealizeObject("loadSrcs", new object[] - { - Scripts.DateTimeBlockSrc, - Scripts.ThreadBlockSrc, - Scripts.SystemsBlockSrc, - Scripts.AdamThreeBlockSrc, - Scripts.AdamTwoBlockSrc, - Scripts.AdamCommonBlockSrc, - }); - - - string loadLocalAdamPythonGenSrc = Scripts.SerealizeObject("loadSrcs", new object[] - { - Scripts.DateTimePytnonGenSrc, - Scripts.ThreadPytnonGenSrc, - Scripts.SystemsPythonGenSrc, - Scripts.AdamThreePytnonGenSrc, - Scripts.AdamTwoPytnonGenSrc, - Scripts.AdamCommonPytnonGenSrc - }); - - _ = await ScratchControl.ExecuteScript(loadLocalSrc); - - //Thread.Sleep(1000); - Thread.Sleep(500); - _ = await ScratchControl.ExecuteScript(loadLocalAdamBlockSrc); - - //Thread.Sleep(1000); - Thread.Sleep(500); - _ = await ScratchControl.ExecuteScript(loadLocalAdamPythonGenSrc); - } - - /// - /// Loading block language - /// - /// - private async Task LoadBlocklyBlockLocalLangSrc(BlocklyLanguage language) - { - switch (language) - { - case BlocklyLanguage.ru: - { - _ = await ExecuteScriptFunctionAsync("loadSrc", Scripts.BlockLanguageRu); - break; - } - case BlocklyLanguage.zh: - { - _ = await ExecuteScriptFunctionAsync("loadSrc", Scripts.BlockLanguageZnHans); - break; - } - case BlocklyLanguage.en: - { - _ = await ExecuteScriptFunctionAsync("loadSrc", Scripts.BlockLanguageEn); - break; - } - } - } - - #endregion - - #region Result text editor - - private string resultTextEditor; - public string ResultTextEditor - { - get => resultTextEditor; - set - { - if (value == resultTextEditor) return; - - resultTextEditor = value; - ResultTextEditorLength = value.Length; - - OnPropertyChanged(nameof(ResultTextEditor)); - } - } - - #endregion - - #region Result text editor length - - private int resultTextEditorLength; - public int ResultTextEditorLength - { - get => resultTextEditorLength; - set - { - if (value == resultTextEditorLength) return; - - resultTextEditorLength = value; - OnPropertyChanged(nameof(ResultTextEditorLength)); - } - } - - #endregion - - #region Result text editor panel field - - private string resultTextEditorError; - public string ResultTextEditorError - { - get => resultTextEditorError; - set - { - if (value == resultTextEditorError) return; - - - if (value.Length > 0) - resultTextEditorError = $"Error: {value}"; - else - resultTextEditorError = value; - - OnPropertyChanged(nameof(ResultTextEditorError)); - } - } - - private string pythonVersion; - public string PythonVersion - { - get => pythonVersion; - set - { - if (value == pythonVersion) return; - - pythonVersion = value; - OnPropertyChanged(nameof(PythonVersion)); - } - } - - private string pythonBinPath; - public string PythonBinPath - { - get => pythonBinPath; - set - { - if (value == pythonBinPath) return; - - pythonBinPath = value; - OnPropertyChanged(nameof(PythonBinPath)); - } - } - - private string pythonWorkDir; - public string PythonWorkDir - { - get => pythonWorkDir; - set - { - if (value == pythonWorkDir) return; - - pythonWorkDir = value; - OnPropertyChanged(nameof(PythonWorkDir)); - } - } - - #endregion - - #region Source text editor - - private string sourceTextEditor; - public string SourceTextEditor - { - get => sourceTextEditor; - set - { - if (value == sourceTextEditor) return; - - sourceTextEditor = value; - OnPropertyChanged(nameof(SourceTextEditor)); - } - } - - #endregion - - #region Command - - private RelayCommand reloadWebViewCommand; - public RelayCommand ReloadWebViewCommand => reloadWebViewCommand ??= new RelayCommand(obj => - { - SourceTextEditor = string.Empty; - ReloadWebView(); - }); - - private RelayCommand sendToExternalSourceEditor; - public RelayCommand SendToExternalSourceEditor => sendToExternalSourceEditor ??= new RelayCommand(obj => - { - SetSelectedPageIndex(1); - SendSourceToScriptEditor(SourceTextEditor); - - }, canExecute => SourceTextEditor?.Length > 0); - - private RelayCommand showSaveFileDialogCommand; - public RelayCommand ShowSaveFileDialogCommand => showSaveFileDialogCommand ??= new RelayCommand(async obj => - { - string workspace = await ScratchControl.ExecuteScript("getSavedWorkspace()"); - string xmlWorkspace = JsonConvert.DeserializeObject(workspace); - - if (IDialogManager.ShowSaveFileDialog("Сохранить рабочую область", Properties.Settings.Default.SavedUserWorkspaceFolderPath, "workspace", ".xml", "XML documents (.xml)|*.xml")) - { - string path = IDialogManager.FilePathToSave; - await FileHelper.WriteAsync(path, xmlWorkspace); - - AppLogStatusBarAction($"Файл {IDialogManager.FilePathToSave} сохранен"); - } - else - { - AppLogStatusBarAction("Файл не сохранен"); - } - }); - - private RelayCommand showOpenFileDialogCommand; - public RelayCommand ShowOpenFileDialogCommand => showOpenFileDialogCommand ??= new RelayCommand(async obj => - { - if (IDialogManager.ShowFileBrowser("Выберите сохранененную рабочую область", Properties.Settings.Default.SavedUserWorkspaceFolderPath, "XML documents(.xml) | *.xml")) - { - string path = IDialogManager.FilePath; - if (path == "") return; - - string xml = await FileHelper.ReadTextAsStringAsync(path); - _ = await ExecuteScriptFunctionAsync("loadSavedWorkspace", new object[] { xml }); - - AppLogStatusBarAction($"Файл {path} загружен"); - } - else - { - AppLogStatusBarAction("Файл рабочей области не выбран"); - } - }); - - private RelayCommand runCode; - public RelayCommand RunCode => runCode ??= new RelayCommand(async obj => - { - ResultTextEditorError = string.Empty; - ExtendedCommandExecuteResult executeResult = new(); - - try - { - var command = new WebApi.Client.v1.RequestModel.PythonCommand - { - Command = SourceTextEditor - }; - - executeResult = await BaseApi.PythonExecuteAsync(command); - } - catch (Exception ex) - { - ResultTextEditorError = ex.Message.ToString(); - } - - if (Settings.Default.ChangeExtendedExecuteReportToggleSwitchState) - { - ResultTextEditor += "Отчет о инициализации процесса программы\n" + - "======================\n" + - $"Начало инициализации: {executeResult.StartTime}\n" + - $"Завершение инициализации: {executeResult.EndTime}\n" + - $"Общее время инициализации: {executeResult.RunTime}\n" + - $"Код выхода: {executeResult.ExitCode}\n" + - $"Статус успешности инициализации: {executeResult.Succeesed}" + - "\n======================\n"; - } - - if (!string.IsNullOrEmpty(executeResult?.StandardError)) - ResultTextEditor += $"Ошибка: {executeResult.StandardError}" + - "\n======================"; - - }, canExecute => !string.IsNullOrEmpty(SourceTextEditor) && ComunicateHelper.TcpClientIsConnected); - - private RelayCommand stopExecute; - public RelayCommand StopExecute => stopExecute ??= new RelayCommand(async obj=> - { - if (ComunicateHelper.TcpClientIsConnected) - { - try - { - await BaseApi.StopPythonExecute(); - } - catch (Exception ex) - { - ResultTextEditorError = ex.Message.ToString(); - } - } - }); - - private RelayCommand toZeroPositionCommand; - public RelayCommand ToZeroPositionCommand => toZeroPositionCommand ??= new RelayCommand(async obj => - { - try - { - await BaseApi.StopPythonExecute(); - //await BaseApi.MoveToZeroPosition(); - } - catch (Exception ex) - { - ResultTextEditorError = ex.Message.ToString(); - } - - }, canExecute => ComunicateHelper.TcpClientIsConnected); - - private RelayCommand cleanExecuteEditor; - public RelayCommand CleanExecuteEditor => cleanExecuteEditor ??= new RelayCommand(async obj => - { - await Task.Run(() => - { - ResultTextEditorError = string.Empty; - ResultTextEditor = string.Empty; - }); - }); - - #region ShowSaveFileDialogCommand - - private RelayCommand showSaveFileSourceTextDialogCommand; - public RelayCommand ShowSaveFileSourceTextDialogCommand => showSaveFileSourceTextDialogCommand ??= new RelayCommand(async obj => - { - string pythonProgram = SourceTextEditor; - - if (IDialogManager.ShowSaveFileDialog("Сохранить файл программы", Properties.Settings.Default.SavedUserScriptsFolderPath, - "new_program", ".py", "PythonScript file (.py)|*.py|Все файлы|*.*")) - { - string path = IDialogManager.FilePathToSave; - await FileHelper.WriteAsync(path, pythonProgram); - - AppLogStatusBarAction($"Файл {IDialogManager.FilePathToSave} сохранен"); - } - else - { - AppLogStatusBarAction("Файл не сохранен"); - } - }, canExecute => SourceTextEditor?.Length > 0); - - #endregion - - #endregion - - #region ExecuteScripts - - private static async Task ExecuteScriptFunctionAsync(string functionName, params object[] parameters) - { - string script = Scripts.SerealizeObject(functionName, parameters); - return await ScratchControl.ExecuteScript(script); - } - - #endregion - - } -} diff --git a/AdamController/ViewModels/ScriptEditorControlView.cs b/AdamController/ViewModels/ScriptEditorControlView.cs deleted file mode 100644 index 9e4380a..0000000 --- a/AdamController/ViewModels/ScriptEditorControlView.cs +++ /dev/null @@ -1,339 +0,0 @@ -using AdamController.Commands; -using AdamController.Helpers; -using AdamController.ViewModels.HamburgerMenu; -using AdamController.WebApi.Client.v1; -using AdamController.WebApi.Client.v1.ResponseModel; -using MessageDialogManagerLib; -using System; -using System.Threading.Tasks; -using System.Windows; - -namespace AdamController.ViewModels -{ - public class ScriptEditorControlView : HamburgerMenuItemView - { - public static Action AppLogStatusBarAction { get; set; } - - private bool mIsWarningStackOwerflowAlreadyShow; - private readonly IMessageDialogManager IDialogManager; - - public ScriptEditorControlView(HamburgerMenuView hamburgerMenuView = null) : base(hamburgerMenuView) - { - IDialogManager = new MessageDialogManagerMahapps(Application.Current); - - InitAction(); - PythonExecuteEvent(); - } - - #region Python execute event - - private void PythonExecuteEvent() - { - PythonScriptExecuteHelper.OnExecuteStartEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 1) - return; - - ResultTextEditor = string.Empty; - IsCodeExecuted = true; - mIsWarningStackOwerflowAlreadyShow = false; - ResultTextEditor += message; - }; - - PythonScriptExecuteHelper.OnStandartOutputEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 1) - return; - - if (ResultTextEditorLength > 10000) - { - if (!mIsWarningStackOwerflowAlreadyShow) - { - ResultTextEditor += "\nДальнейший вывод результата, приведет к переполнению буфера, поэтому будет скрыт."; - ResultTextEditor += "\nПрограмма продолжает выполняться в неинтерактивном режиме."; - ResultTextEditor += "\nДля остановки нажмите \"Stop\". Или дождитесь завершения."; - - mIsWarningStackOwerflowAlreadyShow = true; - } - - return; - } - - ResultTextEditor += message; - }; - - PythonScriptExecuteHelper.OnExecuteFinishEvent += (message) => - { - if (MainWindowView.GetSelectedPageIndex != 1) - return; - - IsCodeExecuted = false; - ResultTextEditor += message; - }; - } - - #endregion - - #region Source text editor - - private string sourceTextEditor; - public string SourceTextEditor - { - get => sourceTextEditor; - set - { - if (value == sourceTextEditor) return; - - sourceTextEditor = value; - OnPropertyChanged(nameof(SourceTextEditor)); - } - } - - private string selectedText; - public string SelectedText - { - get => selectedText; - set - { - if (value == selectedText) return; - - selectedText = value; - OnPropertyChanged(nameof(SelectedText)); - } - } - - #endregion - - #region SendSourceToScriptEditor Action - - private void InitAction() - { - if(ScratchControlView.SendSourceToScriptEditor == null) - { - ScratchControlView.SendSourceToScriptEditor = new Action(source => SourceTextEditor = source); - } - } - - #endregion - - #region Result text editor - - private string resultTextEditor; - public string ResultTextEditor - { - get => resultTextEditor; - set - { - if (value == resultTextEditor) return; - - resultTextEditor = value; - ResultTextEditorLength = value.Length; - - OnPropertyChanged(nameof(ResultTextEditor)); - } - } - - #endregion - - #region ResultTextEditorLength - - private int resultTextEditorLength; - public int ResultTextEditorLength - { - get => resultTextEditorLength; - set - { - if (value == resultTextEditorLength) return; - - resultTextEditorLength = value; - OnPropertyChanged(nameof(ResultTextEditorLength)); - } - } - - #endregion - - #region IsCodeExecuted field - - private bool isCodeExecuted = false; - public bool IsCodeExecuted - { - get => isCodeExecuted; - set - { - if (value == isCodeExecuted) return; - - isCodeExecuted = value; - OnPropertyChanged(nameof(IsCodeExecuted)); - } - } - - #endregion - - #region ResultTextEditorError - - private string resultTextEditorError; - public string ResultTextEditorError - { - get => resultTextEditorError; - set - { - if (value == resultTextEditorError) return; - - if(value.Length > 0) - resultTextEditorError = $"Error: {value}"; - else - resultTextEditorError = value; - - OnPropertyChanged(nameof(ResultTextEditorError)); - } - } - - #endregion - - #region Command - - #region Run code button - - private RelayCommand runCode; - public RelayCommand RunCode => runCode ??= new RelayCommand(async obj => - { - ResultTextEditorError = string.Empty; - ExtendedCommandExecuteResult executeResult = new(); - - try - { - if(ComunicateHelper.TcpClientIsConnected) - { - var command = new WebApi.Client.v1.RequestModel.PythonCommand - { - Command = SourceTextEditor - }; - executeResult = await BaseApi.PythonExecuteAsync(command); - } - - } - catch (Exception ex) - { - ResultTextEditorError = ex.Message.ToString(); - } - - if (Properties.Settings.Default.ChangeExtendedExecuteReportToggleSwitchState) - { - ResultTextEditor += "Отчет о инициализации процесса программы\n" + - "======================\n" + - $"Начало инициализации: {executeResult.StartTime}\n" + - $"Завершение инициализации: {executeResult.EndTime}\n" + - $"Общее время инициализации: {executeResult.RunTime}\n" + - $"Код выхода: {executeResult.ExitCode}\n" + - $"Статус успешности инициализации: {executeResult.Succeesed}" + - "\n======================\n"; - } - - if (!string.IsNullOrEmpty(executeResult?.StandardError)) - ResultTextEditor += $"Ошибка: {executeResult?.StandardError}" + - "\n======================"; - - }, canExecute => !string.IsNullOrEmpty(SourceTextEditor)); - - #endregion - - private RelayCommand copyToClipboard; - public RelayCommand CopyToClipboard => copyToClipboard ??= new RelayCommand(obj => - { - if (SelectedText == null) - return; - - Clipboard.SetText(SelectedText); - }); - - private RelayCommand cutToClipboard; - public RelayCommand CutToClipboard => cutToClipboard ??= new RelayCommand(obj => - { - if (SourceTextEditor == null) - return; - - Clipboard.SetText(SourceTextEditor); - SourceTextEditor = string.Empty; - }); - - private RelayCommand pasteFromClipboard; - public RelayCommand PasteFromClipboard => pasteFromClipboard ??= new RelayCommand(obj => - { - string text = Clipboard.GetText(); - SourceTextEditor += text; - }); - - private RelayCommand stopExecute; - public RelayCommand StopExecute => stopExecute ??= new RelayCommand(async obj => - { - try - { - await BaseApi.StopPythonExecute(); - } - catch(Exception ex) - { - ResultTextEditorError = ex.Message; - } - - }); - - private RelayCommand cleanExecuteEditor; - public RelayCommand CleanExecuteEditor => cleanExecuteEditor ??= new RelayCommand(async obj => - { - await Task.Run(() => - { - ResultTextEditorError = string.Empty; - ResultTextEditor = string.Empty; - }); - }); - - #region OpenFileDialogCommand - - private RelayCommand showOpenFileDialogCommand; - public RelayCommand ShowOpenFileDialogCommand => showOpenFileDialogCommand ??= new RelayCommand(async obj => - { - if (IDialogManager.ShowFileBrowser("Выберите файл с исходным кодом программы", - Properties.Settings.Default.SavedUserScriptsFolderPath, "PythonScript file (.py)|*.py|Все файлы|*.*")) - { - string path = IDialogManager.FilePath; - if (path == "") return; - - string pythonProgram = await FileHelper.ReadTextAsStringAsync(path); - SourceTextEditor = pythonProgram; - - AppLogStatusBarAction($"Файл {path} загружен"); - } - else - { - AppLogStatusBarAction("Файл c исходным кодом не выбран"); - } - }); - - #endregion - - #region ShowSaveFileDialogCommand - - private RelayCommand showSaveFileDialogCommand; - public RelayCommand ShowSaveFileDialogCommand => showSaveFileDialogCommand ??= new RelayCommand(async obj => - { - string pythonProgram = SourceTextEditor; - - if (IDialogManager.ShowSaveFileDialog("Сохранить файл программы", Properties.Settings.Default.SavedUserScriptsFolderPath, - "new_program", ".py", "PythonScript file (.py)|*.py|Все файлы|*.*")) - { - string path = IDialogManager.FilePathToSave; - await FileHelper.WriteAsync(path, pythonProgram); - - AppLogStatusBarAction($"Файл {IDialogManager.FilePathToSave} сохранен"); - } - else - { - AppLogStatusBarAction("Файл не сохранен"); - } - }, canExecute => SourceTextEditor?.Length > 0); - - #endregion - - #endregion - } -} diff --git a/AdamController/ViewModels/SettingsWindowView.cs b/AdamController/ViewModels/SettingsWindowView.cs deleted file mode 100644 index 6a86f99..0000000 --- a/AdamController/ViewModels/SettingsWindowView.cs +++ /dev/null @@ -1,134 +0,0 @@ -using AdamController.Commands; -using AdamController.ViewModels.Common; -using FolderBrowserEx; -using System.Windows; -using System.Windows.Forms; - -namespace AdamController.ViewModels -{ - public class SettingsWindowView : BaseViewModel - { - private readonly IFolderBrowserDialog IFolderBrowser; - - public SettingsWindowView() - { - IFolderBrowser = new FolderBrowserEx.FolderBrowserDialog(); - } - - #region UI behavior - - private bool settingWindowActivated; - public bool SettingWindowActivated - { - get => settingWindowActivated; - set - { - if (value == settingWindowActivated) return; - - settingWindowActivated = value; - OnPropertyChanged(nameof(SettingWindowActivated)); - - } - } - - #endregion - - #region Command - - private RelayCommand showOpenFolderDialogCommand; - public RelayCommand ShowOpenFolderDialogCommand => showOpenFolderDialogCommand ??= new RelayCommand(obj => - { - string dialogPathType = obj; - - if (string.IsNullOrEmpty(dialogPathType)) return; - - switch (dialogPathType) - { - case "workspace": - { - string savedPath = OpenFolderDialog("Выберите директорию для сохранения рабочих областей", Properties.Settings.Default.SavedUserWorkspaceFolderPath); - - if (string.IsNullOrEmpty(savedPath)) return; - - Properties.Settings.Default.SavedUserWorkspaceFolderPath = savedPath; - break; - } - case "toolbox": - { - string savedPath = OpenFolderDialog("Выберите директорию для сохранения панелей инструментов", Properties.Settings.Default.SavedUserToolboxFolderPath); - - if (string.IsNullOrEmpty(savedPath)) return; - - Properties.Settings.Default.SavedUserToolboxFolderPath = savedPath; - break; - } - case "blocks": - { - string savedPath = OpenFolderDialog("Выберите директорию для сохранения блоков", Properties.Settings.Default.SavedUserCustomBlocksFolderPath); - - if (string.IsNullOrEmpty(savedPath)) return; - - Properties.Settings.Default.SavedUserCustomBlocksFolderPath = savedPath; - break; - } - case "script": - { - string savedPath = OpenFolderDialog("Выберите директорию для сохранения скриптов", Properties.Settings.Default.SavedUserScriptsFolderPath); - - if (string.IsNullOrEmpty(savedPath)) return; - - Properties.Settings.Default.SavedUserScriptsFolderPath = savedPath; - break; - } - case "testResult": - { - string savedPath = OpenFolderDialog("Выберите директорию для сохранения результатов тестов", Properties.Settings.Default.SavedResultsNetworkTestsFolderPath); - - if (string.IsNullOrEmpty(savedPath)) return; - - Properties.Settings.Default.SavedResultsNetworkTestsFolderPath = savedPath; - break; - } - - default: - break; - } - }); - - private RelayCommand closeWindowCommand; - public RelayCommand CloseWindowCommand => closeWindowCommand ??= new RelayCommand(obj => - { - ((Window)obj).Close(); - }); - - #endregion - - #region Methods - - private string OpenFolderDialog(string title, string openDialogPath) - { - IFolderBrowser.Title = title; - IFolderBrowser.InitialFolder = openDialogPath; - IFolderBrowser.AllowMultiSelect = false; - - if (IFolderBrowser.ShowDialog() == DialogResult.Cancel) - { - SettingWindowActivated = true; - return null; - } - - SettingWindowActivated = true; - return IFolderBrowser.SelectedFolder; - } - - #endregion - - #region IWindowParam - - public override string WindowTitle => @"Настройки Adam IDE"; - public override double Width => 800; - public override double Height => 500; - - #endregion - } -} diff --git a/AdamController/ViewModels/VisualSettingsControlView.cs b/AdamController/ViewModels/VisualSettingsControlView.cs deleted file mode 100644 index 7bb1bed..0000000 --- a/AdamController/ViewModels/VisualSettingsControlView.cs +++ /dev/null @@ -1,184 +0,0 @@ -using AdamBlocklyLibrary.Enum; -using AdamController.Commands; -using AdamController.DataSource; -using AdamController.Model; -using AdamController.Properties; -using AdamController.ViewModels.HamburgerMenu; -using ControlzEx.Theming; -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Windows; - -namespace AdamController.ViewModels -{ - public class VisualSettingsControlView : HamburgerMenuItemView - { - public VisualSettingsControlView(HamburgerMenuView hamburgerMenuView) : base(hamburgerMenuView) {} - - public static ObservableCollection BlocklyThemes { get; private set; } = ThemesCollection.BlocklyThemes; - - #region LanguageSettings - - #region AppLanguage - - public static ObservableCollection LanguageApp { get; private set; } = LanguagesCollection.AppLanguageCollection; - - private AppLanguageModel selectedLanguageApp = LanguageApp.FirstOrDefault(x => x.AppLanguage == Properties.Settings.Default.AppLanguage); - public AppLanguageModel SelectedLanguageApp - { - get => selectedLanguageApp; - set - { - if (value == selectedLanguageApp) - { - return; - } - - selectedLanguageApp = value; - - OnPropertyChanged(nameof(SelectedLanguageApp)); - Properties.Settings.Default.AppLanguage = selectedLanguageApp.AppLanguage; - } - } - - #endregion - - #region BlocklyLanguage - - public static ObservableCollection BlocklyLanguageCollection { get; private set; } = LanguagesCollection.BlocklyLanguageCollection; - - private BlocklyLanguageModel selectedBlocklyWorkspaceLanguage = BlocklyLanguageCollection.FirstOrDefault(x => x.BlocklyLanguage == Properties.Settings.Default.BlocklyWorkspaceLanguage); - public BlocklyLanguageModel SelectedBlocklyWorkspaceLanguage - { - get => selectedBlocklyWorkspaceLanguage; - set - { - if (value == selectedBlocklyWorkspaceLanguage) - { - return; - } - - selectedBlocklyWorkspaceLanguage = value; - OnPropertyChanged(nameof(SelectedBlocklyWorkspaceLanguage)); - - if (!Properties.Settings.Default.ChangeToolboxLanguageToggleSwitchState) - { - SetToolboxLanguage(selectedBlocklyWorkspaceLanguage); - } - - Properties.Settings.Default.BlocklyWorkspaceLanguage = selectedBlocklyWorkspaceLanguage.BlocklyLanguage; - } - } - - #endregion - - #endregion - - #region ColorScheme Settings - - public ReadOnlyObservableCollection ColorScheme { get; set; } = ThemeManager.Current.ColorSchemes; - - private string selectedColorScheme = ThemeManager.Current.DetectTheme(Application.Current).ColorScheme; - public string SelectedColorScheme - { - get => selectedColorScheme; - set - { - if (value == selectedColorScheme) - { - return; - } - - selectedColorScheme = value; - - ChangeThemeColorScheme(selectedColorScheme); - OnPropertyChanged(nameof(SelectedColorScheme)); - } - } - - #endregion - - #region BlocklyGridLenth settings - //TODO unused this variable - private short blocklyGridLenth = Properties.Settings.Default.BlocklyGridLenth; - public short BlocklyGridLenth - { - get => blocklyGridLenth; - set - { - if (value == blocklyGridLenth) - { - return; - } - - blocklyGridLenth = value; - OnPropertyChanged(nameof(BlocklyGridLenth)); - - Settings.Default.BlocklyGridLenth = BlocklyGridLenth; - } - } - - #endregion - - private double notificationOpacity = Settings.Default.NotificationOpacity; - public double NotificationOpacity - { - get => notificationOpacity; - set - { - if (value == notificationOpacity) return; - - notificationOpacity = value; - - ChangeNotificationOpacity(notificationOpacity); - OnPropertyChanged(nameof(NotificationOpacity)); - } - } - - - #region Command - - private RelayCommand openAdvancedBlocklySettingsCommand; - public RelayCommand OpenAdvancedBlocklySettingsCommand => openAdvancedBlocklySettingsCommand ??= new RelayCommand(obj => - { - OpenAdvancedBlocklySettings(true); - }); - - private RelayCommand changeBaseColorTheme; - public RelayCommand ChangeBaseColorTheme => changeBaseColorTheme ??= new RelayCommand(obj => - { - string mainTheme = obj; - - if (mainTheme == null) return; - - ChangeBaseTheme(mainTheme); - - if (!Settings.Default.ChangeBlocklyThemeToggleSwitchState) - { - if (mainTheme == "Dark") - { - SetBlocklyThemeAndGridColor(BlocklyThemes.FirstOrDefault(x => x.BlocklyTheme == BlocklyTheme.Dark)); - } - else if (mainTheme == "Light") - { - SetBlocklyThemeAndGridColor(BlocklyThemes.FirstOrDefault(x => x.BlocklyTheme == BlocklyTheme.Classic)); - } - } - - }); - - #endregion - - #region Action - - public static Action ChangeNotificationOpacity { get; set; } - public static Action ChangeBaseTheme { get; set; } - public static Action ChangeThemeColorScheme { get; set; } - public static Action OpenAdvancedBlocklySettings { get; set; } - public static Action SetToolboxLanguage { get; set; } - public static Action SetBlocklyThemeAndGridColor { get; set; } - - #endregion - } -} diff --git a/AdamController/Views/HamburgerPage/ComputerVisionControl.xaml.cs b/AdamController/Views/HamburgerPage/ComputerVisionControl.xaml.cs deleted file mode 100644 index 4197031..0000000 --- a/AdamController/Views/HamburgerPage/ComputerVisionControl.xaml.cs +++ /dev/null @@ -1,78 +0,0 @@ -using AdamController.Helpers; -using AdamController.Properties; -using LibVLCSharp.Shared; -using System; -using System.Drawing; -using System.Windows; -using System.Windows.Controls; - -namespace AdamController.Views.HamburgerPage -{ - /// - /// Логика взаимодействия для ComputerVisionControl.xaml - /// - public partial class ComputerVisionControl : UserControl, IDisposable - { - private LibVLC mLibVLC; - private MediaPlayer mMediaPlayer; - - public ComputerVisionControl() - { - InitializeComponent(); - - VideoView.Loaded += VideoView_Loaded; - Unloaded += UserControlUnloaded; - } - - private void VideoView_Loaded(object sender, RoutedEventArgs e) - { - mLibVLC = new LibVLC(enableDebugLogs: false); - mMediaPlayer = new MediaPlayer(mLibVLC); - - VideoView.MediaPlayer = mMediaPlayer; - - mMediaPlayer.EnableHardwareDecoding = true; - mMediaPlayer.NetworkCaching = 1000; - mMediaPlayer.Scale = 0.72f; - } - - private void UserControlUnloaded(object sender, RoutedEventArgs e) - { - Dispose(); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - mMediaPlayer.Dispose(); - mLibVLC.Dispose(); - } - } - - private void Button_Click(object sender, RoutedEventArgs e) - { - string ip = Settings.Default.ServerIP; - string port = Settings.Default.VideoDataExchangePort; - - if (!VideoView.MediaPlayer.IsPlaying) - { - using var media = new Media(mLibVLC, new Uri($"http://{ip}:{port}/stream/0")); - VideoView.MediaPlayer.Play(media); - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - //public string DownRightDirection { get; private set; } = "{\"move\":{\"x\": 0, \"y\": 1, \"z\": 0}}"; - - /*private void Button_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) - { - ComunicateHelper.WebSocketSendTextMessage(DownRightDirection); - }*/ - } -} diff --git a/AdamController/Views/HamburgerPage/ScratchControl.xaml b/AdamController/Views/HamburgerPage/ScratchControl.xaml deleted file mode 100644 index ad70bfa..0000000 --- a/AdamController/Views/HamburgerPage/ScratchControl.xaml +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AdamController/Views/HamburgerPage/ScratchControl.xaml.cs b/AdamController/Views/HamburgerPage/ScratchControl.xaml.cs deleted file mode 100644 index 5445734..0000000 --- a/AdamController/Views/HamburgerPage/ScratchControl.xaml.cs +++ /dev/null @@ -1,143 +0,0 @@ -using AdamController.Helpers; -using AdamController.Model; -using AdamController.ViewModels; -using Microsoft.Web.WebView2.Core; -using Newtonsoft.Json; -using System; -using System.IO; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Threading; - -namespace AdamController.Views.HamburgerPage -{ - public partial class ScratchControl : UserControl - { - #region Singelton - - private static ScratchControl mInstance = null; - private static readonly object padlock = new(); - - public static ScratchControl Instance - { - get - { - lock (padlock) - { - if (mInstance == null) - { - mInstance = new ScratchControl(); - } - return mInstance; - } - } - } - - #endregion - - #region Action - - public static Action NavigationComplete { get; set; } - public static Action WebMessageReceived { get; set; } - - #endregion - - private readonly string mPathToSource = Path.Combine(FolderHelper.CommonDirAppData, "BlocklySource"); - private readonly string mPath = Path.Combine(Path.GetTempPath(), "AdamBrowser"); - - public ScratchControl() - { - mInstance = this; - InitializeComponent(); - - WebView.CoreWebView2InitializationCompleted += WebViewCoreWebView2InitializationCompleted; - WebView.NavigationCompleted += WebViewNavigationCompleted; - WebView.WebMessageReceived += WebViewWebMessageReceived; - - InitializeWebViewCore(); - - TextResulEditor.TextChanged += TextResulEditorTextChanged; - - if (ScratchControlView.ReloadWebView == null) - { - ScratchControlView.ReloadWebView = new Action(() => WebView.CoreWebView2.Reload()); - } - } - - private void TextResulEditorTextChanged(object sender, EventArgs e) - { - Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => - { - TextResulEditor.ScrollToEnd(); - })); - } - - private async void InitializeWebViewCore() - { - CoreWebView2Environment env = await CoreWebView2Environment.CreateAsync(userDataFolder: mPath); - await WebView.EnsureCoreWebView2Async(env); - } - - private void WebViewCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) - { - WebView.CoreWebView2.Settings.AreDevToolsEnabled = true; - WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = !Properties.Settings.Default.DontShowBrowserMenuInBlockly; - - WebView.CoreWebView2.Settings.AreHostObjectsAllowed = true; - - WebView.CoreWebView2.SetVirtualHostNameToFolderMapping("localhost", mPathToSource, CoreWebView2HostResourceAccessKind.Allow); - WebView.CoreWebView2.Navigate("https://localhost/index.html"); - } - - #region Func - - public static Func> ExecuteScript = async script => await mInstance.ExecuteScripts(script); - - public async Task ExecuteScripts(string script) - { - string result = await WebView.ExecuteScriptAsync(script); - return result; - } - - #endregion - - private void WebViewNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) => NavigationComplete(); - - private void WebViewWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e) - { - ParseJsonReceived(e.WebMessageAsJson); - } - - private async void ParseJsonReceived(string json) - { - await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => - { - dynamic jsonClean = JsonConvert.DeserializeObject(json); - WebMessageJsonReceived results = JsonConvert.DeserializeObject(jsonClean); - if (results == null) return; - - WebMessageReceived(results); - })); - } - } - - public static class Extensions - { - public static string ToRbgColor(this string hexColorString) - { - if(string.IsNullOrEmpty(hexColorString)) - { - return ""; - } - - byte R = Convert.ToByte(hexColorString.Substring(3, 2), 16); - byte G = Convert.ToByte(hexColorString.Substring(5, 2), 16); - byte B = Convert.ToByte(hexColorString.Substring(7, 2), 16); - - return $"rgb({R}, {G}, {B})"; - } - } - - //TODO To HUE COLOR -} diff --git a/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml b/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml deleted file mode 100644 index 128f083..0000000 --- a/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml +++ /dev/null @@ -1,448 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml.cs b/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml.cs deleted file mode 100644 index b7bfd09..0000000 --- a/AdamController/Views/HamburgerPage/ScriptEditorControl.xaml.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Threading; - - -namespace AdamController.Views.HamburgerPage -{ - public partial class ScriptEditorControl : UserControl - { - public ScriptEditorControl() - { - InitializeComponent(); - //LoadHighlighting(); - - TextResulEditor.TextChanged += TextResulEditorTextChanged; - } - - private void TextResulEditorTextChanged(object sender, EventArgs e) - { - Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => - { - TextResulEditor.ScrollToEnd(); - })); - - } - - #region Example code - - /*public ScriptEditorControl() - { - //IHighlightingDefinition customHighlighting = HighlightingManager.Instance.HighlightingDefinitions[0]; - - InitializeComponent(); - - //textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#"); - //textEditor.SyntaxHighlighting = customHighlighting; - // initial highlighting now set by XAML - - //textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering; - //textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered; - - /*DispatcherTimer foldingUpdateTimer = new() - { - Interval = TimeSpan.FromSeconds(2) - }; - - foldingUpdateTimer.Tick += foldingUpdateTimer_Tick; - foldingUpdateTimer.Start(); - } - string currentFileName; - - void openFileClick(object sender, RoutedEventArgs e) - { - OpenFileDialog dlg = new() - { - CheckFileExists = true - }; - - if (dlg.ShowDialog() ?? false) - { - currentFileName = dlg.FileName; - textEditor.Load(currentFileName); - textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(currentFileName)); - } - } - - void saveFileClick(object sender, EventArgs e) - { - if (currentFileName == null) - { - SaveFileDialog dlg = new SaveFileDialog(); - dlg.DefaultExt = ".txt"; - if (dlg.ShowDialog() ?? false) - { - currentFileName = dlg.FileName; - } - else - { - return; - } - } - textEditor.Save(currentFileName); - } - - - - CompletionWindow completionWindow; - - void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e) - { - if (e.Text == ".") - { - // open code completion after the user has pressed dot: - completionWindow = new CompletionWindow(textEditor.TextArea); - - // provide AvalonEdit with the data: - IList data = completionWindow.CompletionList.CompletionData; - - data.Add(new EditorModel("Item1")); - data.Add(new EditorModel("Item2")); - data.Add(new EditorModel("Item3")); - data.Add(new EditorModel("Another item")); - completionWindow.Show(); - completionWindow.Closed += delegate { - completionWindow = null; - }; - } - } - - void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e) - { - if (e.Text.Length > 0 && completionWindow != null) - { - if (!char.IsLetterOrDigit(e.Text[0])) - { - // Whenever a non-letter is typed while the completion window is open, - // insert the currently selected element. - completionWindow.CompletionList.RequestInsertion(e); - } - } - // do not set e.Handled=true - we still want to insert the character that was typed - } - - #region Folding - private FoldingManager foldingManager; - private XmlFoldingStrategy foldingStrategy; - - void HighlightingComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (textEditor.SyntaxHighlighting == null) - { - foldingStrategy = null; - } - else - { - switch (textEditor.SyntaxHighlighting.Name) - { - case "XML": - foldingStrategy = new XmlFoldingStrategy(); - textEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.DefaultIndentationStrategy(); - break; - case "C#": - case "C++": - case "PHP": - case "Java": - textEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.CSharp.CSharpIndentationStrategy(textEditor.Options); - foldingStrategy = new XmlFoldingStrategy(); - break; - default: - textEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.DefaultIndentationStrategy(); - foldingStrategy = null; - break; - } - } - if (foldingStrategy != null) - { - if (foldingManager == null) - foldingManager = FoldingManager.Install(textEditor.TextArea); - - foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); - } - else - { - if (foldingManager != null) - { - FoldingManager.Uninstall(foldingManager); - foldingManager = null; - } - } - } - - void foldingUpdateTimer_Tick(object sender, EventArgs e) - { - if (foldingStrategy != null) - { - foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); - } - } - - }*/ - - #endregion - } -} diff --git a/AdamController/Views/HamburgerPage/VisualSettingsControl.xaml b/AdamController/Views/HamburgerPage/VisualSettingsControl.xaml deleted file mode 100644 index 7b56149..0000000 --- a/AdamController/Views/HamburgerPage/VisualSettingsControl.xaml +++ /dev/null @@ -1,551 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/Modules/AdamController.Modules.ContentRegion/Views/ScratchControlView.xaml.cs b/Modules/AdamController.Modules.ContentRegion/Views/ScratchControlView.xaml.cs new file mode 100644 index 0000000..38efa24 --- /dev/null +++ b/Modules/AdamController.Modules.ContentRegion/Views/ScratchControlView.xaml.cs @@ -0,0 +1,143 @@ +using AdamController.Controls.CustomControls.Services; +using AdamController.Core.Properties; +using AdamController.Services.Interfaces; +using AdamController.Services.WebViewProviderDependency; +using Microsoft.Web.WebView2.Core; +using System; +using System.IO; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; + +namespace AdamController.Modules.ContentRegion.Views +{ + public partial class ScratchControlView : UserControl + { + #region Services + + private readonly IWebViewProvider mWebViewProvider; + private readonly IStatusBarNotificationDeliveryService mStatusBarNotification; + private readonly IControlHelper mControlHelper; + + #endregion + + #region Var + + private readonly string mPathToSource; + private readonly string mPath; + + #endregion + + public ScratchControlView(IWebViewProvider webViewProvider, IStatusBarNotificationDeliveryService statusBarNotification, IFolderManagmentService folderManagment, IControlHelper controlHelper) + { + InitializeComponent(); + InitializeWebViewCore(); + + mWebViewProvider = webViewProvider; + mStatusBarNotification = statusBarNotification; + mControlHelper = controlHelper; + + mPathToSource = Path.Combine(folderManagment.CommonDirAppData, "BlocklySource"); + mPath = Path.Combine(Path.GetTempPath(), "AdamBrowser"); + + WebView.CoreWebView2InitializationCompleted += WebViewCoreWebView2InitializationCompleted; + WebView.NavigationCompleted += WebViewNavigationCompleted; + WebView.WebMessageReceived += WebViewWebMessageReceived; + + mWebViewProvider.RaiseExecuteJavaScriptEvent += RaiseExecuteJavaScriptEvent; + mWebViewProvider.RaiseExecuteReloadWebViewEvent += RaiseExecuteReloadWebViewEvent; + + /*element event */ + TextResulEditor.TextChanged += TextResulEditorTextChanged; + MainGrid.SizeChanged += MainGridSizeChanged; + SourceEditor.SizeChanged += TextResulEditorSizeChanged; + + /* service event */ + mControlHelper.RaiseBlocklyColumnWidthChangeEvent += RaiseBlocklyColumnWidthChangeEvent; + } + + private void RaiseBlocklyColumnWidthChangeEvent(object sender) + { + double doubleWidth = mControlHelper.BlocklyColumnWidth; + GridLength width = new(doubleWidth); + BlocklyColumn.Width = width; + } + + private void TextResulEditorSizeChanged(object sender, SizeChangedEventArgs e) + { + mControlHelper.BlocklyColumnActualWidth = BlocklyColumn.ActualWidth; + } + + private void MainGridSizeChanged(object sender, SizeChangedEventArgs e) + { + mControlHelper.MainGridActualWidth = MainGrid.ActualWidth; + } + + private void RaiseExecuteReloadWebViewEvent(object sender) + { + WebView?.CoreWebView2?.Reload(); + } + + private async Task RaiseExecuteJavaScriptEvent(object sender, string script, bool deserializeResultToString = false) + { + string result = await WebView.ExecuteScriptAsync(script); + + if (deserializeResultToString) + { + string deserealizeString = JsonSerializer.Deserialize(result); + return deserealizeString; + } + + return result; + } + + private void WebViewNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) + { + mWebViewProvider.NavigationComplete(); + } + + private void TextResulEditorTextChanged(object sender, EventArgs e) + { + Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(TextResulEditor.ScrollToEnd)); + } + + private async void InitializeWebViewCore() + { + CoreWebView2Environment env = await CoreWebView2Environment.CreateAsync(userDataFolder: mPath); + await WebView.EnsureCoreWebView2Async(env); + } + + private void WebViewCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) + { + WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = !Settings.Default.DontShowBrowserMenuInBlockly; + WebView.CoreWebView2.SetVirtualHostNameToFolderMapping("localhost", mPathToSource, CoreWebView2HostResourceAccessKind.Allow); + WebView.CoreWebView2.Navigate("https://localhost/index.html"); + } + + private void WebViewWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e) + { + JsonSerializerOptions options = new() + { + NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString + }; + + WebMessageJsonReceived receivedResult; + + try + { + string receivedString = e.TryGetWebMessageAsString(); + receivedResult = JsonSerializer.Deserialize(receivedString, options); + } + catch + { + mStatusBarNotification.AppLogMessage = "Error reading blokly code"; + receivedResult = new WebMessageJsonReceived { Action = string.Empty, Data = string.Empty }; + } + + mWebViewProvider.WebViewMessageReceived(receivedResult); + } + } +} diff --git a/Modules/AdamController.Modules.ContentRegion/Views/VisualSettingsControlView.xaml b/Modules/AdamController.Modules.ContentRegion/Views/VisualSettingsControlView.xaml new file mode 100644 index 0000000..1d61dd2 --- /dev/null +++ b/Modules/AdamController.Modules.ContentRegion/Views/VisualSettingsControlView.xaml @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/NotificationView.xaml.cs b/Modules/AdamController.Modules.FlayoutsRegion/Views/NotificationView.xaml.cs new file mode 100644 index 0000000..ec9c626 --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/NotificationView.xaml.cs @@ -0,0 +1,12 @@ +using System.Windows.Controls; + +namespace AdamController.Modules.FlayoutsRegion.Views +{ + public partial class NotificationView : UserControl + { + public NotificationView() + { + InitializeComponent(); + } + } +} diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml b/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml new file mode 100644 index 0000000..f206996 --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml.cs b/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml.cs new file mode 100644 index 0000000..e2028ba --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/PortSettingsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace AdamController.Modules.FlayoutsRegion.Views +{ + /// + /// Логика взаимодействия для PortSettingsView.xaml + /// + public partial class PortSettingsView : UserControl + { + public PortSettingsView() + { + InitializeComponent(); + } + } +} diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml b/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml new file mode 100644 index 0000000..4c45a7d --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml.cs b/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml.cs new file mode 100644 index 0000000..f736456 --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/UserFoldersSettingsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace AdamController.Modules.FlayoutsRegion.Views +{ + /// + /// Логика взаимодействия для UserFoldersSettingsView.xaml + /// + public partial class UserFoldersSettingsView : UserControl + { + public UserFoldersSettingsView() + { + InitializeComponent(); + } + } +} diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml b/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml new file mode 100644 index 0000000..0b499cd --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml.cs b/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml.cs new file mode 100644 index 0000000..f508d6f --- /dev/null +++ b/Modules/AdamController.Modules.FlayoutsRegion/Views/WebApiSettingsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace AdamController.Modules.FlayoutsRegion.Views +{ + /// + /// Логика взаимодействия для WebApiSettingsView.xaml + /// + public partial class WebApiSettingsView : UserControl + { + public WebApiSettingsView() + { + InitializeComponent(); + } + } +} diff --git a/Modules/AdamController.Modules.MenuRegion/AdamController.Modules.MenuRegion.csproj b/Modules/AdamController.Modules.MenuRegion/AdamController.Modules.MenuRegion.csproj new file mode 100644 index 0000000..ecb20a5 --- /dev/null +++ b/Modules/AdamController.Modules.MenuRegion/AdamController.Modules.MenuRegion.csproj @@ -0,0 +1,12 @@ + + + net7.0-windows7.0 + true + + + + + + + + \ No newline at end of file diff --git a/Modules/AdamController.Modules.MenuRegion/MenuRegionModule.cs b/Modules/AdamController.Modules.MenuRegion/MenuRegionModule.cs new file mode 100644 index 0000000..eb6bf92 --- /dev/null +++ b/Modules/AdamController.Modules.MenuRegion/MenuRegionModule.cs @@ -0,0 +1,30 @@ +using AdamController.Core; +using AdamController.Modules.MenuRegion.Views; +using Prism.Ioc; +using Prism.Modularity; +using Prism.Regions; + +namespace AdamController.Modules.MenuRegion +{ + public class MenuRegionModule : IModule + { + private readonly IRegionManager mRegionManager; + + public MenuRegionModule(IRegionManager regionManager) + { + mRegionManager = regionManager; + } + + public void OnInitialized(IContainerProvider containerProvider) + { + mRegionManager.RequestNavigate(RegionNames.MenuRegion, nameof(MenuRegionView)); + } + + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterForNavigation(); + + containerRegistry.RegisterForNavigation(nameof(MenuRegionView)); + } + } +} \ No newline at end of file diff --git a/Modules/AdamController.Modules.MenuRegion/ViewModels/MenuRegionViewModel.cs b/Modules/AdamController.Modules.MenuRegion/ViewModels/MenuRegionViewModel.cs new file mode 100644 index 0000000..59f44ac --- /dev/null +++ b/Modules/AdamController.Modules.MenuRegion/ViewModels/MenuRegionViewModel.cs @@ -0,0 +1,160 @@ +using AdamController.Core; +using AdamController.Core.Mvvm; +using Prism.Commands; +using Prism.Regions; +using System.Windows; +using System; +using AdamController.Services.Interfaces; + +namespace AdamController.Modules.MenuRegion.ViewModels +{ + public class MenuRegionViewModel : RegionViewModelBase + { + + #region DelegateCommands + + public DelegateCommand CloseAppCommand { get; } + public DelegateCommand ShowRegionCommand { get; } + + #endregion + + #region Services + + private readonly ISubRegionChangeAwareService mSubRegionChangeAware; + + #endregion + + public MenuRegionViewModel(IRegionManager regionManager,ISubRegionChangeAwareService subRegionChangeAware) : base(regionManager) + { + mSubRegionChangeAware = subRegionChangeAware; + + CloseAppCommand = new DelegateCommand(CloseApp); + ShowRegionCommand = new DelegateCommand(ShowRegion); + } + + #region Navigation + + public override void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) + { + base.ConfirmNavigationRequest(navigationContext, continuationCallback); + } + + public override void OnNavigatedTo(NavigationContext navigationContext) + { + Subscribe(); + + base.OnNavigatedTo(navigationContext); + } + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + Unsubscribe(); + + base.OnNavigatedFrom(navigationContext); + } + + #endregion + + #region Public fields + + private bool isCheckedScratchMenuItem; + public bool IsCheckedScratchMenuItem + { + get => isCheckedScratchMenuItem; + set => SetProperty(ref isCheckedScratchMenuItem, value); + } + + private bool isCheckedComputerVisionMenuItem; + public bool IsCheckedComputerVisionMenuItem + { + get => isCheckedComputerVisionMenuItem; + set => SetProperty(ref isCheckedComputerVisionMenuItem, value); + } + + private bool isCheckedVisualSettingsMenuItem; + public bool IsCheckedVisualSettingsMenuItem + { + get => isCheckedVisualSettingsMenuItem; + set => SetProperty(ref isCheckedVisualSettingsMenuItem, value); + } + + #endregion + + #region Private methods + + private void ChangeCheckedMenuItem(string selectedSubRegionName) + { + ResetIsCheckedMenuItem(); + + switch (selectedSubRegionName) + { + case SubRegionNames.SubRegionScratch: + IsCheckedScratchMenuItem = true; + break; + case SubRegionNames.SubRegionComputerVisionControl: + IsCheckedComputerVisionMenuItem = true; + break; + case SubRegionNames.SubRegionVisualSettings: + IsCheckedVisualSettingsMenuItem = true; + break; + } + } + + private void ResetIsCheckedMenuItem() + { + IsCheckedScratchMenuItem = false; + IsCheckedComputerVisionMenuItem = false; + IsCheckedVisualSettingsMenuItem = false; + } + + #endregion + + #region Subscription + + private void Subscribe() + { + mSubRegionChangeAware.RaiseSubRegionChangeEvent += RaiseSubRegionChangeEvent; + } + + private void Unsubscribe() + { + mSubRegionChangeAware.RaiseSubRegionChangeEvent -= RaiseSubRegionChangeEvent; + } + + #endregion + + #region Event methods + + private void RaiseSubRegionChangeEvent(object sender) + { + ChangeCheckedMenuItem(mSubRegionChangeAware.InsideRegionNavigationRequestName); + } + + #endregion + + #region Command methods + + private void ShowRegion(string subRegionName) + { + switch (subRegionName) + { + case SubRegionNames.SubRegionScratch: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionScratch); + break; + case SubRegionNames.SubRegionComputerVisionControl: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionComputerVisionControl); + break; + case SubRegionNames.SubRegionVisualSettings: + RegionManager.RequestNavigate(RegionNames.ContentRegion, SubRegionNames.SubRegionVisualSettings); + break; + } + } + + private void CloseApp() + { + Application.Current.Shutdown(); + } + + #endregion + } +} diff --git a/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml b/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml new file mode 100644 index 0000000..1bb61cd --- /dev/null +++ b/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml.cs b/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml.cs new file mode 100644 index 0000000..0581765 --- /dev/null +++ b/Modules/AdamController.Modules.MenuRegion/Views/MenuRegionView.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace AdamController.Modules.MenuRegion.Views +{ + /// + /// Interaction logic for ViewA.xaml + /// + public partial class MenuRegionView : UserControl + { + public MenuRegionView() + { + InitializeComponent(); + } + } +} diff --git a/Modules/AdamController.Modules.StatusBar/AdamController.Modules.StatusBarRegion.csproj b/Modules/AdamController.Modules.StatusBar/AdamController.Modules.StatusBarRegion.csproj new file mode 100644 index 0000000..ecb20a5 --- /dev/null +++ b/Modules/AdamController.Modules.StatusBar/AdamController.Modules.StatusBarRegion.csproj @@ -0,0 +1,12 @@ + + + net7.0-windows7.0 + true + + + + + + + + \ No newline at end of file diff --git a/Modules/AdamController.Modules.StatusBar/StatusBarRegionModule.cs b/Modules/AdamController.Modules.StatusBar/StatusBarRegionModule.cs new file mode 100644 index 0000000..484ed6c --- /dev/null +++ b/Modules/AdamController.Modules.StatusBar/StatusBarRegionModule.cs @@ -0,0 +1,30 @@ +using AdamController.Core; +using AdamController.Modules.StatusBarRegion.Views; +using Prism.Ioc; +using Prism.Modularity; +using Prism.Regions; + +namespace AdamController.Modules.StatusBarRegion +{ + public class StatusBarRegionModule : IModule + { + private readonly IRegionManager mRegionManager; + + public StatusBarRegionModule(IRegionManager regionManager) + { + mRegionManager = regionManager; + } + + public void OnInitialized(IContainerProvider containerProvider) + { + mRegionManager.RequestNavigate(RegionNames.StatusBarRegion, nameof(StatusBarView)); + } + + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterForNavigation(); + + containerRegistry.RegisterForNavigation(nameof(StatusBarView)); + } + } +} \ No newline at end of file diff --git a/Modules/AdamController.Modules.StatusBar/ViewModels/StatusBarViewModel.cs b/Modules/AdamController.Modules.StatusBar/ViewModels/StatusBarViewModel.cs new file mode 100644 index 0000000..cace90f --- /dev/null +++ b/Modules/AdamController.Modules.StatusBar/ViewModels/StatusBarViewModel.cs @@ -0,0 +1,335 @@ +using AdamController.Controls.CustomControls.Services; +using AdamController.Controls.Enums; +using AdamController.Core; +using AdamController.Core.Mvvm; +using AdamController.Services.Interfaces; +using MahApps.Metro.IconPacks; +using Prism.Commands; +using Prism.Regions; +using System; + +namespace AdamController.Modules.StatusBarRegion.ViewModels +{ + public class StatusBarViewModel : RegionViewModelBase + { + #region DelegateCommands + + public DelegateCommand OpenNotificationPanelDelegateCommand { get; } + + #endregion + + #region Services + + private readonly IFlyoutManager mFlyoutManager; + private readonly ICommunicationProviderService mCommunicationProviderService; + private readonly IStatusBarNotificationDeliveryService mStatusBarNotificationDelivery; + private readonly IFlyoutStateChecker mFlyoutState; + private readonly ICultureProvider mCultureProvider; + private readonly IControlHelper mControlHelper; + + #endregion + + #region Var + + private string mTextOnStatusConnectToolbarDisconnected; + private string mTextOnStatusConnectToolbarConnected; + private string mTextOnStatusConnectToolbarReconnected; + + private string mCompileLogStatusBar; + private string mAppLogStatusBar; + private string mChangAppLanguageLogMessage; + + #endregion + + #region ~ + + public StatusBarViewModel(IRegionManager regionManager, IFlyoutManager flyoutManager, IFlyoutStateChecker flyoutState, ICommunicationProviderService communicationProviderService, + IStatusBarNotificationDeliveryService statusBarNotification, ICultureProvider cultureProvider, IControlHelper controlHelper) : base(regionManager) + { + mFlyoutManager = flyoutManager; + mCommunicationProviderService = communicationProviderService; + mStatusBarNotificationDelivery = statusBarNotification; + mFlyoutState = flyoutState; + mCultureProvider = cultureProvider; + mControlHelper = controlHelper; + + OpenNotificationPanelDelegateCommand = new DelegateCommand(OpenNotificationPanel, OpenNotificationPanelCanExecute); + + LoadResource(); + LoadDefaultFieldValue(); + } + + #endregion + + #region DelegateCommands methods + + private void OpenNotificationPanel() + { + if(mControlHelper.CurrentBlocklyViewMode == BlocklyViewMode.FullScreen) + { + mControlHelper.CurrentBlocklyViewMode = BlocklyViewMode.MiddleScreen; + } + + mFlyoutManager.OpenFlyout(FlyoutNames.FlyoutNotification); + + } + + private bool OpenNotificationPanelCanExecute() + { + return !mFlyoutState.IsNotificationFlyoutOpened; + } + + #endregion + + #region Navigation + + public override void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) + { + base.ConfirmNavigationRequest(navigationContext, continuationCallback); + } + + public override void OnNavigatedTo(NavigationContext navigationContext) + { + Subscribe(); + + base.OnNavigatedTo(navigationContext); + } + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + Unsubscribe(); + + base.OnNavigatedFrom(navigationContext); + } + + + #endregion + + #region Public fields + + private bool progressRingStart; + public bool ProgressRingStart + { + get { return progressRingStart; } + set { SetProperty(ref progressRingStart, value); } + } + + private string compileLogStatusBar; + public string CompileLogStatusBar + { + get { return compileLogStatusBar; } + set { SetProperty(ref compileLogStatusBar, value); } + } + + private string appLogStatusBar; + public string AppLogStatusBar + { + get { return appLogStatusBar; } + set { SetProperty(ref appLogStatusBar, value); } + } + + private PackIconModernKind connectIcon; + public PackIconModernKind ConnectIcon + { + get { return connectIcon; } + set { SetProperty(ref connectIcon, value); } + } + + private string textOnStatusConnectToolbar; + public string TextOnStatusConnectToolbar + { + get { return textOnStatusConnectToolbar; } + set { SetProperty(ref textOnStatusConnectToolbar, value); } + } + + private string notificationBadge; + public string NotificationBadge + { + get { return notificationBadge; } + set { SetProperty(ref notificationBadge, value); } + } + + #endregion + + #region Private fields + + private int badgeCounter = 0; + private int BadgeCounter + { + get { return badgeCounter; } + set + { + var isNewValue = SetProperty(ref badgeCounter, value); + + if (isNewValue) + UpdateNotificationBagde(); + + if (BadgeCounter == 0) + NotificationBadge = string.Empty; + } + } + + private bool? isConnected = false; + public bool? IsConnected + { + get => isConnected; + set + { + var isNewValue = SetProperty(ref isConnected, value); + + if (isNewValue) + UpdateStatusConnectToolbar(); + } + + } + + + #endregion + + #region Private methods + + private void LoadDefaultFieldValue() + { + CompileLogStatusBar = mCompileLogStatusBar; + AppLogStatusBar = mAppLogStatusBar; + TextOnStatusConnectToolbar = mTextOnStatusConnectToolbarDisconnected; + ConnectIcon = PackIconModernKind.Connect; + + } + + /// + /// BadgeCounter < 2 + /// Restricts the notification counter so that it is not updated on repeated connections. + /// Only one notification will work. When the second one appears, they will need to be distinguished somehow. + /// + private void UpdateNotificationBagde() + { + if(BadgeCounter < 2) + NotificationBadge = $"{BadgeCounter}"; + } + + private void LoadResource() + { + mTextOnStatusConnectToolbarDisconnected = mCultureProvider.FindResource("StatusBarViewModel.TextOnStatusConnectToolbarDisconnected"); + mTextOnStatusConnectToolbarConnected = mCultureProvider.FindResource("StatusBarViewModel.TextOnStatusConnectToolbarConnected"); + mTextOnStatusConnectToolbarReconnected = mCultureProvider.FindResource("StatusBarViewModel.TextOnStatusConnectToolbarReconnected"); + + mCompileLogStatusBar = mCultureProvider.FindResource("StatusBarViewModel.CompileLogStatusBar"); + mAppLogStatusBar = mCultureProvider.FindResource("StatusBarViewModel.AppLogStatusBar"); + + mChangAppLanguageLogMessage = mCultureProvider.FindResource("StatusBarViewModel.ChangAppLanguage.LogMessage"); + } + + private void UpdateStatusConnectToolbar() + { + if(IsConnected == true) + { + TextOnStatusConnectToolbar = mTextOnStatusConnectToolbarConnected; + ConnectIcon = PackIconModernKind.Disconnect; + } + + if (IsConnected == false) + { + TextOnStatusConnectToolbar = mTextOnStatusConnectToolbarDisconnected; + ConnectIcon = PackIconModernKind.Connect; + } + + AppLogStatusBar = mChangAppLanguageLogMessage; + } + + #endregion + + #region Subscribes + + private void Subscribe() + { + mCommunicationProviderService.RaiseTcpServiceCientConnectedEvent += RaiseAdamTcpCientConnectedEvent; + mCommunicationProviderService.RaiseTcpServiceClientDisconnectEvent += RaiseAdamTcpClientDisconnectEvent; + mCommunicationProviderService.RaiseTcpServiceClientReconnectedEvent += RaiseTcpServiceClientReconnectedEvent; + + mStatusBarNotificationDelivery.RaiseChangeProgressRingStateEvent += RaiseChangeProgressRingStateEvent; + mStatusBarNotificationDelivery.RaiseNewCompileLogMessageEvent += RaiseNewCompileLogMessageEvent; + mStatusBarNotificationDelivery.RaiseNewAppLogMessageEvent += RaiseNewAppLogMessageEvent; + mStatusBarNotificationDelivery.RaiseUpdateNotificationCounterEvent += RaiseUpdateNotificationCounterEvent; + + mFlyoutState.IsNotificationFlyoutOpenedStateChangeEvent += IsOpenedStateChangeEvent; + + mCultureProvider.RaiseCurrentAppCultureLoadOrChangeEvent += RaiseCurrentAppCultureLoadOrChangeEvent; + } + + private void Unsubscribe() + { + mCommunicationProviderService.RaiseTcpServiceCientConnectedEvent -= RaiseAdamTcpCientConnectedEvent; + mCommunicationProviderService.RaiseTcpServiceClientDisconnectEvent -= RaiseAdamTcpClientDisconnectEvent; + mCommunicationProviderService.RaiseTcpServiceClientReconnectedEvent -= RaiseTcpServiceClientReconnectedEvent; + + mStatusBarNotificationDelivery.RaiseChangeProgressRingStateEvent -= RaiseChangeProgressRingStateEvent; + mStatusBarNotificationDelivery.RaiseNewCompileLogMessageEvent -= RaiseNewCompileLogMessageEvent; + mStatusBarNotificationDelivery.RaiseNewAppLogMessageEvent -= RaiseNewAppLogMessageEvent; + + mFlyoutState.IsNotificationFlyoutOpenedStateChangeEvent -= IsOpenedStateChangeEvent; + + mCultureProvider.RaiseCurrentAppCultureLoadOrChangeEvent -= RaiseCurrentAppCultureLoadOrChangeEvent; + } + + #endregion + + #region Event methods + + private void RaiseAdamTcpCientConnectedEvent(object sender) + { + IsConnected = true; + } + + private void RaiseTcpServiceClientReconnectedEvent(object sender, int reconnectCounter) + { + mStatusBarNotificationDelivery.NotificationCounter++; + ConnectIcon = PackIconModernKind.TransitConnectionDeparture; + TextOnStatusConnectToolbar = $"{mTextOnStatusConnectToolbarReconnected} {reconnectCounter}"; + } + + private void RaiseAdamTcpClientDisconnectEvent(object sender, bool isUserRequest) + { + + IsConnected = false; + + if(!isUserRequest) + mStatusBarNotificationDelivery.NotificationCounter++; + } + + private void RaiseChangeProgressRingStateEvent(object sender, bool newState) + { + ProgressRingStart = newState; + } + + private void RaiseNewCompileLogMessageEvent(object sender, string message) + { + CompileLogStatusBar = message; + } + + private void RaiseNewAppLogMessageEvent(object sender, string message) + { + AppLogStatusBar = message; + } + + private void RaiseUpdateNotificationCounterEvent(object sender, int counter) + { + BadgeCounter = counter; + } + + private void IsOpenedStateChangeEvent(object sender) + { + OpenNotificationPanelDelegateCommand.RaiseCanExecuteChanged(); + } + + private void RaiseCurrentAppCultureLoadOrChangeEvent(object sender) + { + LoadResource(); + UpdateStatusConnectToolbar(); + } + + #endregion + + + } +} diff --git a/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml b/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml new file mode 100644 index 0000000..b4e675d --- /dev/null +++ b/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml.cs b/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml.cs new file mode 100644 index 0000000..090c59c --- /dev/null +++ b/Modules/AdamController.Modules.StatusBar/Views/StatusBarView.xaml.cs @@ -0,0 +1,12 @@ +using System.Windows.Controls; + +namespace AdamController.Modules.StatusBarRegion.Views +{ + public partial class StatusBarView : UserControl + { + public StatusBarView() + { + InitializeComponent(); + } + } +} diff --git a/README.md b/README.md index 9d95b2e..1e302b7 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,7 @@ For a successful launch, the following components must be installed in the syste * [MicrosoftEdgeWebView2RuntimeInstaller.113.0.1774.50.X64](https://disk.yandex.ru/d/vT4lVRCzDylGYA) * [VC_redist.14.29.30135.0.x64](https://disk.yandex.ru/d/0hzuZSiQIxZxLQ) * [windowsdesktop-runtime-7.0.5-win-x64](https://disk.yandex.ru/d/TQ2qIRYBnq2Ecw) + +# Thanks + +The Flyout solution is copied from [here](https://github.com/alsiola/FlyoutManager).