1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

UI - Rewrote screen activation logic

UI - Changed autorun method to shortcut in startup folder to avoid permission issues
UI - Properly added Robot Mono font and use it in the exception dialog
This commit is contained in:
SpoinkyNL 2020-02-24 22:07:40 +01:00
parent 2b66ba656b
commit 41c381cd50
8 changed files with 145 additions and 59 deletions

View File

@ -40,4 +40,10 @@
<Compile Remove="obj\x64\Debug\GeneratedInternalTypeHelper.g.i.cs" /> <Compile Remove="obj\x64\Debug\GeneratedInternalTypeHelper.g.i.cs" />
<Compile Remove="obj\x64\Debug\UserControl1.g.i.cs" /> <Compile Remove="obj\x64\Debug\UserControl1.g.i.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Resources\Fonts\RobotoMono-Regular.ttf" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Fonts\RobotoMono-Regular.ttf" />
</ItemGroup>
</Project> </Project>

View File

@ -12,19 +12,21 @@
d:DataContext="{d:DesignInstance dialogs:ExceptionDialogViewModel}"> d:DataContext="{d:DesignInstance dialogs:ExceptionDialogViewModel}">
<StackPanel Margin="16"> <StackPanel Margin="16">
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Text="{Binding Header}" TextWrapping="Wrap" /> <TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Text="{Binding Header}" TextWrapping="Wrap" />
<TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" Margin="0 20 0 20" Text="{Binding Exception.Message}" TextWrapping="Wrap" />
<Separator></Separator> <Separator Margin="0 15" />
<TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" Text="Stack trace" TextWrapping="Wrap" FontWeight="Bold" Margin="20 5 0 0"/> <TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" FontWeight="Bold" Margin="22 0">Exception message</TextBlock>
<avalonedit:TextEditor SyntaxHighlighting="C#" <TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" Text="{Binding Exception.Message}" TextWrapping="Wrap" Margin="22 5" />
FontFamily="Resources\Fonts\RobotoMono-Regular.ttf" <Separator Margin="0 15" />
FontSize="10pt" <TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" Text="Stack trace" TextWrapping="Wrap" FontWeight="Bold" Margin="22 0" />
IsReadOnly="True" <avalonedit:TextEditor SyntaxHighlighting="C#"
Document="{Binding Document}" FontFamily="pack://application:,,,/Resources/Fonts/#Roboto Mono"
HorizontalScrollBarVisibility="Auto" FontSize="10pt"
IsReadOnly="True"
Document="{Binding Document}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
Margin="0 10"/> Margin="0 10" />
<Separator></Separator>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 0 0" <Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 0 0"

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -62,6 +62,9 @@
</DrawingImage.Drawing> </DrawingImage.Drawing>
</DrawingImage> </DrawingImage>
<FontFamily x:Key="RobotoMono">pack://application:,,,/Resources/Fonts/#Roboto Mono</FontFamily>
<!-- Disable tab stop/focusable on all content controls --> <!-- Disable tab stop/focusable on all content controls -->
<Style TargetType="ContentControl"> <Style TargetType="ContentControl">
<Setter Property="IsTabStop" Value="False" /> <Setter Property="IsTabStop" Value="False" />

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Abstract;
@ -15,6 +16,7 @@ using Artemis.UI.Screens.Settings.Tabs.Devices;
using Artemis.UI.Screens.Settings.Tabs.Plugins; using Artemis.UI.Screens.Settings.Tabs.Plugins;
using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Services.Interfaces;
using Artemis.UI.Shared.Utilities; using Artemis.UI.Shared.Utilities;
using Artemis.UI.Utilities;
using Microsoft.Win32; using Microsoft.Win32;
using Ninject; using Ninject;
using Serilog.Events; using Serilog.Events;
@ -152,14 +154,28 @@ namespace Artemis.UI.Screens.Settings
_windowManager.ShowWindow(_kernel.Get<DebugViewModel>()); _windowManager.ShowWindow(_kernel.Get<DebugViewModel>());
} }
public void ShowLogsFolder() public async Task ShowLogsFolder()
{ {
Process.Start(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); try
{
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"));
}
catch (Exception e)
{
await _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
}
} }
public void ShowDataFolder() public async Task ShowDataFolder()
{ {
Process.Start(Constants.DataFolder); try
{
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Constants.DataFolder);
}
catch (Exception e)
{
await _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the data folder for you", e);
}
} }
protected override void OnInitialActivate() protected override void OnInitialActivate()
@ -189,14 +205,13 @@ namespace Artemis.UI.Screens.Settings
{ {
try try
{ {
var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); var autoRunFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "Artemis.lnk");
if (key == null) var executableFile = Process.GetCurrentProcess().MainModule.FileName;
key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
if (File.Exists(autoRunFile))
File.Delete(autoRunFile);
if (StartWithWindows) if (StartWithWindows)
key.SetValue("Artemis", $"\"{Process.GetCurrentProcess().MainModule.FileName}\" -autorun"); ShortcutUtilities.Create(autoRunFile, executableFile, "-autorun", new FileInfo(executableFile).DirectoryName, "Artemis", "", "");
else
key.DeleteValue("Artemis", false);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -5,24 +5,31 @@ using System.Threading.Tasks;
using Artemis.Core.Events; using Artemis.Core.Events;
using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Interfaces;
using Artemis.UI.Ninject.Factories; using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Home;
using Artemis.UI.Screens.News;
using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop;
using MaterialDesignExtensions.Controls; using MaterialDesignExtensions.Controls;
using MaterialDesignExtensions.Model; using MaterialDesignExtensions.Model;
using MaterialDesignThemes.Wpf; using MaterialDesignThemes.Wpf;
using Ninject;
using Stylet; using Stylet;
namespace Artemis.UI.Screens.Sidebar namespace Artemis.UI.Screens.Sidebar
{ {
public class SidebarViewModel : PropertyChangedBase public class SidebarViewModel : PropertyChangedBase
{ {
private readonly IKernel _kernel;
private readonly IModuleVmFactory _moduleVmFactory; private readonly IModuleVmFactory _moduleVmFactory;
private readonly IPluginService _pluginService; private readonly IPluginService _pluginService;
public SidebarViewModel(List<MainScreenViewModel> defaultSidebarItems, IModuleVmFactory moduleVmFactory, IPluginService pluginService) public SidebarViewModel(IKernel kernel, IModuleVmFactory moduleVmFactory, IPluginService pluginService)
{ {
_kernel = kernel;
_moduleVmFactory = moduleVmFactory; _moduleVmFactory = moduleVmFactory;
_pluginService = pluginService; _pluginService = pluginService;
DefaultSidebarItems = defaultSidebarItems;
SidebarModules = new Dictionary<INavigationItem, Core.Plugins.Abstract.Module>(); SidebarModules = new Dictionary<INavigationItem, Core.Plugins.Abstract.Module>();
SidebarItems = new BindableCollection<INavigationItem>(); SidebarItems = new BindableCollection<INavigationItem>();
@ -31,7 +38,6 @@ namespace Artemis.UI.Screens.Sidebar
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled; _pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
} }
public List<MainScreenViewModel> DefaultSidebarItems { get; set; }
public BindableCollection<INavigationItem> SidebarItems { get; set; } public BindableCollection<INavigationItem> SidebarItems { get; set; }
public Dictionary<INavigationItem, Core.Plugins.Abstract.Module> SidebarModules { get; set; } public Dictionary<INavigationItem, Core.Plugins.Abstract.Module> SidebarModules { get; set; }
public IScreen SelectedItem { get; set; } public IScreen SelectedItem { get; set; }
@ -62,28 +68,49 @@ namespace Artemis.UI.Screens.Sidebar
private async Task SelectSidebarItem(INavigationItem sidebarItem) private async Task SelectSidebarItem(INavigationItem sidebarItem)
{ {
if (SelectedItem != null)
{
var canClose = await SelectedItem.CanCloseAsync();
if (!canClose)
return;
SelectedItem.Close();
}
// A module was selected if the dictionary contains the selected item // A module was selected if the dictionary contains the selected item
if (SidebarModules.ContainsKey(sidebarItem)) if (SidebarModules.ContainsKey(sidebarItem))
await ActivateModule(sidebarItem);
else if (sidebarItem is FirstLevelNavigationItem navigationItem)
{ {
SelectedItem = _moduleVmFactory.Create(SidebarModules[sidebarItem]); if (navigationItem.Label == "Home")
await ActivateViewModel<HomeViewModel>();
else if (navigationItem.Label == "News")
await ActivateViewModel<NewsViewModel>();
else if (navigationItem.Label == "Workshop")
await ActivateViewModel<WorkshopViewModel>();
else if (navigationItem.Label == "Surface Editor")
await ActivateViewModel<SurfaceEditorViewModel>();
else if (navigationItem.Label == "Settings")
await ActivateViewModel<SettingsViewModel>();
} }
else else if (await CloseCurrentItem())
{
SelectedItem = null; SelectedItem = null;
} }
// TODO: Remove this bad boy, just testing private async Task<bool> CloseCurrentItem()
GC.Collect(); {
GC.WaitForPendingFinalizers(); if (SelectedItem == null)
GC.Collect(); return true;
var canClose = await SelectedItem.CanCloseAsync();
if (!canClose)
return false;
SelectedItem.Close();
return true;
}
private async Task ActivateViewModel<T>()
{
if (await CloseCurrentItem())
SelectedItem = (IScreen) _kernel.Get<T>();
}
private async Task ActivateModule(INavigationItem sidebarItem)
{
if (await CloseCurrentItem())
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.Create(SidebarModules[sidebarItem]) : null;
} }
// ReSharper disable once UnusedMember.Global - Called by view // ReSharper disable once UnusedMember.Global - Called by view

View File

@ -0,0 +1,52 @@
using System;
using System.Runtime.InteropServices;
namespace Artemis.UI.Utilities
{
public class ShortcutUtilities
{
private static Type m_type = Type.GetTypeFromProgID("WScript.Shell");
private static object m_shell = Activator.CreateInstance(m_type);
[ComImport, TypeLibType((short)0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
private interface IWshShortcut
{
[DispId(0)]
string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; }
[DispId(0x3e8)]
string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; }
[DispId(0x3e9)]
string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; }
[DispId(0x3ea)]
string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; }
[DispId(0x3eb)]
string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; }
[DispId(0x3ec)]
string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; }
[DispId(0x3ed)]
string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; }
[DispId(0x3ee)]
int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; }
[DispId(0x3ef)]
string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; }
[TypeLibFunc((short)0x40), DispId(0x7d0)]
void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink);
[DispId(0x7d1)]
void Save();
}
public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
{
IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName });
shortcut.Description = description;
shortcut.Hotkey = hotkey;
shortcut.TargetPath = targetPath;
shortcut.WorkingDirectory = workingDirectory;
shortcut.Arguments = arguments;
if (!string.IsNullOrEmpty(iconPath))
shortcut.IconLocation = iconPath;
shortcut.Save();
}
}
}