diff --git a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs index 29cbad1e..5602ac8b 100644 --- a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs @@ -61,7 +61,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations taskbarSettings.ShowApplicationLog = true; taskbarSettings.ShowKeyboardLayout = true; - taskbarSettings.AllowWirelessNetwork = true; + taskbarSettings.ShowWirelessNetwork = true; taskbarSettings.EnableTaskbar = true; systemInfoMock.SetupGet(s => s.HasBattery).Returns(true); uiFactoryMock.Setup(u => u.CreateNotificationControl(It.IsAny(), It.IsAny())).Returns(new Mock().Object); diff --git a/SafeExamBrowser.Client/Operations/ShellOperation.cs b/SafeExamBrowser.Client/Operations/ShellOperation.cs index 9c399960..bfa3ee07 100644 --- a/SafeExamBrowser.Client/Operations/ShellOperation.cs +++ b/SafeExamBrowser.Client/Operations/ShellOperation.cs @@ -242,14 +242,20 @@ namespace SafeExamBrowser.Client.Operations private void InitializeWirelessNetworkForActionCenter() { - // TODO + if (actionCenterSettings.ShowWirelessNetwork) + { + var control = uiFactory.CreateWirelessNetworkControl(Location.ActionCenter); + + wirelessNetwork.Register(control); + actionCenter.AddSystemControl(control); + } } private void InitializeWirelessNetworkForTaskbar() { - if (taskbarSettings.AllowWirelessNetwork) + if (taskbarSettings.ShowWirelessNetwork) { - var control = uiFactory.CreateWirelessNetworkControl(); + var control = uiFactory.CreateWirelessNetworkControl(Location.Taskbar); wirelessNetwork.Register(control); taskbar.AddSystemControl(control); diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs index 90134111..a316741c 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs @@ -40,7 +40,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData { if (value is bool enabled) { - settings.Taskbar.AllowWirelessNetwork = enabled; + settings.Taskbar.ShowWirelessNetwork = enabled; } } diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs index fd910378..ca6c9ad4 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs @@ -140,13 +140,14 @@ namespace SafeExamBrowser.Configuration.ConfigurationData settings.Taskbar.ShowApplicationLog = false; settings.Taskbar.ShowKeyboardLayout = true; - settings.Taskbar.AllowWirelessNetwork = false; + settings.Taskbar.ShowWirelessNetwork = false; settings.Taskbar.EnableTaskbar = true; settings.Taskbar.ShowClock = true; // TODO: Default values for testing of alpha version only, remove for final release! settings.ActionCenter.ShowApplicationLog = true; settings.ActionCenter.ShowKeyboardLayout = true; + settings.ActionCenter.ShowWirelessNetwork = true; settings.Browser.AllowDeveloperConsole = true; settings.Browser.MainWindowSettings.AllowAddressBar = true; settings.Taskbar.ShowApplicationLog = true; diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs index a7495234..51aa4c04 100644 --- a/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs +++ b/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs @@ -30,5 +30,10 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings /// Determines whether the system control for the keyboard layout is accessible via the action center. /// public bool ShowKeyboardLayout { get; set; } + + /// + /// Determines whether the system control for the wireless network is accessible via the action center. + /// + public bool ShowWirelessNetwork { get; set; } } } diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs index aa69a467..e2524fbb 100644 --- a/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs +++ b/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs @@ -39,6 +39,6 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings /// /// Determines whether the system control for the wireless network is accessible via the taskbar. /// - public bool AllowWirelessNetwork { get; set; } + public bool ShowWirelessNetwork { get; set; } } } diff --git a/SafeExamBrowser.Contracts/I18n/IText.cs b/SafeExamBrowser.Contracts/I18n/IText.cs index 271f8607..9af9a808 100644 --- a/SafeExamBrowser.Contracts/I18n/IText.cs +++ b/SafeExamBrowser.Contracts/I18n/IText.cs @@ -9,8 +9,7 @@ namespace SafeExamBrowser.Contracts.I18n { /// - /// Provides access to text data. IMPORTANT: To allow for a complete internationalization of the application, all text elements which - /// are visible to the user must be retrieved via this module! + /// Provides access to text data. /// public interface IText { diff --git a/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs b/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs index 30ec82d2..81e6550f 100644 --- a/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs +++ b/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs @@ -19,9 +19,7 @@ using SafeExamBrowser.Contracts.UserInterface.Windows; namespace SafeExamBrowser.Contracts.UserInterface { /// - /// The factory for user interface elements which cannot be instantiated at the composition root. IMPORTANT: To allow for decoupling - /// from the particular user interface framework in use, all dynamically generated user interface elements must be generated by this - /// factory. + /// The factory for user interface elements which cannot be instantiated at the composition root. /// public interface IUserInterfaceFactory { @@ -84,6 +82,6 @@ namespace SafeExamBrowser.Contracts.UserInterface /// /// Creates a system control which allows to change the wireless network connection of the computer. /// - ISystemWirelessNetworkControl CreateWirelessNetworkControl(); + ISystemWirelessNetworkControl CreateWirelessNetworkControl(Location location); } } diff --git a/SafeExamBrowser.Contracts/UserInterface/Shell/Events/WirelessNetworkSelectedEventHandler.cs b/SafeExamBrowser.Contracts/UserInterface/Shell/Events/WirelessNetworkSelectedEventHandler.cs index 762f6b30..0a251ce2 100644 --- a/SafeExamBrowser.Contracts/UserInterface/Shell/Events/WirelessNetworkSelectedEventHandler.cs +++ b/SafeExamBrowser.Contracts/UserInterface/Shell/Events/WirelessNetworkSelectedEventHandler.cs @@ -6,12 +6,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -using SafeExamBrowser.Contracts.SystemComponents; +using System; namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events { /// - /// Indicates that a particular has been selected by the user. + /// Indicates that a particular wireless network has been selected by the user. /// - public delegate void WirelessNetworkSelectedEventHandler(IWirelessNetwork network); + public delegate void WirelessNetworkSelectedEventHandler(Guid id); } diff --git a/SafeExamBrowser.SystemComponents/WirelessNetwork.cs b/SafeExamBrowser.SystemComponents/WirelessNetwork.cs index b318bd29..2fc82bb1 100644 --- a/SafeExamBrowser.SystemComponents/WirelessNetwork.cs +++ b/SafeExamBrowser.SystemComponents/WirelessNetwork.cs @@ -22,11 +22,11 @@ namespace SafeExamBrowser.SystemComponents { public class WirelessNetwork : ISystemComponent { - private const int TWO_SECONDS = 2000; + private const int FIVE_SECONDS = 5000; private readonly object @lock = new object(); - private IList controls; - private IList networks; + private List controls; + private List networks; private bool hasWifiAdapter; private ILogger logger; private IText text; @@ -49,10 +49,8 @@ namespace SafeExamBrowser.SystemComponents if (hasWifiAdapter) { - timer = new Timer(TWO_SECONDS); - timer.Elapsed += Timer_Elapsed; - timer.AutoReset = true; - timer.Start(); + UpdateAvailableNetworks(); + StartTimer(); logger.Info("Started monitoring the wireless network adapter."); } @@ -97,23 +95,28 @@ namespace SafeExamBrowser.SystemComponents } } - private void Control_NetworkSelected(IWirelessNetwork network) + private void Control_NetworkSelected(Guid id) { - try + lock (@lock) { - var accessPoint = networks.First(n => n.Id == network.Id).AccessPoint; - var authRequest = new AuthRequest(accessPoint); + var network = networks.First(n => n.Id == id); - accessPoint.ConnectAsync(authRequest, false, (success) => AccessPoint_OnConnectComplete(network.Name, success)); - - foreach (var control in controls) + try { - control.IsConnecting = true; + var request = new AuthRequest(network.AccessPoint); + + logger.Info($"Attempting to connect to '{network.Name}'..."); + network.AccessPoint.ConnectAsync(request, false, (success) => AccessPoint_OnConnectComplete(network.Name, success)); + + foreach (var control in controls) + { + control.IsConnecting = true; + } + } + catch (Exception e) + { + logger.Error($"Failed to connect to wireless network '{network.Name}!'", e); } - } - catch (Exception e) - { - logger.Error($"Failed to connect to wireless network '{network.Name}!'", e); } } @@ -133,16 +136,19 @@ namespace SafeExamBrowser.SystemComponents control.IsConnecting = false; } + UpdateAvailableNetworks(); UpdateControls(); } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { + UpdateAvailableNetworks(); UpdateControls(); } private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e) { + UpdateAvailableNetworks(); UpdateControls(); } @@ -177,22 +183,7 @@ namespace SafeExamBrowser.SystemComponents { try { - var isConnected = false; - var networkName = string.Empty; - - networks.Clear(); - - foreach (var accessPoint in wifi.GetAccessPoints()) - { - // The user may only connect to an already configured wireless network! - if (accessPoint.HasProfile) - { - networkName = accessPoint.Name; - isConnected = accessPoint.IsConnected; - - networks.Add(ToDefinition(accessPoint)); - } - } + var currentNetwork = networks.FirstOrDefault(n => n.Status == WirelessNetworkStatus.Connected); foreach (var control in controls) { @@ -201,13 +192,13 @@ namespace SafeExamBrowser.SystemComponents control.SetInformation(text.Get(TextKey.SystemControl_WirelessDisconnected)); } - if (isConnected) + if (currentNetwork != null) { - control.SetInformation(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", networkName)); + control.SetInformation(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", currentNetwork.Name)); } control.NetworkStatus = ToStatus(wifi.ConnectionStatus); - control.Update(new List(networks)); + control.Update(networks.ToList()); } } catch (Exception e) @@ -217,6 +208,31 @@ namespace SafeExamBrowser.SystemComponents } } + private void UpdateAvailableNetworks() + { + lock (@lock) + { + networks.Clear(); + + foreach (var accessPoint in wifi.GetAccessPoints()) + { + // The user may only connect to an already configured wireless network! + if (accessPoint.HasProfile) + { + networks.Add(ToDefinition(accessPoint)); + } + } + } + } + + private void StartTimer() + { + timer = new Timer(FIVE_SECONDS); + timer.Elapsed += Timer_Elapsed; + timer.AutoReset = true; + timer.Start(); + } + private WirelessNetworkDefinition ToDefinition(AccessPoint accessPoint) { return new WirelessNetworkDefinition diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml index 2a05366e..ae81bfae 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml @@ -18,7 +18,7 @@ - + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml new file mode 100644 index 00000000..ed6cf9fe --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml.cs new file mode 100644 index 00000000..4d40b056 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkButton.xaml.cs @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System.Windows; +using System.Windows.Controls; +using SafeExamBrowser.Contracts.SystemComponents; +using SafeExamBrowser.Contracts.UserInterface.Shell.Events; + +namespace SafeExamBrowser.UserInterface.Desktop.Controls +{ + public partial class ActionCenterWirelessNetworkButton : UserControl + { + private IWirelessNetwork network; + + public bool IsCurrent + { + set { IsCurrentTextBlock.Visibility = value ? Visibility.Visible : Visibility.Hidden; } + } + + public string NetworkName + { + set { NetworkNameTextBlock.Text = value; } + } + + public int SignalStrength + { + set { SignalStrengthTextBlock.Text = $"{value}%"; } + } + + public event WirelessNetworkSelectedEventHandler NetworkSelected; + + public ActionCenterWirelessNetworkButton(IWirelessNetwork network) + { + this.network = network; + + InitializeComponent(); + InitializeEvents(); + } + + private void InitializeEvents() + { + Button.Click += (o, args) => NetworkSelected?.Invoke(network.Id); + } + } +} diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml new file mode 100644 index 00000000..6fa74ae8 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml.cs new file mode 100644 index 00000000..9e037a60 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterWirelessNetworkControl.xaml.cs @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using FontAwesome.WPF; +using SafeExamBrowser.Contracts.SystemComponents; +using SafeExamBrowser.Contracts.UserInterface.Shell; +using SafeExamBrowser.Contracts.UserInterface.Shell.Events; +using SafeExamBrowser.UserInterface.Desktop.Utilities; + +namespace SafeExamBrowser.UserInterface.Desktop.Controls +{ + public partial class ActionCenterWirelessNetworkControl : UserControl, ISystemWirelessNetworkControl + { + public bool HasWirelessNetworkAdapter + { + set + { + Dispatcher.Invoke(() => + { + Button.IsEnabled = value; + NoAdapterIcon.Visibility = value ? Visibility.Collapsed : Visibility.Visible; + }); + } + } + + public bool IsConnecting + { + set + { + Dispatcher.Invoke(() => + { + LoadingIcon.Visibility = value ? Visibility.Visible : Visibility.Collapsed; + SignalStrengthIcon.Visibility = value ? Visibility.Collapsed : Visibility.Visible; + NetworkStatusIcon.Visibility = value ? Visibility.Collapsed : Visibility.Visible; + }); + } + } + + public WirelessNetworkStatus NetworkStatus + { + set + { + Dispatcher.Invoke(() => + { + var icon = value == WirelessNetworkStatus.Connected ? FontAwesomeIcon.Check : FontAwesomeIcon.Close; + var brush = value == WirelessNetworkStatus.Connected ? Brushes.Green : Brushes.Orange; + + if (value == WirelessNetworkStatus.Disconnected) + { + SignalStrengthIcon.Child = GetIcon(0); + } + + NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(icon, brush); + }); + } + } + + public event WirelessNetworkSelectedEventHandler NetworkSelected; + + public ActionCenterWirelessNetworkControl() + { + InitializeComponent(); + InitializeWirelessNetworkControl(); + } + + public void Close() + { + Dispatcher.Invoke(() => Popup.IsOpen = false); + } + + public void SetInformation(string text) + { + Dispatcher.Invoke(() => + { + Button.ToolTip = text; + Text.Text = text; + }); + } + + public void Update(IEnumerable networks) + { + Dispatcher.Invoke(() => + { + NetworksStackPanel.Children.Clear(); + + foreach (var network in networks) + { + var button = new ActionCenterWirelessNetworkButton(network); + var isCurrent = network.Status == WirelessNetworkStatus.Connected; + + button.IsCurrent = isCurrent; + button.NetworkName = network.Name; + button.SignalStrength = network.SignalStrength; + button.NetworkSelected += (id) => NetworkSelected?.Invoke(id); + + if (isCurrent) + { + NetworkStatus = network.Status; + SignalStrengthIcon.Child = GetIcon(network.SignalStrength); + } + + NetworksStackPanel.Children.Add(button); + } + }); + } + + private void InitializeWirelessNetworkControl() + { + var originalBrush = Grid.Background; + + SignalStrengthIcon.Child = GetIcon(0); + Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen; + Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver)); + Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver)); + Popup.Opened += (o, args) => Grid.Background = Brushes.Gray; + Popup.Closed += (o, args) => Grid.Background = originalBrush; + } + + private UIElement GetIcon(int signalStrength) + { + var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0")); + var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_Light_{icon}.xaml"); + var resource = new XamlIconResource(uri); + + return IconResourceLoader.Load(resource); + } + } +} diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml index 8aa7ceda..1c1e48ee 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml @@ -3,7 +3,6 @@ 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.Desktop.Controls" mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40"> @@ -25,27 +24,9 @@ diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkButton.xaml similarity index 98% rename from SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkButton.xaml rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkButton.xaml index 3e6629a7..6b972368 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkButton.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkButton.xaml @@ -1,4 +1,4 @@ - Click?.Invoke(o, args); + public TaskbarWirelessNetworkButton(IWirelessNetwork network) + { + this.network = network; + + InitializeComponent(); + InitializeEvents(); + } + + private void InitializeEvents() + { + Button.Click += (o, args) => NetworkSelected?.Invoke(network.Id); } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml similarity index 81% rename from SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml index 3f7335f0..3030c42b 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml @@ -1,4 +1,4 @@ - + - - - 5 - + @@ -29,9 +27,9 @@ diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml.cs similarity index 90% rename from SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml.cs rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml.cs index 1c2460d6..6c655c7d 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/WirelessNetworkControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarWirelessNetworkControl.xaml.cs @@ -20,7 +20,7 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities; namespace SafeExamBrowser.UserInterface.Desktop.Controls { - public partial class WirelessNetworkControl : UserControl, ISystemWirelessNetworkControl + public partial class TaskbarWirelessNetworkControl : UserControl, ISystemWirelessNetworkControl { public bool HasWirelessNetworkAdapter { @@ -56,6 +56,11 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls var icon = value == WirelessNetworkStatus.Connected ? FontAwesomeIcon.Check : FontAwesomeIcon.Close; var brush = value == WirelessNetworkStatus.Connected ? Brushes.Green : Brushes.Orange; + if (value == WirelessNetworkStatus.Disconnected) + { + SignalStrengthIcon.Child = GetIcon(0); + } + NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(icon, brush); }); } @@ -63,7 +68,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls public event WirelessNetworkSelectedEventHandler NetworkSelected; - public WirelessNetworkControl() + public TaskbarWirelessNetworkControl() { InitializeComponent(); InitializeWirelessNetworkControl(); @@ -87,16 +92,13 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls foreach (var network in networks) { - var button = new WirelessNetworkButton(); + var button = new TaskbarWirelessNetworkButton(network); var isCurrent = network.Status == WirelessNetworkStatus.Connected; - button.Click += (o, args) => - { - NetworkSelected?.Invoke(network); - }; button.IsCurrent = isCurrent; button.NetworkName = network.Name; button.SignalStrength = network.SignalStrength; + button.NetworkSelected += (id) => NetworkSelected?.Invoke(id); if (isCurrent) { diff --git a/SafeExamBrowser.UserInterface.Desktop/Images/AboutNotification.xaml b/SafeExamBrowser.UserInterface.Desktop/Images/AboutNotification.xaml index aefae141..7d70c974 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Images/AboutNotification.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Images/AboutNotification.xaml @@ -1,8 +1,14 @@  - - - + + + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_0.xaml b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_0.xaml new file mode 100644 index 00000000..07d4c0f4 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_0.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_100.xaml b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_100.xaml new file mode 100644 index 00000000..849e6b15 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_100.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_33.xaml b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_33.xaml new file mode 100644 index 00000000..3c1820c4 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_33.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_66.xaml b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_66.xaml new file mode 100644 index 00000000..006337de --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Images/WiFi_Light_66.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml b/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml index af8b51fe..845db8fb 100644 --- a/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml @@ -4,11 +4,17 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop" - mc:Ignorable="d" - Title="{Binding Path=WindowTitle}" Background="WhiteSmoke" Height="500" Width="1100" MinHeight="350" MinWidth="350" + mc:Ignorable="d" Title="{Binding Path=WindowTitle}" Background="Black" Height="500" Width="1100" MinHeight="350" MinWidth="350" WindowStartupLocation="CenterScreen" Icon="./Images/LogNotification.ico"> + + + + + + + - + diff --git a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj index 9f46a5f8..a9c47ceb 100644 --- a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj +++ b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj @@ -92,6 +92,12 @@ ActionCenterPowerSupplyControl.xaml + + ActionCenterWirelessNetworkButton.xaml + + + ActionCenterWirelessNetworkControl.xaml + TaskbarApplicationControl.xaml @@ -116,11 +122,11 @@ QuitButton.xaml - - WirelessNetworkButton.xaml + + TaskbarWirelessNetworkButton.xaml - - WirelessNetworkControl.xaml + + TaskbarWirelessNetworkControl.xaml LogWindow.xaml @@ -179,6 +185,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -215,6 +229,22 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -271,11 +301,11 @@ MSBuild:Compile Designer - + Designer MSBuild:Compile - + Designer MSBuild:Compile diff --git a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs index 41d059ea..f4da5966 100644 --- a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs +++ b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs @@ -157,9 +157,16 @@ namespace SafeExamBrowser.UserInterface.Desktop return splashScreen; } - public ISystemWirelessNetworkControl CreateWirelessNetworkControl() + public ISystemWirelessNetworkControl CreateWirelessNetworkControl(Location location) { - return new WirelessNetworkControl(); + if (location == Location.ActionCenter) + { + return new ActionCenterWirelessNetworkControl(); + } + else + { + return new TaskbarWirelessNetworkControl(); + } } private void InitializeFontAwesome() diff --git a/SafeExamBrowser.UserInterface.Desktop/ViewModels/LogViewModel.cs b/SafeExamBrowser.UserInterface.Desktop/ViewModels/LogViewModel.cs index 0e14caae..740b545a 100644 --- a/SafeExamBrowser.UserInterface.Desktop/ViewModels/LogViewModel.cs +++ b/SafeExamBrowser.UserInterface.Desktop/ViewModels/LogViewModel.cs @@ -54,7 +54,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.ViewModels { var isHeader = logText.Text.StartsWith("/* "); var isComment = logText.Text.StartsWith("# "); - var brush = isHeader || isComment ? Brushes.ForestGreen : textBlock.Foreground; + var brush = isHeader || isComment ? Brushes.LimeGreen : textBlock.Foreground; textBlock.Inlines.Add(new Run($"{logText.Text}{Environment.NewLine}") { @@ -74,7 +74,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.ViewModels var threadName = message.ThreadInfo.HasName ? ": " + message.ThreadInfo.Name : string.Empty; var threadInfo = $"[{threadId}{threadName}]"; - var infoRun = new Run($"{date} {threadInfo} - ") { Foreground = Brushes.Gray }; + var infoRun = new Run($"{date} {threadInfo} - ") { Foreground = Brushes.DarkGray }; var messageRun = new Run($"{severity}: {message.Message}{Environment.NewLine}") { Foreground = GetBrushFor(message.Severity) }; textBlock.Inlines.Add(infoRun); @@ -87,13 +87,13 @@ namespace SafeExamBrowser.UserInterface.Desktop.ViewModels switch (severity) { case LogLevel.Debug: - return Brushes.Gray; + return Brushes.DarkGray; case LogLevel.Error: return Brushes.Red; case LogLevel.Warning: return Brushes.Orange; default: - return Brushes.Black; + return Brushes.White; } } }