SEBWIN-223, SEBWIN-224: Implemented user interface and browser configuration mapping.
This commit is contained in:
parent
b4839641d4
commit
704aea3a45
59 changed files with 224 additions and 2204 deletions
|
@ -116,7 +116,8 @@ namespace SafeExamBrowser.Browser
|
|||
{
|
||||
CachePath = appConfig.BrowserCachePath,
|
||||
LogFile = appConfig.BrowserLogFile,
|
||||
LogSeverity = error ? LogSeverity.Error : (warning ? LogSeverity.Warning : LogSeverity.Info)
|
||||
LogSeverity = error ? LogSeverity.Error : (warning ? LogSeverity.Warning : LogSeverity.Info),
|
||||
UserAgent = settings.UseCustomUserAgent ? settings.CustomUserAgent : string.Empty
|
||||
};
|
||||
|
||||
logger.Debug($"CEF cache path is '{cefSettings.CachePath}'.");
|
||||
|
|
|
@ -65,12 +65,11 @@ namespace SafeExamBrowser.Browser
|
|||
|
||||
downloadHandler.ConfigurationDownloadRequested += DownloadHandler_ConfigurationDownloadRequested;
|
||||
|
||||
control = new BrowserControl(appConfig, settings, controlLogger, text);
|
||||
control = new BrowserControl(appConfig, settings, downloadHandler, controlLogger, text);
|
||||
control.AddressChanged += Control_AddressChanged;
|
||||
control.LoadingStateChanged += Control_LoadingStateChanged;
|
||||
control.TitleChanged += Control_TitleChanged;
|
||||
(control as BrowserControl).DownloadHandler = downloadHandler;
|
||||
(control as BrowserControl).Initialize();
|
||||
control.Initialize();
|
||||
|
||||
logger.Debug("Initialized browser control.");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace SafeExamBrowser.Browser
|
|||
{
|
||||
private AppConfig appConfig;
|
||||
private BrowserSettings settings;
|
||||
private IDownloadHandler downloadHandler;
|
||||
private ILogger logger;
|
||||
private IText text;
|
||||
|
||||
|
@ -48,9 +49,15 @@ namespace SafeExamBrowser.Browser
|
|||
remove { titleChanged -= value; }
|
||||
}
|
||||
|
||||
public BrowserControl(AppConfig appConfig, BrowserSettings settings, ILogger logger, IText text) : base(settings.StartUrl)
|
||||
public BrowserControl(
|
||||
AppConfig appConfig,
|
||||
BrowserSettings settings,
|
||||
IDownloadHandler downloadHandler,
|
||||
ILogger logger,
|
||||
IText text) : base(settings.StartUrl)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.downloadHandler = downloadHandler;
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
this.text = text;
|
||||
|
@ -62,6 +69,7 @@ namespace SafeExamBrowser.Browser
|
|||
LoadingStateChanged += (o, args) => loadingStateChanged?.Invoke(args.IsLoading);
|
||||
TitleChanged += (o, args) => titleChanged?.Invoke(args.Title);
|
||||
|
||||
DownloadHandler = downloadHandler;
|
||||
KeyboardHandler = new KeyboardHandler(settings);
|
||||
MenuHandler = new ContextMenuHandler(settings, text);
|
||||
RequestHandler = new RequestHandler(appConfig);
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace SafeExamBrowser.Client.Operations
|
|||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeTaskbar);
|
||||
|
||||
AddAboutNotification();
|
||||
taskbar.ShowClock = settings.ShowClock;
|
||||
|
||||
if (settings.AllowApplicationLog)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||
{
|
||||
internal partial class DataMapper
|
||||
{
|
||||
private void MapMainWindowMode(Settings settings, object value)
|
||||
{
|
||||
const int FULLSCREEN = 1;
|
||||
|
||||
if (value is int mode)
|
||||
{
|
||||
settings.Browser.FullScreenMode = mode == FULLSCREEN;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapUserAgentMode(IDictionary<string, object> rawData, Settings settings)
|
||||
{
|
||||
const int DEFAULT = 0;
|
||||
|
||||
var useCustomForDesktop = rawData.TryGetValue(Keys.Browser.UserAgentModeDesktop, out var value) && value as int? != DEFAULT;
|
||||
var useCustomForMobile = rawData.TryGetValue(Keys.Browser.UserAgentModeMobile, out value) && value as int? != DEFAULT;
|
||||
|
||||
if (settings.UserInterfaceMode == UserInterfaceMode.Desktop && useCustomForDesktop)
|
||||
{
|
||||
settings.Browser.UseCustomUserAgent = true;
|
||||
settings.Browser.CustomUserAgent = rawData[Keys.Browser.CustomUserAgentDesktop] as string;
|
||||
}
|
||||
else if (settings.UserInterfaceMode == UserInterfaceMode.Mobile && useCustomForMobile)
|
||||
{
|
||||
settings.Browser.UseCustomUserAgent = true;
|
||||
settings.Browser.CustomUserAgent = rawData[Keys.Browser.CustomUserAgentMobile] as string;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapZoomMode(Settings settings, object value)
|
||||
{
|
||||
const int PAGE = 0;
|
||||
|
||||
if (value is int mode)
|
||||
{
|
||||
// TODO: settings.Browser.ZoomMode = mode == PAGE ? BrowserZoomMode.Page : BrowserZoomMode.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||
{
|
||||
internal partial class DataMapper
|
||||
{
|
||||
private void MapClock(Settings settings, object value)
|
||||
{
|
||||
if (value is bool show)
|
||||
{
|
||||
settings.Taskbar.ShowClock = show;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapKeyboardLayout(Settings settings, object value)
|
||||
{
|
||||
if (value is bool enabled)
|
||||
{
|
||||
settings.Taskbar.AllowKeyboardLayout = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapWirelessNetwork(Settings settings, object value)
|
||||
{
|
||||
if (value is bool enabled)
|
||||
{
|
||||
settings.Taskbar.AllowWirelessNetwork = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapUserInterfaceMode(Settings settings, object value)
|
||||
{
|
||||
if (value is bool mobile)
|
||||
{
|
||||
settings.UserInterfaceMode = mobile ? UserInterfaceMode.Mobile : UserInterfaceMode.Desktop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,12 +19,26 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
{
|
||||
Map(item.Key, item.Value, settings);
|
||||
}
|
||||
|
||||
MapUserAgentMode(rawData, settings);
|
||||
}
|
||||
|
||||
private void Map(string key, object value, Settings settings)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Keys.Browser.EnablePageZoom:
|
||||
// TODO: MapPageZoom(settings, value);
|
||||
break;
|
||||
case Keys.Browser.EnableTextZoom:
|
||||
// TODO: MapTextZoom(settings, value);
|
||||
break;
|
||||
case Keys.Browser.MainWindowMode:
|
||||
MapMainWindowMode(settings, value);
|
||||
break;
|
||||
case Keys.Browser.ZoomMode:
|
||||
MapZoomMode(settings, value);
|
||||
break;
|
||||
case Keys.ConfigurationFile.ConfigurationPurpose:
|
||||
MapConfigurationMode(settings, value);
|
||||
break;
|
||||
|
@ -97,6 +111,18 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
case Keys.Input.Mouse.EnableRightMouse:
|
||||
MapEnableRightMouse(settings, value);
|
||||
break;
|
||||
case Keys.UserInterface.ShowClock:
|
||||
MapClock(settings, value);
|
||||
break;
|
||||
case Keys.UserInterface.AllowKeyboardLayout:
|
||||
MapKeyboardLayout(settings, value);
|
||||
break;
|
||||
case Keys.UserInterface.AllowWirelessNetwork:
|
||||
MapWirelessNetwork(settings, value);
|
||||
break;
|
||||
case Keys.UserInterface.UserInterfaceMode:
|
||||
MapUserInterfaceMode(settings, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
settings.Taskbar.AllowApplicationLog = false;
|
||||
settings.Taskbar.AllowKeyboardLayout = true;
|
||||
settings.Taskbar.AllowWirelessNetwork = false;
|
||||
settings.Taskbar.ShowClock = true;
|
||||
|
||||
// TODO: Default values for alpha version only, remove for final release!
|
||||
settings.Browser.AllowAddressBar = true;
|
||||
|
|
|
@ -20,6 +20,14 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
|
||||
internal static class Browser
|
||||
{
|
||||
internal const string CustomUserAgentDesktop = "browserUserAgentWinDesktopModeCustom";
|
||||
internal const string CustomUserAgentMobile = "browserUserAgentWinTouchModeCustom";
|
||||
internal const string EnablePageZoom = "enableZoomPage";
|
||||
internal const string EnableTextZoom = "enableZoomText";
|
||||
internal const string MainWindowMode = "browserViewMode";
|
||||
internal const string UserAgentModeDesktop = "browserUserAgentWinDesktopMode";
|
||||
internal const string UserAgentModeMobile = "browserUserAgentWinTouchMode";
|
||||
internal const string ZoomMode = "zoomMode";
|
||||
}
|
||||
|
||||
internal static class ConfigurationFile
|
||||
|
@ -90,6 +98,10 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
|
||||
internal static class UserInterface
|
||||
{
|
||||
internal const string AllowKeyboardLayout = "showInputLanguage";
|
||||
internal const string AllowWirelessNetwork = "allowWlan";
|
||||
internal const string ShowClock = "showTime";
|
||||
internal const string UserInterfaceMode = "touchOptimized";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
<Compile Include="DataFormats\BinarySerializer.cs" />
|
||||
<Compile Include="DataFormats\BinaryBlock.cs" />
|
||||
<Compile Include="ConfigurationData\DataMapper.cs" />
|
||||
<Compile Include="ConfigurationData\DataMapper.Browser.cs">
|
||||
<DependentUpon>DataMapper.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ConfigurationData\DataMapper.ConfigurationFile.cs">
|
||||
<DependentUpon>DataMapper.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -78,6 +81,9 @@
|
|||
<Compile Include="ConfigurationData\DataMapper.Input.cs">
|
||||
<DependentUpon>DataMapper.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ConfigurationData\DataMapper.UserInterface.cs">
|
||||
<DependentUpon>DataMapper.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Cryptography\HashAlgorithm.cs" />
|
||||
<Compile Include="DataFormats\XmlElement.cs" />
|
||||
<Compile Include="DataFormats\XmlParser.cs" />
|
||||
|
|
|
@ -51,6 +51,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
/// </summary>
|
||||
public bool AllowReloading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The custom user agent to optionally be used for all requests.
|
||||
/// </summary>
|
||||
public string CustomUserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the main browser window should be rendered in fullscreen mode, i.e. without window frame.
|
||||
/// </summary>
|
||||
|
@ -60,5 +65,10 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
/// The start URL with which a new browser window should be loaded.
|
||||
/// </summary>
|
||||
public string StartUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a custom user agent should be used for all requests, see <see cref="CustomUserAgent"/>.
|
||||
/// </summary>
|
||||
public bool UseCustomUserAgent { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
/// </summary>
|
||||
public TaskbarSettings Taskbar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The mode which determines the look & feel of the user interface.
|
||||
/// </summary>
|
||||
public UserInterfaceMode UserInterfaceMode { get; set; }
|
||||
|
||||
public Settings()
|
||||
{
|
||||
Browser = new BrowserSettings();
|
||||
|
|
|
@ -30,5 +30,10 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
/// Determines whether the user may control the wireless network connection during runtime.
|
||||
/// </summary>
|
||||
public bool AllowWirelessNetwork { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current date and time will be rendered in the taskbar.
|
||||
/// </summary>
|
||||
public bool ShowClock { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Configuration.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines all possible look & feel options for the application.
|
||||
/// </summary>
|
||||
public enum UserInterfaceMode
|
||||
{
|
||||
/// <summary>
|
||||
/// In this mode, the user interface is optimized for desktop computers with keyboard and mouse.
|
||||
/// </summary>
|
||||
Desktop,
|
||||
|
||||
/// <summary>
|
||||
/// In this mode, the user interface is optimized for mobile computers with touch capability.
|
||||
/// </summary>
|
||||
Mobile
|
||||
}
|
||||
}
|
|
@ -70,6 +70,7 @@
|
|||
<Compile Include="Configuration\DataResources\IResourceLoader.cs" />
|
||||
<Compile Include="Configuration\DataResources\IResourceSaver.cs" />
|
||||
<Compile Include="Configuration\SaveStatus.cs" />
|
||||
<Compile Include="Configuration\Settings\UserInterfaceMode.cs" />
|
||||
<Compile Include="Core\Events\InstanceTerminatedEventHandler.cs" />
|
||||
<Compile Include="Core\Events\NameChangedEventHandler.cs" />
|
||||
<Compile Include="Core\IApplicationController.cs" />
|
||||
|
|
|
@ -31,6 +31,11 @@ namespace SafeExamBrowser.Contracts.UserInterface.Browser
|
|||
/// </summary>
|
||||
event TitleChangedEventHandler TitleChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the browser control.
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to the previous page in the browser control history.
|
||||
/// </summary>
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
|
|||
/// </summary>
|
||||
public interface ITaskbar
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls the visibility of the clock.
|
||||
/// </summary>
|
||||
bool ShowClock { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the user clicked the quit button in the taskbar.
|
||||
/// </summary>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</ScrollViewer>
|
||||
<StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<StackPanel Grid.Column="2" x:Name="SystemControlStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<local:DateTimeControl Grid.Column="3" Foreground="DimGray" Padding="10,0,10,0" />
|
||||
<local:DateTimeControl Grid.Column="3" x:Name="Clock" Foreground="DimGray" Padding="10,0,10,0" />
|
||||
<local:QuitButton Grid.Column="4" x:Name="QuitButton" />
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
@ -20,6 +20,11 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
private bool allowClose;
|
||||
private ILogger logger;
|
||||
|
||||
public bool ShowClock
|
||||
{
|
||||
set { Dispatcher.Invoke(() => Clock.Visibility = value ? Visibility.Visible : Visibility.Collapsed); }
|
||||
}
|
||||
|
||||
public event QuitButtonClickedEventHandler QuitButtonClicked;
|
||||
|
||||
public Taskbar(ILogger logger)
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<Window x:Class="SafeExamBrowser.UserInterface.Windows10.AboutWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10"
|
||||
mc:Ignorable="d"
|
||||
Title="About Safe Exam Browser" Height="350" Width="450" ResizeMode="NoResize" Icon="./Images/SafeExamBrowser.ico"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterScreen">
|
||||
<Window.Background>
|
||||
<SolidColorBrush Color="Black" Opacity="0.8" />
|
||||
</Window.Background>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Windows10;component/Images/SplashScreen.png" Margin="0,5,0,0" />
|
||||
<TextBlock x:Name="VersionInfo" Grid.Row="0" Grid.Column="1" Foreground="DarkGray" Margin="25,70,50,10" TextWrapping="Wrap" />
|
||||
<ScrollViewer Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="MainText" Foreground="White" Margin="10" FontSize="10" TextWrapping="Wrap">
|
||||
This application is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this application, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
<Bold><Underline>CefSharp (.NET bindings for the Chromium Embedded Framework)</Underline></Bold>
|
||||
<LineBreak />
|
||||
Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
<Bold><Underline>CEF (Chromium Embedded Framework)</Underline></Bold>
|
||||
<LineBreak />
|
||||
Copyright © 2008-2014 Marshall A. Greenblatt. Portions Copyright © 2006-2009 Google Inc. All rights reserved.
|
||||
</TextBlock>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Windows;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public partial class AboutWindow : Window, IWindow
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private IText text;
|
||||
private WindowClosingEventHandler closing;
|
||||
|
||||
event WindowClosingEventHandler IWindow.Closing
|
||||
{
|
||||
add { closing += value; }
|
||||
remove { closing -= value; }
|
||||
}
|
||||
|
||||
public AboutWindow(AppConfig appConfig, IText text)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.text = text;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeAboutWindow();
|
||||
}
|
||||
|
||||
public void BringToForeground()
|
||||
{
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void InitializeAboutWindow()
|
||||
{
|
||||
Closing += (o, args) => closing?.Invoke();
|
||||
VersionInfo.Inlines.Add(new Run($"{text.Get(TextKey.Version)} {appConfig.ProgramVersion}") { FontStyle = FontStyles.Italic });
|
||||
VersionInfo.Inlines.Add(new LineBreak());
|
||||
VersionInfo.Inlines.Add(new LineBreak());
|
||||
VersionInfo.Inlines.Add(new Run(appConfig.ProgramCopyright) { FontSize = 10 });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<Window x:Class="SafeExamBrowser.UserInterface.Windows10.BrowserWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10"
|
||||
mc:Ignorable="d"
|
||||
Title="BrowserWindow" Height="500" Width="500" WindowState="Maximized" Icon=".\Images\Chromium.ico">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0" x:Name="UrlTextBox" Margin="5,5,2.5,5" Height="20" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" />
|
||||
<Button Grid.Column="1" x:Name="ReloadButton" Margin="2.5,5,2.5,5" HorizontalAlignment="Center" VerticalAlignment="Center">Reload</Button>
|
||||
<Button Grid.Column="2" x:Name="BackButton" Margin="2.5,5,2.5,5" HorizontalAlignment="Center" VerticalAlignment="Center">Back</Button>
|
||||
<Button Grid.Column="3" x:Name="ForwardButton" Margin="2.5,5,5,5" HorizontalAlignment="Center" VerticalAlignment="Center">Forward</Button>
|
||||
</Grid>
|
||||
<WindowsFormsHost Grid.Row="1" x:Name="BrowserControlHost" />
|
||||
</Grid>
|
||||
</Window>
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public partial class BrowserWindow : Window // TODO, IBrowserWindow
|
||||
{
|
||||
//private bool isMainWindow;
|
||||
//private BrowserSettings settings;
|
||||
//public WindowClosingEventHandler closing;
|
||||
|
||||
//public bool IsMainWindow
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return isMainWindow;
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// isMainWindow = value;
|
||||
// ApplySettings();
|
||||
// }
|
||||
//}
|
||||
|
||||
//public event AddressChangedEventHandler AddressChanged;
|
||||
//public event ActionRequestedEventHandler BackwardNavigationRequested;
|
||||
//public event ActionRequestedEventHandler ForwardNavigationRequested;
|
||||
//public event ActionRequestedEventHandler ReloadRequested;
|
||||
|
||||
//event WindowClosingEventHandler IWindow.Closing
|
||||
//{
|
||||
// add { closing += value; }
|
||||
// remove { closing -= value; }
|
||||
//}
|
||||
|
||||
//public BrowserWindow(IBrowserControl browserControl, BrowserSettings settings)
|
||||
//{
|
||||
// this.settings = settings;
|
||||
|
||||
// InitializeComponent();
|
||||
// InitializeBrowserWindow(browserControl);
|
||||
//}
|
||||
|
||||
//public void BringToForeground()
|
||||
//{
|
||||
// Dispatcher.Invoke(() =>
|
||||
// {
|
||||
// if (WindowState == WindowState.Minimized)
|
||||
// {
|
||||
// WindowState = WindowState.Normal;
|
||||
// }
|
||||
|
||||
// Activate();
|
||||
// });
|
||||
//}
|
||||
|
||||
//public new void Close()
|
||||
//{
|
||||
// Dispatcher.Invoke(base.Close);
|
||||
//}
|
||||
|
||||
//public new void Hide()
|
||||
//{
|
||||
// Dispatcher.Invoke(base.Hide);
|
||||
//}
|
||||
|
||||
//public new void Show()
|
||||
//{
|
||||
// Dispatcher.Invoke(base.Show);
|
||||
//}
|
||||
|
||||
//public void UpdateAddress(string url)
|
||||
//{
|
||||
// Dispatcher.Invoke(() => UrlTextBox.Text = url);
|
||||
//}
|
||||
|
||||
//public void UpdateTitle(string title)
|
||||
//{
|
||||
// Dispatcher.Invoke(() => Title = title);
|
||||
//}
|
||||
|
||||
//private void InitializeBrowserWindow(IBrowserControl browserControl)
|
||||
//{
|
||||
// if (browserControl is System.Windows.Forms.Control control)
|
||||
// {
|
||||
// BrowserControlHost.Child = control;
|
||||
// }
|
||||
|
||||
// Closing += (o, args) => closing?.Invoke();
|
||||
// KeyUp += BrowserWindow_KeyUp;
|
||||
// UrlTextBox.KeyUp += UrlTextBox_KeyUp;
|
||||
// ReloadButton.Click += (o, args) => ReloadRequested?.Invoke();
|
||||
// BackButton.Click += (o, args) => BackwardNavigationRequested?.Invoke();
|
||||
// ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
|
||||
|
||||
// ApplySettings();
|
||||
//}
|
||||
|
||||
//private void BrowserWindow_KeyUp(object sender, KeyEventArgs e)
|
||||
//{
|
||||
// if (e.Key == Key.F5)
|
||||
// {
|
||||
// ReloadRequested?.Invoke();
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void UrlTextBox_KeyUp(object sender, KeyEventArgs e)
|
||||
//{
|
||||
// if (e.Key == Key.Enter)
|
||||
// {
|
||||
// AddressChanged?.Invoke(UrlTextBox.Text);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void ApplySettings()
|
||||
//{
|
||||
// if (IsMainWindow && settings.FullScreenMode)
|
||||
// {
|
||||
// MaxHeight = SystemParameters.WorkArea.Height;
|
||||
// ResizeMode = ResizeMode.NoResize;
|
||||
// WindowState = WindowState.Maximized;
|
||||
// WindowStyle = WindowStyle.None;
|
||||
// }
|
||||
|
||||
// UrlTextBox.IsEnabled = settings.AllowAddressBar;
|
||||
|
||||
// ReloadButton.IsEnabled = settings.AllowReloading;
|
||||
// ReloadButton.Visibility = settings.AllowReloading ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
// BackButton.IsEnabled = settings.AllowBackwardNavigation;
|
||||
// BackButton.Visibility = settings.AllowBackwardNavigation ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
// ForwardButton.IsEnabled = settings.AllowForwardNavigation;
|
||||
// ForwardButton.Visibility = settings.AllowForwardNavigation ? Visibility.Visible : Visibility.Collapsed;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.ApplicationButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="50">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Templates/Buttons.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Popup x:Name="InstancePopup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}" AllowsTransparency="True">
|
||||
<ScrollViewer x:Name="InstanceScrollViewer" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Background>
|
||||
<SolidColorBrush Color="Black" Opacity="0.8" />
|
||||
</ScrollViewer.Background>
|
||||
<ScrollViewer.Resources>
|
||||
<s:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">5</s:Double>
|
||||
</ScrollViewer.Resources>
|
||||
<StackPanel x:Name="InstanceStackPanel" />
|
||||
</ScrollViewer>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="#00000000" BorderThickness="0" Click="Button_Click" Padding="5"
|
||||
Template="{StaticResource ResourceKey=TaskbarButton}" Width="50" />
|
||||
<Grid Panel.ZIndex="10">
|
||||
<Rectangle x:Name="ActiveBar" Height="2" Width="40" VerticalAlignment="Bottom" Fill="LightSteelBlue" Visibility="Collapsed" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using SafeExamBrowser.Contracts.Core;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.UserInterface.Windows10.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class ApplicationButton : UserControl, IApplicationButton
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
|
||||
|
||||
public event ApplicationButtonClickedEventHandler Clicked;
|
||||
|
||||
public ApplicationButton(IApplicationInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeApplicationButton();
|
||||
}
|
||||
|
||||
public void RegisterInstance(IApplicationInstance instance)
|
||||
{
|
||||
var instanceButton = new ApplicationInstanceButton(instance, info);
|
||||
|
||||
instanceButton.Clicked += (id) => Clicked?.Invoke(id);
|
||||
instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
|
||||
|
||||
instances.Add(instance);
|
||||
InstanceStackPanel.Children.Add(instanceButton);
|
||||
|
||||
ActiveBar.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void InitializeApplicationButton()
|
||||
{
|
||||
Button.ToolTip = info.Tooltip;
|
||||
Button.Content = IconResourceLoader.Load(info.IconResource);
|
||||
|
||||
Button.MouseEnter += (o, args) => InstancePopup.IsOpen = instances.Count > 1;
|
||||
Button.MouseLeave += (o, args) => InstancePopup.IsOpen &= InstancePopup.IsMouseOver || ActiveBar.IsMouseOver;
|
||||
ActiveBar.MouseLeave += (o, args) => InstancePopup.IsOpen &= InstancePopup.IsMouseOver || Button.IsMouseOver;
|
||||
InstancePopup.MouseLeave += (o, args) => InstancePopup.IsOpen = false;
|
||||
|
||||
InstancePopup.Opened += (o, args) =>
|
||||
{
|
||||
ActiveBar.Width = Double.NaN;
|
||||
Background = (Brush) new BrushConverter().ConvertFrom("#2AFFFFFF");
|
||||
};
|
||||
|
||||
InstancePopup.Closed += (o, args) =>
|
||||
{
|
||||
ActiveBar.Width = 40;
|
||||
Background = (Brush) new BrushConverter().ConvertFrom("#00000000");
|
||||
};
|
||||
|
||||
InstanceStackPanel.SizeChanged += (o, args) =>
|
||||
{
|
||||
if (instances.Count > 9)
|
||||
{
|
||||
InstanceScrollViewer.MaxHeight = InstanceScrollViewer.ActualHeight;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (instances.Count <= 1)
|
||||
{
|
||||
Clicked?.Invoke(instances.FirstOrDefault()?.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
InstancePopup.IsOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Instance_OnTerminated(InstanceIdentifier id, ApplicationInstanceButton instanceButton)
|
||||
{
|
||||
instances.Remove(instances.FirstOrDefault(i => i.Id == id));
|
||||
InstanceStackPanel.Children.Remove(instanceButton);
|
||||
|
||||
if (!instances.Any())
|
||||
{
|
||||
ActiveBar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.ApplicationInstanceButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="250">
|
||||
<Grid>
|
||||
<Button x:Name="Button" BorderThickness="0" Click="Button_Click" Height="25">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="ButtonContent" Background="#00000000" Padding="5">
|
||||
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" ContentSource="Content" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#2AFFFFFF" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#10FFFFFF" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ContentControl x:Name="Icon" />
|
||||
<TextBlock x:Name="Text" Foreground="White" Padding="5,0,5,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Contracts.Core;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.UserInterface.Windows10.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class ApplicationInstanceButton : UserControl
|
||||
{
|
||||
private IApplicationInfo info;
|
||||
private IApplicationInstance instance;
|
||||
|
||||
internal event ApplicationButtonClickedEventHandler Clicked;
|
||||
|
||||
public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.instance = instance;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeApplicationInstanceButton();
|
||||
}
|
||||
|
||||
private void InitializeApplicationInstanceButton()
|
||||
{
|
||||
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||
Text.Text = instance.Name;
|
||||
Button.ToolTip = instance.Name;
|
||||
|
||||
instance.NameChanged += (name) =>
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
Text.Text = name;
|
||||
Button.ToolTip = name;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Clicked?.Invoke(instance.Id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.DateTimeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="75">
|
||||
<Button Background="#00000000" BorderThickness="0" ToolTip="{Binding Path=ToolTip}">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="ButtonContent" Background="{TemplateBinding Background}">
|
||||
<ContentPresenter ContentSource="Content" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#2AFFFFFF" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#2AFFFFFF" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
<Grid Margin="5,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="1*" />
|
||||
<RowDefinition Height="1*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Name="TimeTextBlock" Grid.Row="0" Text="{Binding Path=Time}" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<TextBlock x:Name="DateTextBlock" Grid.Row="1" Text="{Binding Path=Date}" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</UserControl>
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.UserInterface.Windows10.ViewModels;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class DateTimeControl : UserControl
|
||||
{
|
||||
private DateTimeViewModel model = new DateTimeViewModel();
|
||||
|
||||
public DateTimeControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = model;
|
||||
TimeTextBlock.DataContext = model;
|
||||
DateTextBlock.DataContext = model;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.NotificationButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="28">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Templates/Buttons.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Button x:Name="IconButton" Click="Icon_Click" Background="#00000000" BorderThickness="0" Padding="5,0"
|
||||
Template="{StaticResource ResourceKey=TaskbarButton}" Width="28"/>
|
||||
</UserControl>
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.UserInterface.Windows10.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class NotificationButton : UserControl, INotificationButton
|
||||
{
|
||||
public event NotificationButtonClickedEventHandler Clicked;
|
||||
|
||||
public NotificationButton(INotificationInfo info)
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeNotificationIcon(info);
|
||||
}
|
||||
|
||||
private void Icon_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Clicked?.Invoke();
|
||||
}
|
||||
|
||||
private void InitializeNotificationIcon(INotificationInfo info)
|
||||
{
|
||||
IconButton.ToolTip = info.Tooltip;
|
||||
IconButton.Content = IconResourceLoader.Load(info.IconResource);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.PowerSupplyControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="28">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Templates/Buttons.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}" AllowsTransparency="True">
|
||||
<Border BorderBrush="White" BorderThickness="0.5,0.5,0.5,0" MaxWidth="250" Padding="20,10,20,20">
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="#404040" Opacity="0.8" />
|
||||
</Border.Background>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="1" Background="Transparent" Click="Button_Click" Cursor="Hand" FontWeight="Bold"
|
||||
Foreground="White" Margin="0,0,0,5" Template="{StaticResource ResourceKey=TaskbarButton}" Width="20">X</Button>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" x:Name="PopupText" Foreground="White" TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="#00000000" BorderThickness="0" Foreground="White" Padding="5,0"
|
||||
Template="{StaticResource ResourceKey=TaskbarButton}" Width="28">
|
||||
<Viewbox Stretch="Uniform" Width="Auto">
|
||||
<Canvas Height="18" Width="18">
|
||||
<Path Stroke="White" Data="M3,6 H17 V9 H18 V11 H17 V9 H17 V14 H3 Z" Panel.ZIndex="2" />
|
||||
<Rectangle x:Name="BatteryCharge" Canvas.Left="3.5" Canvas.Top="6" Fill="Green" Height="8" Width="13" />
|
||||
<Grid x:Name="PowerPlug" Panel.ZIndex="3">
|
||||
<Path Stroke="White" Fill="Black" Data="M2.5,14.5 V10 Q5,10 5,6 H4 V4 H4 V6 H1 V4 H1 V6 H0 Q0,10 2.5,10" Panel.ZIndex="2" />
|
||||
<Path Stroke="Black" Data="M4,14.5 V10 Q6,10 6,5.5" Panel.ZIndex="1" />
|
||||
</Grid>
|
||||
<TextBlock x:Name="Warning" FontSize="18" FontWeight="ExtraBold" Foreground="Red" Canvas.Left="7" Canvas.Top="-3.5" Panel.ZIndex="3">!</TextBlock>
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class PowerSupplyControl : UserControl, ISystemPowerSupplyControl
|
||||
{
|
||||
private double BATTERY_CHARGE_MAX_WIDTH;
|
||||
|
||||
public PowerSupplyControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
BATTERY_CHARGE_MAX_WIDTH = BatteryCharge.Width;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
}
|
||||
|
||||
public void SetBatteryCharge(double charge, BatteryChargeStatus status)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var width = BATTERY_CHARGE_MAX_WIDTH * charge;
|
||||
|
||||
width = width > BATTERY_CHARGE_MAX_WIDTH ? BATTERY_CHARGE_MAX_WIDTH : width;
|
||||
width = width < 0 ? 0 : width;
|
||||
|
||||
BatteryCharge.Width = width;
|
||||
BatteryCharge.Fill = status == BatteryChargeStatus.Low ? Brushes.Orange : BatteryCharge.Fill;
|
||||
BatteryCharge.Fill = status == BatteryChargeStatus.Critical ? Brushes.Red : BatteryCharge.Fill;
|
||||
Warning.Visibility = status == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetPowerGridConnection(bool connected)
|
||||
{
|
||||
Dispatcher.Invoke(() => PowerPlug.Visibility = connected ? Visibility.Visible : Visibility.Collapsed);
|
||||
}
|
||||
|
||||
public void SetTooltip(string text)
|
||||
{
|
||||
Dispatcher.Invoke(() => Button.ToolTip = text);
|
||||
}
|
||||
|
||||
public void ShowCriticalBatteryWarning(string warning)
|
||||
{
|
||||
Dispatcher.Invoke(() => ShowPopup(warning));
|
||||
}
|
||||
|
||||
public void ShowLowBatteryInfo(string info)
|
||||
{
|
||||
Dispatcher.Invoke(() => ShowPopup(info));
|
||||
}
|
||||
|
||||
private void ShowPopup(string text)
|
||||
{
|
||||
Popup.IsOpen = true;
|
||||
PopupText.Text = text;
|
||||
Background = (Brush) new BrushConverter().ConvertFrom("#2AFFFFFF");
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
Background = (Brush) new BrushConverter().ConvertFrom("#00000000");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Windows10.Controls.QuitButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="40" d:DesignWidth="40">
|
||||
<Grid>
|
||||
<Button Click="Button_Click" Content="Quit" Background="#00000000" Foreground="White">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="ButtonContent" Background="{TemplateBinding Background}" Padding="5">
|
||||
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#50FF0000" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#40FF0000" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Controls
|
||||
{
|
||||
public partial class QuitButton : UserControl
|
||||
{
|
||||
public event QuitButtonClickedEventHandler Clicked;
|
||||
|
||||
public QuitButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Clicked?.Invoke(new CancelEventArgs());
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 187 KiB |
Binary file not shown.
Before Width: | Height: | Size: 91 KiB |
Binary file not shown.
Before Width: | Height: | Size: 361 KiB |
Binary file not shown.
Before Width: | Height: | Size: 39 KiB |
|
@ -1,18 +0,0 @@
|
|||
<Window x:Class="SafeExamBrowser.UserInterface.Windows10.LogWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10"
|
||||
mc:Ignorable="d"
|
||||
Title="{Binding Path=WindowTitle}" Height="500" Width="1100" MinHeight="350" MinWidth="350" WindowStartupLocation="CenterScreen"
|
||||
Icon="./Images/LogNotification.ico">
|
||||
<Window.Background>
|
||||
<SolidColorBrush Color="Black" Opacity="0.8" />
|
||||
</Window.Background>
|
||||
<Grid>
|
||||
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="LogContent" Background="Transparent" FontFamily="Consolas" Foreground="White" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Windows;
|
||||
using SafeExamBrowser.UserInterface.Windows10.ViewModels;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public partial class LogWindow : Window, IWindow
|
||||
{
|
||||
private ILogger logger;
|
||||
private LogViewModel model;
|
||||
private WindowClosingEventHandler closing;
|
||||
|
||||
event WindowClosingEventHandler IWindow.Closing
|
||||
{
|
||||
add { closing += value; }
|
||||
remove { closing -= value; }
|
||||
}
|
||||
|
||||
public LogWindow(ILogger logger, IText text)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.logger = logger;
|
||||
this.model = new LogViewModel(text, ScrollViewer, LogContent);
|
||||
|
||||
InitializeLogWindow();
|
||||
}
|
||||
|
||||
public void BringToForeground()
|
||||
{
|
||||
Dispatcher.Invoke(Activate);
|
||||
}
|
||||
|
||||
public new void Close()
|
||||
{
|
||||
Dispatcher.Invoke(base.Close);
|
||||
}
|
||||
|
||||
public new void Hide()
|
||||
{
|
||||
Dispatcher.Invoke(base.Hide);
|
||||
}
|
||||
|
||||
public new void Show()
|
||||
{
|
||||
Dispatcher.Invoke(base.Show);
|
||||
}
|
||||
|
||||
private void InitializeLogWindow()
|
||||
{
|
||||
DataContext = model;
|
||||
Closing += LogWindow_Closing;
|
||||
Loaded += LogWindow_Loaded;
|
||||
}
|
||||
|
||||
private void LogWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var log = logger.GetLog();
|
||||
|
||||
foreach (var content in log)
|
||||
{
|
||||
model.Notify(content);
|
||||
}
|
||||
|
||||
logger.Subscribe(model);
|
||||
logger.Info("Opened log window.");
|
||||
}
|
||||
|
||||
private void LogWindow_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
logger.Unsubscribe(model);
|
||||
logger.Info("Closed log window.");
|
||||
|
||||
closing?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SafeExamBrowser.UserInterface")]
|
||||
[assembly: AssemblyDescription("Safe Exam Browser")]
|
||||
[assembly: AssemblyCompany("ETH Zürich")]
|
||||
[assembly: AssemblyProduct("SafeExamBrowser.UserInterface")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019 ETH Zürich, Educational Development and Technology (LET)")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//In order to begin building localizable applications, set
|
||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
//the line below to match the UICulture setting in the project file.
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,63 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SafeExamBrowser.UserInterface.Windows10.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -1,26 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
|
@ -1,194 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E1BE031A-4354-41E7-83E8-843DED4489FF}</ProjectGuid>
|
||||
<OutputType>library</OutputType>
|
||||
<RootNamespace>SafeExamBrowser.UserInterface.Windows10</RootNamespace>
|
||||
<AssemblyName>SafeExamBrowser.UserInterface.Windows10</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WindowsFormsIntegration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AboutWindow.xaml.cs">
|
||||
<DependentUpon>AboutWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BrowserWindow.xaml.cs">
|
||||
<DependentUpon>BrowserWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ApplicationInstanceButton.xaml.cs">
|
||||
<DependentUpon>ApplicationInstanceButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\DateTimeControl.xaml.cs">
|
||||
<DependentUpon>DateTimeControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ApplicationButton.xaml.cs">
|
||||
<DependentUpon>ApplicationButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\NotificationButton.xaml.cs">
|
||||
<DependentUpon>NotificationButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\PowerSupplyControl.xaml.cs">
|
||||
<DependentUpon>PowerSupplyControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\QuitButton.xaml.cs">
|
||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LogWindow.xaml.cs">
|
||||
<DependentUpon>LogWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="SplashScreen.xaml.cs">
|
||||
<DependentUpon>SplashScreen.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Taskbar.xaml.cs">
|
||||
<DependentUpon>Taskbar.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UserInterfaceFactory.cs" />
|
||||
<Compile Include="Utilities\IconResourceLoader.cs" />
|
||||
<Compile Include="Utilities\VisualExtensions.cs" />
|
||||
<Compile Include="ViewModels\DateTimeViewModel.cs" />
|
||||
<Compile Include="ViewModels\LogViewModel.cs" />
|
||||
<Compile Include="ViewModels\SplashScreenViewModel.cs" />
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="AboutWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="BrowserWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\ApplicationInstanceButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\DateTimeControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\ApplicationButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\NotificationButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\PowerSupplyControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\QuitButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="LogWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="SplashScreen.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Templates\Buttons.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Taskbar.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
|
||||
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
|
||||
<Name>SafeExamBrowser.Contracts</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\SplashScreen.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\SafeExamBrowser.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Chromium.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\LogNotification.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,30 +0,0 @@
|
|||
<Window x:Class="SafeExamBrowser.UserInterface.Windows10.SplashScreen"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="SplashScreen" Height="200" Width="350" WindowStyle="None" AllowsTransparency="True" WindowStartupLocation="CenterScreen"
|
||||
Cursor="Wait" Icon="./Images/SafeExamBrowser.ico" ResizeMode="NoResize" Topmost="True">
|
||||
<Window.Background>
|
||||
<SolidColorBrush Color="Black" Opacity="0.8" />
|
||||
</Window.Background>
|
||||
<Border BorderBrush="DodgerBlue" BorderThickness="1">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="25" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="155" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Windows10;component/Images/SplashScreen.png" />
|
||||
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="White" Margin="10,75,10,10" TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<ProgressBar x:Name="ProgressBar" Grid.Row="1" Minimum="0" Maximum="{Binding Path=MaxProgress}" Value="{Binding Path=CurrentProgress}" IsIndeterminate="{Binding Path=IsIndeterminate}" Background="#00000000" BorderThickness="0" />
|
||||
<TextBlock x:Name="StatusTextBlock" Grid.Row="1" Text="{Binding Path=Status}" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Windows;
|
||||
using SafeExamBrowser.UserInterface.Windows10.ViewModels;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public partial class SplashScreen : Window, ISplashScreen
|
||||
{
|
||||
private bool allowClose;
|
||||
private SplashScreenViewModel model = new SplashScreenViewModel();
|
||||
private AppConfig appConfig;
|
||||
private IText text;
|
||||
private WindowClosingEventHandler closing;
|
||||
|
||||
public AppConfig AppConfig
|
||||
{
|
||||
set
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
appConfig = value;
|
||||
UpdateAppInfo();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
event WindowClosingEventHandler IWindow.Closing
|
||||
{
|
||||
add { closing += value; }
|
||||
remove { closing -= value; }
|
||||
}
|
||||
|
||||
public SplashScreen(IText text, AppConfig appConfig = null)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.text = text;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeSplashScreen();
|
||||
}
|
||||
|
||||
public void BringToForeground()
|
||||
{
|
||||
Dispatcher.Invoke(Activate);
|
||||
}
|
||||
|
||||
public new void Close()
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
allowClose = true;
|
||||
base.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public new void Hide()
|
||||
{
|
||||
Dispatcher.Invoke(base.Hide);
|
||||
}
|
||||
|
||||
public new void Show()
|
||||
{
|
||||
Dispatcher.Invoke(base.Show);
|
||||
}
|
||||
|
||||
public void Progress()
|
||||
{
|
||||
model.CurrentProgress += 1;
|
||||
}
|
||||
|
||||
public void Regress()
|
||||
{
|
||||
model.CurrentProgress -= 1;
|
||||
}
|
||||
|
||||
public void SetIndeterminate()
|
||||
{
|
||||
model.IsIndeterminate = true;
|
||||
}
|
||||
|
||||
public void SetMaxValue(int max)
|
||||
{
|
||||
model.MaxProgress = max;
|
||||
}
|
||||
|
||||
public void SetValue(int value)
|
||||
{
|
||||
model.CurrentProgress = value;
|
||||
}
|
||||
|
||||
public void UpdateStatus(TextKey key, bool showBusyIndication = false)
|
||||
{
|
||||
// TODO: Handle auto-start of busy indication
|
||||
model.Status = text.Get(key);
|
||||
}
|
||||
|
||||
private void InitializeSplashScreen()
|
||||
{
|
||||
UpdateAppInfo();
|
||||
|
||||
StatusTextBlock.DataContext = model;
|
||||
ProgressBar.DataContext = model;
|
||||
|
||||
// To prevent the progress bar going from max to min value at startup...
|
||||
model.MaxProgress = 1;
|
||||
|
||||
Closing += (o, args) => args.Cancel = !allowClose;
|
||||
}
|
||||
|
||||
private void UpdateAppInfo()
|
||||
{
|
||||
if (appConfig != null)
|
||||
{
|
||||
InfoTextBlock.Inlines.Add(new Run($"Version {appConfig.ProgramVersion}") { FontStyle = FontStyles.Italic });
|
||||
InfoTextBlock.Inlines.Add(new LineBreak());
|
||||
InfoTextBlock.Inlines.Add(new LineBreak());
|
||||
InfoTextBlock.Inlines.Add(new Run(appConfig.ProgramCopyright) { FontSize = 10 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<Window x:Class="SafeExamBrowser.UserInterface.Windows10.Taskbar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Controls"
|
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"
|
||||
mc:Ignorable="d"
|
||||
Title="Taskbar" Height="40" Width="750" WindowStyle="None" AllowsTransparency="True" Topmost="True" Visibility="Collapsed"
|
||||
ResizeMode="NoResize" Icon="./Images/SafeExamBrowser.ico">
|
||||
<Window.Background>
|
||||
<SolidColorBrush Color="Black" Opacity="0.8" />
|
||||
</Window.Background>
|
||||
<Border BorderBrush="White" BorderThickness="0,0.5,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="40" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ScrollViewer Grid.Column="0" x:Name="ApplicationScrollViewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<s:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">5</s:Double>
|
||||
</ScrollViewer.Resources>
|
||||
<StackPanel x:Name="ApplicationStackPanel" Orientation="Horizontal" />
|
||||
</ScrollViewer>
|
||||
<StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Margin="5,0,0,0" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<StackPanel Grid.Column="2" x:Name="SystemControlStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
|
||||
<local:DateTimeControl Grid.Column="3" />
|
||||
<local:QuitButton Grid.Column="4" x:Name="QuitButton" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events;
|
||||
using SafeExamBrowser.UserInterface.Windows10.Utilities;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public partial class Taskbar : Window, ITaskbar
|
||||
{
|
||||
private bool allowClose;
|
||||
private ILogger logger;
|
||||
|
||||
public event QuitButtonClickedEventHandler QuitButtonClicked;
|
||||
|
||||
public Taskbar(ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Closing += Taskbar_Closing;
|
||||
Loaded += (o, args) => InitializeBounds();
|
||||
QuitButtonClicked += QuitButton_Clicked;
|
||||
}
|
||||
|
||||
public void AddApplication(IApplicationButton button)
|
||||
{
|
||||
if (button is UIElement uiElement)
|
||||
{
|
||||
ApplicationStackPanel.Children.Add(uiElement);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddNotification(INotificationButton button)
|
||||
{
|
||||
if (button is UIElement uiElement)
|
||||
{
|
||||
NotificationStackPanel.Children.Add(uiElement);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSystemControl(ISystemControl control)
|
||||
{
|
||||
if (control is UIElement uiElement)
|
||||
{
|
||||
SystemControlStackPanel.Children.Add(uiElement);
|
||||
}
|
||||
}
|
||||
|
||||
public new void Close()
|
||||
{
|
||||
Dispatcher.Invoke(base.Close);
|
||||
}
|
||||
|
||||
public int GetAbsoluteHeight()
|
||||
{
|
||||
return Dispatcher.Invoke(() =>
|
||||
{
|
||||
var height = (int) this.TransformToPhysical(Width, Height).Y;
|
||||
|
||||
logger.Info($"Calculated physical taskbar height is {height}px.");
|
||||
|
||||
return height;
|
||||
});
|
||||
}
|
||||
|
||||
public void InitializeBounds()
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
Width = SystemParameters.WorkArea.Right;
|
||||
Left = SystemParameters.WorkArea.Right - Width;
|
||||
Top = SystemParameters.WorkArea.Bottom;
|
||||
|
||||
var position = this.TransformToPhysical(Left, Top);
|
||||
var size = this.TransformToPhysical(Width, Height);
|
||||
|
||||
logger.Info($"Set taskbar bounds to {Width}x{Height} at ({Left}/{Top}), in physical pixels: {size.X}x{size.Y} at ({position.X}/{position.Y}).");
|
||||
});
|
||||
}
|
||||
|
||||
private void QuitButton_Clicked(CancelEventArgs args)
|
||||
{
|
||||
QuitButtonClicked?.Invoke(args);
|
||||
allowClose = !args.Cancel;
|
||||
}
|
||||
|
||||
private void Taskbar_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (!allowClose)
|
||||
{
|
||||
e.Cancel = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var child in SystemControlStackPanel.Children)
|
||||
{
|
||||
if (child is ISystemControl systemControl)
|
||||
{
|
||||
systemControl.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Windows10.Styles">
|
||||
<ControlTemplate x:Key="TaskbarButton" TargetType="Button">
|
||||
<Border x:Name="ButtonContent" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter ContentSource="Content" HorizontalAlignment="Center" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="HighQuality" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#2AFFFFFF" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="ButtonContent" Property="Background" Value="#10FFFFFF" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</ResourceDictionary>
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Threading;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Browser;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Windows;
|
||||
using SafeExamBrowser.UserInterface.Windows10.Controls;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10
|
||||
{
|
||||
public class UserInterfaceFactory : IUserInterfaceFactory
|
||||
{
|
||||
private IText text;
|
||||
|
||||
public UserInterfaceFactory(IText text)
|
||||
{
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public IWindow CreateAboutWindow(AppConfig appConfig)
|
||||
{
|
||||
return new AboutWindow(appConfig, text);
|
||||
}
|
||||
|
||||
public IApplicationButton CreateApplicationButton(IApplicationInfo info)
|
||||
{
|
||||
return new ApplicationButton(info);
|
||||
}
|
||||
|
||||
public IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings)
|
||||
{
|
||||
// TODO
|
||||
// return new BrowserWindow(control, settings);
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public IWindow CreateLogWindow(ILogger logger)
|
||||
{
|
||||
LogWindow logWindow = null;
|
||||
var logWindowReadyEvent = new AutoResetEvent(false);
|
||||
var logWindowThread = new Thread(() =>
|
||||
{
|
||||
logWindow = new LogWindow(logger, text);
|
||||
logWindow.Closed += (o, args) => logWindow.Dispatcher.InvokeShutdown();
|
||||
logWindow.Show();
|
||||
|
||||
logWindowReadyEvent.Set();
|
||||
|
||||
System.Windows.Threading.Dispatcher.Run();
|
||||
});
|
||||
|
||||
logWindowThread.SetApartmentState(ApartmentState.STA);
|
||||
logWindowThread.IsBackground = true;
|
||||
logWindowThread.Start();
|
||||
|
||||
logWindowReadyEvent.WaitOne();
|
||||
|
||||
return logWindow;
|
||||
}
|
||||
|
||||
public INotificationButton CreateNotification(INotificationInfo info)
|
||||
{
|
||||
return new NotificationButton(info);
|
||||
}
|
||||
|
||||
public ISystemKeyboardLayoutControl CreateKeyboardLayoutControl()
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public IPasswordDialog CreatePasswordDialog(string message, string title)
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public IPasswordDialog CreatePasswordDialog(TextKey message, TextKey title)
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public ISystemPowerSupplyControl CreatePowerSupplyControl()
|
||||
{
|
||||
return new PowerSupplyControl();
|
||||
}
|
||||
|
||||
public IRuntimeWindow CreateRuntimeWindow(AppConfig appConfig)
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public ISplashScreen CreateSplashScreen(AppConfig appConfig = null)
|
||||
{
|
||||
SplashScreen splashScreen = null;
|
||||
var splashReadyEvent = new AutoResetEvent(false);
|
||||
var splashScreenThread = new Thread(() =>
|
||||
{
|
||||
splashScreen = new SplashScreen(text, appConfig);
|
||||
splashScreen.Closed += (o, args) => splashScreen.Dispatcher.InvokeShutdown();
|
||||
splashScreen.Show();
|
||||
|
||||
splashReadyEvent.Set();
|
||||
|
||||
System.Windows.Threading.Dispatcher.Run();
|
||||
});
|
||||
|
||||
splashScreenThread.SetApartmentState(ApartmentState.STA);
|
||||
splashScreenThread.Name = nameof(SplashScreen);
|
||||
splashScreenThread.IsBackground = true;
|
||||
splashScreenThread.Start();
|
||||
|
||||
splashReadyEvent.WaitOne();
|
||||
|
||||
return splashScreen;
|
||||
}
|
||||
|
||||
public ISystemWirelessNetworkControl CreateWirelessNetworkControl()
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Utilities
|
||||
{
|
||||
internal static class IconResourceLoader
|
||||
{
|
||||
internal static UIElement Load(IIconResource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resource.IsBitmapResource)
|
||||
{
|
||||
return LoadBitmapResource(resource);
|
||||
}
|
||||
else if (resource.IsXamlResource)
|
||||
{
|
||||
return LoadXamlResource(resource);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new TextBlock(new Run("X") { Foreground = Brushes.Red, FontWeight = FontWeights.Bold });
|
||||
}
|
||||
|
||||
throw new NotSupportedException($"Application icon resource of type '{resource.GetType()}' is not supported!");
|
||||
}
|
||||
|
||||
private static UIElement LoadBitmapResource(IIconResource resource)
|
||||
{
|
||||
return new Image
|
||||
{
|
||||
Source = new BitmapImage(resource.Uri)
|
||||
};
|
||||
}
|
||||
|
||||
private static UIElement LoadXamlResource(IIconResource resource)
|
||||
{
|
||||
using (var stream = Application.GetResourceStream(resource.Uri)?.Stream)
|
||||
{
|
||||
return XamlReader.Load(stream) as UIElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.Utilities
|
||||
{
|
||||
internal static class VisualExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// WPF works with device-independent pixels. This method is required to
|
||||
/// transform such values to their absolute, device-specific pixel value.
|
||||
/// Source: https://stackoverflow.com/questions/3286175/how-do-i-convert-a-wpf-size-to-physical-pixels
|
||||
/// </summary>
|
||||
internal static Vector TransformToPhysical(this Visual visual, double x, double y)
|
||||
{
|
||||
Matrix transformToDevice;
|
||||
var source = PresentationSource.FromVisual(visual);
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
transformToDevice = source.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var newSource = new HwndSource(new HwndSourceParameters()))
|
||||
{
|
||||
transformToDevice = newSource.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return transformToDevice.Transform(new Vector(x, y));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Timers;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.ViewModels
|
||||
{
|
||||
class DateTimeViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private Timer timer;
|
||||
|
||||
public string Date { get; private set; }
|
||||
public string Time { get; private set; }
|
||||
public string ToolTip { get; private set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public DateTimeViewModel()
|
||||
{
|
||||
timer = new Timer(1000);
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var date = DateTime.Now;
|
||||
|
||||
Date = date.ToShortDateString();
|
||||
Time = date.ToShortTimeString();
|
||||
ToolTip = $"{date.ToLongDateString()} {date.ToLongTimeString()}";
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Time)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Date)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ToolTip)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.ViewModels
|
||||
{
|
||||
internal class LogViewModel : ILogObserver
|
||||
{
|
||||
private IText text;
|
||||
private ScrollViewer scrollViewer;
|
||||
private TextBlock textBlock;
|
||||
|
||||
public string WindowTitle => text.Get(TextKey.LogWindow_Title);
|
||||
|
||||
public LogViewModel(IText text, ScrollViewer scrollViewer, TextBlock textBlock)
|
||||
{
|
||||
this.text = text;
|
||||
this.scrollViewer = scrollViewer;
|
||||
this.textBlock = textBlock;
|
||||
}
|
||||
|
||||
public void Notify(ILogContent content)
|
||||
{
|
||||
switch (content)
|
||||
{
|
||||
case ILogText text:
|
||||
AppendLogText(text);
|
||||
break;
|
||||
case ILogMessage message:
|
||||
AppendLogMessage(message);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"The log window is not yet implemented for log content of type {content.GetType()}!");
|
||||
}
|
||||
|
||||
scrollViewer.Dispatcher.Invoke(scrollViewer.ScrollToEnd);
|
||||
}
|
||||
|
||||
private void AppendLogText(ILogText logText)
|
||||
{
|
||||
textBlock.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var isHeader = logText.Text.StartsWith("/* ");
|
||||
var isComment = logText.Text.StartsWith("# ");
|
||||
var brush = isHeader || isComment ? Brushes.ForestGreen : textBlock.Foreground;
|
||||
|
||||
textBlock.Inlines.Add(new Run($"{logText.Text}{Environment.NewLine}")
|
||||
{
|
||||
FontWeight = isHeader ? FontWeights.Bold : FontWeights.Normal,
|
||||
Foreground = brush
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void AppendLogMessage(ILogMessage message)
|
||||
{
|
||||
textBlock.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var date = message.DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var severity = message.Severity.ToString().ToUpper();
|
||||
var threadInfo = $"{message.ThreadInfo.Id}{(message.ThreadInfo.HasName ? ": " + message.ThreadInfo.Name : string.Empty)}";
|
||||
|
||||
var infoRun = new Run($"{date} [{threadInfo}] - ") { Foreground = Brushes.Gray };
|
||||
var messageRun = new Run($"{severity}: {message.Message}{Environment.NewLine}") { Foreground = GetBrushFor(message.Severity) };
|
||||
|
||||
textBlock.Inlines.Add(infoRun);
|
||||
textBlock.Inlines.Add(messageRun);
|
||||
});
|
||||
}
|
||||
|
||||
private Brush GetBrushFor(LogLevel severity)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
case LogLevel.Debug:
|
||||
return Brushes.Gray;
|
||||
case LogLevel.Error:
|
||||
return Brushes.Red;
|
||||
case LogLevel.Warning:
|
||||
return Brushes.Yellow;
|
||||
default:
|
||||
return Brushes.White;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Timers;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Windows10.ViewModels
|
||||
{
|
||||
class SplashScreenViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private int currentProgress;
|
||||
private bool isIndeterminate;
|
||||
private int maxProgress;
|
||||
private string status;
|
||||
private Timer busyTimer;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public int CurrentProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentProgress;
|
||||
}
|
||||
set
|
||||
{
|
||||
currentProgress = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentProgress)));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsIndeterminate
|
||||
{
|
||||
get
|
||||
{
|
||||
return isIndeterminate;
|
||||
}
|
||||
set
|
||||
{
|
||||
isIndeterminate = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsIndeterminate)));
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxProgress;
|
||||
}
|
||||
set
|
||||
{
|
||||
maxProgress = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MaxProgress)));
|
||||
}
|
||||
}
|
||||
|
||||
public string Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return status;
|
||||
}
|
||||
set
|
||||
{
|
||||
status = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Status)));
|
||||
}
|
||||
}
|
||||
|
||||
public void StartBusyIndication()
|
||||
{
|
||||
StopBusyIndication();
|
||||
|
||||
busyTimer = new Timer
|
||||
{
|
||||
AutoReset = true,
|
||||
Interval = 750
|
||||
};
|
||||
|
||||
busyTimer.Elapsed += BusyTimer_Elapsed;
|
||||
busyTimer.Start();
|
||||
}
|
||||
|
||||
public void StopBusyIndication()
|
||||
{
|
||||
busyTimer?.Stop();
|
||||
busyTimer?.Close();
|
||||
}
|
||||
|
||||
private void BusyTimer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var next = Status ?? string.Empty;
|
||||
|
||||
if (next.EndsWith("..."))
|
||||
{
|
||||
next = Status.Substring(0, Status.Length - 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
next += ".";
|
||||
}
|
||||
|
||||
Status = next;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,8 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
LICENSE.txt = LICENSE.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.UserInterface.Windows10", "SafeExamBrowser.UserInterface.Windows10\SafeExamBrowser.UserInterface.Windows10.csproj", "{E1BE031A-4354-41E7-83E8-843DED4489FF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Core.UnitTests", "SafeExamBrowser.Core.UnitTests\SafeExamBrowser.Core.UnitTests.csproj", "{48B9F2A1-B87D-40F0-BEC9-399E8909860F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Contracts", "SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj", "{47DA5933-BEF8-4729-94E6-ABDE2DB12262}"
|
||||
|
@ -80,14 +78,6 @@ Global
|
|||
{3D6FDBB6-A4AF-4626-BB2B-BF329D44F9CC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3D6FDBB6-A4AF-4626-BB2B-BF329D44F9CC}.Release|x86.ActiveCfg = Release|x86
|
||||
{3D6FDBB6-A4AF-4626-BB2B-BF329D44F9CC}.Release|x86.Build.0 = Release|x86
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Debug|x86.Build.0 = Debug|x86
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Release|x86.ActiveCfg = Release|x86
|
||||
{E1BE031A-4354-41E7-83E8-843DED4489FF}.Release|x86.Build.0 = Release|x86
|
||||
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Debug|x86.ActiveCfg = Debug|x86
|
||||
|
|
Loading…
Reference in a new issue