From 5ba6e6345cc6b756345549ee4bbb34d2eb9bbe08 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Tue, 12 Mar 2019 16:18:27 +0100 Subject: [PATCH] SEBWIN-141: Extended / changed implementation of keyboard layout for action center and taskbar. --- .../Operations/ShellOperationTests.cs | 4 +- .../Operations/ShellOperation.cs | 16 ++-- .../DataMapper.UserInterface.cs | 4 +- .../ConfigurationData/DataValues.cs | 9 ++- .../Settings/ActionCenterSettings.cs | 15 ++-- .../Configuration/Settings/TaskbarSettings.cs | 30 +++---- .../SystemComponents/IKeyboardLayout.cs | 5 -- .../UserInterface/IUserInterfaceFactory.cs | 2 +- .../KeyboardLayoutSelectedEventHandler.cs | 6 +- .../Shell/ISystemKeyboardLayoutControl.cs | 5 ++ .../KeyboardLayout.cs | 74 +++++++++++------ .../KeyboardLayoutDefinition.cs | 5 +- .../SafeExamBrowser.SystemComponents.csproj | 1 + .../ActionCenter.xaml | 2 +- .../ActionCenterKeyboardLayoutButton.xaml | 30 +++++++ .../ActionCenterKeyboardLayoutButton.xaml.cs | 56 +++++++++++++ .../ActionCenterKeyboardLayoutControl.xaml | 37 +++++++++ .../ActionCenterKeyboardLayoutControl.xaml.cs | 81 +++++++++++++++++++ .../ActionCenterNotificationButton.xaml | 10 +-- ....xaml => TaskbarKeyboardLayoutButton.xaml} | 2 +- ...cs => TaskbarKeyboardLayoutButton.xaml.cs} | 26 ++++-- ...xaml => TaskbarKeyboardLayoutControl.xaml} | 24 +++--- ...s => TaskbarKeyboardLayoutControl.xaml.cs} | 64 +++++++-------- .../LogWindow.xaml.cs | 4 +- ...feExamBrowser.UserInterface.Desktop.csproj | 26 ++++-- .../Templates/Colors.xaml | 1 + .../UserInterfaceFactory.cs | 11 ++- 27 files changed, 412 insertions(+), 138 deletions(-) create mode 100644 SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml create mode 100644 SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml.cs create mode 100644 SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml create mode 100644 SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml.cs rename SafeExamBrowser.UserInterface.Desktop/Controls/{KeyboardLayoutButton.xaml => TaskbarKeyboardLayoutButton.xaml} (98%) rename SafeExamBrowser.UserInterface.Desktop/Controls/{KeyboardLayoutButton.xaml.cs => TaskbarKeyboardLayoutButton.xaml.cs} (56%) rename SafeExamBrowser.UserInterface.Desktop/Controls/{KeyboardLayoutControl.xaml => TaskbarKeyboardLayoutControl.xaml} (73%) rename SafeExamBrowser.UserInterface.Desktop/Controls/{KeyboardLayoutControl.xaml.cs => TaskbarKeyboardLayoutControl.xaml.cs} (60%) diff --git a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs index 9c326314..29cbad1e 100644 --- a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs @@ -59,8 +59,8 @@ namespace SafeExamBrowser.Client.UnitTests.Operations taskbarSettings = new TaskbarSettings(); uiFactoryMock = new Mock(); - taskbarSettings.AllowApplicationLog = true; - taskbarSettings.AllowKeyboardLayout = true; + taskbarSettings.ShowApplicationLog = true; + taskbarSettings.ShowKeyboardLayout = true; taskbarSettings.AllowWirelessNetwork = true; taskbarSettings.EnableTaskbar = true; systemInfoMock.SetupGet(s => s.HasBattery).Returns(true); diff --git a/SafeExamBrowser.Client/Operations/ShellOperation.cs b/SafeExamBrowser.Client/Operations/ShellOperation.cs index 3422b7c8..5855d0d6 100644 --- a/SafeExamBrowser.Client/Operations/ShellOperation.cs +++ b/SafeExamBrowser.Client/Operations/ShellOperation.cs @@ -191,7 +191,7 @@ namespace SafeExamBrowser.Client.Operations private void InitializeLogNotificationForActionCenter() { - if (actionCenterSettings.AllowApplicationLog) + if (actionCenterSettings.ShowApplicationLog) { var notification = uiFactory.CreateNotificationControl(logInfo, Location.ActionCenter); @@ -202,7 +202,7 @@ namespace SafeExamBrowser.Client.Operations private void InitializeLogNotificationForTaskbar() { - if (taskbarSettings.AllowApplicationLog) + if (taskbarSettings.ShowApplicationLog) { var notification = uiFactory.CreateNotificationControl(logInfo, Location.Taskbar); @@ -213,14 +213,20 @@ namespace SafeExamBrowser.Client.Operations private void InitializeKeyboardLayoutForActionCenter() { - // TODO + if (actionCenterSettings.ShowKeyboardLayout) + { + var control = uiFactory.CreateKeyboardLayoutControl(Location.ActionCenter); + + keyboardLayout.Register(control); + actionCenter.AddSystemControl(control); + } } private void InitializeKeyboardLayoutForTaskbar() { - if (taskbarSettings.AllowKeyboardLayout) + if (taskbarSettings.ShowKeyboardLayout) { - var control = uiFactory.CreateKeyboardLayoutControl(); + var control = uiFactory.CreateKeyboardLayoutControl(Location.Taskbar); keyboardLayout.Register(control); taskbar.AddSystemControl(control); diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs index f7ba0a23..90134111 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.UserInterface.cs @@ -16,7 +16,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData { if (value is bool allow) { - settings.Taskbar.AllowApplicationLog = allow; + settings.Taskbar.ShowApplicationLog = allow; } } @@ -32,7 +32,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData { if (value is bool enabled) { - settings.Taskbar.AllowKeyboardLayout = enabled; + settings.Taskbar.ShowKeyboardLayout = enabled; } } diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs index c9dac541..fd910378 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs @@ -138,17 +138,18 @@ namespace SafeExamBrowser.Configuration.ConfigurationData settings.ServicePolicy = ServicePolicy.Optional; - settings.Taskbar.AllowApplicationLog = false; - settings.Taskbar.AllowKeyboardLayout = true; + settings.Taskbar.ShowApplicationLog = false; + settings.Taskbar.ShowKeyboardLayout = true; settings.Taskbar.AllowWirelessNetwork = false; settings.Taskbar.EnableTaskbar = true; settings.Taskbar.ShowClock = true; // TODO: Default values for testing of alpha version only, remove for final release! - settings.ActionCenter.AllowApplicationLog = true; + settings.ActionCenter.ShowApplicationLog = true; + settings.ActionCenter.ShowKeyboardLayout = true; settings.Browser.AllowDeveloperConsole = true; settings.Browser.MainWindowSettings.AllowAddressBar = true; - settings.Taskbar.AllowApplicationLog = true; + settings.Taskbar.ShowApplicationLog = true; return settings; } diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs index 534d87be..a7495234 100644 --- a/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs +++ b/SafeExamBrowser.Contracts/Configuration/Settings/ActionCenterSettings.cs @@ -16,14 +16,19 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings [Serializable] public class ActionCenterSettings { - /// - /// Determines whether the user may access the application log during runtime. - /// - public bool AllowApplicationLog { get; set; } - /// /// Determines whether the action center itself is enabled and visible to the user. /// public bool EnableActionCenter { get; set; } + + /// + /// Determines whether the application log is accessible via the action center. + /// + public bool ShowApplicationLog { get; set; } + + /// + /// Determines whether the system control for the keyboard layout is accessible via the action center. + /// + public bool ShowKeyboardLayout { get; set; } } } diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs index 411c0692..aa69a467 100644 --- a/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs +++ b/SafeExamBrowser.Contracts/Configuration/Settings/TaskbarSettings.cs @@ -16,29 +16,29 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings [Serializable] public class TaskbarSettings { - /// - /// Determines whether the user may switch the keyboard layout during runtime. - /// - public bool AllowKeyboardLayout { get; set; } - - /// - /// Determines whether the user may access the application log during runtime. - /// - public bool AllowApplicationLog { get; set; } - - /// - /// Determines whether the user may control the wireless network connection during runtime. - /// - public bool AllowWirelessNetwork { get; set; } - /// /// Determines whether the taskbar itself is enabled and visible to the user. /// public bool EnableTaskbar { get; set; } + /// + /// Determines whether the application log is accessible via the taskbar. + /// + public bool ShowApplicationLog { get; set; } + /// /// Determines whether the current date and time will be rendered in the taskbar. /// public bool ShowClock { get; set; } + + /// + /// Determines whether the system control for the keyboard layout is accessible via the taskbar. + /// + public bool ShowKeyboardLayout { get; set; } + + /// + /// Determines whether the system control for the wireless network is accessible via the taskbar. + /// + public bool AllowWirelessNetwork { get; set; } } } diff --git a/SafeExamBrowser.Contracts/SystemComponents/IKeyboardLayout.cs b/SafeExamBrowser.Contracts/SystemComponents/IKeyboardLayout.cs index b0155642..42f99e78 100644 --- a/SafeExamBrowser.Contracts/SystemComponents/IKeyboardLayout.cs +++ b/SafeExamBrowser.Contracts/SystemComponents/IKeyboardLayout.cs @@ -25,11 +25,6 @@ namespace SafeExamBrowser.Contracts.SystemComponents /// Guid Id { get; } - /// - /// Specifies whether this is the current keyboard layout. - /// - bool IsCurrent { get; } - /// /// The name of this keyboard layout. /// diff --git a/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs b/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs index 064b16e4..a5d4b604 100644 --- a/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs +++ b/SafeExamBrowser.Contracts/UserInterface/IUserInterfaceFactory.cs @@ -43,7 +43,7 @@ namespace SafeExamBrowser.Contracts.UserInterface /// /// Creates a system control which allows to change the keyboard layout of the computer. /// - ISystemKeyboardLayoutControl CreateKeyboardLayoutControl(); + ISystemKeyboardLayoutControl CreateKeyboardLayoutControl(Location location); /// /// Creates a new log window which runs on its own thread. diff --git a/SafeExamBrowser.Contracts/UserInterface/Shell/Events/KeyboardLayoutSelectedEventHandler.cs b/SafeExamBrowser.Contracts/UserInterface/Shell/Events/KeyboardLayoutSelectedEventHandler.cs index c6ecb118..ea91ea31 100644 --- a/SafeExamBrowser.Contracts/UserInterface/Shell/Events/KeyboardLayoutSelectedEventHandler.cs +++ b/SafeExamBrowser.Contracts/UserInterface/Shell/Events/KeyboardLayoutSelectedEventHandler.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 keyboard layout has been selected by the user. /// - public delegate void KeyboardLayoutSelectedEventHandler(IKeyboardLayout layout); + public delegate void KeyboardLayoutSelectedEventHandler(Guid id); } diff --git a/SafeExamBrowser.Contracts/UserInterface/Shell/ISystemKeyboardLayoutControl.cs b/SafeExamBrowser.Contracts/UserInterface/Shell/ISystemKeyboardLayoutControl.cs index 2f8b84e8..111c88ec 100644 --- a/SafeExamBrowser.Contracts/UserInterface/Shell/ISystemKeyboardLayoutControl.cs +++ b/SafeExamBrowser.Contracts/UserInterface/Shell/ISystemKeyboardLayoutControl.cs @@ -25,5 +25,10 @@ namespace SafeExamBrowser.Contracts.UserInterface.Shell /// Adds the given layout to the list of selectable keyboard layouts. /// void Add(IKeyboardLayout layout); + + /// + /// Defines the given keyboard layout as the currently active one. + /// + void SetCurrent(IKeyboardLayout layout); } } diff --git a/SafeExamBrowser.SystemComponents/KeyboardLayout.cs b/SafeExamBrowser.SystemComponents/KeyboardLayout.cs index b9322d5b..f76ec5f8 100644 --- a/SafeExamBrowser.SystemComponents/KeyboardLayout.cs +++ b/SafeExamBrowser.SystemComponents/KeyboardLayout.cs @@ -6,9 +6,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; -using System.Windows.Forms; +using System.Windows.Input; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.SystemComponents; @@ -18,57 +20,70 @@ namespace SafeExamBrowser.SystemComponents { public class KeyboardLayout : ISystemComponent { - private IList layouts = new List(); + private const int TWO_SECONDS = 2000; + + private KeyboardLayoutDefinition currentLayout; + private IList layouts; private ILogger logger; - private InputLanguage originalLanguage; + private CultureInfo originalLanguage; private IList controls; private IText text; public KeyboardLayout(ILogger logger, IText text) { this.controls = new List(); + this.layouts = new List(); this.logger = logger; this.text = text; } public void Initialize() { - originalLanguage = InputLanguage.CurrentInputLanguage; + originalLanguage = InputLanguageManager.Current.CurrentInputLanguage; logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}."); - foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) + foreach (CultureInfo info in InputLanguageManager.Current.AvailableInputLanguages) { var layout = new KeyboardLayoutDefinition { - CultureCode = language.Culture.ThreeLetterISOLanguageName.ToUpper(), - IsCurrent = originalLanguage.Equals(language), - Language = language, - Name = language.LayoutName + CultureCode = info.ThreeLetterISOLanguageName.ToUpper(), + CultureInfo = info, + Name = info.NativeName }; + if (originalLanguage.Equals(info)) + { + currentLayout = layout; + } + layouts.Add(layout); - logger.Info($"Detected keyboard layout {ToString(language)}."); + logger.Info($"Detected keyboard layout {ToString(info)}."); } + + InputLanguageManager.Current.InputLanguageChanged += Current_InputLanguageChanged; } public void Register(ISystemKeyboardLayoutControl control) { - control.LayoutSelected += Control_LayoutSelected; - control.SetTooltip(text.Get(TextKey.SystemControl_KeyboardLayoutTooltip)); - foreach (var layout in layouts) { control.Add(layout); } + control.LayoutSelected += Control_LayoutSelected; + control.SetCurrent(currentLayout); + control.SetTooltip(text.Get(TextKey.SystemControl_KeyboardLayoutTooltip)); + controls.Add(control); } public void Terminate() { + InputLanguageManager.Current.InputLanguageChanged -= Current_InputLanguageChanged; + if (originalLanguage != null) { - InputLanguage.CurrentInputLanguage = originalLanguage; + InputLanguageManager.Current.CurrentInputLanguage = originalLanguage; logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}."); } @@ -78,23 +93,30 @@ namespace SafeExamBrowser.SystemComponents } } - private void Control_LayoutSelected(IKeyboardLayout layout) + private void Control_LayoutSelected(Guid id) { - var language = layouts.First(l => l.Id == layout.Id).Language; + var layout = layouts.First(l => l.Id == id); - InputLanguage.CurrentInputLanguage = language; - - foreach (var l in layouts) - { - l.IsCurrent = l.Id == layout.Id; - } - - logger.Info($"Changed keyboard layout to {ToString(language)}."); + InputLanguageManager.Current.CurrentInputLanguage = layout.CultureInfo; + logger.Info($"Changed keyboard layout to {ToString(layout.CultureInfo)}."); } - private string ToString(InputLanguage language) + private void Current_InputLanguageChanged(object sender, InputLanguageEventArgs e) { - return $"'{language.LayoutName}' ({language.Culture.ThreeLetterISOLanguageName.ToUpper()})"; + var newLayout = layouts.First(l => l.CultureInfo.Equals(e.NewLanguage)); + + logger.Info($"Detected keyboard layout change from {ToString(e.PreviousLanguage)} to {ToString(e.NewLanguage)}."); + currentLayout = newLayout; + + foreach (var control in controls) + { + control.SetCurrent(newLayout); + } + } + + private string ToString(CultureInfo info) + { + return $"'{info.DisplayName}' ({info.ThreeLetterISOLanguageName.ToUpper()})"; } } } diff --git a/SafeExamBrowser.SystemComponents/KeyboardLayoutDefinition.cs b/SafeExamBrowser.SystemComponents/KeyboardLayoutDefinition.cs index e3fc90e1..c908e7e0 100644 --- a/SafeExamBrowser.SystemComponents/KeyboardLayoutDefinition.cs +++ b/SafeExamBrowser.SystemComponents/KeyboardLayoutDefinition.cs @@ -7,18 +7,17 @@ */ using System; -using System.Windows.Forms; +using System.Globalization; using SafeExamBrowser.Contracts.SystemComponents; namespace SafeExamBrowser.SystemComponents { internal class KeyboardLayoutDefinition : IKeyboardLayout { - internal InputLanguage Language { get; set; } + internal CultureInfo CultureInfo { get; set; } public string CultureCode { get; set; } public Guid Id { get; } - public bool IsCurrent { get; set; } public string Name { get; set; } public KeyboardLayoutDefinition() diff --git a/SafeExamBrowser.SystemComponents/SafeExamBrowser.SystemComponents.csproj b/SafeExamBrowser.SystemComponents/SafeExamBrowser.SystemComponents.csproj index ede946cf..cb8754e9 100644 --- a/SafeExamBrowser.SystemComponents/SafeExamBrowser.SystemComponents.csproj +++ b/SafeExamBrowser.SystemComponents/SafeExamBrowser.SystemComponents.csproj @@ -47,6 +47,7 @@ prompt + False ..\Libraries\SimpleWifi.dll diff --git a/SafeExamBrowser.UserInterface.Desktop/ActionCenter.xaml b/SafeExamBrowser.UserInterface.Desktop/ActionCenter.xaml index b3b84901..cef54573 100644 --- a/SafeExamBrowser.UserInterface.Desktop/ActionCenter.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/ActionCenter.xaml @@ -20,6 +20,6 @@ - + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml new file mode 100644 index 00000000..ffcf0fe8 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml.cs new file mode 100644 index 00000000..2eaa8ec2 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutButton.xaml.cs @@ -0,0 +1,56 @@ +/* + * 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.Windows; +using System.Windows.Controls; +using SafeExamBrowser.Contracts.SystemComponents; +using SafeExamBrowser.Contracts.UserInterface.Shell.Events; + +namespace SafeExamBrowser.UserInterface.Desktop.Controls +{ + public partial class ActionCenterKeyboardLayoutButton : UserControl + { + private IKeyboardLayout layout; + + public event KeyboardLayoutSelectedEventHandler LayoutSelected; + + public string CultureCode + { + set { CultureCodeTextBlock.Text = value; } + } + + public bool IsCurrent + { + set { IsCurrentTextBlock.Visibility = value ? Visibility.Visible : Visibility.Hidden; } + } + + public string LayoutName + { + set { LayoutNameTextBlock.Text = value; } + } + + public Guid LayoutId + { + get { return layout.Id; } + } + + public ActionCenterKeyboardLayoutButton(IKeyboardLayout layout) + { + this.layout = layout; + + InitializeComponent(); + InitializeEvents(); + } + + private void InitializeEvents() + { + Button.Click += (o, args) => LayoutSelected?.Invoke(layout.Id); + } + } +} diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml new file mode 100644 index 00000000..9b89d427 --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml.cs new file mode 100644 index 00000000..30f8f1ad --- /dev/null +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterKeyboardLayoutControl.xaml.cs @@ -0,0 +1,81 @@ +/* + * 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.Threading.Tasks; +using System.Windows.Controls; +using SafeExamBrowser.Contracts.SystemComponents; +using SafeExamBrowser.Contracts.UserInterface.Shell; +using SafeExamBrowser.Contracts.UserInterface.Shell.Events; + +namespace SafeExamBrowser.UserInterface.Desktop.Controls +{ + public partial class ActionCenterKeyboardLayoutControl : UserControl, ISystemKeyboardLayoutControl + { + public event KeyboardLayoutSelectedEventHandler LayoutSelected; + + public ActionCenterKeyboardLayoutControl() + { + InitializeComponent(); + InitializeKeyboardLayoutControl(); + } + + public void Add(IKeyboardLayout layout) + { + Dispatcher.Invoke(() => + { + var button = new ActionCenterKeyboardLayoutButton(layout); + + button.LayoutSelected += Button_LayoutSelected; + button.CultureCode = layout.CultureCode; + button.LayoutName = layout.Name; + + LayoutsStackPanel.Children.Add(button); + }); + } + + public void Close() + { + Dispatcher.Invoke(() => Popup.IsOpen = false); + } + + public void SetCurrent(IKeyboardLayout layout) + { + Dispatcher.Invoke(() => + { + foreach (var child in LayoutsStackPanel.Children) + { + if (child is ActionCenterKeyboardLayoutButton layoutButton) + { + layoutButton.IsCurrent = layout.Id == layoutButton.LayoutId; + } + } + + Text.Text = layout.Name; + }); + } + + public void SetTooltip(string text) + { + Dispatcher.Invoke(() => Button.ToolTip = text); + } + + private void InitializeKeyboardLayoutControl() + { + 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)); + } + + private void Button_LayoutSelected(Guid id) + { + Popup.IsOpen = false; + LayoutSelected?.Invoke(id); + } + } +} diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterNotificationButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterNotificationButton.xaml index b8e093e7..1136ce45 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterNotificationButton.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenterNotificationButton.xaml @@ -4,7 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls" - mc:Ignorable="d" d:DesignHeight="60" d:DesignWidth="80"> + mc:Ignorable="d" d:DesignHeight="100" d:DesignWidth="125"> @@ -13,15 +13,15 @@ - + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutButton.xaml similarity index 98% rename from SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutButton.xaml rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutButton.xaml index c269cf43..74d81996 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutButton.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutButton.xaml @@ -1,4 +1,4 @@ - Click?.Invoke(o, args); + public TaskbarKeyboardLayoutButton(IKeyboardLayout layout) + { + this.layout = layout; + + InitializeComponent(); + InitializeEvents(); + } + + private void InitializeEvents() + { + Button.Click += (o, args) => LayoutSelected?.Invoke(layout.Id); } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml similarity index 73% rename from SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml index b898d843..8aa7ceda 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml @@ -1,4 +1,4 @@ - + - - - 5 - + @@ -34,18 +32,18 @@ - - + + + + + + - - - - - - + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml.cs similarity index 60% rename from SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml.cs rename to SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml.cs index 9906b210..9bace59a 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/KeyboardLayoutControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/TaskbarKeyboardLayoutControl.xaml.cs @@ -17,11 +17,11 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events; namespace SafeExamBrowser.UserInterface.Desktop.Controls { - public partial class KeyboardLayoutControl : UserControl, ISystemKeyboardLayoutControl + public partial class TaskbarKeyboardLayoutControl : UserControl, ISystemKeyboardLayoutControl { public event KeyboardLayoutSelectedEventHandler LayoutSelected; - public KeyboardLayoutControl() + public TaskbarKeyboardLayoutControl() { InitializeComponent(); InitializeKeyboardLayoutControl(); @@ -29,33 +29,44 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls public void Add(IKeyboardLayout layout) { - var button = new KeyboardLayoutButton(); - - button.Click += (o, args) => + Dispatcher.Invoke(() => { - SetCurrent(button, layout); - Popup.IsOpen = false; - LayoutSelected?.Invoke(layout); - }; - button.CultureCode = layout.CultureCode; - button.LayoutName = layout.Name; + var button = new TaskbarKeyboardLayoutButton(layout); - LayoutsStackPanel.Children.Add(button); + button.LayoutSelected += Button_LayoutSelected; + button.CultureCode = layout.CultureCode; + button.LayoutName = layout.Name; - if (layout.IsCurrent) - { - SetCurrent(button, layout); - } + LayoutsStackPanel.Children.Add(button); + }); } public void Close() { - Popup.IsOpen = false; + Dispatcher.Invoke(() => Popup.IsOpen = false); + } + + public void SetCurrent(IKeyboardLayout layout) + { + Dispatcher.Invoke(() => + { + 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) + { + if (child is TaskbarKeyboardLayoutButton layoutButton) + { + layoutButton.IsCurrent = layout.Id == layoutButton.LayoutId; + } + } + + LayoutCultureCode.Text = layout.CultureCode; + }); } public void SetTooltip(string text) { - Button.ToolTip = text; + Dispatcher.Invoke(() => Button.ToolTip = text); } private void InitializeKeyboardLayoutControl() @@ -79,21 +90,10 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls }; } - private void SetCurrent(KeyboardLayoutButton button, IKeyboardLayout layout) + private void Button_LayoutSelected(Guid id) { - 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) - { - if (child is KeyboardLayoutButton keyboardLayoutButton) - { - keyboardLayoutButton.IsCurrent = false; - } - } - - button.IsCurrent = true; - LayoutCultureCode.Text = layout.CultureCode; - LayoutName.Text = name; + Popup.IsOpen = false; + LayoutSelected?.Invoke(id); } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml.cs index 1666394c..8c6060f3 100644 --- a/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/LogWindow.xaml.cs @@ -83,13 +83,13 @@ namespace SafeExamBrowser.UserInterface.Desktop } logger.Subscribe(model); - logger.Info("Opened log window."); + logger.Debug("Opened log window."); } private void LogWindow_Closing(object sender, CancelEventArgs e) { logger.Unsubscribe(model); - logger.Info("Closed log window."); + logger.Debug("Closed log window."); closing?.Invoke(); } diff --git a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj index e0f0a2ab..69efc3e2 100644 --- a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj +++ b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj @@ -80,6 +80,12 @@ ActionCenterApplicationButton.xaml + + ActionCenterKeyboardLayoutButton.xaml + + + ActionCenterKeyboardLayoutControl.xaml + ActionCenterNotificationButton.xaml @@ -92,11 +98,11 @@ DateTimeControl.xaml - - KeyboardLayoutButton.xaml + + TaskbarKeyboardLayoutButton.xaml - - KeyboardLayoutControl.xaml + + TaskbarKeyboardLayoutControl.xaml TaskbarNotificationButton.xaml @@ -154,6 +160,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -170,11 +184,11 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile - + Designer MSBuild:Compile diff --git a/SafeExamBrowser.UserInterface.Desktop/Templates/Colors.xaml b/SafeExamBrowser.UserInterface.Desktop/Templates/Colors.xaml index 9dc2d951..53b030d0 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Templates/Colors.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Templates/Colors.xaml @@ -2,4 +2,5 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Templates"> #FFF0F0F0 + #AA808080 \ No newline at end of file diff --git a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs index bb9613cf..0ac39827 100644 --- a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs +++ b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs @@ -57,9 +57,16 @@ namespace SafeExamBrowser.UserInterface.Desktop return new BrowserWindow(control, settings, isMainWindow, text); } - public ISystemKeyboardLayoutControl CreateKeyboardLayoutControl() + public ISystemKeyboardLayoutControl CreateKeyboardLayoutControl(Location location) { - return new KeyboardLayoutControl(); + if (location == Location.ActionCenter) + { + return new ActionCenterKeyboardLayoutControl(); + } + else + { + return new TaskbarKeyboardLayoutControl(); + } } public IWindow CreateLogWindow(ILogger logger)