SEBWIN-342: Removed UI dependencies from audio system component.
This commit is contained in:
parent
d8752b5558
commit
7506ebaf10
24 changed files with 451 additions and 528 deletions
|
@ -15,6 +15,7 @@ using SafeExamBrowser.Configuration.Contracts.Settings;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
@ -28,6 +29,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
private Mock<IActionCenter> actionCenter;
|
private Mock<IActionCenter> actionCenter;
|
||||||
private List<IActionCenterActivator> activators;
|
private List<IActionCenterActivator> activators;
|
||||||
private ActionCenterSettings actionCenterSettings;
|
private ActionCenterSettings actionCenterSettings;
|
||||||
|
private Mock<IAudio> audio;
|
||||||
private Mock<ILogger> logger;
|
private Mock<ILogger> logger;
|
||||||
private TaskbarSettings taskbarSettings;
|
private TaskbarSettings taskbarSettings;
|
||||||
private Mock<ITerminationActivator> terminationActivator;
|
private Mock<ITerminationActivator> terminationActivator;
|
||||||
|
@ -37,7 +39,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
private Mock<INotificationInfo> logInfo;
|
private Mock<INotificationInfo> logInfo;
|
||||||
private Mock<INotificationController> logController;
|
private Mock<INotificationController> logController;
|
||||||
// TODO
|
// TODO
|
||||||
//private Mock<ISystemComponent<ISystemAudioControl>> audio;
|
|
||||||
//private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupply;
|
//private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupply;
|
||||||
//private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetwork;
|
//private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetwork;
|
||||||
private Mock<ISystemInfo> systemInfo;
|
private Mock<ISystemInfo> systemInfo;
|
||||||
|
@ -53,6 +54,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
actionCenter = new Mock<IActionCenter>();
|
actionCenter = new Mock<IActionCenter>();
|
||||||
activators = new List<IActionCenterActivator>();
|
activators = new List<IActionCenterActivator>();
|
||||||
actionCenterSettings = new ActionCenterSettings();
|
actionCenterSettings = new ActionCenterSettings();
|
||||||
|
audio = new Mock<IAudio>();
|
||||||
logger = new Mock<ILogger>();
|
logger = new Mock<ILogger>();
|
||||||
aboutInfo = new Mock<INotificationInfo>();
|
aboutInfo = new Mock<INotificationInfo>();
|
||||||
aboutController = new Mock<INotificationController>();
|
aboutController = new Mock<INotificationController>();
|
||||||
|
@ -60,7 +62,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
logInfo = new Mock<INotificationInfo>();
|
logInfo = new Mock<INotificationInfo>();
|
||||||
logController = new Mock<INotificationController>();
|
logController = new Mock<INotificationController>();
|
||||||
// TODO
|
// TODO
|
||||||
//audio = new Mock<ISystemComponent<ISystemAudioControl>>();
|
|
||||||
//powerSupply = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
//powerSupply = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
||||||
//wirelessNetwork = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
//wirelessNetwork = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||||
systemInfo = new Mock<ISystemInfo>();
|
systemInfo = new Mock<ISystemInfo>();
|
||||||
|
@ -76,6 +77,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
actionCenter.Object,
|
actionCenter.Object,
|
||||||
activators,
|
activators,
|
||||||
actionCenterSettings,
|
actionCenterSettings,
|
||||||
|
audio.Object,
|
||||||
logger.Object,
|
logger.Object,
|
||||||
aboutInfo.Object,
|
aboutInfo.Object,
|
||||||
aboutController.Object,
|
aboutController.Object,
|
||||||
|
@ -196,7 +198,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
taskbarSettings.ShowWirelessNetwork = true;
|
taskbarSettings.ShowWirelessNetwork = true;
|
||||||
|
|
||||||
systemInfo.SetupGet(s => s.HasBattery).Returns(true);
|
systemInfo.SetupGet(s => s.HasBattery).Returns(true);
|
||||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<Location>())).Returns(new Mock<ISystemAudioControl>().Object);
|
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<Location>())).Returns(new Mock<ISystemPowerSupplyControl>().Object);
|
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<Location>())).Returns(new Mock<ISystemPowerSupplyControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<Location>())).Returns(new Mock<ISystemWirelessNetworkControl>().Object);
|
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<Location>())).Returns(new Mock<ISystemWirelessNetworkControl>().Object);
|
||||||
|
@ -225,7 +227,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
taskbarSettings.ShowWirelessNetwork = false;
|
taskbarSettings.ShowWirelessNetwork = false;
|
||||||
|
|
||||||
systemInfo.SetupGet(s => s.HasBattery).Returns(false);
|
systemInfo.SetupGet(s => s.HasBattery).Returns(false);
|
||||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<Location>())).Returns(new Mock<ISystemAudioControl>().Object);
|
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<Location>())).Returns(new Mock<ISystemPowerSupplyControl>().Object);
|
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<Location>())).Returns(new Mock<ISystemPowerSupplyControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<Location>())).Returns(new Mock<ISystemWirelessNetworkControl>().Object);
|
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<Location>())).Returns(new Mock<ISystemWirelessNetworkControl>().Object);
|
||||||
|
|
|
@ -39,7 +39,9 @@ using SafeExamBrowser.Monitoring.Mouse;
|
||||||
using SafeExamBrowser.Monitoring.Processes;
|
using SafeExamBrowser.Monitoring.Processes;
|
||||||
using SafeExamBrowser.Monitoring.Windows;
|
using SafeExamBrowser.Monitoring.Windows;
|
||||||
using SafeExamBrowser.SystemComponents;
|
using SafeExamBrowser.SystemComponents;
|
||||||
|
using SafeExamBrowser.SystemComponents.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
@ -270,6 +272,7 @@ namespace SafeExamBrowser.Client
|
||||||
actionCenter,
|
actionCenter,
|
||||||
activators,
|
activators,
|
||||||
configuration.Settings.ActionCenter,
|
configuration.Settings.ActionCenter,
|
||||||
|
audio,
|
||||||
logger,
|
logger,
|
||||||
aboutInfo,
|
aboutInfo,
|
||||||
aboutController,
|
aboutController,
|
||||||
|
@ -277,7 +280,6 @@ namespace SafeExamBrowser.Client
|
||||||
logInfo,
|
logInfo,
|
||||||
logController,
|
logController,
|
||||||
// TODO
|
// TODO
|
||||||
//audio,
|
|
||||||
//powerSupply,
|
//powerSupply,
|
||||||
//wirelessNetwork,
|
//wirelessNetwork,
|
||||||
systemInfo,
|
systemInfo,
|
||||||
|
|
|
@ -14,6 +14,7 @@ using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
@ -26,13 +27,13 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
private IActionCenter actionCenter;
|
private IActionCenter actionCenter;
|
||||||
private IEnumerable<IActionCenterActivator> activators;
|
private IEnumerable<IActionCenterActivator> activators;
|
||||||
private ActionCenterSettings actionCenterSettings;
|
private ActionCenterSettings actionCenterSettings;
|
||||||
|
private IAudio audio;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private INotificationInfo aboutInfo;
|
private INotificationInfo aboutInfo;
|
||||||
private INotificationController aboutController;
|
private INotificationController aboutController;
|
||||||
private IKeyboard keyboard;
|
private IKeyboard keyboard;
|
||||||
private INotificationInfo logInfo;
|
private INotificationInfo logInfo;
|
||||||
private INotificationController logController;
|
private INotificationController logController;
|
||||||
// TODO private ISystemComponent<ISystemAudioControl> audio;
|
|
||||||
// TODO private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
// TODO private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
||||||
// TODO private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
// TODO private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
||||||
private ISystemInfo systemInfo;
|
private ISystemInfo systemInfo;
|
||||||
|
@ -49,13 +50,13 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
IActionCenter actionCenter,
|
IActionCenter actionCenter,
|
||||||
IEnumerable<IActionCenterActivator> activators,
|
IEnumerable<IActionCenterActivator> activators,
|
||||||
ActionCenterSettings actionCenterSettings,
|
ActionCenterSettings actionCenterSettings,
|
||||||
|
IAudio audio,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
INotificationInfo aboutInfo,
|
INotificationInfo aboutInfo,
|
||||||
INotificationController aboutController,
|
INotificationController aboutController,
|
||||||
IKeyboard keyboard,
|
IKeyboard keyboard,
|
||||||
INotificationInfo logInfo,
|
INotificationInfo logInfo,
|
||||||
INotificationController logController,
|
INotificationController logController,
|
||||||
// TODO ISystemComponent<ISystemAudioControl> audio,
|
|
||||||
// TODO ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
// TODO ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
||||||
// TODO ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
// TODO ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
||||||
ISystemInfo systemInfo,
|
ISystemInfo systemInfo,
|
||||||
|
@ -70,11 +71,11 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
this.actionCenter = actionCenter;
|
this.actionCenter = actionCenter;
|
||||||
this.activators = activators;
|
this.activators = activators;
|
||||||
this.actionCenterSettings = actionCenterSettings;
|
this.actionCenterSettings = actionCenterSettings;
|
||||||
|
this.audio = audio;
|
||||||
this.keyboard = keyboard;
|
this.keyboard = keyboard;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.logInfo = logInfo;
|
this.logInfo = logInfo;
|
||||||
this.logController = logController;
|
this.logController = logController;
|
||||||
// TODO this.audio = audio;
|
|
||||||
// TODO this.powerSupply = powerSupply;
|
// TODO this.powerSupply = powerSupply;
|
||||||
this.systemInfo = systemInfo;
|
this.systemInfo = systemInfo;
|
||||||
this.taskbarSettings = taskbarSettings;
|
this.taskbarSettings = taskbarSettings;
|
||||||
|
@ -168,9 +169,9 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
|
|
||||||
private void InitializeSystemComponents()
|
private void InitializeSystemComponents()
|
||||||
{
|
{
|
||||||
// TODO
|
audio.Initialize();
|
||||||
//audio.Initialize();
|
|
||||||
keyboard.Initialize();
|
keyboard.Initialize();
|
||||||
|
// TODO
|
||||||
//powerSupply.Initialize();
|
//powerSupply.Initialize();
|
||||||
//wirelessNetwork.Initialize();
|
//wirelessNetwork.Initialize();
|
||||||
}
|
}
|
||||||
|
@ -201,10 +202,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
{
|
{
|
||||||
if (actionCenterSettings.ShowAudio)
|
if (actionCenterSettings.ShowAudio)
|
||||||
{
|
{
|
||||||
var control = uiFactory.CreateAudioControl(Location.ActionCenter);
|
actionCenter.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.ActionCenter));
|
||||||
|
|
||||||
// TODO audio.Register(control);
|
|
||||||
actionCenter.AddSystemControl(control);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,10 +210,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
{
|
{
|
||||||
if (taskbarSettings.ShowAudio)
|
if (taskbarSettings.ShowAudio)
|
||||||
{
|
{
|
||||||
var control = uiFactory.CreateAudioControl(Location.Taskbar);
|
taskbar.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.Taskbar));
|
||||||
|
|
||||||
// TODO audio.Register(control);
|
|
||||||
taskbar.AddSystemControl(control);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,11 +327,11 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
|
|
||||||
private void TerminateSystemComponents()
|
private void TerminateSystemComponents()
|
||||||
{
|
{
|
||||||
|
audio.Terminate();
|
||||||
|
keyboard.Terminate();
|
||||||
// TODO
|
// TODO
|
||||||
//audio.Terminate();
|
|
||||||
//powerSupply.Terminate();
|
//powerSupply.Terminate();
|
||||||
//wirelessNetwork.Terminate();
|
//wirelessNetwork.Terminate();
|
||||||
keyboard.Terminate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Contracts.Shell.Events
|
namespace SafeExamBrowser.SystemComponents.Contracts.Audio.Events
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the user would like to change the audio mute status to the given value.
|
/// Indicates that the volume of the system audio component has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void AudioMuteRequestedEventHandler(bool mute);
|
public delegate void AudioVolumeChangedEventHandler(double volume, bool muted);
|
||||||
}
|
}
|
63
SafeExamBrowser.SystemComponents.Contracts/Audio/IAudio.cs
Normal file
63
SafeExamBrowser.SystemComponents.Contracts/Audio/IAudio.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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 SafeExamBrowser.SystemComponents.Contracts.Audio.Events;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.SystemComponents.Contracts.Audio
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the functionality of the audio system component.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAudio : ISystemComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The full name of the audio device, or an empty string if not available.
|
||||||
|
/// </summary>
|
||||||
|
string DeviceFullName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The short audio device name, or an empty string if not available.
|
||||||
|
/// </summary>
|
||||||
|
string DeviceShortName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether an audio output device is available.
|
||||||
|
/// </summary>
|
||||||
|
bool HasOutputDevice { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the audio output is currently muted.
|
||||||
|
/// </summary>
|
||||||
|
bool OutputMuted { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current audio output volume.
|
||||||
|
/// </summary>
|
||||||
|
double OutputVolume { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when the volume of the audio device has changed.
|
||||||
|
/// </summary>
|
||||||
|
event AudioVolumeChangedEventHandler VolumeChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mutes the currently active audio device.
|
||||||
|
/// </summary>
|
||||||
|
void Mute();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unmutes the currently active audio device.
|
||||||
|
/// </summary>
|
||||||
|
void Unmute();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the volume of the currently active audio device to the given value.
|
||||||
|
/// </summary>
|
||||||
|
void SetVolume(double value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,8 @@
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Audio\Events\AudioVolumeChangedEventHandler.cs" />
|
||||||
|
<Compile Include="Audio\IAudio.cs" />
|
||||||
<Compile Include="BatteryChargeStatus.cs" />
|
<Compile Include="BatteryChargeStatus.cs" />
|
||||||
<Compile Include="Keyboard\Events\KeyboardLayoutChangedEventHandler.cs" />
|
<Compile Include="Keyboard\Events\KeyboardLayoutChangedEventHandler.cs" />
|
||||||
<Compile Include="Keyboard\IKeyboard.cs" />
|
<Compile Include="Keyboard\IKeyboard.cs" />
|
||||||
|
|
|
@ -12,24 +12,33 @@ using NAudio.CoreAudioApi;
|
||||||
using SafeExamBrowser.Configuration.Contracts.Settings;
|
using SafeExamBrowser.Configuration.Contracts.Settings;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio.Events;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents
|
namespace SafeExamBrowser.SystemComponents.Audio
|
||||||
{
|
{
|
||||||
public class Audio// TODO : ISystemComponent<ISystemAudioControl>
|
public class Audio : IAudio
|
||||||
{
|
{
|
||||||
private readonly object @lock = new object();
|
private readonly object @lock = new object();
|
||||||
|
|
||||||
private AudioSettings settings;
|
private AudioSettings settings;
|
||||||
private MMDevice audioDevice;
|
private MMDevice audioDevice;
|
||||||
|
private string audioDeviceFullName;
|
||||||
private string audioDeviceShortName;
|
private string audioDeviceShortName;
|
||||||
// TODOprivate List<ISystemAudioControl> controls;
|
|
||||||
private float originalVolume;
|
private float originalVolume;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
|
public string DeviceFullName => audioDeviceFullName ?? string.Empty;
|
||||||
|
public string DeviceShortName => audioDeviceShortName ?? string.Empty;
|
||||||
|
public bool HasOutputDevice => audioDevice != default(MMDevice);
|
||||||
|
public bool OutputMuted => audioDevice?.AudioEndpointVolume.Mute == true;
|
||||||
|
public double OutputVolume => audioDevice?.AudioEndpointVolume.MasterVolumeLevelScalar ?? 0;
|
||||||
|
|
||||||
|
public event AudioVolumeChangedEventHandler VolumeChanged;
|
||||||
|
|
||||||
public Audio(AudioSettings settings, ILogger logger, IText text)
|
public Audio(AudioSettings settings, ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
// TODOthis.controls = new List<ISystemAudioControl>();
|
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
@ -48,19 +57,29 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
public void Mute()
|
||||||
//public void Register(ISystemAudioControl control)
|
{
|
||||||
//{
|
if (audioDevice != default(MMDevice))
|
||||||
// control.MuteRequested += Control_MuteRequested;
|
{
|
||||||
// control.VolumeSelected += Control_VolumeSelected;
|
audioDevice.AudioEndpointVolume.Mute = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// lock (@lock)
|
public void Unmute()
|
||||||
// {
|
{
|
||||||
// controls.Add(control);
|
if (audioDevice != default(MMDevice))
|
||||||
// }
|
{
|
||||||
|
audioDevice.AudioEndpointVolume.Mute = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateControls();
|
public void SetVolume(double value)
|
||||||
//}
|
{
|
||||||
|
if (audioDevice != default(MMDevice))
|
||||||
|
{
|
||||||
|
audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar = (float) value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
|
@ -69,12 +88,6 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
RevertSettings();
|
RevertSettings();
|
||||||
FinalizeAudioDevice();
|
FinalizeAudioDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
//foreach (var control in controls)
|
|
||||||
//{
|
|
||||||
// control.Close();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryLoadAudioDevice()
|
private bool TryLoadAudioDevice()
|
||||||
|
@ -98,6 +111,7 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
{
|
{
|
||||||
logger.Info($"Found '{audioDevice}' to be the active audio device.");
|
logger.Info($"Found '{audioDevice}' to be the active audio device.");
|
||||||
audioDevice.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
|
audioDevice.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
|
||||||
|
audioDeviceFullName = audioDevice.FriendlyName;
|
||||||
audioDeviceShortName = audioDevice.FriendlyName.Length > 25 ? audioDevice.FriendlyName.Split(' ').First() : audioDevice.FriendlyName;
|
audioDeviceShortName = audioDevice.FriendlyName.Length > 25 ? audioDevice.FriendlyName.Split(' ').First() : audioDevice.FriendlyName;
|
||||||
logger.Info("Started monitoring the audio device.");
|
logger.Info("Started monitoring the audio device.");
|
||||||
}
|
}
|
||||||
|
@ -145,75 +159,9 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
{
|
{
|
||||||
lock (@lock)
|
lock (@lock)
|
||||||
{
|
{
|
||||||
var info = BuildInfoText(data.MasterVolume, data.Muted);
|
|
||||||
|
|
||||||
logger.Debug($"Volume is set to {data.MasterVolume * 100}%, audio device is {(data.Muted ? "muted" : "not muted")}.");
|
logger.Debug($"Volume is set to {data.MasterVolume * 100}%, audio device is {(data.Muted ? "muted" : "not muted")}.");
|
||||||
|
VolumeChanged?.Invoke(data.MasterVolume, data.Muted);
|
||||||
// TODO
|
|
||||||
//foreach (var control in controls)
|
|
||||||
//{
|
|
||||||
// control.OutputDeviceMuted = data.Muted;
|
|
||||||
// control.OutputDeviceVolume = data.MasterVolume;
|
|
||||||
// control.SetInformation(info);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Control_MuteRequested(bool mute)
|
|
||||||
{
|
|
||||||
audioDevice.AudioEndpointVolume.Mute = mute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Control_VolumeSelected(double volume)
|
|
||||||
{
|
|
||||||
audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar = (float) volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateControls()
|
|
||||||
{
|
|
||||||
lock (@lock)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (audioDevice != default(MMDevice))
|
|
||||||
{
|
|
||||||
var info = BuildInfoText(audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar, audioDevice.AudioEndpointVolume.Mute);
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
//foreach (var control in controls)
|
|
||||||
//{
|
|
||||||
// control.HasOutputDevice = true;
|
|
||||||
// control.OutputDeviceMuted = audioDevice.AudioEndpointVolume.Mute;
|
|
||||||
// control.OutputDeviceName = audioDevice.FriendlyName;
|
|
||||||
// control.OutputDeviceVolume = audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar;
|
|
||||||
// control.SetInformation(info);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
//foreach (var control in controls)
|
|
||||||
//{
|
|
||||||
// control.HasOutputDevice = false;
|
|
||||||
// control.SetInformation(text.Get(TextKey.SystemControl_AudioDeviceNotFound));
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error("Failed to update audio device status!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string BuildInfoText(float volume, bool muted)
|
|
||||||
{
|
|
||||||
var info = text.Get(muted ? TextKey.SystemControl_AudioDeviceInfoMuted : TextKey.SystemControl_AudioDeviceInfo);
|
|
||||||
|
|
||||||
info = info.Replace("%%NAME%%", audioDeviceShortName);
|
|
||||||
info = info.Replace("%%VOLUME%%", Convert.ToString(Math.Round(volume * 100)));
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@ using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard.Events;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard.Events;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents
|
namespace SafeExamBrowser.SystemComponents.Keyboard
|
||||||
{
|
{
|
||||||
public class Keyboard : IKeyboard
|
public class Keyboard : IKeyboard
|
||||||
{
|
{
|
|
@ -10,7 +10,7 @@ using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents
|
namespace SafeExamBrowser.SystemComponents.Keyboard
|
||||||
{
|
{
|
||||||
internal class KeyboardLayout : IKeyboardLayout
|
internal class KeyboardLayout : IKeyboardLayout
|
||||||
{
|
{
|
|
@ -62,9 +62,9 @@
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Audio.cs" />
|
<Compile Include="Audio\Audio.cs" />
|
||||||
<Compile Include="KeyboardLayout.cs" />
|
<Compile Include="Keyboard\KeyboardLayout.cs" />
|
||||||
<Compile Include="Keyboard.cs" />
|
<Compile Include="Keyboard\Keyboard.cs" />
|
||||||
<Compile Include="PowerSupply.cs" />
|
<Compile Include="PowerSupply.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SystemInfo.cs" />
|
<Compile Include="SystemInfo.cs" />
|
||||||
|
|
|
@ -12,6 +12,7 @@ using SafeExamBrowser.Configuration.Contracts;
|
||||||
using SafeExamBrowser.Configuration.Contracts.Settings;
|
using SafeExamBrowser.Configuration.Contracts.Settings;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
@ -37,7 +38,7 @@ namespace SafeExamBrowser.UserInterface.Contracts
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a system control which allows to change the audio settings of the computer.
|
/// Creates a system control which allows to change the audio settings of the computer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ISystemAudioControl CreateAudioControl(Location location);
|
ISystemControl CreateAudioControl(IAudio audio, Location location);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new browser window loaded with the given browser control and settings.
|
/// Creates a new browser window loaded with the given browser control and settings.
|
||||||
|
|
|
@ -67,8 +67,6 @@
|
||||||
<Compile Include="MessageBox\MessageBoxResult.cs" />
|
<Compile Include="MessageBox\MessageBoxResult.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Shell\Events\ActivatorEventHandler.cs" />
|
<Compile Include="Shell\Events\ActivatorEventHandler.cs" />
|
||||||
<Compile Include="Shell\Events\AudioMuteRequestedEventHandler.cs" />
|
|
||||||
<Compile Include="Shell\Events\AudioVolumeSelectedEventHandler.cs" />
|
|
||||||
<Compile Include="Shell\Events\NotificationControlClickedEventHandler.cs" />
|
<Compile Include="Shell\Events\NotificationControlClickedEventHandler.cs" />
|
||||||
<Compile Include="Shell\Events\QuitButtonClickedEventHandler.cs" />
|
<Compile Include="Shell\Events\QuitButtonClickedEventHandler.cs" />
|
||||||
<Compile Include="Shell\Events\WirelessNetworkSelectedEventHandler.cs" />
|
<Compile Include="Shell\Events\WirelessNetworkSelectedEventHandler.cs" />
|
||||||
|
@ -76,7 +74,6 @@
|
||||||
<Compile Include="Shell\IActionCenterActivator.cs" />
|
<Compile Include="Shell\IActionCenterActivator.cs" />
|
||||||
<Compile Include="Shell\IApplicationControl.cs" />
|
<Compile Include="Shell\IApplicationControl.cs" />
|
||||||
<Compile Include="Shell\INotificationControl.cs" />
|
<Compile Include="Shell\INotificationControl.cs" />
|
||||||
<Compile Include="Shell\ISystemAudioControl.cs" />
|
|
||||||
<Compile Include="Shell\ISystemControl.cs" />
|
<Compile Include="Shell\ISystemControl.cs" />
|
||||||
<Compile Include="Shell\ISystemPowerSupplyControl.cs" />
|
<Compile Include="Shell\ISystemPowerSupplyControl.cs" />
|
||||||
<Compile Include="Shell\ISystemWirelessNetworkControl.cs" />
|
<Compile Include="Shell\ISystemWirelessNetworkControl.cs" />
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* 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/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Contracts.Shell.Events
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that the user would like to set the audio volume to the given value, where <c>0.0</c> is the lowest and <c>1.0</c> the highest
|
|
||||||
/// possible value.
|
|
||||||
/// </summary>
|
|
||||||
public delegate void AudioVolumeSelectedEventHandler(double volume);
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The control of the audio system component.
|
|
||||||
/// </summary>
|
|
||||||
public interface ISystemAudioControl : ISystemControl
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Defines whether the computer has an audio output device.
|
|
||||||
/// </summary>
|
|
||||||
bool HasOutputDevice { set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the current output device is muted.
|
|
||||||
/// </summary>
|
|
||||||
bool OutputDeviceMuted { set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows the name of the currently active audio output device.
|
|
||||||
/// </summary>
|
|
||||||
string OutputDeviceName { set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows the current audio output volume, where <c>0.0</c> is the lowest and <c>1.0</c> the highest possible value.
|
|
||||||
/// </summary>
|
|
||||||
double OutputDeviceVolume { set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event fired when the user requests to mute the current output device.
|
|
||||||
/// </summary>
|
|
||||||
event AudioMuteRequestedEventHandler MuteRequested;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event fired when the user requests to set the volume of the current output device.
|
|
||||||
/// </summary>
|
|
||||||
event AudioVolumeSelectedEventHandler VolumeSelected;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,7 +37,7 @@
|
||||||
<RowDefinition Height="2*" />
|
<RowDefinition Height="2*" />
|
||||||
<RowDefinition Height="3*" />
|
<RowDefinition Height="3*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<ContentControl x:Name="TaskbarIcon" />
|
<ContentControl x:Name="ButtonIcon" />
|
||||||
<TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
<TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -14,123 +14,80 @@ using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
{
|
{
|
||||||
public partial class ActionCenterAudioControl : UserControl, ISystemAudioControl
|
public partial class ActionCenterAudioControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
|
private readonly IAudio audio;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private bool muted;
|
private bool muted;
|
||||||
private XamlIconResource MutedIcon;
|
private XamlIconResource MutedIcon;
|
||||||
private XamlIconResource NoDeviceIcon;
|
private XamlIconResource NoDeviceIcon;
|
||||||
|
|
||||||
public event AudioMuteRequestedEventHandler MuteRequested;
|
public ActionCenterAudioControl(IAudio audio, IText text)
|
||||||
public event AudioVolumeSelectedEventHandler VolumeSelected;
|
|
||||||
|
|
||||||
public ActionCenterAudioControl(IText text)
|
|
||||||
{
|
{
|
||||||
|
this.audio = audio;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeAudioControl();
|
InitializeAudioControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasOutputDevice
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.IsEnabled = value;
|
|
||||||
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OutputDeviceMuted
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
muted = value;
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
|
||||||
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
|
||||||
TaskbarIcon.Content = LoadIcon(Volume.Value / 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputDeviceName
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => AudioDeviceName.Text = value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double OutputDeviceVolume
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Volume.ValueChanged -= Volume_ValueChanged;
|
|
||||||
Volume.Value = Math.Round(value * 100);
|
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
|
||||||
|
|
||||||
if (!muted)
|
|
||||||
{
|
|
||||||
PopupIcon.Content = LoadIcon(value);
|
|
||||||
TaskbarIcon.Content = LoadIcon(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Popup.IsOpen = false;
|
Popup.IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInformation(string text)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
Text.Text = text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeAudioControl()
|
private void InitializeAudioControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Grid.Background;
|
var originalBrush = Grid.Background;
|
||||||
|
|
||||||
|
audio.VolumeChanged += Audio_VolumeChanged;
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
MuteButton.Click += (o, args) => MuteRequested?.Invoke(!muted);
|
MuteButton.Click += MuteButton_Click;
|
||||||
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
||||||
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_NoDevice.xaml"));
|
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_NoDevice.xaml"));
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
||||||
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (audio.HasOutputDevice)
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = audio.DeviceFullName;
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
UpdateVolume(audio.OutputVolume, audio.OutputMuted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
||||||
|
Text.Text = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Audio_VolumeChanged(double volume, bool muted)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => UpdateVolume(volume, muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MuteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
audio.Unmute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audio.Mute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
||||||
|
@ -140,13 +97,49 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
|
|
||||||
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVolume(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = BuildInfoText(volume, muted);
|
||||||
|
|
||||||
|
this.muted = muted;
|
||||||
|
|
||||||
|
Button.ToolTip = info;
|
||||||
|
Text.Text = info;
|
||||||
|
Volume.ValueChanged -= Volume_ValueChanged;
|
||||||
|
Volume.Value = Math.Round(volume * 100);
|
||||||
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
||||||
|
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ButtonIcon.Content = LoadIcon(volume);
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
||||||
|
PopupIcon.Content = LoadIcon(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildInfoText(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = text.Get(muted ? TextKey.SystemControl_AudioDeviceInfoMuted : TextKey.SystemControl_AudioDeviceInfo);
|
||||||
|
|
||||||
|
info = info.Replace("%%NAME%%", audio.DeviceShortName);
|
||||||
|
info = info.Replace("%%VOLUME%%", Convert.ToString(Math.Round(volume * 100)));
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIElement LoadIcon(double volume)
|
private UIElement LoadIcon(double volume)
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="40">
|
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="40">
|
||||||
<ContentControl x:Name="TaskbarIcon" />
|
<ContentControl x:Name="ButtonIcon" />
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -13,113 +13,42 @@ using System.Windows.Controls;
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
{
|
{
|
||||||
public partial class TaskbarAudioControl : UserControl, ISystemAudioControl
|
public partial class TaskbarAudioControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
|
private readonly IAudio audio;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private bool muted;
|
private bool muted;
|
||||||
private XamlIconResource MutedIcon;
|
private XamlIconResource MutedIcon;
|
||||||
private XamlIconResource NoDeviceIcon;
|
private XamlIconResource NoDeviceIcon;
|
||||||
|
|
||||||
public event AudioMuteRequestedEventHandler MuteRequested;
|
public TaskbarAudioControl(IAudio audio, IText text)
|
||||||
public event AudioVolumeSelectedEventHandler VolumeSelected;
|
|
||||||
|
|
||||||
public TaskbarAudioControl(IText text)
|
|
||||||
{
|
{
|
||||||
|
this.audio = audio;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeAudioControl();
|
InitializeAudioControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasOutputDevice
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.IsEnabled = value;
|
|
||||||
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OutputDeviceMuted
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
muted = value;
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
|
||||||
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
|
||||||
TaskbarIcon.Content = LoadIcon(Volume.Value / 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputDeviceName
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => AudioDeviceName.Text = value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double OutputDeviceVolume
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Volume.ValueChanged -= Volume_ValueChanged;
|
|
||||||
Volume.Value = Math.Round(value * 100);
|
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
|
||||||
|
|
||||||
if (!muted)
|
|
||||||
{
|
|
||||||
PopupIcon.Content = LoadIcon(value);
|
|
||||||
TaskbarIcon.Content = LoadIcon(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Popup.IsOpen = false;
|
Popup.IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInformation(string text)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => Button.ToolTip = text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeAudioControl()
|
private void InitializeAudioControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
|
audio.VolumeChanged += Audio_VolumeChanged;
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
MuteButton.Click += (o, args) => MuteRequested?.Invoke(!muted);
|
MuteButton.Click += MuteButton_Click;
|
||||||
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
||||||
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_NoDevice.xaml"));
|
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_NoDevice.xaml"));
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
|
@ -136,6 +65,37 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
Background = originalBrush;
|
Background = originalBrush;
|
||||||
Button.Background = originalBrush;
|
Button.Background = originalBrush;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (audio.HasOutputDevice)
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = audio.DeviceFullName;
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
UpdateVolume(audio.OutputVolume, audio.OutputMuted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Audio_VolumeChanged(double volume, bool muted)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => UpdateVolume(volume, muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MuteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
audio.Unmute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audio.Mute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
||||||
|
@ -145,13 +105,48 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
|
|
||||||
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVolume(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = BuildInfoText(volume, muted);
|
||||||
|
|
||||||
|
this.muted = muted;
|
||||||
|
|
||||||
|
Button.ToolTip = info;
|
||||||
|
Volume.ValueChanged -= Volume_ValueChanged;
|
||||||
|
Volume.Value = Math.Round(volume * 100);
|
||||||
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
||||||
|
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
||||||
|
PopupIcon.Content = LoadIcon(volume);
|
||||||
|
ButtonIcon.Content = LoadIcon(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildInfoText(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = text.Get(muted ? TextKey.SystemControl_AudioDeviceInfoMuted : TextKey.SystemControl_AudioDeviceInfo);
|
||||||
|
|
||||||
|
info = info.Replace("%%NAME%%", audio.DeviceShortName);
|
||||||
|
info = info.Replace("%%VOLUME%%", Convert.ToString(Math.Round(volume * 100)));
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIElement LoadIcon(double volume)
|
private UIElement LoadIcon(double volume)
|
||||||
|
|
|
@ -16,6 +16,7 @@ using SafeExamBrowser.Configuration.Contracts;
|
||||||
using SafeExamBrowser.Configuration.Contracts.Settings;
|
using SafeExamBrowser.Configuration.Contracts.Settings;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
|
@ -53,15 +54,15 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISystemAudioControl CreateAudioControl(Location location)
|
public ISystemControl CreateAudioControl(IAudio audio, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
{
|
{
|
||||||
return new ActionCenterAudioControl(text);
|
return new ActionCenterAudioControl(audio, text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new TaskbarAudioControl(text);
|
return new TaskbarAudioControl(audio, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<RowDefinition Height="2*" />
|
<RowDefinition Height="2*" />
|
||||||
<RowDefinition Height="3*" />
|
<RowDefinition Height="3*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<ContentControl x:Name="TaskbarIcon" />
|
<ContentControl x:Name="ButtonIcon" />
|
||||||
<TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
<TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -14,123 +14,79 @@ using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
{
|
{
|
||||||
public partial class ActionCenterAudioControl : UserControl, ISystemAudioControl
|
public partial class ActionCenterAudioControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
|
private readonly IAudio audio;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private bool muted;
|
private bool muted;
|
||||||
private XamlIconResource MutedIcon;
|
private XamlIconResource MutedIcon;
|
||||||
private XamlIconResource NoDeviceIcon;
|
private XamlIconResource NoDeviceIcon;
|
||||||
|
|
||||||
public event AudioMuteRequestedEventHandler MuteRequested;
|
public ActionCenterAudioControl(IAudio audio, IText text)
|
||||||
public event AudioVolumeSelectedEventHandler VolumeSelected;
|
|
||||||
|
|
||||||
public ActionCenterAudioControl(IText text)
|
|
||||||
{
|
{
|
||||||
|
this.audio = audio;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeAudioControl();
|
InitializeAudioControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasOutputDevice
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.IsEnabled = value;
|
|
||||||
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OutputDeviceMuted
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
muted = value;
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
|
||||||
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
|
||||||
TaskbarIcon.Content = LoadIcon(Volume.Value / 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputDeviceName
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => AudioDeviceName.Text = value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double OutputDeviceVolume
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Volume.ValueChanged -= Volume_ValueChanged;
|
|
||||||
Volume.Value = Math.Round(value * 100);
|
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
|
||||||
|
|
||||||
if (!muted)
|
|
||||||
{
|
|
||||||
PopupIcon.Content = LoadIcon(value);
|
|
||||||
TaskbarIcon.Content = LoadIcon(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Popup.IsOpen = false;
|
Popup.IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInformation(string text)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
Text.Text = text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeAudioControl()
|
private void InitializeAudioControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Grid.Background;
|
var originalBrush = Grid.Background;
|
||||||
|
|
||||||
|
audio.VolumeChanged += Audio_VolumeChanged;
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
MuteButton.Click += (o, args) => MuteRequested?.Invoke(!muted);
|
MuteButton.Click += MuteButton_Click;
|
||||||
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml"));
|
||||||
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_NoDevice.xaml"));
|
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Light_NoDevice.xaml"));
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
||||||
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (audio.HasOutputDevice)
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = audio.DeviceFullName;
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
UpdateVolume(audio.OutputVolume, audio.OutputMuted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Audio_VolumeChanged(double volume, bool muted)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => UpdateVolume(volume, muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MuteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
audio.Unmute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audio.Mute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
||||||
|
@ -140,19 +96,55 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
|
|
||||||
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVolume(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = BuildInfoText(volume, muted);
|
||||||
|
|
||||||
|
this.muted = muted;
|
||||||
|
|
||||||
|
Button.ToolTip = info;
|
||||||
|
Text.Text = info;
|
||||||
|
Volume.ValueChanged -= Volume_ValueChanged;
|
||||||
|
Volume.Value = Math.Round(volume * 100);
|
||||||
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
||||||
|
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ButtonIcon.Content = LoadIcon(volume);
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
||||||
|
PopupIcon.Content = LoadIcon(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildInfoText(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = text.Get(muted ? TextKey.SystemControl_AudioDeviceInfoMuted : TextKey.SystemControl_AudioDeviceInfo);
|
||||||
|
|
||||||
|
info = info.Replace("%%NAME%%", audio.DeviceShortName);
|
||||||
|
info = info.Replace("%%VOLUME%%", Convert.ToString(Math.Round(volume * 100)));
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIElement LoadIcon(double volume)
|
private UIElement LoadIcon(double volume)
|
||||||
{
|
{
|
||||||
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
|
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Light_{icon}.xaml");
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Light_{icon}.xaml");
|
||||||
var resource = new XamlIconResource(uri);
|
var resource = new XamlIconResource(uri);
|
||||||
|
|
||||||
return IconResourceLoader.Load(resource);
|
return IconResourceLoader.Load(resource);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="60">
|
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="60">
|
||||||
<ContentControl x:Name="TaskbarIcon" />
|
<ContentControl x:Name="ButtonIcon" />
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -13,115 +13,44 @@ using System.Windows.Controls;
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
{
|
{
|
||||||
public partial class TaskbarAudioControl : UserControl, ISystemAudioControl
|
public partial class TaskbarAudioControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
|
private readonly IAudio audio;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private bool muted;
|
private bool muted;
|
||||||
private XamlIconResource MutedIcon;
|
private XamlIconResource MutedIcon;
|
||||||
private XamlIconResource NoDeviceIcon;
|
private XamlIconResource NoDeviceIcon;
|
||||||
|
|
||||||
public event AudioMuteRequestedEventHandler MuteRequested;
|
public TaskbarAudioControl(IAudio audio, IText text)
|
||||||
public event AudioVolumeSelectedEventHandler VolumeSelected;
|
|
||||||
|
|
||||||
public TaskbarAudioControl(IText text)
|
|
||||||
{
|
{
|
||||||
|
this.audio = audio;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeAudioControl();
|
InitializeAudioControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasOutputDevice
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Button.IsEnabled = value;
|
|
||||||
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OutputDeviceMuted
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
muted = value;
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
|
||||||
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
TaskbarIcon.Content = IconResourceLoader.Load(MutedIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
|
||||||
TaskbarIcon.Content = LoadIcon(Volume.Value / 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputDeviceName
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => AudioDeviceName.Text = value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double OutputDeviceVolume
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
Volume.ValueChanged -= Volume_ValueChanged;
|
|
||||||
Volume.Value = Math.Round(value * 100);
|
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
|
||||||
|
|
||||||
if (!muted)
|
|
||||||
{
|
|
||||||
PopupIcon.Content = LoadIcon(value);
|
|
||||||
TaskbarIcon.Content = LoadIcon(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Popup.IsOpen = false;
|
Popup.IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInformation(string text)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => Button.ToolTip = text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeAudioControl()
|
private void InitializeAudioControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
|
audio.VolumeChanged += Audio_VolumeChanged;
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
MuteButton.Click += (o, args) => MuteRequested?.Invoke(!muted);
|
MuteButton.Click += MuteButton_Click;
|
||||||
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_Muted.xaml"));
|
MutedIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_Muted.xaml"));
|
||||||
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_NoDevice.xaml"));
|
NoDeviceIcon = new XamlIconResource(new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_NoDevice.xaml"));
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
@ -136,6 +65,37 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
Background = originalBrush;
|
Background = originalBrush;
|
||||||
Button.Background = originalBrush;
|
Button.Background = originalBrush;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (audio.HasOutputDevice)
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = audio.DeviceFullName;
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
UpdateVolume(audio.OutputVolume, audio.OutputMuted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AudioDeviceName.Text = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceNotFound);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(NoDeviceIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Audio_VolumeChanged(double volume, bool muted)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => UpdateVolume(volume, muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MuteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
audio.Unmute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audio.Mute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
private void Volume_DragStarted(object sender, DragStartedEventArgs e)
|
||||||
|
@ -145,19 +105,54 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
|
|
||||||
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
private void Volume_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
Volume.ValueChanged += Volume_ValueChanged;
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||||
{
|
{
|
||||||
VolumeSelected?.Invoke(Volume.Value / 100);
|
audio.SetVolume(Volume.Value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVolume(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = BuildInfoText(volume, muted);
|
||||||
|
|
||||||
|
this.muted = muted;
|
||||||
|
|
||||||
|
Button.ToolTip = info;
|
||||||
|
Volume.ValueChanged -= Volume_ValueChanged;
|
||||||
|
Volume.Value = Math.Round(volume * 100);
|
||||||
|
Volume.ValueChanged += Volume_ValueChanged;
|
||||||
|
|
||||||
|
if (muted)
|
||||||
|
{
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceUnmuteTooltip);
|
||||||
|
PopupIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
ButtonIcon.Content = IconResourceLoader.Load(MutedIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MuteButton.ToolTip = text.Get(TextKey.SystemControl_AudioDeviceMuteTooltip);
|
||||||
|
PopupIcon.Content = LoadIcon(volume);
|
||||||
|
ButtonIcon.Content = LoadIcon(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildInfoText(double volume, bool muted)
|
||||||
|
{
|
||||||
|
var info = text.Get(muted ? TextKey.SystemControl_AudioDeviceInfoMuted : TextKey.SystemControl_AudioDeviceInfo);
|
||||||
|
|
||||||
|
info = info.Replace("%%NAME%%", audio.DeviceShortName);
|
||||||
|
info = info.Replace("%%VOLUME%%", Convert.ToString(Math.Round(volume * 100)));
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIElement LoadIcon(double volume)
|
private UIElement LoadIcon(double volume)
|
||||||
{
|
{
|
||||||
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
|
var icon = volume > 0.66 ? "100" : (volume > 0.33 ? "66" : "33");
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/Audio_{icon}.xaml");
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/Audio_{icon}.xaml");
|
||||||
var resource = new XamlIconResource(uri);
|
var resource = new XamlIconResource(uri);
|
||||||
|
|
||||||
return IconResourceLoader.Load(resource);
|
return IconResourceLoader.Load(resource);
|
||||||
|
|
|
@ -16,6 +16,7 @@ using SafeExamBrowser.Configuration.Contracts;
|
||||||
using SafeExamBrowser.Configuration.Contracts.Settings;
|
using SafeExamBrowser.Configuration.Contracts.Settings;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
|
@ -53,15 +54,15 @@ namespace SafeExamBrowser.UserInterface.Mobile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISystemAudioControl CreateAudioControl(Location location)
|
public ISystemControl CreateAudioControl(IAudio audio, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
{
|
{
|
||||||
return new ActionCenterAudioControl(text);
|
return new ActionCenterAudioControl(audio, text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new TaskbarAudioControl(text);
|
return new TaskbarAudioControl(audio, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue