SEBWIN-141: Implemented draft of application controls for action center.
This commit is contained in:
		
							parent
							
								
									1991f9c2d1
								
							
						
					
					
						commit
						519fb9e57b
					
				
					 39 changed files with 474 additions and 115 deletions
				
			
		| 
						 | 
				
			
			@ -29,7 +29,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
		private int instanceIdCounter = default(int);
 | 
			
		||||
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private IApplicationButton button;
 | 
			
		||||
		private IList<IApplicationControl> controls;
 | 
			
		||||
		private IList<IApplicationInstance> instances;
 | 
			
		||||
		private IMessageBox messageBox;
 | 
			
		||||
		private IModuleLogger logger;
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +48,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			IUserInterfaceFactory uiFactory)
 | 
			
		||||
		{
 | 
			
		||||
			this.appConfig = appConfig;
 | 
			
		||||
			this.controls = new List<IApplicationControl>();
 | 
			
		||||
			this.instances = new List<IApplicationInstance>();
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.messageBox = messageBox;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,10 +70,10 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RegisterApplicationButton(IApplicationButton button)
 | 
			
		||||
		public void RegisterApplicationControl(IApplicationControl control)
 | 
			
		||||
		{
 | 
			
		||||
			this.button = button;
 | 
			
		||||
			this.button.Clicked += Button_OnClick;
 | 
			
		||||
			control.Clicked += ApplicationControl_Clicked;
 | 
			
		||||
			controls.Add(control);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Start()
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +109,11 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			instance.PopupRequested += Instance_PopupRequested;
 | 
			
		||||
			instance.Terminated += Instance_Terminated;
 | 
			
		||||
 | 
			
		||||
			button.RegisterInstance(instance);
 | 
			
		||||
			foreach (var control in controls)
 | 
			
		||||
			{
 | 
			
		||||
				control.RegisterInstance(instance);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			instances.Add(instance);
 | 
			
		||||
			instance.Window.Show();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +140,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			return cefSettings;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Button_OnClick(InstanceIdentifier id = null)
 | 
			
		||||
		private void ApplicationControl_Clicked(InstanceIdentifier id = null)
 | 
			
		||||
		{
 | 
			
		||||
			if (id == null)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,14 +11,14 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		|||
 | 
			
		||||
namespace SafeExamBrowser.Client.UnitTests.Notifications
 | 
			
		||||
{
 | 
			
		||||
	class NotificationButtonMock : INotificationButton
 | 
			
		||||
	class NotificationButtonMock : INotificationControl
 | 
			
		||||
	{
 | 
			
		||||
		private NotificationButtonClickedEventHandler clicked;
 | 
			
		||||
		private NotificationControlClickedEventHandler clicked;
 | 
			
		||||
 | 
			
		||||
		public bool HasSubscribed;
 | 
			
		||||
		public bool HasUnsubscribed;
 | 
			
		||||
 | 
			
		||||
		public event NotificationButtonClickedEventHandler Clicked
 | 
			
		||||
		public event NotificationControlClickedEventHandler Clicked
 | 
			
		||||
		{
 | 
			
		||||
			add
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,24 +19,26 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
	[TestClass]
 | 
			
		||||
	public class BrowserOperationTests
 | 
			
		||||
	{
 | 
			
		||||
		private Mock<IApplicationController> controllerMock;
 | 
			
		||||
		private Mock<IApplicationInfo> appInfoMock;
 | 
			
		||||
		private Mock<ILogger> loggerMock;
 | 
			
		||||
		private Mock<ITaskbar> taskbarMock;
 | 
			
		||||
		private Mock<IUserInterfaceFactory> uiFactoryMock;
 | 
			
		||||
		private Mock<IActionCenter> actionCenter;
 | 
			
		||||
		private Mock<IApplicationController> controller;
 | 
			
		||||
		private Mock<IApplicationInfo> appInfo;
 | 
			
		||||
		private Mock<ILogger> logger;
 | 
			
		||||
		private Mock<ITaskbar> taskbar;
 | 
			
		||||
		private Mock<IUserInterfaceFactory> uiFactory;
 | 
			
		||||
 | 
			
		||||
		private BrowserOperation sut;
 | 
			
		||||
 | 
			
		||||
		[TestInitialize]
 | 
			
		||||
		public void Initialize()
 | 
			
		||||
		{
 | 
			
		||||
			controllerMock = new Mock<IApplicationController>();
 | 
			
		||||
			appInfoMock = new Mock<IApplicationInfo>();
 | 
			
		||||
			loggerMock = new Mock<ILogger>();
 | 
			
		||||
			taskbarMock = new Mock<ITaskbar>();
 | 
			
		||||
			uiFactoryMock = new Mock<IUserInterfaceFactory>();
 | 
			
		||||
			actionCenter = new Mock<IActionCenter>();
 | 
			
		||||
			controller = new Mock<IApplicationController>();
 | 
			
		||||
			appInfo = new Mock<IApplicationInfo>();
 | 
			
		||||
			logger = new Mock<ILogger>();
 | 
			
		||||
			taskbar = new Mock<ITaskbar>();
 | 
			
		||||
			uiFactory = new Mock<IUserInterfaceFactory>();
 | 
			
		||||
 | 
			
		||||
			sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object);
 | 
			
		||||
			sut = new BrowserOperation(actionCenter.Object, controller.Object, appInfo.Object, logger.Object, taskbar.Object, uiFactory.Object);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[TestMethod]
 | 
			
		||||
| 
						 | 
				
			
			@ -44,15 +46,15 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
		{
 | 
			
		||||
			var order = 0;
 | 
			
		||||
 | 
			
		||||
			controllerMock.Setup(c => c.Initialize()).Callback(() => Assert.AreEqual(++order, 1));
 | 
			
		||||
			controllerMock.Setup(c => c.RegisterApplicationButton(It.IsAny<IApplicationButton>())).Callback(() => Assert.AreEqual(++order, 2));
 | 
			
		||||
			taskbarMock.Setup(t => t.AddApplication(It.IsAny<IApplicationButton>())).Callback(() => Assert.AreEqual(++order, 3));
 | 
			
		||||
			controller.Setup(c => c.Initialize()).Callback(() => Assert.AreEqual(++order, 1));
 | 
			
		||||
			controller.Setup(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 2));
 | 
			
		||||
			taskbar.Setup(t => t.AddApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 3));
 | 
			
		||||
 | 
			
		||||
			sut.Perform();
 | 
			
		||||
 | 
			
		||||
			controllerMock.Verify(c => c.Initialize(), Times.Once);
 | 
			
		||||
			controllerMock.Verify(c => c.RegisterApplicationButton(It.IsAny<IApplicationButton>()), Times.Once);
 | 
			
		||||
			taskbarMock.Verify(t => t.AddApplication(It.IsAny<IApplicationButton>()), Times.Once);
 | 
			
		||||
			controller.Verify(c => c.Initialize(), Times.Once);
 | 
			
		||||
			controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
 | 
			
		||||
			taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[TestMethod]
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +62,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
		{
 | 
			
		||||
			sut.Revert();
 | 
			
		||||
 | 
			
		||||
			controllerMock.Verify(c => c.Terminate(), Times.Once);
 | 
			
		||||
			controller.Verify(c => c.Terminate(), Times.Once);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ using Moq;
 | 
			
		|||
using SafeExamBrowser.Client.Operations;
 | 
			
		||||
using SafeExamBrowser.Contracts.Client;
 | 
			
		||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
			
		||||
using SafeExamBrowser.Contracts.I18n;
 | 
			
		||||
using SafeExamBrowser.Contracts.Logging;
 | 
			
		||||
using SafeExamBrowser.Contracts.SystemComponents;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +57,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
			settings.AllowWirelessNetwork = true;
 | 
			
		||||
			settings.EnableTaskbar = true;
 | 
			
		||||
			systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
 | 
			
		||||
			uiFactoryMock.Setup(u => u.CreateNotification(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationButton>().Object);
 | 
			
		||||
			uiFactoryMock.Setup(u => u.CreateNotificationControl(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationControl>().Object);
 | 
			
		||||
 | 
			
		||||
			sut = new TaskbarOperation(
 | 
			
		||||
				loggerMock.Object,
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +83,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
			powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
 | 
			
		||||
			wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
 | 
			
		||||
			taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
 | 
			
		||||
			taskbarMock.Verify(t => t.AddNotification(It.IsAny<INotificationButton>()), Times.Exactly(2));
 | 
			
		||||
			taskbarMock.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[TestMethod]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -230,7 +230,7 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
			var moduleLogger = new ModuleLogger(logger, "BrowserController");
 | 
			
		||||
			var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
 | 
			
		||||
			var browserInfo = new BrowserApplicationInfo();
 | 
			
		||||
			var operation = new BrowserOperation(browserController, browserInfo, logger, taskbar, uiFactory);
 | 
			
		||||
			var operation = new BrowserOperation(actionCenter, browserController, browserInfo, logger, taskbar, uiFactory);
 | 
			
		||||
 | 
			
		||||
			this.browserController = browserController;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
			
		|||
{
 | 
			
		||||
	internal class AboutNotificationController : INotificationController
 | 
			
		||||
	{
 | 
			
		||||
		private INotificationButton notification;
 | 
			
		||||
		private INotificationControl notification;
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private IWindow window;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
			
		|||
			this.uiFactory = uiFactory;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RegisterNotification(INotificationButton notification)
 | 
			
		||||
		public void RegisterNotification(INotificationControl notification)
 | 
			
		||||
		{
 | 
			
		||||
			this.notification = notification;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
			
		|||
{
 | 
			
		||||
	internal class LogNotificationController : INotificationController
 | 
			
		||||
	{
 | 
			
		||||
		private INotificationButton notification;
 | 
			
		||||
		private INotificationControl notification;
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private IWindow window;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
			
		|||
			this.uiFactory = uiFactory;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RegisterNotification(INotificationButton notification)
 | 
			
		||||
		public void RegisterNotification(INotificationControl notification)
 | 
			
		||||
		{
 | 
			
		||||
			this.notification = notification;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ using SafeExamBrowser.Contracts.Client;
 | 
			
		|||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
			
		||||
using SafeExamBrowser.Contracts.Core.OperationModel;
 | 
			
		||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
 | 
			
		||||
using SafeExamBrowser.Contracts.I18n;
 | 
			
		||||
using SafeExamBrowser.Contracts.Logging;
 | 
			
		||||
using SafeExamBrowser.Contracts.SystemComponents;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,21 +70,43 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
 | 
			
		||||
		public OperationResult Perform()
 | 
			
		||||
		{
 | 
			
		||||
			StatusChanged?.Invoke(TextKey.OperationStatus_InitializeActionCenter);
 | 
			
		||||
 | 
			
		||||
			if (settings.EnableActionCenter)
 | 
			
		||||
			{
 | 
			
		||||
				logger.Info("Initializing action center...");
 | 
			
		||||
 | 
			
		||||
				foreach (var activator in activators)
 | 
			
		||||
				{
 | 
			
		||||
					actionCenter.Register(activator);
 | 
			
		||||
					activator.Start();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				logger.Info("Action center is disabled, skipping initialization.");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return OperationResult.Success;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public OperationResult Revert()
 | 
			
		||||
		{
 | 
			
		||||
			StatusChanged?.Invoke(TextKey.OperationStatus_TerminateActionCenter);
 | 
			
		||||
 | 
			
		||||
			if (settings.EnableActionCenter)
 | 
			
		||||
			{
 | 
			
		||||
				logger.Info("Terminating action center...");
 | 
			
		||||
 | 
			
		||||
				foreach (var activator in activators)
 | 
			
		||||
				{
 | 
			
		||||
					activator.Stop();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				logger.Info("Action center was disabled, skipping termination.");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return OperationResult.Success;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
{
 | 
			
		||||
	internal class BrowserOperation : IOperation
 | 
			
		||||
	{
 | 
			
		||||
		private IActionCenter actionCenter;
 | 
			
		||||
		private IApplicationController browserController;
 | 
			
		||||
		private IApplicationInfo browserInfo;
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,12 +29,14 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
		public event StatusChangedEventHandler StatusChanged;
 | 
			
		||||
 | 
			
		||||
		public BrowserOperation(
 | 
			
		||||
			IActionCenter actionCenter,
 | 
			
		||||
			IApplicationController browserController,
 | 
			
		||||
			IApplicationInfo browserInfo,
 | 
			
		||||
			ILogger logger,
 | 
			
		||||
			ITaskbar taskbar,
 | 
			
		||||
			IUserInterfaceFactory uiFactory)
 | 
			
		||||
		{
 | 
			
		||||
			this.actionCenter = actionCenter;
 | 
			
		||||
			this.browserController = browserController;
 | 
			
		||||
			this.browserInfo = browserInfo;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,12 +49,15 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
			logger.Info("Initializing browser...");
 | 
			
		||||
			StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
 | 
			
		||||
 | 
			
		||||
			var browserButton = uiFactory.CreateApplicationButton(browserInfo);
 | 
			
		||||
			var actionCenterControl = uiFactory.CreateApplicationControl(browserInfo, Location.ActionCenter);
 | 
			
		||||
			var taskbarControl = uiFactory.CreateApplicationControl(browserInfo, Location.Taskbar);
 | 
			
		||||
 | 
			
		||||
			browserController.Initialize();
 | 
			
		||||
			browserController.RegisterApplicationButton(browserButton);
 | 
			
		||||
			browserController.RegisterApplicationControl(actionCenterControl);
 | 
			
		||||
			browserController.RegisterApplicationControl(taskbarControl);
 | 
			
		||||
 | 
			
		||||
			taskbar.AddApplication(browserButton);
 | 
			
		||||
			actionCenter.AddApplicationControl(actionCenterControl);
 | 
			
		||||
			taskbar.AddApplicationControl(taskbarControl);
 | 
			
		||||
 | 
			
		||||
			return OperationResult.Success;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,10 +142,10 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
 | 
			
		||||
		private void AddAboutNotification()
 | 
			
		||||
		{
 | 
			
		||||
			var aboutNotification = uiFactory.CreateNotification(aboutInfo);
 | 
			
		||||
			var aboutNotification = uiFactory.CreateNotificationControl(aboutInfo);
 | 
			
		||||
 | 
			
		||||
			aboutController.RegisterNotification(aboutNotification);
 | 
			
		||||
			taskbar.AddNotification(aboutNotification);
 | 
			
		||||
			taskbar.AddNotificationControl(aboutNotification);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void AddKeyboardLayoutControl()
 | 
			
		||||
| 
						 | 
				
			
			@ -158,10 +158,10 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
 | 
			
		||||
		private void AddLogNotification()
 | 
			
		||||
		{
 | 
			
		||||
			var logNotification = uiFactory.CreateNotification(logInfo);
 | 
			
		||||
			var logNotification = uiFactory.CreateNotificationControl(logInfo);
 | 
			
		||||
			
 | 
			
		||||
			logController.RegisterNotification(logNotification);
 | 
			
		||||
			taskbar.AddNotification(logNotification);
 | 
			
		||||
			taskbar.AddNotificationControl(logNotification);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void AddPowerSupplyControl()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,9 +21,9 @@ namespace SafeExamBrowser.Contracts.Applications
 | 
			
		|||
		void Initialize();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Registers the taskbar button for this application.
 | 
			
		||||
		/// Registers an application control for this application.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void RegisterApplicationButton(IApplicationButton button);
 | 
			
		||||
		void RegisterApplicationControl(IApplicationControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Starts the execution of the application.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ namespace SafeExamBrowser.Contracts.Client
 | 
			
		|||
		/// <summary>
 | 
			
		||||
		/// Registers the taskbar notification.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void RegisterNotification(INotificationButton notification);
 | 
			
		||||
		void RegisterNotification(INotificationControl notification);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Instructs the controller to shut down and release all used resources.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,7 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
			
		|||
		OperationStatus_CloseRuntimeConnection,
 | 
			
		||||
		OperationStatus_EmptyClipboard,
 | 
			
		||||
		OperationStatus_FinalizeServiceSession,
 | 
			
		||||
		OperationStatus_InitializeActionCenter,
 | 
			
		||||
		OperationStatus_InitializeBrowser,
 | 
			
		||||
		OperationStatus_InitializeClient,
 | 
			
		||||
		OperationStatus_InitializeConfiguration,
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +81,7 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
			
		|||
		OperationStatus_StopMouseInterception,
 | 
			
		||||
		OperationStatus_StopProcessMonitoring,
 | 
			
		||||
		OperationStatus_StopWindowMonitoring,
 | 
			
		||||
		OperationStatus_TerminateActionCenter,
 | 
			
		||||
		OperationStatus_TerminateBrowser,
 | 
			
		||||
		OperationStatus_TerminateTaskbar,
 | 
			
		||||
		OperationStatus_WaitExplorerStartup,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -188,11 +188,12 @@
 | 
			
		|||
    <Compile Include="UserInterface\MessageBox\IMessageBox.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\IProgressIndicator.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\ActivatorEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\ApplicationButtonClickedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\ApplicationControlClickedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\KeyboardLayoutSelectedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\NotificationButtonClickedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\NotificationControlClickedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\IActionCenter.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\IActionCenterActivator.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Location.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Windows\Events\WindowClosingEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\WirelessNetworkSelectedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\Events\QuitButtonClickedEventHandler.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -200,7 +201,7 @@
 | 
			
		|||
    <Compile Include="UserInterface\Windows\IPasswordDialogResult.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Windows\IRuntimeWindow.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\MessageBox\MessageBoxResult.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\INotificationButton.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\INotificationControl.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Windows\ISplashScreen.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\ISystemKeyboardLayoutControl.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\ISystemPowerSupplyControl.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -209,7 +210,7 @@
 | 
			
		|||
    <Compile Include="UserInterface\Shell\ITaskbar.cs" />
 | 
			
		||||
    <Compile Include="I18n\ITextResource.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\IApplicationButton.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Shell\IApplicationControl.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\IUserInterfaceFactory.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\Windows\IWindow.cs" />
 | 
			
		||||
    <Compile Include="UserInterface\MessageBox\MessageBoxAction.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,9 +31,9 @@ namespace SafeExamBrowser.Contracts.UserInterface
 | 
			
		|||
		IWindow CreateAboutWindow(AppConfig appConfig);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Creates a taskbar button, initialized with the given application information.
 | 
			
		||||
		/// Creates an application control for the specified location, initialized with the given application information.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		IApplicationButton CreateApplicationButton(IApplicationInfo info);
 | 
			
		||||
		IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Creates a new browser window loaded with the given browser control and settings.
 | 
			
		||||
| 
						 | 
				
			
			@ -51,9 +51,9 @@ namespace SafeExamBrowser.Contracts.UserInterface
 | 
			
		|||
		IWindow CreateLogWindow(ILogger logger);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Creates a taskbar notification, initialized with the given notification information.
 | 
			
		||||
		/// Creates a notification control, initialized with the given notification information.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		INotificationButton CreateNotification(INotificationInfo info);
 | 
			
		||||
		INotificationControl CreateNotificationControl(INotificationInfo info);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Creates a password dialog with the given message and title.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,8 @@ using SafeExamBrowser.Contracts.Applications;
 | 
			
		|||
namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Indicates that an <see cref="IApplicationButton"/> has been clicked, optionally specifying the ID of the selected instance (if
 | 
			
		||||
	/// Indicates that an <see cref="IApplicationControl"/> has been clicked, optionally specifying the identifier of the selected instance (if
 | 
			
		||||
	/// multiple instances of the same application are running).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public delegate void ApplicationButtonClickedEventHandler(InstanceIdentifier id = null);
 | 
			
		||||
	public delegate void ApplicationControlClickedEventHandler(InstanceIdentifier id = null);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Indicates that the user clicked on a <see cref="INotificationButton"/> in the <see cref="ITaskbar"/>.
 | 
			
		||||
	/// Indicates that the user clicked on a <see cref="INotificationControl"/> in the shell.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public delegate void NotificationButtonClickedEventHandler();
 | 
			
		||||
	public delegate void NotificationControlClickedEventHandler();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,8 @@
 | 
			
		|||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +15,26 @@ namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
			
		|||
	/// </summary>
 | 
			
		||||
	public interface IActionCenter
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Event fired when the user clicked the quit button.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given application control to the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void AddApplicationControl(IApplicationControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given notification control to the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void AddNotificationControl(INotificationControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given system control to the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void AddSystemControl(ISystemControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Closes the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,18 +12,18 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		|||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// The button of a (third-party) application which can be loaded into the <see cref="ITaskbar"/>.
 | 
			
		||||
	/// The control for a (third-party) application which can be loaded into the shell.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface IApplicationButton
 | 
			
		||||
	public interface IApplicationControl
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Event fired when the user clicked on the application button. If multiple instances of an application are active,
 | 
			
		||||
		/// the handler is only executed when the user selects one of the instances.
 | 
			
		||||
		/// Event fired when the user clicked on the application control. If multiple instances of an application are active,
 | 
			
		||||
		/// the handler should only executed when the user selects one of the instances.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		event ApplicationButtonClickedEventHandler Clicked;
 | 
			
		||||
		event ApplicationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Registers a new instance of an application, to be started / displayed if the user clicked the taskbar button.
 | 
			
		||||
		/// Registers a new instance of an application to be accessed via the application control.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void RegisterInstance(IApplicationInstance instance);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,13 +11,13 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		|||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// The button of a notification which can be loaded into the <see cref="ITaskbar"/>.
 | 
			
		||||
	/// The control for a notification which can be loaded into the shell.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface INotificationButton
 | 
			
		||||
	public interface INotificationControl
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Event fired when the user clicked on the notification icon.
 | 
			
		||||
		/// Event fired when the user clicked on the notification control.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		event NotificationButtonClickedEventHandler Clicked;
 | 
			
		||||
		event NotificationControlClickedEventHandler Clicked;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,14 +26,14 @@ namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
			
		|||
		event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given application button to the taskbar.
 | 
			
		||||
		/// Adds the given application control to the taskbar.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void AddApplication(IApplicationButton button);
 | 
			
		||||
		void AddApplicationControl(IApplicationControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given notification button to the taskbar.
 | 
			
		||||
		/// Adds the given notification control to the taskbar.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void AddNotification(INotificationButton button);
 | 
			
		||||
		void AddNotificationControl(INotificationControl control);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Adds the given system control to the taskbar.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								SafeExamBrowser.Contracts/UserInterface/Shell/Location.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SafeExamBrowser.Contracts/UserInterface/Shell/Location.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Contracts.UserInterface.Shell
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Defines all possible locations of a user control in the shell.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum Location
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A user control styled for and placed in the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		ActionCenter,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A user control styled for and placed in the taskbar.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Taskbar
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +126,9 @@
 | 
			
		|||
  <Entry key="OperationStatus_FinalizeServiceSession">
 | 
			
		||||
    Finalizing service session
 | 
			
		||||
  </Entry>
 | 
			
		||||
  <Entry key="OperationStatus_InitializeActionCenter">
 | 
			
		||||
    Initializing action center
 | 
			
		||||
  </Entry>
 | 
			
		||||
  <Entry key="OperationStatus_InitializeBrowser">
 | 
			
		||||
    Initializing browser
 | 
			
		||||
  </Entry>
 | 
			
		||||
| 
						 | 
				
			
			@ -198,6 +201,9 @@
 | 
			
		|||
  <Entry key="OperationStatus_StopWindowMonitoring">
 | 
			
		||||
    Stopping window monitoring
 | 
			
		||||
  </Entry>
 | 
			
		||||
  <Entry key="OperationStatus_TerminateActionCenter">
 | 
			
		||||
    Terminating action center
 | 
			
		||||
  </Entry>
 | 
			
		||||
  <Entry key="OperationStatus_TerminateBrowser">
 | 
			
		||||
    Terminating browser
 | 
			
		||||
  </Entry>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,30 @@
 | 
			
		|||
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
			
		||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
			
		||||
        xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop"
 | 
			
		||||
        mc:Ignorable="d" Title="ActionCenter" Height="1000" Width="400" Background="#EEF0F0F0" AllowsTransparency="True" WindowStyle="None"
 | 
			
		||||
        Topmost="True" ResizeMode="NoResize">
 | 
			
		||||
        mc:Ignorable="d" Title="ActionCenter" Height="1000" Width="400" Background="#EEF0F0F0" AllowsTransparency="True" WindowStyle="None" Topmost="True" ResizeMode="NoResize">
 | 
			
		||||
    <Window.Resources>
 | 
			
		||||
        <ResourceDictionary>
 | 
			
		||||
            <ResourceDictionary.MergedDictionaries>
 | 
			
		||||
                <ResourceDictionary Source="./Templates/ScrollViewers.xaml" />
 | 
			
		||||
            </ResourceDictionary.MergedDictionaries>
 | 
			
		||||
        </ResourceDictionary>
 | 
			
		||||
    </Window.Resources>
 | 
			
		||||
    <Grid>
 | 
			
		||||
        
 | 
			
		||||
        <Grid.RowDefinitions>
 | 
			
		||||
            <RowDefinition Height="*" />
 | 
			
		||||
            <RowDefinition Height="Auto" />
 | 
			
		||||
        </Grid.RowDefinitions>
 | 
			
		||||
        <ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
            <StackPanel x:Name="ApplicationPanel" Orientation="Vertical" />
 | 
			
		||||
        </ScrollViewer>
 | 
			
		||||
        <UniformGrid x:Name="ControlPanel" Grid.Row="1" Columns="4" Margin="5">
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
            <Label Height="60">Control</Label>
 | 
			
		||||
        </UniformGrid>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</Window>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,16 +10,37 @@ using System;
 | 
			
		|||
using System.Windows;
 | 
			
		||||
using System.Windows.Media.Animation;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		||||
{
 | 
			
		||||
	public partial class ActionCenter : Window, IActionCenter
 | 
			
		||||
	{
 | 
			
		||||
		public event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
			
		||||
 | 
			
		||||
		public ActionCenter()
 | 
			
		||||
		{
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddApplicationControl(IApplicationControl control)
 | 
			
		||||
		{
 | 
			
		||||
			if (control is UIElement uiElement)
 | 
			
		||||
			{
 | 
			
		||||
				ApplicationPanel.Children.Add(uiElement);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddNotificationControl(INotificationControl control)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddSystemControl(ISystemControl control)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public new void Close()
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.Invoke(base.Close);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenterApplicationButton"
 | 
			
		||||
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
			
		||||
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 | 
			
		||||
             xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls"
 | 
			
		||||
             mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800">
 | 
			
		||||
    <UserControl.Resources>
 | 
			
		||||
        <ResourceDictionary>
 | 
			
		||||
            <ResourceDictionary.MergedDictionaries>
 | 
			
		||||
                <ResourceDictionary Source="../Templates/Buttons.xaml" />
 | 
			
		||||
                <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
			
		||||
            </ResourceDictionary.MergedDictionaries>
 | 
			
		||||
        </ResourceDictionary>
 | 
			
		||||
    </UserControl.Resources>
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="40" Padding="10" Template="{StaticResource ActionCenterButton}">
 | 
			
		||||
            <StackPanel Orientation="Horizontal">
 | 
			
		||||
                <ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
 | 
			
		||||
                <TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
 | 
			
		||||
            </StackPanel>
 | 
			
		||||
        </Button>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</UserControl>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
 | 
			
		||||
 * 
 | 
			
		||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.Contracts.Applications;
 | 
			
		||||
using SafeExamBrowser.Contracts.Core;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		||||
{
 | 
			
		||||
	public partial class ActionCenterApplicationButton : UserControl
 | 
			
		||||
	{
 | 
			
		||||
		private IApplicationInfo info;
 | 
			
		||||
		private IApplicationInstance instance;
 | 
			
		||||
 | 
			
		||||
		internal event ApplicationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
 | 
			
		||||
		{
 | 
			
		||||
			this.info = info;
 | 
			
		||||
			this.instance = instance;
 | 
			
		||||
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
			InitializeApplicationInstanceButton();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeApplicationInstanceButton()
 | 
			
		||||
		{
 | 
			
		||||
			Icon.Content = IconResourceLoader.Load(info.IconResource);
 | 
			
		||||
			Text.Text = instance?.Name ?? info.Name;
 | 
			
		||||
			Button.ToolTip = instance?.Name ?? info.Tooltip;
 | 
			
		||||
 | 
			
		||||
			if (instance != null)
 | 
			
		||||
			{
 | 
			
		||||
				instance.IconChanged += Instance_IconChanged;
 | 
			
		||||
				instance.NameChanged += Instance_NameChanged;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Instance_IconChanged(IIconResource icon)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.InvokeAsync(() => Icon.Content = IconResourceLoader.Load(icon));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Instance_NameChanged(string name)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.Invoke(() =>
 | 
			
		||||
			{
 | 
			
		||||
				Text.Text = name;
 | 
			
		||||
				Button.ToolTip = name;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Button_Click(object sender, RoutedEventArgs e)
 | 
			
		||||
		{
 | 
			
		||||
			Clicked?.Invoke(instance?.Id);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenterApplicationControl"
 | 
			
		||||
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
			
		||||
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 | 
			
		||||
             xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls"
 | 
			
		||||
             mc:Ignorable="d" d:DesignHeight="250" d:DesignWidth="500">
 | 
			
		||||
    <UserControl.Resources>
 | 
			
		||||
        <ResourceDictionary>
 | 
			
		||||
            <ResourceDictionary.MergedDictionaries>
 | 
			
		||||
                <ResourceDictionary Source="../Templates/Buttons.xaml" />
 | 
			
		||||
                <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
			
		||||
                <ResourceDictionary Source="../Templates/ScrollViewers.xaml" />
 | 
			
		||||
            </ResourceDictionary.MergedDictionaries>
 | 
			
		||||
        </ResourceDictionary>
 | 
			
		||||
    </UserControl.Resources>
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <Grid.RowDefinitions>
 | 
			
		||||
            <RowDefinition Height="Auto" />
 | 
			
		||||
            <RowDefinition Height="*" />
 | 
			
		||||
            <RowDefinition Height="*" />
 | 
			
		||||
            <RowDefinition Height="Auto" />
 | 
			
		||||
        </Grid.RowDefinitions>
 | 
			
		||||
        <TextBlock Grid.Row="0" x:Name="ApplicationName" Background="#AAD3D3D3" FontWeight="Bold" Padding="5" TextAlignment="Center" />
 | 
			
		||||
        <ContentControl Grid.Row="1" x:Name="ApplicationButton" />
 | 
			
		||||
        <StackPanel Grid.Row="2" x:Name="InstancePanel" Orientation="Vertical" />
 | 
			
		||||
        <Border Grid.Row="3" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="75,4" />
 | 
			
		||||
    </Grid>
 | 
			
		||||
</UserControl>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
 | 
			
		||||
 * 
 | 
			
		||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.Contracts.Applications;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell;
 | 
			
		||||
using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		||||
{
 | 
			
		||||
	public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
 | 
			
		||||
	{
 | 
			
		||||
		private IApplicationInfo info;
 | 
			
		||||
 | 
			
		||||
		public event ApplicationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		public ActionCenterApplicationControl(IApplicationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
			this.info = info;
 | 
			
		||||
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
			InitializeApplicationControl(info);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RegisterInstance(IApplicationInstance instance)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.Invoke(() =>
 | 
			
		||||
			{
 | 
			
		||||
				var button = new ActionCenterApplicationButton(info, instance);
 | 
			
		||||
 | 
			
		||||
				button.Clicked += (id) => Clicked?.Invoke(id);
 | 
			
		||||
				instance.Terminated += (id) => Instance_OnTerminated(id, button);
 | 
			
		||||
				InstancePanel.Children.Add(button);
 | 
			
		||||
 | 
			
		||||
				ApplicationName.Visibility = Visibility.Visible;
 | 
			
		||||
				ApplicationButton.Visibility = Visibility.Collapsed;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeApplicationControl(IApplicationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
			var button = new ActionCenterApplicationButton(info);
 | 
			
		||||
 | 
			
		||||
			button.Button.Click += (o, args) => Clicked?.Invoke();
 | 
			
		||||
			ApplicationName.Text = info.Name;
 | 
			
		||||
			ApplicationButton.Content = button;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Instance_OnTerminated(InstanceIdentifier id, ActionCenterApplicationButton button)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.InvokeAsync(() =>
 | 
			
		||||
			{
 | 
			
		||||
				InstancePanel.Children.Remove(button);
 | 
			
		||||
 | 
			
		||||
				if (InstancePanel.Children.Count == 0)
 | 
			
		||||
				{
 | 
			
		||||
					ApplicationName.Visibility = Visibility.Collapsed;
 | 
			
		||||
					ApplicationButton.Visibility = Visibility.Visible;
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +15,9 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
			
		|||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		||||
{
 | 
			
		||||
	public partial class NotificationButton : UserControl, INotificationButton
 | 
			
		||||
	public partial class NotificationButton : UserControl, INotificationControl
 | 
			
		||||
	{
 | 
			
		||||
		public event NotificationButtonClickedEventHandler Clicked;
 | 
			
		||||
		public event NotificationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		public NotificationButton(INotificationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ApplicationButton"
 | 
			
		||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.TaskbarApplicationControl"
 | 
			
		||||
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
			
		||||
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -20,26 +20,26 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
			
		|||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		||||
{
 | 
			
		||||
	public partial class ApplicationButton : UserControl, IApplicationButton
 | 
			
		||||
	public partial class TaskbarApplicationControl : UserControl, IApplicationControl
 | 
			
		||||
	{
 | 
			
		||||
		private IApplicationInfo info;
 | 
			
		||||
		private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
 | 
			
		||||
 | 
			
		||||
		public event ApplicationButtonClickedEventHandler Clicked;
 | 
			
		||||
		public event ApplicationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		public ApplicationButton(IApplicationInfo info)
 | 
			
		||||
		public TaskbarApplicationControl(IApplicationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
			this.info = info;
 | 
			
		||||
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
			InitializeApplicationButton();
 | 
			
		||||
			InitializeApplicationControl();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RegisterInstance(IApplicationInstance instance)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.Invoke(() =>
 | 
			
		||||
			{
 | 
			
		||||
				var instanceButton = new ApplicationInstanceButton(instance, info);
 | 
			
		||||
				var instanceButton = new TaskbarApplicationInstanceButton(instance, info);
 | 
			
		||||
 | 
			
		||||
				instanceButton.Clicked += (id) => Clicked?.Invoke(id);
 | 
			
		||||
				instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		|||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeApplicationButton()
 | 
			
		||||
		private void InitializeApplicationControl()
 | 
			
		||||
		{
 | 
			
		||||
			var originalBrush = Button.Background;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Instance_OnTerminated(InstanceIdentifier id, ApplicationInstanceButton instanceButton)
 | 
			
		||||
		private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.InvokeAsync(() =>
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ApplicationInstanceButton"
 | 
			
		||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.TaskbarApplicationInstanceButton"
 | 
			
		||||
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
			
		||||
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -15,14 +15,14 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
			
		|||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
			
		||||
{
 | 
			
		||||
	public partial class ApplicationInstanceButton : UserControl
 | 
			
		||||
	public partial class TaskbarApplicationInstanceButton : UserControl
 | 
			
		||||
	{
 | 
			
		||||
		private IApplicationInfo info;
 | 
			
		||||
		private IApplicationInstance instance;
 | 
			
		||||
 | 
			
		||||
		internal event ApplicationButtonClickedEventHandler Clicked;
 | 
			
		||||
		internal event ApplicationControlClickedEventHandler Clicked;
 | 
			
		||||
 | 
			
		||||
		public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
 | 
			
		||||
		public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
			this.info = info;
 | 
			
		||||
			this.instance = instance;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,11 +74,17 @@
 | 
			
		|||
    <Compile Include="BrowserWindow.xaml.cs">
 | 
			
		||||
      <DependentUpon>BrowserWindow.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ApplicationButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>ApplicationButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenterApplicationControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>ActionCenterApplicationControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ApplicationInstanceButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>ApplicationInstanceButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenterApplicationButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>ActionCenterApplicationButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\TaskbarApplicationControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>TaskbarApplicationControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\TaskbarApplicationInstanceButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>TaskbarApplicationInstanceButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\DateTimeControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>DateTimeControl.xaml</DependentUpon>
 | 
			
		||||
| 
						 | 
				
			
			@ -137,11 +143,19 @@
 | 
			
		|||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ApplicationButton.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenterApplicationControl.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ApplicationInstanceButton.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenterApplicationButton.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\TaskbarApplicationControl.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\TaskbarApplicationInstanceButton.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,8 +21,7 @@
 | 
			
		|||
            <ColumnDefinition Width="Auto" />
 | 
			
		||||
            <ColumnDefinition Width="40" />
 | 
			
		||||
        </Grid.ColumnDefinitions>
 | 
			
		||||
        <ScrollViewer Grid.Column="0" x:Name="ApplicationScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"
 | 
			
		||||
                      Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
        <ScrollViewer Grid.Column="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
            <StackPanel x:Name="ApplicationStackPanel" Orientation="Horizontal" />
 | 
			
		||||
        </ScrollViewer>
 | 
			
		||||
        <StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,17 +38,17 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
			QuitButton.Clicked += QuitButton_Clicked;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddApplication(IApplicationButton button)
 | 
			
		||||
		public void AddApplicationControl(IApplicationControl control)
 | 
			
		||||
		{
 | 
			
		||||
			if (button is UIElement uiElement)
 | 
			
		||||
			if (control is UIElement uiElement)
 | 
			
		||||
			{
 | 
			
		||||
				ApplicationStackPanel.Children.Add(uiElement);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddNotification(INotificationButton button)
 | 
			
		||||
		public void AddNotificationControl(INotificationControl control)
 | 
			
		||||
		{
 | 
			
		||||
			if (button is UIElement uiElement)
 | 
			
		||||
			if (control is UIElement uiElement)
 | 
			
		||||
			{
 | 
			
		||||
				NotificationStackPanel.Children.Add(uiElement);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,27 +3,25 @@
 | 
			
		|||
    <ResourceDictionary.MergedDictionaries>
 | 
			
		||||
        <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
			
		||||
    </ResourceDictionary.MergedDictionaries>
 | 
			
		||||
    <ControlTemplate x:Key="TaskbarButton" TargetType="Button">
 | 
			
		||||
        <Border x:Name="ButtonContent" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}"
 | 
			
		||||
                BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
			
		||||
    <ControlTemplate x:Key="ActionCenterButton" TargetType="Button">
 | 
			
		||||
        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
			
		||||
            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
			
		||||
                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
			
		||||
        </Border>
 | 
			
		||||
        <ControlTemplate.Triggers>
 | 
			
		||||
            <Trigger Property="IsMouseOver" Value="True">
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="Background" Value="LightBlue" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="Background" Value="#AAADD8E6" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="DodgerBlue" />
 | 
			
		||||
            </Trigger>
 | 
			
		||||
            <Trigger Property="IsPressed" Value="True">
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="SkyBlue" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="#AA87CEEB" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderThickness" Value="2" />
 | 
			
		||||
                <Setter Property="Cursor" Value="Hand" />
 | 
			
		||||
            </Trigger>
 | 
			
		||||
        </ControlTemplate.Triggers>
 | 
			
		||||
    </ControlTemplate>
 | 
			
		||||
    <ControlTemplate x:Key="BrowserButton" TargetType="Button">
 | 
			
		||||
        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand"
 | 
			
		||||
                Padding="{TemplateBinding Padding}">
 | 
			
		||||
        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
			
		||||
            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
			
		||||
                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
			
		||||
        </Border>
 | 
			
		||||
| 
						 | 
				
			
			@ -42,4 +40,22 @@
 | 
			
		|||
            </Trigger>
 | 
			
		||||
        </ControlTemplate.Triggers>
 | 
			
		||||
    </ControlTemplate>
 | 
			
		||||
    <ControlTemplate x:Key="TaskbarButton" TargetType="Button">
 | 
			
		||||
        <Border x:Name="ButtonContent" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}"
 | 
			
		||||
                BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
			
		||||
            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
			
		||||
                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
			
		||||
        </Border>
 | 
			
		||||
        <ControlTemplate.Triggers>
 | 
			
		||||
            <Trigger Property="IsMouseOver" Value="True">
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="Background" Value="LightBlue" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="DodgerBlue" />
 | 
			
		||||
            </Trigger>
 | 
			
		||||
            <Trigger Property="IsPressed" Value="True">
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="SkyBlue" />
 | 
			
		||||
                <Setter TargetName="ButtonContent" Property="BorderThickness" Value="2" />
 | 
			
		||||
                <Setter Property="Cursor" Value="Hand" />
 | 
			
		||||
            </Trigger>
 | 
			
		||||
        </ControlTemplate.Triggers>
 | 
			
		||||
    </ControlTemplate>
 | 
			
		||||
</ResourceDictionary>
 | 
			
		||||
| 
						 | 
				
			
			@ -40,9 +40,16 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
			return new AboutWindow(appConfig, text);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IApplicationButton CreateApplicationButton(IApplicationInfo info)
 | 
			
		||||
		public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
 | 
			
		||||
		{
 | 
			
		||||
			return new ApplicationButton(info);
 | 
			
		||||
			if (location == Location.ActionCenter)
 | 
			
		||||
			{
 | 
			
		||||
				return new ActionCenterApplicationControl(info);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				return new TaskbarApplicationControl(info);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow)
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +86,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
			return logWindow;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public INotificationButton CreateNotification(INotificationInfo info)
 | 
			
		||||
		public INotificationControl CreateNotificationControl(INotificationInfo info)
 | 
			
		||||
		{
 | 
			
		||||
			return new NotificationButton(info);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue