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
|
||||
{
|
||||
/// <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>
|
||||
public delegate void InstanceTerminatedEventHandler(InstanceIdentifier id);
|
||||
}
|
||||
|
|
|
@ -6,24 +6,30 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Applications.Contracts.Events;
|
||||
|
||||
namespace SafeExamBrowser.Applications.Contracts
|
||||
{
|
||||
/// <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>
|
||||
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>
|
||||
/// Performs any initialization work, if necessary.
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
|
||||
// TODO
|
||||
///// <summary>
|
||||
///// Registers an application control for this application.
|
||||
///// </summary>
|
||||
//void RegisterApplicationControl(IApplicationControl control);
|
||||
|
||||
/// <summary>
|
||||
/// Starts the execution of the application.
|
||||
/// </summary>
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Applications.Contracts
|
|||
InstanceIdentifier Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name or (document) title of the application instance.
|
||||
/// The name or document title of the application instance.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
|
@ -41,10 +41,9 @@ namespace SafeExamBrowser.Applications.Contracts
|
|||
/// </summary>
|
||||
event NameChangedEventHandler NameChanged;
|
||||
|
||||
// TODO
|
||||
///// <summary>
|
||||
///// The main window of the application instance.
|
||||
///// </summary>
|
||||
//IWindow Window { get; }
|
||||
/// <summary>
|
||||
/// Makes this instance the currently active one and brings it to the foreground.
|
||||
/// </summary>
|
||||
void Activate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,9 +54,10 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Events\IconChangedEventHandler.cs" />
|
||||
<Compile Include="Events\InstanceStartedEventHandler.cs" />
|
||||
<Compile Include="Events\InstanceTerminatedEventHandler.cs" />
|
||||
<Compile Include="Events\NameChangedEventHandler.cs" />
|
||||
<Compile Include="IApplicationController.cs" />
|
||||
<Compile Include="IApplication.cs" />
|
||||
<Compile Include="IApplicationInfo.cs" />
|
||||
<Compile Include="IApplicationInstance.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace SafeExamBrowser.Browser.Contracts
|
|||
/// <summary>
|
||||
/// Controls the lifetime and functionality of the browser application.
|
||||
/// </summary>
|
||||
public interface IBrowserApplicationController : IApplicationController
|
||||
public interface IBrowserApplication : IApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// 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="DownloadFinishedCallback.cs" />
|
||||
<Compile Include="DownloadRequestedEventHandler.cs" />
|
||||
<Compile Include="IBrowserApplicationController.cs" />
|
||||
<Compile Include="IBrowserApplication.cs" />
|
||||
<Compile Include="ProgressChangedEventHandler.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -12,6 +12,7 @@ using System.Linq;
|
|||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Applications.Contracts.Events;
|
||||
using SafeExamBrowser.Browser.Contracts;
|
||||
using SafeExamBrowser.Browser.Events;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
|
@ -20,27 +21,28 @@ using SafeExamBrowser.I18n.Contracts;
|
|||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.BrowserSettings;
|
||||
|
||||
namespace SafeExamBrowser.Browser
|
||||
{
|
||||
public class BrowserApplicationController : IBrowserApplicationController
|
||||
public class BrowserApplication : IBrowserApplication
|
||||
{
|
||||
private int instanceIdCounter = default(int);
|
||||
|
||||
private AppConfig appConfig;
|
||||
private IList<IApplicationControl> controls;
|
||||
private IList<IApplicationInstance> instances;
|
||||
private List<BrowserApplicationInstance> instances;
|
||||
private IMessageBox messageBox;
|
||||
private IModuleLogger logger;
|
||||
private BrowserSettings settings;
|
||||
private IText text;
|
||||
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,
|
||||
BrowserSettings settings,
|
||||
IMessageBox messageBox,
|
||||
|
@ -49,8 +51,7 @@ namespace SafeExamBrowser.Browser
|
|||
IUserInterfaceFactory uiFactory)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.controls = new List<IApplicationControl>();
|
||||
this.instances = new List<IApplicationInstance>();
|
||||
this.instances = new List<BrowserApplicationInstance>();
|
||||
this.logger = logger;
|
||||
this.messageBox = messageBox;
|
||||
this.settings = settings;
|
||||
|
@ -63,20 +64,18 @@ namespace SafeExamBrowser.Browser
|
|||
var cefSettings = InitializeCefSettings();
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterApplicationControl(IApplicationControl control)
|
||||
{
|
||||
control.Clicked += ApplicationControl_Clicked;
|
||||
controls.Add(control);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
CreateNewInstance();
|
||||
|
@ -87,13 +86,11 @@ namespace SafeExamBrowser.Browser
|
|||
foreach (var instance in instances)
|
||||
{
|
||||
instance.Terminated -= Instance_Terminated;
|
||||
// TODO instance.Window.Close();
|
||||
|
||||
instance.Terminate();
|
||||
logger.Info($"Terminated browser instance {instance.Id}.");
|
||||
}
|
||||
|
||||
Cef.Shutdown();
|
||||
|
||||
logger.Info("Terminated browser.");
|
||||
}
|
||||
|
||||
|
@ -105,35 +102,17 @@ namespace SafeExamBrowser.Browser
|
|||
var startUrl = url ?? settings.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.IconChanged += Instance_IconChanged;
|
||||
instance.NameChanged += Instance_NameChanged;
|
||||
instance.PopupRequested += Instance_PopupRequested;
|
||||
instance.Terminated += Instance_Terminated;
|
||||
|
||||
instance.Initialize();
|
||||
instances.Add(instance);
|
||||
instance.Window.Show();
|
||||
InstanceStarted?.Invoke(instance);
|
||||
|
||||
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()
|
||||
{
|
||||
var warning = logger.LogLevel == LogLevel.Warning;
|
||||
|
@ -156,18 +135,6 @@ namespace SafeExamBrowser.Browser
|
|||
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)
|
||||
{
|
||||
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.Browser;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
||||
|
||||
namespace SafeExamBrowser.Browser
|
||||
{
|
||||
|
@ -49,7 +48,6 @@ namespace SafeExamBrowser.Browser
|
|||
|
||||
public InstanceIdentifier Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public IWindow Window { get { return window; } }
|
||||
|
||||
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||
public event IconChangedEventHandler IconChanged;
|
||||
|
@ -80,6 +78,11 @@ namespace SafeExamBrowser.Browser
|
|||
this.url = url;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
window?.BringToForeground();
|
||||
}
|
||||
|
||||
internal void Initialize()
|
||||
{
|
||||
var contextMenuHandler = new ContextMenuHandler();
|
||||
|
@ -118,10 +121,16 @@ namespace SafeExamBrowser.Browser
|
|||
window.ZoomOutRequested += ZoomOutRequested;
|
||||
window.ZoomResetRequested += ZoomResetRequested;
|
||||
window.UpdateZoomLevel(CalculateZoomPercentage());
|
||||
window.Show();
|
||||
|
||||
logger.Debug("Initialized browser window.");
|
||||
}
|
||||
|
||||
internal void Terminate()
|
||||
{
|
||||
window?.Close();
|
||||
}
|
||||
|
||||
private void Control_AddressChanged(string address)
|
||||
{
|
||||
logger.Debug($"Navigated to '{address}'.");
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<Reference Include="Microsoft.CSharp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BrowserApplicationController.cs" />
|
||||
<Compile Include="BrowserApplication.cs" />
|
||||
<Compile Include="BrowserApplicationInfo.cs" />
|
||||
<Compile Include="BrowserApplicationInstance.cs" />
|
||||
<Compile Include="BrowserInstanceIdentifier.cs" />
|
||||
|
|
|
@ -25,9 +25,9 @@ namespace SafeExamBrowser.Client.Contracts
|
|||
AppConfig AppConfig { set; }
|
||||
|
||||
/// <summary>
|
||||
/// The controller for the browser application.
|
||||
/// The browser application.
|
||||
/// </summary>
|
||||
IBrowserApplicationController Browser { set; }
|
||||
IBrowserApplication Browser { set; }
|
||||
|
||||
/// <summary>
|
||||
/// The client host used for communication handling.
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace SafeExamBrowser.Client.UnitTests
|
|||
{
|
||||
private AppConfig appConfig;
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private Mock<IBrowserApplicationController> browserController;
|
||||
private Mock<IBrowserApplication> browserController;
|
||||
private Mock<IClientHost> clientHost;
|
||||
private Mock<IDisplayMonitor> displayMonitor;
|
||||
private Mock<IExplorerShell> explorerShell;
|
||||
|
@ -61,7 +61,7 @@ namespace SafeExamBrowser.Client.UnitTests
|
|||
{
|
||||
appConfig = new AppConfig();
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
browserController = new Mock<IBrowserApplicationController>();
|
||||
browserController = new Mock<IBrowserApplication>();
|
||||
clientHost = new Mock<IClientHost>();
|
||||
displayMonitor = new Mock<IDisplayMonitor>();
|
||||
explorerShell = new Mock<IExplorerShell>();
|
||||
|
|
|
@ -20,8 +20,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
public class BrowserOperationTests
|
||||
{
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private Mock<IApplicationController> controller;
|
||||
private Mock<IApplicationInfo> appInfo;
|
||||
private Mock<IApplication> application;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<ITaskbar> taskbar;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
|
@ -32,13 +31,12 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
public void Initialize()
|
||||
{
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
controller = new Mock<IApplicationController>();
|
||||
appInfo = new Mock<IApplicationInfo>();
|
||||
application = new Mock<IApplication>();
|
||||
logger = new Mock<ILogger>();
|
||||
taskbar = new Mock<ITaskbar>();
|
||||
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]
|
||||
|
@ -46,7 +44,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
{
|
||||
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));
|
||||
actionCenter.Verify(a => a.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()
|
||||
{
|
||||
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 AppConfig appConfig;
|
||||
|
||||
public IBrowserApplicationController Browser { private get; set; }
|
||||
public IBrowserApplication Browser { private get; set; }
|
||||
public IClientHost ClientHost { private get; set; }
|
||||
public Guid SessionId { private get; set; }
|
||||
public Settings Settings { private get; set; }
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Client
|
|||
private UserInterfaceMode uiMode;
|
||||
|
||||
private IActionCenter actionCenter;
|
||||
private IBrowserApplicationController browserController;
|
||||
private IBrowserApplication browser;
|
||||
private IClientHost clientHost;
|
||||
private ILogger logger;
|
||||
private IMessageBox messageBox;
|
||||
|
@ -199,11 +199,11 @@ namespace SafeExamBrowser.Client
|
|||
private IOperation BuildBrowserOperation()
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ namespace SafeExamBrowser.Client
|
|||
|
||||
private void UpdateClientControllerDependencies()
|
||||
{
|
||||
ClientController.Browser = browserController;
|
||||
ClientController.Browser = browser;
|
||||
ClientController.ClientHost = clientHost;
|
||||
ClientController.SessionId = configuration.SessionId;
|
||||
ClientController.Settings = configuration.Settings;
|
||||
|
|
|
@ -19,8 +19,7 @@ namespace SafeExamBrowser.Client.Operations
|
|||
internal class BrowserOperation : IOperation
|
||||
{
|
||||
private IActionCenter actionCenter;
|
||||
private IApplicationController browserController;
|
||||
private IApplicationInfo browserInfo;
|
||||
private IApplication browser;
|
||||
private ILogger logger;
|
||||
private ITaskbar taskbar;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
@ -30,15 +29,13 @@ namespace SafeExamBrowser.Client.Operations
|
|||
|
||||
public BrowserOperation(
|
||||
IActionCenter actionCenter,
|
||||
IApplicationController browserController,
|
||||
IApplicationInfo browserInfo,
|
||||
IApplication browser,
|
||||
ILogger logger,
|
||||
ITaskbar taskbar,
|
||||
IUserInterfaceFactory uiFactory)
|
||||
{
|
||||
this.actionCenter = actionCenter;
|
||||
this.browserController = browserController;
|
||||
this.browserInfo = browserInfo;
|
||||
this.browser = browser;
|
||||
this.logger = logger;
|
||||
this.taskbar = taskbar;
|
||||
this.uiFactory = uiFactory;
|
||||
|
@ -49,16 +46,10 @@ namespace SafeExamBrowser.Client.Operations
|
|||
logger.Info("Initializing browser...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
|
||||
|
||||
var actionCenterControl = uiFactory.CreateApplicationControl(browserInfo, Location.ActionCenter);
|
||||
var taskbarControl = uiFactory.CreateApplicationControl(browserInfo, Location.Taskbar);
|
||||
browser.Initialize();
|
||||
|
||||
browserController.Initialize();
|
||||
// TODO
|
||||
//browserController.RegisterApplicationControl(actionCenterControl);
|
||||
//browserController.RegisterApplicationControl(taskbarControl);
|
||||
|
||||
actionCenter.AddApplicationControl(actionCenterControl);
|
||||
taskbar.AddApplicationControl(taskbarControl);
|
||||
actionCenter.AddApplicationControl(uiFactory.CreateApplicationControl(browser, Location.ActionCenter));
|
||||
taskbar.AddApplicationControl(uiFactory.CreateApplicationControl(browser, Location.Taskbar));
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
@ -68,7 +59,7 @@ namespace SafeExamBrowser.Client.Operations
|
|||
logger.Info("Terminating browser...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateBrowser);
|
||||
|
||||
browserController.Terminate();
|
||||
browser.Terminate();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace SafeExamBrowser.UserInterface.Contracts
|
|||
IWindow CreateAboutWindow(AppConfig appConfig);
|
||||
|
||||
/// <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>
|
||||
IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location);
|
||||
IApplicationControl CreateApplicationControl(IApplication application, Location location);
|
||||
|
||||
/// <summary>
|
||||
/// 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/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -15,10 +13,5 @@ namespace SafeExamBrowser.UserInterface.Contracts.Shell
|
|||
/// </summary>
|
||||
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>
|
||||
</UserControl.Resources>
|
||||
<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">
|
||||
<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" />
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||
|
@ -20,7 +19,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
private IApplicationInfo info;
|
||||
private IApplicationInstance instance;
|
||||
|
||||
internal event ApplicationControlClickedEventHandler Clicked;
|
||||
internal event EventHandler Clicked;
|
||||
|
||||
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
||||
{
|
||||
|
@ -35,6 +34,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
{
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
Text.Text = instance?.Name ?? info.Name;
|
||||
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
|
||||
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
||||
|
||||
if (instance != null)
|
||||
|
@ -51,16 +51,11 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
|
||||
private void Instance_NameChanged(string name)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
Text.Text = 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.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||
{
|
||||
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IApplication application;
|
||||
|
||||
public event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public ActionCenterApplicationControl(IApplicationInfo info)
|
||||
public ActionCenterApplicationControl(IApplication application)
|
||||
{
|
||||
this.info = info;
|
||||
this.application = application;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeApplicationControl(info);
|
||||
InitializeApplicationControl();
|
||||
}
|
||||
|
||||
public void RegisterInstance(IApplicationInstance instance)
|
||||
private void InitializeApplicationControl()
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var button = new ActionCenterApplicationButton(info, instance);
|
||||
var button = new ActionCenterApplicationButton(application.Info);
|
||||
|
||||
button.Clicked += (id) => Clicked?.Invoke(id);
|
||||
instance.Terminated += (id) => Instance_OnTerminated(id, button);
|
||||
application.InstanceStarted += Application_InstanceStarted;
|
||||
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);
|
||||
|
||||
ApplicationName.Visibility = Visibility.Visible;
|
||||
|
@ -44,16 +50,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
});
|
||||
}
|
||||
|
||||
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)
|
||||
private void RemoveInstance(ActionCenterApplicationButton button)
|
||||
{
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
|
|
|
@ -6,59 +6,41 @@
|
|||
* 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.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||
{
|
||||
public partial class TaskbarApplicationControl : UserControl, IApplicationControl
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
|
||||
private IApplication application;
|
||||
private IApplicationInstance single;
|
||||
|
||||
public event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public TaskbarApplicationControl(IApplicationInfo info)
|
||||
public TaskbarApplicationControl(IApplication application)
|
||||
{
|
||||
this.info = info;
|
||||
this.application = application;
|
||||
|
||||
InitializeComponent();
|
||||
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()
|
||||
{
|
||||
var originalBrush = Button.Background;
|
||||
|
||||
Button.ToolTip = info.Tooltip;
|
||||
Button.Content = IconResourceLoader.Load(info.IconResource);
|
||||
application.InstanceStarted += Application_InstanceStarted;
|
||||
|
||||
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.ToolTip = application.Info.Tooltip;
|
||||
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -86,12 +88,16 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
|
||||
private void RemoveInstance(TaskbarApplicationInstanceButton button)
|
||||
{
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
instances.Remove(instances.FirstOrDefault(i => i.Id == id));
|
||||
InstanceStackPanel.Children.Remove(instanceButton);
|
||||
InstanceStackPanel.Children.Remove(button);
|
||||
|
||||
if (InstanceStackPanel.Children.Count == 0)
|
||||
{
|
||||
single = default(IApplicationInstance);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<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">
|
||||
<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" />
|
||||
|
|
|
@ -10,7 +10,6 @@ using System.Windows;
|
|||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||
|
@ -20,8 +19,6 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
private IApplicationInfo info;
|
||||
private IApplicationInstance instance;
|
||||
|
||||
internal event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
|
@ -33,12 +30,17 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
|
||||
private void InitializeApplicationInstanceButton()
|
||||
{
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
Text.Text = instance.Name;
|
||||
Button.Click += Button_Click;
|
||||
Button.ToolTip = instance.Name;
|
||||
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
instance.IconChanged += Instance_IconChanged;
|
||||
instance.NameChanged += Instance_NameChanged;
|
||||
Text.Text = instance.Name;
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
instance.Activate();
|
||||
}
|
||||
|
||||
private void Instance_IconChanged(IIconResource icon)
|
||||
|
@ -54,10 +56,5 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
|||
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);
|
||||
}
|
||||
|
||||
public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
|
||||
public IApplicationControl CreateApplicationControl(IApplication application, Location location)
|
||||
{
|
||||
if (location == Location.ActionCenter)
|
||||
{
|
||||
return new ActionCenterApplicationControl(info);
|
||||
return new ActionCenterApplicationControl(application);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TaskbarApplicationControl(info);
|
||||
return new TaskbarApplicationControl(application);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<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">
|
||||
<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" />
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||
|
@ -20,7 +19,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
private IApplicationInfo info;
|
||||
private IApplicationInstance instance;
|
||||
|
||||
internal event ApplicationControlClickedEventHandler Clicked;
|
||||
internal event EventHandler Clicked;
|
||||
|
||||
public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
|
||||
{
|
||||
|
@ -35,6 +34,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
{
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
Text.Text = instance?.Name ?? info.Name;
|
||||
Button.Click += (o, args) => Clicked?.Invoke(this, EventArgs.Empty);
|
||||
Button.ToolTip = instance?.Name ?? info.Tooltip;
|
||||
|
||||
if (instance != null)
|
||||
|
@ -51,16 +51,11 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
|
||||
private void Instance_NameChanged(string name)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
Text.Text = 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.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||
{
|
||||
public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IApplication application;
|
||||
|
||||
public event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public ActionCenterApplicationControl(IApplicationInfo info)
|
||||
public ActionCenterApplicationControl(IApplication application)
|
||||
{
|
||||
this.info = info;
|
||||
this.application = application;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeApplicationControl(info);
|
||||
InitializeApplicationControl();
|
||||
}
|
||||
|
||||
public void RegisterInstance(IApplicationInstance instance)
|
||||
private void InitializeApplicationControl()
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var button = new ActionCenterApplicationButton(info, instance);
|
||||
var button = new ActionCenterApplicationButton(application.Info);
|
||||
|
||||
button.Clicked += (id) => Clicked?.Invoke(id);
|
||||
instance.Terminated += (id) => Instance_OnTerminated(id, button);
|
||||
application.InstanceStarted += Application_InstanceStarted;
|
||||
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);
|
||||
|
||||
ApplicationName.Visibility = Visibility.Visible;
|
||||
|
@ -44,16 +50,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
});
|
||||
}
|
||||
|
||||
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)
|
||||
private void RemoveInstance(ActionCenterApplicationButton button)
|
||||
{
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
|
|
|
@ -6,59 +6,41 @@
|
|||
* 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.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||
{
|
||||
public partial class TaskbarApplicationControl : UserControl, IApplicationControl
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
|
||||
private IApplication application;
|
||||
private IApplicationInstance single;
|
||||
|
||||
public event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public TaskbarApplicationControl(IApplicationInfo info)
|
||||
public TaskbarApplicationControl(IApplication application)
|
||||
{
|
||||
this.info = info;
|
||||
this.application = application;
|
||||
|
||||
InitializeComponent();
|
||||
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()
|
||||
{
|
||||
var originalBrush = Button.Background;
|
||||
|
||||
Button.ToolTip = info.Tooltip;
|
||||
Button.Content = IconResourceLoader.Load(info.IconResource);
|
||||
application.InstanceStarted += Application_InstanceStarted;
|
||||
|
||||
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.ToolTip = application.Info.Tooltip;
|
||||
InstancePopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => InstancePopup.IsOpen = IsMouseOver));
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -86,12 +88,16 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
|
||||
private void RemoveInstance(TaskbarApplicationInstanceButton button)
|
||||
{
|
||||
Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
instances.Remove(instances.FirstOrDefault(i => i.Id == id));
|
||||
InstanceStackPanel.Children.Remove(instanceButton);
|
||||
InstanceStackPanel.Children.Remove(button);
|
||||
|
||||
if (InstanceStackPanel.Children.Count == 0)
|
||||
{
|
||||
single = default(IApplicationInstance);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<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">
|
||||
<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" />
|
||||
|
|
|
@ -10,7 +10,6 @@ using System.Windows;
|
|||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
|
||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
||||
|
@ -20,8 +19,6 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
private IApplicationInfo info;
|
||||
private IApplicationInstance instance;
|
||||
|
||||
internal event ApplicationControlClickedEventHandler Clicked;
|
||||
|
||||
public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
|
@ -33,12 +30,17 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
|
||||
private void InitializeApplicationInstanceButton()
|
||||
{
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
Text.Text = instance.Name;
|
||||
Button.Click += Button_Click;
|
||||
Button.ToolTip = instance.Name;
|
||||
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
instance.IconChanged += Instance_IconChanged;
|
||||
instance.NameChanged += Instance_NameChanged;
|
||||
Text.Text = instance.Name;
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
instance.Activate();
|
||||
}
|
||||
|
||||
private void Instance_IconChanged(IIconResource icon)
|
||||
|
@ -54,10 +56,5 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls
|
|||
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);
|
||||
}
|
||||
|
||||
public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
|
||||
public IApplicationControl CreateApplicationControl(IApplication application, Location location)
|
||||
{
|
||||
if (location == Location.ActionCenter)
|
||||
{
|
||||
return new ActionCenterApplicationControl(info);
|
||||
return new ActionCenterApplicationControl(application);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TaskbarApplicationControl(info);
|
||||
return new TaskbarApplicationControl(application);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue