SEBWIN-104: Revived the about window and overhauled taskbar layout.
This commit is contained in:
parent
d4ef20bd9f
commit
32cecbd5e2
16 changed files with 94 additions and 36 deletions
|
@ -25,6 +25,8 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private TaskbarSettings settings;
|
||||
private Mock<INotificationInfo> aboutInfoMock;
|
||||
private Mock<INotificationController> aboutControllerMock;
|
||||
private Mock<INotificationInfo> logInfoMock;
|
||||
private Mock<INotificationController> logControllerMock;
|
||||
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
|
||||
|
@ -41,6 +43,8 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
public void Initialize()
|
||||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
aboutInfoMock = new Mock<INotificationInfo>();
|
||||
aboutControllerMock = new Mock<INotificationController>();
|
||||
logInfoMock = new Mock<INotificationInfo>();
|
||||
logControllerMock = new Mock<INotificationController>();
|
||||
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
|
||||
|
@ -60,6 +64,8 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
|
||||
sut = new TaskbarOperation(
|
||||
loggerMock.Object,
|
||||
aboutInfoMock.Object,
|
||||
aboutControllerMock.Object,
|
||||
logInfoMock.Object,
|
||||
logControllerMock.Object,
|
||||
keyboardLayoutMock.Object,
|
||||
|
|
|
@ -223,12 +223,14 @@ namespace SafeExamBrowser.Client
|
|||
|
||||
private IOperation BuildTaskbarOperation()
|
||||
{
|
||||
var aboutInfo = new AboutNotificationInfo(text);
|
||||
var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory);
|
||||
var keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, nameof(KeyboardLayout)), text);
|
||||
var logController = new LogNotificationController(logger, uiFactory);
|
||||
var logInfo = new LogNotificationInfo(text);
|
||||
var powerSupply = new PowerSupply(new ModuleLogger(logger, nameof(PowerSupply)), text);
|
||||
var wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, nameof(WirelessNetwork)), text);
|
||||
var operation = new TaskbarOperation(logger, logInfo, logController, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, configuration.Settings.Taskbar, text, uiFactory);
|
||||
var operation = new TaskbarOperation(logger, aboutInfo, aboutController, logInfo, logController, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, configuration.Settings.Taskbar, text, uiFactory);
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace SafeExamBrowser.Client.Notifications
|
|||
{
|
||||
internal class AboutNotificationIconResource : IIconResource
|
||||
{
|
||||
public Uri Uri => new Uri("pack://application:,,,/SafeExamBrowser;component/SafeExamBrowser.ico");
|
||||
public bool IsBitmapResource => true;
|
||||
public bool IsXamlResource => false;
|
||||
public Uri Uri => new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Classic;component/Images/AboutNotification.xaml");
|
||||
public bool IsBitmapResource => false;
|
||||
public bool IsXamlResource => true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ namespace SafeExamBrowser.Client.Operations
|
|||
internal class TaskbarOperation : IOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private INotificationInfo aboutInfo;
|
||||
private INotificationController aboutController;
|
||||
private INotificationInfo logInfo;
|
||||
private INotificationController logController;
|
||||
private TaskbarSettings settings;
|
||||
|
@ -38,6 +40,8 @@ namespace SafeExamBrowser.Client.Operations
|
|||
|
||||
public TaskbarOperation(
|
||||
ILogger logger,
|
||||
INotificationInfo aboutInfo,
|
||||
INotificationController aboutController,
|
||||
INotificationInfo logInfo,
|
||||
INotificationController logController,
|
||||
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
|
||||
|
@ -49,6 +53,8 @@ namespace SafeExamBrowser.Client.Operations
|
|||
IText text,
|
||||
IUserInterfaceFactory uiFactory)
|
||||
{
|
||||
this.aboutInfo = aboutInfo;
|
||||
this.aboutController = aboutController;
|
||||
this.logger = logger;
|
||||
this.logInfo = logInfo;
|
||||
this.logController = logController;
|
||||
|
@ -67,6 +73,8 @@ namespace SafeExamBrowser.Client.Operations
|
|||
logger.Info("Initializing taskbar...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeTaskbar);
|
||||
|
||||
AddAboutNotification();
|
||||
|
||||
if (settings.AllowApplicationLog)
|
||||
{
|
||||
CreateLogNotification();
|
||||
|
@ -77,16 +85,16 @@ namespace SafeExamBrowser.Client.Operations
|
|||
AddKeyboardLayoutControl();
|
||||
}
|
||||
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
AddPowerSupplyControl();
|
||||
}
|
||||
|
||||
if (settings.AllowWirelessNetwork)
|
||||
{
|
||||
AddWirelessNetworkControl();
|
||||
}
|
||||
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
AddPowerSupplyControl();
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
|
@ -95,6 +103,8 @@ namespace SafeExamBrowser.Client.Operations
|
|||
logger.Info("Terminating taskbar...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateTaskbar);
|
||||
|
||||
aboutController.Terminate();
|
||||
|
||||
if (settings.AllowApplicationLog)
|
||||
{
|
||||
logController.Terminate();
|
||||
|
@ -105,19 +115,27 @@ namespace SafeExamBrowser.Client.Operations
|
|||
keyboardLayout.Terminate();
|
||||
}
|
||||
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
powerSupply.Terminate();
|
||||
}
|
||||
|
||||
if (settings.AllowWirelessNetwork)
|
||||
{
|
||||
wirelessNetwork.Terminate();
|
||||
}
|
||||
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
powerSupply.Terminate();
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
private void AddAboutNotification()
|
||||
{
|
||||
var aboutNotification = uiFactory.CreateNotification(aboutInfo);
|
||||
|
||||
aboutController.RegisterNotification(aboutNotification);
|
||||
taskbar.AddNotification(aboutNotification);
|
||||
}
|
||||
|
||||
private void AddKeyboardLayoutControl()
|
||||
{
|
||||
var control = uiFactory.CreateKeyboardLayoutControl();
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace SafeExamBrowser.SystemComponents
|
|||
{
|
||||
var charge = SystemInformation.PowerStatus.BatteryLifePercent;
|
||||
var percentage = Math.Round(charge * 100);
|
||||
var status = charge <= 0.35 ? (charge <= 0.2 ? BatteryChargeStatus.Critical : BatteryChargeStatus.Low) : BatteryChargeStatus.Okay;
|
||||
var status = charge <= 0.4 ? (charge <= 0.2 ? BatteryChargeStatus.Critical : BatteryChargeStatus.Low) : BatteryChargeStatus.Okay;
|
||||
var online = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
|
||||
var tooltip = string.Empty;
|
||||
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic"
|
||||
mc:Ignorable="d"
|
||||
Title="About Safe Exam Browser" Background="White" Height="350" Width="450" ResizeMode="NoResize" Icon="./Images/SafeExamBrowser.ico"
|
||||
Title="Version & License Information" Background="White" Height="325" Width="600" ResizeMode="NoResize" Icon="./Images/SafeExamBrowser.ico"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Classic;component/Images/SplashScreen.png" Margin="0,5,0,0" />
|
||||
<TextBlock x:Name="VersionInfo" Grid.Row="0" Grid.Column="1" Foreground="Gray" Margin="25,70,50,10" TextWrapping="Wrap" />
|
||||
<TextBlock x:Name="VersionInfo" Grid.Row="0" Grid.Column="1" Foreground="Gray" Margin="25,75,125,10" TextWrapping="Wrap" />
|
||||
<ScrollViewer Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="MainText" Margin="10" FontSize="10" TextWrapping="Wrap">
|
||||
This application is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
|
@ -26,7 +26,7 @@
|
|||
<LineBreak />
|
||||
<Bold><Underline>CefSharp (.NET bindings for the Chromium Embedded Framework)</Underline></Bold>
|
||||
<LineBreak />
|
||||
Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
|
||||
Copyright © 2010-2019 The CefSharp Authors. All rights reserved.
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
<Bold><Underline>CEF (Chromium Embedded Framework)</Underline></Bold>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:fa="http://schemas.fontawesome.io/icons/"
|
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40">
|
||||
|
@ -25,15 +26,23 @@
|
|||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="Transparent" HorizontalContentAlignment="Stretch" Template="{StaticResource TaskbarButton}"
|
||||
VerticalContentAlignment="Stretch" Width="40">
|
||||
<Button x:Name="Button" Background="Transparent" Template="{StaticResource TaskbarButton}" Padding="5" Width="40">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Name="LayoutCultureCode" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
|
||||
<TextBlock x:Name="LayoutName" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top" />
|
||||
<fa:ImageAwesome Panel.ZIndex="1" Foreground="LightGray" Icon="KeyboardOutline" VerticalAlignment="Center" />
|
||||
<Viewbox Panel.ZIndex="2" Stretch="Uniform">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Name="LayoutCultureCode" FontWeight="Bold" TextAlignment="Center" Text="ENG">
|
||||
<TextBlock.Effect>
|
||||
<DropShadowEffect Color="White" BlurRadius="5" Direction="0" Opacity="1" ShadowDepth="0" />
|
||||
</TextBlock.Effect>
|
||||
</TextBlock>
|
||||
<TextBlock x:Name="LayoutName" Foreground="Gray" TextAlignment="Center" Text="SG">
|
||||
<TextBlock.Effect>
|
||||
<DropShadowEffect Color="White" BlurRadius="5" Direction="0" Opacity="1" ShadowDepth="0" />
|
||||
</TextBlock.Effect>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Viewbox>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace SafeExamBrowser.UserInterface.Classic.Controls
|
|||
|
||||
private void SetCurrent(KeyboardLayoutButton button, IKeyboardLayout layout)
|
||||
{
|
||||
var name = layout.Name?.Length > 3 ? String.Join(string.Empty, layout.Name.Split(' ').Select(s => s.First())) : layout.Name;
|
||||
var name = layout.Name?.Length > 3 ? String.Join(string.Empty, layout.Name.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.Name;
|
||||
|
||||
foreach (var child in LayoutsStackPanel.Children)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Button x:Name="IconButton" Background="{StaticResource BackgroundBrush}" Click="Icon_Click" Padding="5,0" Template="{StaticResource TaskbarButton}" Width="40"/>
|
||||
<Button x:Name="IconButton" Background="{StaticResource BackgroundBrush}" Click="Icon_Click" Padding="7.5" Template="{StaticResource TaskbarButton}" Width="40" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</Grid>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="Transparent" IsEnabled="False" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True">
|
||||
<Button x:Name="Button" Background="Transparent" IsEnabled="False" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True">
|
||||
<Viewbox Stretch="Uniform" Width="Auto">
|
||||
<Canvas Height="40" Width="40">
|
||||
<Viewbox Stretch="Uniform" Width="40" Panel.ZIndex="2">
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="Transparent" HorizontalContentAlignment="Stretch" Template="{StaticResource TaskbarButton}"
|
||||
<Button x:Name="Button" Background="Transparent" HorizontalContentAlignment="Stretch" Padding="5" Template="{StaticResource TaskbarButton}"
|
||||
ToolTipService.ShowOnDisabled="True" VerticalContentAlignment="Stretch" Width="40">
|
||||
<Grid>
|
||||
<Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<Viewbox
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:fa="http://schemas.fontawesome.io/icons/"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid>
|
||||
<fa:ImageAwesome Foreground="Gray" Icon="InfoCircle" Margin="10" />
|
||||
</Grid>
|
||||
</Viewbox>
|
|
@ -222,6 +222,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Resource Include="Images\AboutNotification.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Resource>
|
||||
<Page Include="LogWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
</ScrollViewer.Resources>
|
||||
<StackPanel x:Name="ApplicationStackPanel" Orientation="Horizontal" />
|
||||
</ScrollViewer>
|
||||
<local:DateTimeControl Grid.Column="1" Foreground="DimGray" />
|
||||
<StackPanel Grid.Column="2" x:Name="NotificationStackPanel" Margin="5,0,0,0" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<StackPanel Grid.Column="3" x:Name="SystemControlStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<StackPanel Grid.Column="2" x:Name="SystemControlStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<local:DateTimeControl Grid.Column="3" Foreground="DimGray" Padding="10,0,10,0" />
|
||||
<local:QuitButton Grid.Column="4" x:Name="QuitButton" />
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using FontAwesome.WPF;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
|
@ -27,6 +29,8 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
public UserInterfaceFactory(IText text)
|
||||
{
|
||||
this.text = text;
|
||||
|
||||
InitializeFontAwesome();
|
||||
}
|
||||
|
||||
public IWindow CreateAboutWindow(AppConfig appConfig)
|
||||
|
@ -122,5 +126,12 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
{
|
||||
return new WirelessNetworkControl();
|
||||
}
|
||||
|
||||
private void InitializeFontAwesome()
|
||||
{
|
||||
// To be able to use FontAwesome in XAML icon resources, we need to make sure that the FontAwesome.WPF assembly is loaded into
|
||||
// the AppDomain before attempting to load an icon resource - thus the creation of an unused image below...
|
||||
ImageAwesome.CreateImageSource(FontAwesomeIcon.FontAwesome, Brushes.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
|||
{
|
||||
textBlock.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var date = message.DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var date = message.DateTime.ToString("HH:mm:ss.fff");
|
||||
var severity = message.Severity.ToString().ToUpper();
|
||||
var threadId = message.ThreadInfo.Id < 10 ? $"0{message.ThreadInfo.Id}" : message.ThreadInfo.Id.ToString();
|
||||
var threadName = message.ThreadInfo.HasName ? ": " + message.ThreadInfo.Name : string.Empty;
|
||||
|
|
Loading…
Reference in a new issue