Resolved dependencies from browser API on UI.
This commit is contained in:
parent
fd20d0d638
commit
affd5de6a7
32 changed files with 245 additions and 276 deletions
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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.Applications.Contracts.Events
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event handler used to inform about the existence of a new <see cref="IApplicationInstance"/>.
|
||||||
|
/// </summary>
|
||||||
|
public delegate void InstanceStartedEventHandler(IApplicationInstance instance);
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ using SafeExamBrowser.Core.Contracts;
|
||||||
namespace SafeExamBrowser.Applications.Contracts.Events
|
namespace SafeExamBrowser.Applications.Contracts.Events
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event handler used to indicate that an <see cref="IApplicationInstance"/> with a particular ID has terminated.
|
/// Event handler used to indicate that an <see cref="IApplicationInstance"/> has terminated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void InstanceTerminatedEventHandler(InstanceIdentifier id);
|
public delegate void InstanceTerminatedEventHandler(InstanceIdentifier id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,30 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using SafeExamBrowser.Applications.Contracts.Events;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Applications.Contracts
|
namespace SafeExamBrowser.Applications.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controls the lifetime and functionality of a (third-party) application which can be accessed via the <see cref="ITaskbar"/>.
|
/// Controls the lifetime and functionality of a (third-party) application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApplicationController
|
public interface IApplication
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides information about the application.
|
||||||
|
/// </summary>
|
||||||
|
IApplicationInfo Info { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a new <see cref="IApplicationInstance"/> has started.
|
||||||
|
/// </summary>
|
||||||
|
event InstanceStartedEventHandler InstanceStarted;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs any initialization work, if necessary.
|
/// Performs any initialization work, if necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
// TODO
|
|
||||||
///// <summary>
|
|
||||||
///// Registers an application control for this application.
|
|
||||||
///// </summary>
|
|
||||||
//void RegisterApplicationControl(IApplicationControl control);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the execution of the application.
|
/// Starts the execution of the application.
|
||||||
/// </summary>
|
/// </summary>
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Applications.Contracts
|
||||||
InstanceIdentifier Id { get; }
|
InstanceIdentifier Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name or (document) title of the application instance.
|
/// The name or document title of the application instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
|
@ -41,10 +41,9 @@ namespace SafeExamBrowser.Applications.Contracts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event NameChangedEventHandler NameChanged;
|
event NameChangedEventHandler NameChanged;
|
||||||
|
|
||||||
// TODO
|
/// <summary>
|
||||||
///// <summary>
|
/// Makes this instance the currently active one and brings it to the foreground.
|
||||||
///// The main window of the application instance.
|
/// </summary>
|
||||||
///// </summary>
|
void Activate();
|
||||||
//IWindow Window { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,10 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Events\IconChangedEventHandler.cs" />
|
<Compile Include="Events\IconChangedEventHandler.cs" />
|
||||||
|
<Compile Include="Events\InstanceStartedEventHandler.cs" />
|
||||||
<Compile Include="Events\InstanceTerminatedEventHandler.cs" />
|
<Compile Include="Events\InstanceTerminatedEventHandler.cs" />
|
||||||
<Compile Include="Events\NameChangedEventHandler.cs" />
|
<Compile Include="Events\NameChangedEventHandler.cs" />
|
||||||
<Compile Include="IApplicationController.cs" />
|
<Compile Include="IApplication.cs" />
|
||||||
<Compile Include="IApplicationInfo.cs" />
|
<Compile Include="IApplicationInfo.cs" />
|
||||||
<Compile Include="IApplicationInstance.cs" />
|
<Compile Include="IApplicationInstance.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SafeExamBrowser.Browser.Contracts
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controls the lifetime and functionality of the browser application.
|
/// Controls the lifetime and functionality of the browser application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBrowserApplicationController : IApplicationController
|
public interface IBrowserApplication : IApplication
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event fired when the browser application detects a download request for an application configuration file.
|
/// Event fired when the browser application detects a download request for an application configuration file.
|
|
@ -56,7 +56,7 @@
|
||||||
<Compile Include="DownloadEventArgs.cs" />
|
<Compile Include="DownloadEventArgs.cs" />
|
||||||
<Compile Include="DownloadFinishedCallback.cs" />
|
<Compile Include="DownloadFinishedCallback.cs" />
|
||||||
<Compile Include="DownloadRequestedEventHandler.cs" />
|
<Compile Include="DownloadRequestedEventHandler.cs" />
|
||||||
<Compile Include="IBrowserApplicationController.cs" />
|
<Compile Include="IBrowserApplication.cs" />
|
||||||
<Compile Include="ProgressChangedEventHandler.cs" />
|
<Compile Include="ProgressChangedEventHandler.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -12,6 +12,7 @@ using System.Linq;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using CefSharp.WinForms;
|
using CefSharp.WinForms;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
|
using SafeExamBrowser.Applications.Contracts.Events;
|
||||||
using SafeExamBrowser.Browser.Contracts;
|
using SafeExamBrowser.Browser.Contracts;
|
||||||
using SafeExamBrowser.Browser.Events;
|
using SafeExamBrowser.Browser.Events;
|
||||||
using SafeExamBrowser.Configuration.Contracts;
|
using SafeExamBrowser.Configuration.Contracts;
|
||||||
|
@ -20,27 +21,28 @@ using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
|
||||||
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.BrowserSettings;
|
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.BrowserSettings;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser
|
namespace SafeExamBrowser.Browser
|
||||||
{
|
{
|
||||||
public class BrowserApplicationController : IBrowserApplicationController
|
public class BrowserApplication : IBrowserApplication
|
||||||
{
|
{
|
||||||
private int instanceIdCounter = default(int);
|
private int instanceIdCounter = default(int);
|
||||||
|
|
||||||
private AppConfig appConfig;
|
private AppConfig appConfig;
|
||||||
private IList<IApplicationControl> controls;
|
private List<BrowserApplicationInstance> instances;
|
||||||
private IList<IApplicationInstance> instances;
|
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
private IModuleLogger logger;
|
private IModuleLogger logger;
|
||||||
private BrowserSettings settings;
|
private BrowserSettings settings;
|
||||||
private IText text;
|
private IText text;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
public IApplicationInfo Info { get; private set; }
|
||||||
|
|
||||||
public BrowserApplicationController(
|
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||||
|
public event InstanceStartedEventHandler InstanceStarted;
|
||||||
|
|
||||||
|
public BrowserApplication(
|
||||||
AppConfig appConfig,
|
AppConfig appConfig,
|
||||||
BrowserSettings settings,
|
BrowserSettings settings,
|
||||||
IMessageBox messageBox,
|
IMessageBox messageBox,
|
||||||
|
@ -49,8 +51,7 @@ namespace SafeExamBrowser.Browser
|
||||||
IUserInterfaceFactory uiFactory)
|
IUserInterfaceFactory uiFactory)
|
||||||
{
|
{
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
this.controls = new List<IApplicationControl>();
|
this.instances = new List<BrowserApplicationInstance>();
|
||||||
this.instances = new List<IApplicationInstance>();
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.messageBox = messageBox;
|
this.messageBox = messageBox;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -63,20 +64,18 @@ namespace SafeExamBrowser.Browser
|
||||||
var cefSettings = InitializeCefSettings();
|
var cefSettings = InitializeCefSettings();
|
||||||
var success = Cef.Initialize(cefSettings, true, default(IApp));
|
var success = Cef.Initialize(cefSettings, true, default(IApp));
|
||||||
|
|
||||||
logger.Info("Initialized browser.");
|
Info = new BrowserApplicationInfo();
|
||||||
|
|
||||||
if (!success)
|
if (success)
|
||||||
|
{
|
||||||
|
logger.Info("Initialized browser.");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to initialize browser!");
|
throw new Exception("Failed to initialize browser!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterApplicationControl(IApplicationControl control)
|
|
||||||
{
|
|
||||||
control.Clicked += ApplicationControl_Clicked;
|
|
||||||
controls.Add(control);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
CreateNewInstance();
|
CreateNewInstance();
|
||||||
|
@ -87,13 +86,11 @@ namespace SafeExamBrowser.Browser
|
||||||
foreach (var instance in instances)
|
foreach (var instance in instances)
|
||||||
{
|
{
|
||||||
instance.Terminated -= Instance_Terminated;
|
instance.Terminated -= Instance_Terminated;
|
||||||
// TODO instance.Window.Close();
|
instance.Terminate();
|
||||||
|
|
||||||
logger.Info($"Terminated browser instance {instance.Id}.");
|
logger.Info($"Terminated browser instance {instance.Id}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Cef.Shutdown();
|
Cef.Shutdown();
|
||||||
|
|
||||||
logger.Info("Terminated browser.");
|
logger.Info("Terminated browser.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,35 +102,17 @@ namespace SafeExamBrowser.Browser
|
||||||
var startUrl = url ?? settings.StartUrl;
|
var startUrl = url ?? settings.StartUrl;
|
||||||
var instance = new BrowserApplicationInstance(appConfig, settings, id, isMainInstance, messageBox, instanceLogger, text, uiFactory, startUrl);
|
var instance = new BrowserApplicationInstance(appConfig, settings, id, isMainInstance, messageBox, instanceLogger, text, uiFactory, startUrl);
|
||||||
|
|
||||||
instance.Initialize();
|
|
||||||
instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
||||||
instance.IconChanged += Instance_IconChanged;
|
|
||||||
instance.NameChanged += Instance_NameChanged;
|
|
||||||
instance.PopupRequested += Instance_PopupRequested;
|
instance.PopupRequested += Instance_PopupRequested;
|
||||||
instance.Terminated += Instance_Terminated;
|
instance.Terminated += Instance_Terminated;
|
||||||
|
|
||||||
|
instance.Initialize();
|
||||||
instances.Add(instance);
|
instances.Add(instance);
|
||||||
instance.Window.Show();
|
InstanceStarted?.Invoke(instance);
|
||||||
|
|
||||||
logger.Info($"Created browser instance {instance.Id}.");
|
logger.Info($"Created browser instance {instance.Id}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_NameChanged(string name)
|
|
||||||
{
|
|
||||||
foreach (var control in controls)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Instance_IconChanged(IIconResource icon)
|
|
||||||
{
|
|
||||||
foreach (var control in controls)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CefSettings InitializeCefSettings()
|
private CefSettings InitializeCefSettings()
|
||||||
{
|
{
|
||||||
var warning = logger.LogLevel == LogLevel.Warning;
|
var warning = logger.LogLevel == LogLevel.Warning;
|
||||||
|
@ -156,18 +135,6 @@ namespace SafeExamBrowser.Browser
|
||||||
return cefSettings;
|
return cefSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplicationControl_Clicked(InstanceIdentifier id = null)
|
|
||||||
{
|
|
||||||
if (id == null)
|
|
||||||
{
|
|
||||||
CreateNewInstance();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO instances.FirstOrDefault(i => i.Id == id)?.Window?.BringToForeground();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Instance_PopupRequested(PopupRequestedEventArgs args)
|
private void Instance_PopupRequested(PopupRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
logger.Info($"Received request to create new instance for '{args.Url}'...");
|
logger.Info($"Received request to create new instance for '{args.Url}'...");
|
|
@ -21,7 +21,6 @@ using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser
|
namespace SafeExamBrowser.Browser
|
||||||
{
|
{
|
||||||
|
@ -49,7 +48,6 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
public InstanceIdentifier Id { get; private set; }
|
public InstanceIdentifier Id { get; private set; }
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
public IWindow Window { get { return window; } }
|
|
||||||
|
|
||||||
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||||
public event IconChangedEventHandler IconChanged;
|
public event IconChangedEventHandler IconChanged;
|
||||||
|
@ -80,6 +78,11 @@ namespace SafeExamBrowser.Browser
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
window?.BringToForeground();
|
||||||
|
}
|
||||||
|
|
||||||
internal void Initialize()
|
internal void Initialize()
|
||||||
{
|
{
|
||||||
var contextMenuHandler = new ContextMenuHandler();
|
var contextMenuHandler = new ContextMenuHandler();
|
||||||
|
@ -118,10 +121,16 @@ namespace SafeExamBrowser.Browser
|
||||||
window.ZoomOutRequested += ZoomOutRequested;
|
window.ZoomOutRequested += ZoomOutRequested;
|
||||||
window.ZoomResetRequested += ZoomResetRequested;
|
window.ZoomResetRequested += ZoomResetRequested;
|
||||||
window.UpdateZoomLevel(CalculateZoomPercentage());
|
window.UpdateZoomLevel(CalculateZoomPercentage());
|
||||||
|
window.Show();
|
||||||
|
|
||||||
logger.Debug("Initialized browser window.");
|
logger.Debug("Initialized browser window.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void Terminate()
|
||||||
|
{
|
||||||
|
window?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
private void Control_AddressChanged(string address)
|
private void Control_AddressChanged(string address)
|
||||||
{
|
{
|
||||||
logger.Debug($"Navigated to '{address}'.");
|
logger.Debug($"Navigated to '{address}'.");
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BrowserApplicationController.cs" />
|
<Compile Include="BrowserApplication.cs" />
|
||||||
<Compile Include="BrowserApplicationInfo.cs" />
|
<Compile Include="BrowserApplicationInfo.cs" />
|
||||||
<Compile Include="BrowserApplicationInstance.cs" />
|
<Compile Include="BrowserApplicationInstance.cs" />
|
||||||
<Compile Include="BrowserInstanceIdentifier.cs" />
|
<Compile Include="BrowserInstanceIdentifier.cs" />
|
||||||
|
|
|
@ -25,9 +25,9 @@ namespace SafeExamBrowser.Client.Contracts
|
||||||
AppConfig AppConfig { set; }
|
AppConfig AppConfig { set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The controller for the browser application.
|
/// The browser application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IBrowserApplicationController Browser { set; }
|
IBrowserApplication Browser { set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The client host used for communication handling.
|
/// The client host used for communication handling.
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace SafeExamBrowser.Client.UnitTests
|
||||||
{
|
{
|
||||||
private AppConfig appConfig;
|
private AppConfig appConfig;
|
||||||
private Mock<IActionCenter> actionCenter;
|
private Mock<IActionCenter> actionCenter;
|
||||||
private Mock<IBrowserApplicationController> browserController;
|
private Mock<IBrowserApplication> browserController;
|
||||||
private Mock<IClientHost> clientHost;
|
private Mock<IClientHost> clientHost;
|
||||||
private Mock<IDisplayMonitor> displayMonitor;
|
private Mock<IDisplayMonitor> displayMonitor;
|
||||||
private Mock<IExplorerShell> explorerShell;
|
private Mock<IExplorerShell> explorerShell;
|
||||||
|
@ -61,7 +61,7 @@ namespace SafeExamBrowser.Client.UnitTests
|
||||||
{
|
{
|
||||||
appConfig = new AppConfig();
|
appConfig = new AppConfig();
|
||||||
actionCenter = new Mock<IActionCenter>();
|
actionCenter = new Mock<IActionCenter>();
|
||||||
browserController = new Mock<IBrowserApplicationController>();
|
browserController = new Mock<IBrowserApplication>();
|
||||||
clientHost = new Mock<IClientHost>();
|
clientHost = new Mock<IClientHost>();
|
||||||
displayMonitor = new Mock<IDisplayMonitor>();
|
displayMonitor = new Mock<IDisplayMonitor>();
|
||||||
explorerShell = new Mock<IExplorerShell>();
|
explorerShell = new Mock<IExplorerShell>();
|
||||||
|
|
|
@ -20,8 +20,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
public class BrowserOperationTests
|
public class BrowserOperationTests
|
||||||
{
|
{
|
||||||
private Mock<IActionCenter> actionCenter;
|
private Mock<IActionCenter> actionCenter;
|
||||||
private Mock<IApplicationController> controller;
|
private Mock<IApplication> application;
|
||||||
private Mock<IApplicationInfo> appInfo;
|
|
||||||
private Mock<ILogger> logger;
|
private Mock<ILogger> logger;
|
||||||
private Mock<ITaskbar> taskbar;
|
private Mock<ITaskbar> taskbar;
|
||||||
private Mock<IUserInterfaceFactory> uiFactory;
|
private Mock<IUserInterfaceFactory> uiFactory;
|
||||||
|
@ -32,13 +31,12 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
actionCenter = new Mock<IActionCenter>();
|
actionCenter = new Mock<IActionCenter>();
|
||||||
controller = new Mock<IApplicationController>();
|
application = new Mock<IApplication>();
|
||||||
appInfo = new Mock<IApplicationInfo>();
|
|
||||||
logger = new Mock<ILogger>();
|
logger = new Mock<ILogger>();
|
||||||
taskbar = new Mock<ITaskbar>();
|
taskbar = new Mock<ITaskbar>();
|
||||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||||
|
|
||||||
sut = new BrowserOperation(actionCenter.Object, controller.Object, appInfo.Object, logger.Object, taskbar.Object, uiFactory.Object);
|
sut = new BrowserOperation(actionCenter.Object, application.Object, logger.Object, taskbar.Object, uiFactory.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -46,7 +44,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
{
|
{
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
controller.Verify(c => c.Initialize(), Times.Once);
|
application.Verify(c => c.Initialize(), Times.Once);
|
||||||
// TODO controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Exactly(2));
|
// TODO controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Exactly(2));
|
||||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
||||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
||||||
|
@ -56,7 +54,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
public void MustRevertCorrectly()
|
public void MustRevertCorrectly()
|
||||||
{
|
{
|
||||||
sut.Revert();
|
sut.Revert();
|
||||||
controller.Verify(c => c.Terminate(), Times.Once);
|
application.Verify(c => c.Terminate(), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Client
|
||||||
private IWindowMonitor windowMonitor;
|
private IWindowMonitor windowMonitor;
|
||||||
private AppConfig appConfig;
|
private AppConfig appConfig;
|
||||||
|
|
||||||
public IBrowserApplicationController Browser { private get; set; }
|
public IBrowserApplication Browser { private get; set; }
|
||||||
public IClientHost ClientHost { private get; set; }
|
public IClientHost ClientHost { private get; set; }
|
||||||
public Guid SessionId { private get; set; }
|
public Guid SessionId { private get; set; }
|
||||||
public Settings Settings { private get; set; }
|
public Settings Settings { private get; set; }
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Client
|
||||||
private UserInterfaceMode uiMode;
|
private UserInterfaceMode uiMode;
|
||||||
|
|
||||||
private IActionCenter actionCenter;
|
private IActionCenter actionCenter;
|
||||||
private IBrowserApplicationController browserController;
|
private IBrowserApplication browser;
|
||||||
private IClientHost clientHost;
|
private IClientHost clientHost;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
|
@ -199,11 +199,11 @@ namespace SafeExamBrowser.Client
|
||||||
private IOperation BuildBrowserOperation()
|
private IOperation BuildBrowserOperation()
|
||||||
{
|
{
|
||||||
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
||||||
var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
|
var browser = new BrowserApplication(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
|
||||||
var browserInfo = new BrowserApplicationInfo();
|
var browserInfo = new BrowserApplicationInfo();
|
||||||
var operation = new BrowserOperation(actionCenter, browserController, browserInfo, logger, taskbar, uiFactory);
|
var operation = new BrowserOperation(actionCenter, browser, logger, taskbar, uiFactory);
|
||||||
|
|
||||||
this.browserController = browserController;
|
this.browser = browser;
|
||||||
|
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ namespace SafeExamBrowser.Client
|
||||||
|
|
||||||
private void UpdateClientControllerDependencies()
|
private void UpdateClientControllerDependencies()
|
||||||
{
|
{
|
||||||
ClientController.Browser = browserController;
|
ClientController.Browser = browser;
|
||||||
ClientController.ClientHost = clientHost;
|
ClientController.ClientHost = clientHost;
|
||||||
ClientController.SessionId = configuration.SessionId;
|
ClientController.SessionId = configuration.SessionId;
|
||||||
ClientController.Settings = configuration.Settings;
|
ClientController.Settings = configuration.Settings;
|
||||||
|
|
|
@ -19,8 +19,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
internal class BrowserOperation : IOperation
|
internal class BrowserOperation : IOperation
|
||||||
{
|
{
|
||||||
private IActionCenter actionCenter;
|
private IActionCenter actionCenter;
|
||||||
private IApplicationController browserController;
|
private IApplication browser;
|
||||||
private IApplicationInfo browserInfo;
|
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private ITaskbar taskbar;
|
private ITaskbar taskbar;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
@ -30,15 +29,13 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
|
|
||||||
public BrowserOperation(
|
public BrowserOperation(
|
||||||
IActionCenter actionCenter,
|
IActionCenter actionCenter,
|
||||||
IApplicationController browserController,
|
IApplication browser,
|
||||||
IApplicationInfo browserInfo,
|
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
ITaskbar taskbar,
|
ITaskbar taskbar,
|
||||||
IUserInterfaceFactory uiFactory)
|
IUserInterfaceFactory uiFactory)
|
||||||
{
|
{
|
||||||
this.actionCenter = actionCenter;
|
this.actionCenter = actionCenter;
|
||||||
this.browserController = browserController;
|
this.browser = browser;
|
||||||
this.browserInfo = browserInfo;
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.taskbar = taskbar;
|
this.taskbar = taskbar;
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
|
@ -49,16 +46,10 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
logger.Info("Initializing browser...");
|
logger.Info("Initializing browser...");
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
|
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
|
||||||
|
|
||||||
var actionCenterControl = uiFactory.CreateApplicationControl(browserInfo, Location.ActionCenter);
|
browser.Initialize();
|
||||||
var taskbarControl = uiFactory.CreateApplicationControl(browserInfo, Location.Taskbar);
|
|
||||||
|
|
||||||
browserController.Initialize();
|
actionCenter.AddApplicationControl(uiFactory.CreateApplicationControl(browser, Location.ActionCenter));
|
||||||
// TODO
|
taskbar.AddApplicationControl(uiFactory.CreateApplicationControl(browser, Location.Taskbar));
|
||||||
//browserController.RegisterApplicationControl(actionCenterControl);
|
|
||||||
//browserController.RegisterApplicationControl(taskbarControl);
|
|
||||||
|
|
||||||
actionCenter.AddApplicationControl(actionCenterControl);
|
|
||||||
taskbar.AddApplicationControl(taskbarControl);
|
|
||||||
|
|
||||||
return OperationResult.Success;
|
return OperationResult.Success;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +59,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
logger.Info("Terminating browser...");
|
logger.Info("Terminating browser...");
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateBrowser);
|
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateBrowser);
|
||||||
|
|
||||||
browserController.Terminate();
|
browser.Terminate();
|
||||||
|
|
||||||
return OperationResult.Success;
|
return OperationResult.Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,9 @@ namespace SafeExamBrowser.UserInterface.Contracts
|
||||||
IWindow CreateAboutWindow(AppConfig appConfig);
|
IWindow CreateAboutWindow(AppConfig appConfig);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an application control for the specified location, initialized with the given application information.
|
/// Creates an application control for the specified application and location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location);
|
IApplicationControl CreateApplicationControl(IApplication application, Location location);
|
||||||
|
|
||||||
/// <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.
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -15,10 +13,5 @@ namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApplicationControl
|
public interface IApplicationControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 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 ApplicationControlClickedEventHandler Clicked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="40" Padding="10" Template="{StaticResource ActionCenterButton}">
|
<Button x:Name="Button" Background="Transparent" Height="40" Padding="10" Template="{StaticResource ActionCenterButton}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
|
<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" />
|
<TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
|
||||||
|
|
|
@ -6,11 +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/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Windows;
|
using System;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
using SafeExamBrowser.Core.Contracts;
|
||||||
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
|
||||||
|
@ -20,7 +19,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
private IApplicationInfo info;
|
private IApplicationInfo info;
|
||||||
private IApplicationInstance instance;
|
private IApplicationInstance instance;
|
||||||
|
|
||||||
internal event ApplicationControlClickedEventHandler Clicked;
|
internal event EventHandler Clicked;
|
||||||
|
|
||||||
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +34,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
{
|
{
|
||||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||||
Text.Text = instance?.Name ?? info.Name;
|
Text.Text = instance?.Name ?? info.Name;
|
||||||
|
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
|
||||||
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
||||||
|
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
|
@ -51,16 +51,11 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
|
|
||||||
private void Instance_NameChanged(string name)
|
private void Instance_NameChanged(string name)
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
Text.Text = name;
|
Text.Text = name;
|
||||||
Button.ToolTip = name;
|
Button.ToolTip = name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
Clicked?.Invoke(instance?.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,34 +9,40 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
{
|
{
|
||||||
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
||||||
{
|
{
|
||||||
private IApplicationInfo info;
|
private IApplication application;
|
||||||
|
|
||||||
public event ApplicationControlClickedEventHandler Clicked;
|
public ActionCenterApplicationControl(IApplication application)
|
||||||
|
|
||||||
public ActionCenterApplicationControl(IApplicationInfo info)
|
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.application = application;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeApplicationControl(info);
|
InitializeApplicationControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterInstance(IApplicationInstance instance)
|
private void InitializeApplicationControl()
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
var button = new ActionCenterApplicationButton(application.Info);
|
||||||
{
|
|
||||||
var button = new ActionCenterApplicationButton(info, instance);
|
|
||||||
|
|
||||||
button.Clicked += (id) => Clicked?.Invoke(id);
|
application.InstanceStarted += Application_InstanceStarted;
|
||||||
instance.Terminated += (id) => Instance_OnTerminated(id, button);
|
button.Clicked += (o, args) => application.Start();
|
||||||
|
ApplicationName.Text = application.Info.Name;
|
||||||
|
ApplicationButton.Content = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Application_InstanceStarted(IApplicationInstance instance)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
var button = new ActionCenterApplicationButton(application.Info, instance);
|
||||||
|
|
||||||
|
button.Clicked += (o, args) => instance.Activate();
|
||||||
|
instance.Terminated += (_) => RemoveInstance(button);
|
||||||
InstancePanel.Children.Add(button);
|
InstancePanel.Children.Add(button);
|
||||||
|
|
||||||
ApplicationName.Visibility = Visibility.Visible;
|
ApplicationName.Visibility = Visibility.Visible;
|
||||||
|
@ -44,16 +50,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeApplicationControl(IApplicationInfo info)
|
private void RemoveInstance(ActionCenterApplicationButton button)
|
||||||
{
|
|
||||||
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(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,59 +6,41 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
|
||||||
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 TaskbarApplicationControl : UserControl, IApplicationControl
|
public partial class TaskbarApplicationControl : UserControl, IApplicationControl
|
||||||
{
|
{
|
||||||
private IApplicationInfo info;
|
private IApplication application;
|
||||||
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
|
private IApplicationInstance single;
|
||||||
|
|
||||||
public event ApplicationControlClickedEventHandler Clicked;
|
public TaskbarApplicationControl(IApplication application)
|
||||||
|
|
||||||
public TaskbarApplicationControl(IApplicationInfo info)
|
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.application = application;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeApplicationControl();
|
InitializeApplicationControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterInstance(IApplicationInstance instance)
|
|
||||||
{
|
|
||||||
Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
var instanceButton = new TaskbarApplicationInstanceButton(instance, info);
|
|
||||||
|
|
||||||
instanceButton.Clicked += (id) => Clicked?.Invoke(id);
|
|
||||||
instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
|
|
||||||
|
|
||||||
instances.Add(instance);
|
|
||||||
InstanceStackPanel.Children.Add(instanceButton);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeApplicationControl()
|
private void InitializeApplicationControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
Button.ToolTip = info.Tooltip;
|
application.InstanceStarted += Application_InstanceStarted;
|
||||||
Button.Content = IconResourceLoader.Load(info.IconResource);
|
|
||||||
|
|
||||||
Button.MouseEnter += (o, args) => InstancePopup.IsOpen = instances.Count > 1;
|
Button.Click += Button_Click;
|
||||||
|
Button.Content = IconResourceLoader.Load(application.Info.IconResource);
|
||||||
|
Button.MouseEnter += (o, args) => InstancePopup.IsOpen = InstanceStackPanel.Children.Count > 1;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = InstancePopup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = InstancePopup.IsMouseOver));
|
||||||
|
Button.ToolTip = application.Info.Tooltip;
|
||||||
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
||||||
|
|
||||||
InstancePopup.Opened += (o, args) =>
|
InstancePopup.Opened += (o, args) =>
|
||||||
|
@ -74,11 +56,31 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Application_InstanceStarted(IApplicationInstance instance)
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
var button = new TaskbarApplicationInstanceButton(instance, application.Info);
|
||||||
|
|
||||||
|
instance.Terminated += (_) => RemoveInstance(button);
|
||||||
|
InstanceStackPanel.Children.Add(button);
|
||||||
|
|
||||||
|
if (single == default(IApplicationInstance))
|
||||||
|
{
|
||||||
|
single = instance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (instances.Count <= 1)
|
if (InstanceStackPanel.Children.Count == 0)
|
||||||
{
|
{
|
||||||
Clicked?.Invoke(instances.FirstOrDefault()?.Id);
|
application.Start();
|
||||||
|
}
|
||||||
|
else if (InstanceStackPanel.Children.Count == 1)
|
||||||
|
{
|
||||||
|
single.Activate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -86,12 +88,16 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
|
private void RemoveInstance(TaskbarApplicationInstanceButton button)
|
||||||
{
|
{
|
||||||
Dispatcher.InvokeAsync(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
instances.Remove(instances.FirstOrDefault(i => i.Id == id));
|
InstanceStackPanel.Children.Remove(button);
|
||||||
InstanceStackPanel.Children.Remove(instanceButton);
|
|
||||||
|
if (InstanceStackPanel.Children.Count == 0)
|
||||||
|
{
|
||||||
|
single = default(IApplicationInstance);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="40" Padding="10" Template="{StaticResource TaskbarButton}">
|
<Button x:Name="Button" Background="Transparent" Height="40" Padding="10" Template="{StaticResource TaskbarButton}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
|
<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" />
|
<TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
|
||||||
|
|
|
@ -10,7 +10,6 @@ using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
using SafeExamBrowser.Core.Contracts;
|
||||||
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
|
||||||
|
@ -20,8 +19,6 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
private IApplicationInfo info;
|
private IApplicationInfo info;
|
||||||
private IApplicationInstance instance;
|
private IApplicationInstance instance;
|
||||||
|
|
||||||
internal event ApplicationControlClickedEventHandler Clicked;
|
|
||||||
|
|
||||||
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
@ -33,12 +30,17 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
|
|
||||||
private void InitializeApplicationInstanceButton()
|
private void InitializeApplicationInstanceButton()
|
||||||
{
|
{
|
||||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
Button.Click += Button_Click;
|
||||||
Text.Text = instance.Name;
|
|
||||||
Button.ToolTip = instance.Name;
|
Button.ToolTip = instance.Name;
|
||||||
|
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||||
instance.IconChanged += Instance_IconChanged;
|
instance.IconChanged += Instance_IconChanged;
|
||||||
instance.NameChanged += Instance_NameChanged;
|
instance.NameChanged += Instance_NameChanged;
|
||||||
|
Text.Text = instance.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
instance.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_IconChanged(IIconResource icon)
|
private void Instance_IconChanged(IIconResource icon)
|
||||||
|
@ -54,10 +56,5 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
Button.ToolTip = name;
|
Button.ToolTip = name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
Clicked?.Invoke(instance.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,15 +40,15 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
return new AboutWindow(appConfig, text);
|
return new AboutWindow(appConfig, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
|
public IApplicationControl CreateApplicationControl(IApplication application, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
{
|
{
|
||||||
return new ActionCenterApplicationControl(info);
|
return new ActionCenterApplicationControl(application);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new TaskbarApplicationControl(info);
|
return new TaskbarApplicationControl(application);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="60" Padding="10" Template="{StaticResource ActionCenterButton}">
|
<Button x:Name="Button" Background="Transparent" Height="60" Padding="10" Template="{StaticResource ActionCenterButton}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
|
<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" />
|
<TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
|
||||||
|
|
|
@ -6,11 +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/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Windows;
|
using System;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
using SafeExamBrowser.Core.Contracts;
|
||||||
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
|
||||||
|
@ -20,7 +19,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
private IApplicationInfo info;
|
private IApplicationInfo info;
|
||||||
private IApplicationInstance instance;
|
private IApplicationInstance instance;
|
||||||
|
|
||||||
internal event ApplicationControlClickedEventHandler Clicked;
|
internal event EventHandler Clicked;
|
||||||
|
|
||||||
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +34,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
{
|
{
|
||||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||||
Text.Text = instance?.Name ?? info.Name;
|
Text.Text = instance?.Name ?? info.Name;
|
||||||
|
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
|
||||||
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
||||||
|
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
|
@ -51,16 +51,11 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
|
|
||||||
private void Instance_NameChanged(string name)
|
private void Instance_NameChanged(string name)
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
Text.Text = name;
|
Text.Text = name;
|
||||||
Button.ToolTip = name;
|
Button.ToolTip = name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
Clicked?.Invoke(instance?.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,34 +9,40 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
{
|
{
|
||||||
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
||||||
{
|
{
|
||||||
private IApplicationInfo info;
|
private IApplication application;
|
||||||
|
|
||||||
public event ApplicationControlClickedEventHandler Clicked;
|
public ActionCenterApplicationControl(IApplication application)
|
||||||
|
|
||||||
public ActionCenterApplicationControl(IApplicationInfo info)
|
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.application = application;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeApplicationControl(info);
|
InitializeApplicationControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterInstance(IApplicationInstance instance)
|
private void InitializeApplicationControl()
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
var button = new ActionCenterApplicationButton(application.Info);
|
||||||
{
|
|
||||||
var button = new ActionCenterApplicationButton(info, instance);
|
|
||||||
|
|
||||||
button.Clicked += (id) => Clicked?.Invoke(id);
|
application.InstanceStarted += Application_InstanceStarted;
|
||||||
instance.Terminated += (id) => Instance_OnTerminated(id, button);
|
button.Clicked += (o, args) => application.Start();
|
||||||
|
ApplicationName.Text = application.Info.Name;
|
||||||
|
ApplicationButton.Content = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Application_InstanceStarted(IApplicationInstance instance)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
var button = new ActionCenterApplicationButton(application.Info, instance);
|
||||||
|
|
||||||
|
button.Clicked += (o, args) => instance.Activate();
|
||||||
|
instance.Terminated += (_) => RemoveInstance(button);
|
||||||
InstancePanel.Children.Add(button);
|
InstancePanel.Children.Add(button);
|
||||||
|
|
||||||
ApplicationName.Visibility = Visibility.Visible;
|
ApplicationName.Visibility = Visibility.Visible;
|
||||||
|
@ -44,16 +50,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeApplicationControl(IApplicationInfo info)
|
private void RemoveInstance(ActionCenterApplicationButton button)
|
||||||
{
|
|
||||||
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(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,59 +6,41 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
|
||||||
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 TaskbarApplicationControl : UserControl, IApplicationControl
|
public partial class TaskbarApplicationControl : UserControl, IApplicationControl
|
||||||
{
|
{
|
||||||
private IApplicationInfo info;
|
private IApplication application;
|
||||||
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
|
private IApplicationInstance single;
|
||||||
|
|
||||||
public event ApplicationControlClickedEventHandler Clicked;
|
public TaskbarApplicationControl(IApplication application)
|
||||||
|
|
||||||
public TaskbarApplicationControl(IApplicationInfo info)
|
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.application = application;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeApplicationControl();
|
InitializeApplicationControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterInstance(IApplicationInstance instance)
|
|
||||||
{
|
|
||||||
Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
var instanceButton = new TaskbarApplicationInstanceButton(instance, info);
|
|
||||||
|
|
||||||
instanceButton.Clicked += (id) => Clicked?.Invoke(id);
|
|
||||||
instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
|
|
||||||
|
|
||||||
instances.Add(instance);
|
|
||||||
InstanceStackPanel.Children.Add(instanceButton);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeApplicationControl()
|
private void InitializeApplicationControl()
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
Button.ToolTip = info.Tooltip;
|
application.InstanceStarted += Application_InstanceStarted;
|
||||||
Button.Content = IconResourceLoader.Load(info.IconResource);
|
|
||||||
|
|
||||||
Button.MouseEnter += (o, args) => InstancePopup.IsOpen = instances.Count > 1;
|
Button.Click += Button_Click;
|
||||||
|
Button.Content = IconResourceLoader.Load(application.Info.IconResource);
|
||||||
|
Button.MouseEnter += (o, args) => InstancePopup.IsOpen = InstanceStackPanel.Children.Count > 1;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = InstancePopup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = InstancePopup.IsMouseOver));
|
||||||
|
Button.ToolTip = application.Info.Tooltip;
|
||||||
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
||||||
|
|
||||||
InstancePopup.Opened += (o, args) =>
|
InstancePopup.Opened += (o, args) =>
|
||||||
|
@ -74,11 +56,31 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Application_InstanceStarted(IApplicationInstance instance)
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
var button = new TaskbarApplicationInstanceButton(instance, application.Info);
|
||||||
|
|
||||||
|
instance.Terminated += (_) => RemoveInstance(button);
|
||||||
|
InstanceStackPanel.Children.Add(button);
|
||||||
|
|
||||||
|
if (single == default(IApplicationInstance))
|
||||||
|
{
|
||||||
|
single = instance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (instances.Count <= 1)
|
if (InstanceStackPanel.Children.Count == 0)
|
||||||
{
|
{
|
||||||
Clicked?.Invoke(instances.FirstOrDefault()?.Id);
|
application.Start();
|
||||||
|
}
|
||||||
|
else if (InstanceStackPanel.Children.Count == 1)
|
||||||
|
{
|
||||||
|
single.Activate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -86,12 +88,16 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
|
private void RemoveInstance(TaskbarApplicationInstanceButton button)
|
||||||
{
|
{
|
||||||
Dispatcher.InvokeAsync(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
instances.Remove(instances.FirstOrDefault(i => i.Id == id));
|
InstanceStackPanel.Children.Remove(button);
|
||||||
InstanceStackPanel.Children.Remove(instanceButton);
|
|
||||||
|
if (InstanceStackPanel.Children.Count == 0)
|
||||||
|
{
|
||||||
|
single = default(IApplicationInstance);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="60" Padding="10" Template="{StaticResource TaskbarButton}">
|
<Button x:Name="Button" Background="Transparent" Height="60" Padding="10" Template="{StaticResource TaskbarButton}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
|
<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" />
|
<TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
|
||||||
|
|
|
@ -10,7 +10,6 @@ using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
using SafeExamBrowser.Core.Contracts;
|
using SafeExamBrowser.Core.Contracts;
|
||||||
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
|
||||||
|
@ -20,8 +19,6 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
private IApplicationInfo info;
|
private IApplicationInfo info;
|
||||||
private IApplicationInstance instance;
|
private IApplicationInstance instance;
|
||||||
|
|
||||||
internal event ApplicationControlClickedEventHandler Clicked;
|
|
||||||
|
|
||||||
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
@ -33,12 +30,17 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
|
|
||||||
private void InitializeApplicationInstanceButton()
|
private void InitializeApplicationInstanceButton()
|
||||||
{
|
{
|
||||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
Button.Click += Button_Click;
|
||||||
Text.Text = instance.Name;
|
|
||||||
Button.ToolTip = instance.Name;
|
Button.ToolTip = instance.Name;
|
||||||
|
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||||
instance.IconChanged += Instance_IconChanged;
|
instance.IconChanged += Instance_IconChanged;
|
||||||
instance.NameChanged += Instance_NameChanged;
|
instance.NameChanged += Instance_NameChanged;
|
||||||
|
Text.Text = instance.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
instance.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_IconChanged(IIconResource icon)
|
private void Instance_IconChanged(IIconResource icon)
|
||||||
|
@ -54,10 +56,5 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||||
Button.ToolTip = name;
|
Button.ToolTip = name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
Clicked?.Invoke(instance.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,15 +40,15 @@ namespace SafeExamBrowser.UserInterface.Mobile
|
||||||
return new AboutWindow(appConfig, text);
|
return new AboutWindow(appConfig, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
|
public IApplicationControl CreateApplicationControl(IApplication application, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
{
|
{
|
||||||
return new ActionCenterApplicationControl(info);
|
return new ActionCenterApplicationControl(application);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new TaskbarApplicationControl(info);
|
return new TaskbarApplicationControl(application);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue