mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-07-01 08:23:42 -04:00
Add project files.
This commit is contained in:
13
ObservatoryCore/UI/MainApplication.axaml
Normal file
13
ObservatoryCore/UI/MainApplication.axaml
Normal file
@ -0,0 +1,13 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Observatory.UI"
|
||||
x:Class="Observatory.UI.MainApplication">
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
<Application.Styles>
|
||||
<FluentTheme Mode="Dark"/>
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/>
|
||||
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
29
ObservatoryCore/UI/MainApplication.axaml.cs
Normal file
29
ObservatoryCore/UI/MainApplication.axaml.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Observatory.UI.ViewModels;
|
||||
|
||||
namespace Observatory.UI
|
||||
{
|
||||
public class MainApplication : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
var pluginManager = PluginManagement.PluginManager.GetInstance;
|
||||
desktop.MainWindow = new Views.MainWindow()
|
||||
{
|
||||
DataContext = new MainWindowViewModel(pluginManager)
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
14
ObservatoryCore/UI/Models/BasicUIModel.cs
Normal file
14
ObservatoryCore/UI/Models/BasicUIModel.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Observatory.UI.Models
|
||||
{
|
||||
public class BasicUIModel
|
||||
{
|
||||
public string Time { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
17
ObservatoryCore/UI/Models/CoreModel.cs
Normal file
17
ObservatoryCore/UI/Models/CoreModel.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Observatory.UI.ViewModels;
|
||||
|
||||
namespace Observatory.UI.Models
|
||||
{
|
||||
public class CoreModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public ViewModelBase UI { get; set; }
|
||||
|
||||
}
|
||||
}
|
14
ObservatoryCore/UI/Models/NotificationModel.cs
Normal file
14
ObservatoryCore/UI/Models/NotificationModel.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Observatory.UI.Models
|
||||
{
|
||||
public class NotificationModel
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Detail { get; set; }
|
||||
}
|
||||
}
|
31
ObservatoryCore/UI/TabTemplateSelector.cs
Normal file
31
ObservatoryCore/UI/TabTemplateSelector.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Metadata;
|
||||
using Observatory.UI.Views;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Observatory.UI
|
||||
{
|
||||
public class TabTemplateSelector : IDataTemplate
|
||||
{
|
||||
public bool SupportsRecycling => false;
|
||||
|
||||
[Content]
|
||||
public Dictionary<string, IDataTemplate> Templates { get; } = new Dictionary<string, IDataTemplate>();
|
||||
|
||||
|
||||
public IControl Build(object param)
|
||||
{
|
||||
return new BasicUIView(); //Templates[param].Build(param);
|
||||
}
|
||||
|
||||
public bool Match(object data)
|
||||
{
|
||||
return data is BasicUIView;
|
||||
}
|
||||
}
|
||||
}
|
32
ObservatoryCore/UI/ViewLocator.cs
Normal file
32
ObservatoryCore/UI/ViewLocator.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Observatory.UI.ViewModels;
|
||||
using System;
|
||||
|
||||
namespace Observatory.UI
|
||||
{
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
public bool SupportsRecycling => false;
|
||||
|
||||
public IControl Build(object data)
|
||||
{
|
||||
var name = data.GetType().FullName!.Replace("ViewModel", "View");
|
||||
var type = Type.GetType(name);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return (Control)Activator.CreateInstance(type)!;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
}
|
||||
|
||||
public bool Match(object data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
}
|
||||
}
|
||||
}
|
67
ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
Normal file
67
ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.ObjectModel;
|
||||
using Observatory.UI.Models;
|
||||
using ReactiveUI;
|
||||
using System.Reactive.Linq;
|
||||
using Observatory.Framework;
|
||||
|
||||
namespace Observatory.UI.ViewModels
|
||||
{
|
||||
public class BasicUIViewModel : ViewModelBase
|
||||
{
|
||||
private ObservableCollection<object> basicUIGrid;
|
||||
|
||||
|
||||
public ObservableCollection<object> BasicUIGrid
|
||||
{
|
||||
get => basicUIGrid;
|
||||
set
|
||||
{
|
||||
basicUIGrid = value;
|
||||
this.RaisePropertyChanged(nameof(BasicUIGrid));
|
||||
}
|
||||
}
|
||||
|
||||
public BasicUIViewModel(ObservableCollection<object> BasicUIGrid)
|
||||
{
|
||||
|
||||
this.BasicUIGrid = new();
|
||||
this.BasicUIGrid = BasicUIGrid;
|
||||
|
||||
//// Create a timer and set a two second interval.
|
||||
//var aTimer = new System.Timers.Timer();
|
||||
//aTimer.Interval = 2000;
|
||||
|
||||
//// Hook up the Elapsed event for the timer.
|
||||
//aTimer.Elapsed += OnTimedEvent;
|
||||
|
||||
//// Have the timer fire repeated events (true is the default)
|
||||
//aTimer.AutoReset = true;
|
||||
|
||||
//// Start the timer
|
||||
//aTimer.Enabled = true;
|
||||
}
|
||||
|
||||
private PluginUI.UIType uiType;
|
||||
|
||||
public PluginUI.UIType UIType
|
||||
{
|
||||
get => uiType;
|
||||
set
|
||||
{
|
||||
uiType = value;
|
||||
this.RaisePropertyChanged(nameof(UIType));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
basicUIGrid.Count();
|
||||
}
|
||||
}
|
||||
}
|
110
ObservatoryCore/UI/ViewModels/CoreViewModel.cs
Normal file
110
ObservatoryCore/UI/ViewModels/CoreViewModel.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using Observatory.Framework.Interfaces;
|
||||
using Observatory.UI.Models;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Observatory.UI.ViewModels
|
||||
{
|
||||
public class CoreViewModel : ViewModelBase
|
||||
{
|
||||
private readonly ObservableCollection<IObservatoryNotifier> notifiers;
|
||||
private readonly ObservableCollection<IObservatoryWorker> workers;
|
||||
private readonly ObservableCollection<CoreModel> tabs;
|
||||
private string toggleButtonText;
|
||||
|
||||
public CoreViewModel(IEnumerable<(IObservatoryWorker plugin, PluginManagement.PluginManager.PluginStatus signed)> workers, IEnumerable<(IObservatoryNotifier plugin, PluginManagement.PluginManager.PluginStatus signed)> notifiers)
|
||||
{
|
||||
this.notifiers = new ObservableCollection<IObservatoryNotifier>(notifiers.Select(p => p.plugin));
|
||||
this.workers = new ObservableCollection<IObservatoryWorker>(workers.Select(p => p.plugin));
|
||||
ToggleButtonText = "Start Monitor";
|
||||
tabs = new ObservableCollection<CoreModel>();
|
||||
|
||||
foreach(var worker in workers.Select(p => p.plugin))
|
||||
{
|
||||
if (worker.PluginUI.PluginUIType == Framework.PluginUI.UIType.Basic)
|
||||
{
|
||||
CoreModel coreModel = new();
|
||||
coreModel.Name = worker.ShortName;
|
||||
coreModel.UI = new();
|
||||
var uiViewModel = new BasicUIViewModel(worker.PluginUI.DataGrid)
|
||||
{
|
||||
UIType = worker.PluginUI.PluginUIType
|
||||
};
|
||||
coreModel.UI = uiViewModel;
|
||||
|
||||
tabs.Add(coreModel);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var notifier in notifiers.Select(p => p.plugin))
|
||||
{
|
||||
Panel notifierPanel = new Panel();
|
||||
TextBlock notifierTextBlock = new TextBlock();
|
||||
notifierTextBlock.Text = notifier.Name;
|
||||
notifierPanel.Children.Add(notifierTextBlock);
|
||||
//tabs.Add(new CoreModel() { Name = notifier.ShortName, UI = (ViewModelBase)notifier.UI });
|
||||
}
|
||||
|
||||
|
||||
tabs.Add(new CoreModel() { Name = "Core", UI = new BasicUIViewModel(new ObservableCollection<object>()) { UIType = Framework.PluginUI.UIType.Core } });
|
||||
|
||||
}
|
||||
|
||||
public void ReadAll()
|
||||
{
|
||||
foreach (var worker in workers)
|
||||
{
|
||||
worker.ReadAllStarted();
|
||||
}
|
||||
LogMonitor.GetInstance.ReadAllJournals();
|
||||
}
|
||||
|
||||
public void ToggleMonitor()
|
||||
{
|
||||
var logMonitor = LogMonitor.GetInstance;
|
||||
|
||||
if (logMonitor.IsMonitoring())
|
||||
{
|
||||
logMonitor.Stop();
|
||||
ToggleButtonText = "Start Monitor";
|
||||
}
|
||||
else
|
||||
{
|
||||
logMonitor.Start();
|
||||
ToggleButtonText = "Stop Monitor";
|
||||
}
|
||||
}
|
||||
|
||||
public string ToggleButtonText
|
||||
{
|
||||
get => toggleButtonText;
|
||||
set
|
||||
{
|
||||
if (toggleButtonText != value)
|
||||
{
|
||||
toggleButtonText = value;
|
||||
this.RaisePropertyChanged(nameof(ToggleButtonText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<IObservatoryWorker> Workers
|
||||
{
|
||||
get { return workers; }
|
||||
}
|
||||
|
||||
public ObservableCollection<IObservatoryNotifier> Notifiers
|
||||
{
|
||||
get { return notifiers; }
|
||||
}
|
||||
|
||||
public ObservableCollection<CoreModel> Tabs
|
||||
{
|
||||
get { return tabs; }
|
||||
}
|
||||
}
|
||||
}
|
16
ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs
Normal file
16
ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Observatory.UI.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
public MainWindowViewModel(PluginManagement.PluginManager pluginManager)
|
||||
{
|
||||
core = new CoreViewModel(pluginManager.workerPlugins, pluginManager.notifyPlugins);
|
||||
}
|
||||
|
||||
public CoreViewModel core { get; }
|
||||
}
|
||||
}
|
18
ObservatoryCore/UI/ViewModels/NotificationViewModel.cs
Normal file
18
ObservatoryCore/UI/ViewModels/NotificationViewModel.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Observatory.UI.ViewModels
|
||||
{
|
||||
public class NotificationViewModel : ViewModelBase
|
||||
{
|
||||
public NotificationViewModel(string title, string detail)
|
||||
{
|
||||
Notification = new() { Title = title, Detail = detail };
|
||||
}
|
||||
|
||||
public Models.NotificationModel Notification;
|
||||
}
|
||||
}
|
11
ObservatoryCore/UI/ViewModels/ViewModelBase.cs
Normal file
11
ObservatoryCore/UI/ViewModels/ViewModelBase.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Observatory.UI.ViewModels
|
||||
{
|
||||
public class ViewModelBase : ReactiveObject
|
||||
{
|
||||
}
|
||||
}
|
10
ObservatoryCore/UI/Views/BasicUIView.axaml
Normal file
10
ObservatoryCore/UI/Views/BasicUIView.axaml
Normal file
@ -0,0 +1,10 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Observatory.UI.Views.BasicUIView">
|
||||
<Panel Name="UIPanel">
|
||||
|
||||
</Panel>
|
||||
</UserControl>
|
404
ObservatoryCore/UI/Views/BasicUIView.axaml.cs
Normal file
404
ObservatoryCore/UI/Views/BasicUIView.axaml.cs
Normal file
@ -0,0 +1,404 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using System.Text.RegularExpressions;
|
||||
using Observatory.Framework;
|
||||
using Observatory.Framework.Interfaces;
|
||||
using System.Linq;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace Observatory.UI.Views
|
||||
{
|
||||
public class BasicUIView : UserControl
|
||||
{
|
||||
public BasicUIView()
|
||||
{
|
||||
Initialized += OnInitialized;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public static readonly DirectProperty<BasicUIView, PluginUI.UIType> UITypeProperty =
|
||||
AvaloniaProperty.RegisterDirect<BasicUIView, PluginUI.UIType>(
|
||||
nameof(UIType),
|
||||
o => o.UIType,
|
||||
(o, v) => o.UIType = v,
|
||||
PluginUI.UIType.None,
|
||||
BindingMode.OneWay
|
||||
);
|
||||
|
||||
public PluginUI.UIType UIType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uitype;
|
||||
}
|
||||
set
|
||||
{
|
||||
_uitype = value;
|
||||
UITypeChange();
|
||||
}
|
||||
}
|
||||
|
||||
private PluginUI.UIType _uitype;
|
||||
|
||||
|
||||
private void ColumnGeneration(object sender, DataGridAutoGeneratingColumnEventArgs e)
|
||||
{
|
||||
e.Column.Header = SplitCamelCase(e.PropertyName);
|
||||
e.Column.CanUserReorder = true;
|
||||
e.Column.CanUserResize = true;
|
||||
e.Column.CanUserSort = true;
|
||||
}
|
||||
|
||||
private void OnInitialized(object sender, System.EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void UITypeChange()
|
||||
{
|
||||
var uiPanel = this.Find<Panel>("UIPanel");
|
||||
|
||||
switch (UIType)
|
||||
{
|
||||
case PluginUI.UIType.None:
|
||||
break;
|
||||
case PluginUI.UIType.Basic:
|
||||
DataGrid dataGrid = new()
|
||||
{
|
||||
[!DataGrid.ItemsProperty] = new Binding("BasicUIGrid"),
|
||||
SelectionMode = DataGridSelectionMode.Extended,
|
||||
GridLinesVisibility = DataGridGridLinesVisibility.Vertical,
|
||||
AutoGenerateColumns = true
|
||||
};
|
||||
dataGrid.AutoGeneratingColumn += ColumnGeneration;
|
||||
uiPanel.Children.Clear();
|
||||
uiPanel.Children.Add(dataGrid);
|
||||
break;
|
||||
case PluginUI.UIType.Avalonia:
|
||||
break;
|
||||
case PluginUI.UIType.Core:
|
||||
uiPanel.Children.Clear();
|
||||
ScrollViewer scrollViewer = new();
|
||||
scrollViewer.Content = GenerateCoreUI();
|
||||
uiPanel.Children.Add(scrollViewer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Grid GenerateCoreUI()
|
||||
{
|
||||
|
||||
Grid corePanel = new();
|
||||
|
||||
ColumnDefinitions columns = new()
|
||||
{
|
||||
new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) },
|
||||
new ColumnDefinition() { Width = new GridLength(300) },
|
||||
new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) }
|
||||
};
|
||||
corePanel.ColumnDefinitions = columns;
|
||||
|
||||
RowDefinitions rows = new()
|
||||
{
|
||||
new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) },
|
||||
new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) }
|
||||
};
|
||||
corePanel.RowDefinitions = rows;
|
||||
|
||||
var pluginManager = PluginManagement.PluginManager.GetInstance;
|
||||
|
||||
#region Journal Location
|
||||
TextBlock journalPathLabel = new()
|
||||
{
|
||||
Text = "Journal Path: ",
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
|
||||
};
|
||||
|
||||
TextBox journalPath = new()
|
||||
{
|
||||
Text = Properties.Core.Default.JournalFolder
|
||||
};
|
||||
|
||||
Button journalBrowse = new()
|
||||
{
|
||||
Content = "Browse",
|
||||
Height = 30,
|
||||
Width = 100,
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
|
||||
HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center
|
||||
};
|
||||
|
||||
journalBrowse.Click += (object source, RoutedEventArgs e) =>
|
||||
{
|
||||
OpenFolderDialog openFolderDialog = new()
|
||||
{
|
||||
Directory = journalPath.Text
|
||||
};
|
||||
var browseTask = openFolderDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
|
||||
string path = browseTask.Result;
|
||||
if (path != string.Empty)
|
||||
{
|
||||
journalPath.Text = path;
|
||||
Properties.Core.Default.JournalFolder = path;
|
||||
Properties.Core.Default.Save();
|
||||
}
|
||||
};
|
||||
|
||||
corePanel.AddControl(journalPathLabel, 1, 0);
|
||||
corePanel.AddControl(journalPath, 1, 1);
|
||||
corePanel.AddControl(journalBrowse, 1, 2);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugin List
|
||||
DataGrid pluginList = new() { Margin = new Thickness(0, 20) };
|
||||
|
||||
pluginList.Columns.Add(new DataGridTextColumn()
|
||||
{
|
||||
Header = "Plugin",
|
||||
Binding = new Binding("Name")
|
||||
});
|
||||
|
||||
pluginList.Columns.Add(new DataGridTextColumn()
|
||||
{
|
||||
Header = "Version",
|
||||
Binding = new Binding("Version")
|
||||
});
|
||||
|
||||
pluginList.Columns.Add(new DataGridTextColumn()
|
||||
{
|
||||
Header = "Status",
|
||||
Binding = new Binding("Status")
|
||||
});
|
||||
|
||||
System.Collections.Generic.List<PluginView> allPlugins = new();
|
||||
|
||||
foreach(var (plugin, signed) in pluginManager.workerPlugins)
|
||||
{
|
||||
allPlugins.Add(new PluginView() { Name = plugin.Name, Version = plugin.Version, Status = GetStatusText(signed) });
|
||||
}
|
||||
|
||||
foreach (var (plugin, signed) in pluginManager.notifyPlugins)
|
||||
{
|
||||
allPlugins.Add(new PluginView() { Name = plugin.Name, Version = plugin.Version, Status = GetStatusText(signed) });
|
||||
}
|
||||
|
||||
pluginList.Items = allPlugins;
|
||||
corePanel.AddControl(pluginList, 0, 0, 2);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugin Settings
|
||||
|
||||
foreach(var plugin in pluginManager.workerPlugins.Select(p => p.plugin))
|
||||
{
|
||||
GeneratePluginSettingUI(corePanel, plugin);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return corePanel;
|
||||
}
|
||||
|
||||
private void GeneratePluginSettingUI(Grid gridPanel, IObservatoryPlugin plugin)
|
||||
{
|
||||
//var plugin = pluginSettings.Key;
|
||||
|
||||
var displayedSettings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin.Settings);
|
||||
|
||||
if (displayedSettings.Count > 0)
|
||||
{
|
||||
Expander expander = new()
|
||||
{
|
||||
Header = $"{plugin.Name} - {plugin.Version}",
|
||||
DataContext = plugin.Settings,
|
||||
Margin = new Thickness(0, 20)
|
||||
};
|
||||
|
||||
Grid settingsGrid = new();
|
||||
ColumnDefinitions settingColumns = new()
|
||||
{
|
||||
new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
|
||||
new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
|
||||
new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }
|
||||
};
|
||||
settingsGrid.ColumnDefinitions = settingColumns;
|
||||
expander.Content = settingsGrid;
|
||||
|
||||
int nextRow = gridPanel.RowDefinitions.Count;
|
||||
gridPanel.RowDefinitions.Add(new RowDefinition());
|
||||
gridPanel.AddControl(expander, nextRow, 0, 3);
|
||||
|
||||
foreach (var setting in displayedSettings.Where(s => !System.Attribute.IsDefined(s.Key, typeof(SettingIgnore))))
|
||||
{
|
||||
if (setting.Key.PropertyType != typeof(bool) || settingsGrid.Children.Count % 2 == 0)
|
||||
{
|
||||
settingsGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(21) });
|
||||
}
|
||||
|
||||
TextBlock label = new() { Text = setting.Value };
|
||||
|
||||
switch (setting.Key.GetValue(plugin.Settings))
|
||||
{
|
||||
case bool boolSetting:
|
||||
CheckBox checkBox = new() { IsChecked = boolSetting, Content = label };
|
||||
|
||||
checkBox.Checked += (object sender, RoutedEventArgs e) =>
|
||||
{
|
||||
setting.Key.SetValue(plugin.Settings, true);
|
||||
PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
|
||||
};
|
||||
|
||||
checkBox.Unchecked += (object sender, RoutedEventArgs e) =>
|
||||
{
|
||||
setting.Key.SetValue(plugin.Settings, false);
|
||||
PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
|
||||
};
|
||||
|
||||
//settingsGrid.Children.Add(checkBox);
|
||||
settingsGrid.AddControl(checkBox, settingsGrid.RowDefinitions.Count - 1, settingsGrid.Children.Count % 2 == 0 ? 0 : 1);
|
||||
|
||||
break;
|
||||
case string stringSetting:
|
||||
TextBox textBox = new() { Text = stringSetting };
|
||||
settingsGrid.Children.Add(label);
|
||||
settingsGrid.Children.Add(textBox);
|
||||
break;
|
||||
case int intSetting:
|
||||
NumericUpDown numericUpDown = new() { Text = intSetting.ToString(), AllowSpin = true };
|
||||
settingsGrid.Children.Add(label);
|
||||
settingsGrid.Children.Add(numericUpDown);
|
||||
break;
|
||||
case System.IO.FileInfo fileSetting:
|
||||
label.Text += ": ";
|
||||
|
||||
TextBox settingPath = new()
|
||||
{
|
||||
Text = fileSetting.FullName,
|
||||
Width = 250,
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right
|
||||
};
|
||||
|
||||
Button settingBrowse = new()
|
||||
{
|
||||
Content = "Browse",
|
||||
Height = 30,
|
||||
Width = 100,
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
|
||||
HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center
|
||||
};
|
||||
|
||||
settingBrowse.Click += (object source, RoutedEventArgs e) =>
|
||||
{
|
||||
OpenFileDialog openFileDialog = new()
|
||||
{
|
||||
Directory = fileSetting.DirectoryName,
|
||||
AllowMultiple = false
|
||||
};
|
||||
var browseTask = openFileDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
|
||||
|
||||
if (browseTask.Result.Count() > 0)
|
||||
{
|
||||
string path = browseTask.Result[0];
|
||||
settingPath.Text = path;
|
||||
|
||||
setting.Key.SetValue(plugin.Settings, new System.IO.FileInfo(path));
|
||||
PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
StackPanel stackPanel = new() { Orientation = Avalonia.Layout.Orientation.Horizontal };
|
||||
stackPanel.Children.Add(label);
|
||||
stackPanel.Children.Add(settingPath);
|
||||
|
||||
settingsGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(21) });
|
||||
//settingsGrid.AddControl(label, settingsGrid.RowDefinitions.Count - 1, 0, 2);
|
||||
settingsGrid.AddControl(stackPanel, settingsGrid.RowDefinitions.Count - 1, 0, 2);
|
||||
settingsGrid.AddControl(settingBrowse, settingsGrid.RowDefinitions.Count - 1, 2);
|
||||
|
||||
break;
|
||||
}
|
||||
//wrapPanel.Children.Add(panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetStatusText(PluginManagement.PluginManager.PluginStatus status)
|
||||
{
|
||||
string statusText;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case PluginManagement.PluginManager.PluginStatus.Signed:
|
||||
statusText = "Signed";
|
||||
break;
|
||||
case PluginManagement.PluginManager.PluginStatus.Unsigned:
|
||||
statusText = "Unsigned";
|
||||
break;
|
||||
case PluginManagement.PluginManager.PluginStatus.InvalidSignature:
|
||||
statusText = "Signature Invalid";
|
||||
break;
|
||||
case PluginManagement.PluginManager.PluginStatus.InvalidPlugin:
|
||||
statusText = "No Interface";
|
||||
break;
|
||||
case PluginManagement.PluginManager.PluginStatus.InvalidLibrary:
|
||||
statusText = "Invalid Library";
|
||||
break;
|
||||
default:
|
||||
statusText = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return statusText;
|
||||
}
|
||||
|
||||
//From https://stackoverflow.com/questions/5796383/insert-spaces-between-words-on-a-camel-cased-token
|
||||
private static string SplitCamelCase(string str)
|
||||
{
|
||||
return Regex.Replace(
|
||||
Regex.Replace(
|
||||
str,
|
||||
@"(\P{Ll})(\P{Ll}\p{Ll})",
|
||||
"$1 $2"
|
||||
),
|
||||
@"(\p{Ll})(\P{Ll})",
|
||||
"$1 $2"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
internal class PluginView
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Status { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
internal static class GridExtention
|
||||
{
|
||||
public static void AddControl(this Grid grid, Control control, int row, int column, int span = 1)
|
||||
{
|
||||
grid.Children.Add(control);
|
||||
Grid.SetColumnSpan(control, span);
|
||||
Grid.SetColumn(control, column);
|
||||
Grid.SetRow(control, row);
|
||||
}
|
||||
}
|
||||
}
|
43
ObservatoryCore/UI/Views/CoreView.axaml
Normal file
43
ObservatoryCore/UI/Views/CoreView.axaml
Normal file
@ -0,0 +1,43 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vw="clr-namespace:Observatory.UI.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Observatory.UI.Views.CoreView">
|
||||
<Grid RowDefinitions="30,*,Auto">
|
||||
<TextBlock Grid.Row="0" VerticalAlignment="Center" Padding="10,0,0,0">
|
||||
Elite Observatory - v1.0core
|
||||
</TextBlock>
|
||||
<TabControl Name="CoreTabs"
|
||||
Grid.Row="1" Grid.Column="1"
|
||||
VerticalAlignment="Stretch"
|
||||
TabStripPlacement="Left"
|
||||
Items="{Binding Tabs}"
|
||||
BorderBrush="Black"
|
||||
BorderThickness="1">
|
||||
<TabControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</TabItem.Header>
|
||||
</TabItem>
|
||||
</DataTemplate>
|
||||
</TabControl.ItemTemplate>
|
||||
<TabControl.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<vw:BasicUIView DataContext="{Binding UI}" UIType="{Binding UIType}"/>
|
||||
</DataTemplate>
|
||||
</TabControl.ContentTemplate>
|
||||
</TabControl>
|
||||
<WrapPanel Height="50" Grid.Row="2" Grid.Column="0" VerticalAlignment="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Name="ToggleMonitor" Margin="10" Command="{Binding ToggleMonitor}" Content="{Binding ToggleButtonText}">
|
||||
Start Monitor
|
||||
</Button>
|
||||
<Button Name="ReadAll" Margin="10" Command="{Binding ReadAll}">
|
||||
Read All
|
||||
</Button>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
21
ObservatoryCore/UI/Views/CoreView.axaml.cs
Normal file
21
ObservatoryCore/UI/Views/CoreView.axaml.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using System.Linq;
|
||||
|
||||
namespace Observatory.UI.Views
|
||||
{
|
||||
public class CoreView : UserControl
|
||||
{
|
||||
public CoreView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
11
ObservatoryCore/UI/Views/MainWindow.axaml
Normal file
11
ObservatoryCore/UI/Views/MainWindow.axaml
Normal file
@ -0,0 +1,11 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:views="clr-namespace:Observatory.UI.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Observatory.UI.Views.MainWindow"
|
||||
Title="Elite Observatory"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
Content="{Binding core}">
|
||||
</Window>
|
26
ObservatoryCore/UI/Views/MainWindow.axaml.cs
Normal file
26
ObservatoryCore/UI/Views/MainWindow.axaml.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
|
||||
namespace Observatory.UI.Views
|
||||
{
|
||||
public class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
13
ObservatoryCore/UI/Views/NotificationView.axaml
Normal file
13
ObservatoryCore/UI/Views/NotificationView.axaml
Normal file
@ -0,0 +1,13 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Observatory.UI.Views.NotificationView"
|
||||
|
||||
Title="Notification">
|
||||
<StackPanel DataContext="{Binding Notification}">
|
||||
<TextBlock Text="{Binding Title}" />
|
||||
<TextBlock Text="{Binding Detail}" />
|
||||
</StackPanel>
|
||||
</Window>
|
22
ObservatoryCore/UI/Views/NotificationView.axaml.cs
Normal file
22
ObservatoryCore/UI/Views/NotificationView.axaml.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Observatory.UI.Views
|
||||
{
|
||||
public partial class NotificationView : Window
|
||||
{
|
||||
public NotificationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user