diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs
index 8cffa761..1fb6b630 100644
--- a/SafeExamBrowser.Client/ClientController.cs
+++ b/SafeExamBrowser.Client/ClientController.cs
@@ -110,7 +110,7 @@ namespace SafeExamBrowser.Client
if (communication.Success)
{
- splashScreen.Hide();
+ splashScreen.Close();
logger.Info("Application successfully initialized.");
logger.Log(string.Empty);
@@ -135,8 +135,8 @@ namespace SafeExamBrowser.Client
logger.Log(string.Empty);
logger.Info("Initiating shutdown procedure...");
+ splashScreen = uiFactory.CreateSplashScreen(appConfig);
splashScreen.Show();
- splashScreen.BringToForeground();
DeregisterEvents();
@@ -153,7 +153,7 @@ namespace SafeExamBrowser.Client
logger.Log(string.Empty);
}
- splashScreen?.Close();
+ splashScreen.Close();
}
private void RegisterEvents()
@@ -307,7 +307,7 @@ namespace SafeExamBrowser.Client
private void Operations_StatusChanged(TextKey status)
{
- splashScreen?.UpdateText(status);
+ splashScreen?.UpdateStatus(status, true);
}
private void Runtime_ConnectionLost()
diff --git a/SafeExamBrowser.Contracts/UserInterface/IProgressIndicator.cs b/SafeExamBrowser.Contracts/UserInterface/IProgressIndicator.cs
index fb2a0705..a773b6ca 100644
--- a/SafeExamBrowser.Contracts/UserInterface/IProgressIndicator.cs
+++ b/SafeExamBrowser.Contracts/UserInterface/IProgressIndicator.cs
@@ -42,8 +42,7 @@ namespace SafeExamBrowser.Contracts.UserInterface
///
/// Updates the status text. If the busy flag is set, an animation will be shown to indicate a long-running operation.
- /// TODO: Automatically show busy indication in implementations after e.g. 2 seconds!
///
- void UpdateText(TextKey key, bool showBusyIndication = false);
+ void UpdateStatus(TextKey key, bool busyIndication = false);
}
}
diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/ServiceOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/ServiceOperationTests.cs
index ab747cb8..7c122e1e 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Operations/ServiceOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Operations/ServiceOperationTests.cs
@@ -14,7 +14,6 @@ using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
-using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Runtime.Operations;
namespace SafeExamBrowser.Runtime.UnitTests.Operations
@@ -27,7 +26,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
private Mock configuration;
private Mock session;
private Settings settings;
- private Mock progressIndicator;
private ServiceOperation sut;
[TestInitialize]
@@ -38,7 +36,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
configuration = new Mock();
session = new Mock();
settings = new Settings();
- progressIndicator = new Mock();
configuration.SetupGet(c => c.CurrentSession).Returns(session.Object);
configuration.SetupGet(c => c.CurrentSettings).Returns(settings);
diff --git a/SafeExamBrowser.Runtime/RuntimeController.cs b/SafeExamBrowser.Runtime/RuntimeController.cs
index c1ee5415..81b8afb4 100644
--- a/SafeExamBrowser.Runtime/RuntimeController.cs
+++ b/SafeExamBrowser.Runtime/RuntimeController.cs
@@ -94,7 +94,7 @@ namespace SafeExamBrowser.Runtime
logger.Info("Application successfully initialized.");
logger.Log(string.Empty);
logger.Subscribe(runtimeWindow);
- splashScreen.Hide();
+ splashScreen.Close();
StartSession(true);
}
@@ -120,8 +120,9 @@ namespace SafeExamBrowser.Runtime
logger.Unsubscribe(runtimeWindow);
runtimeWindow?.Close();
- splashScreen?.Show();
- splashScreen?.BringToForeground();
+
+ splashScreen = uiFactory.CreateSplashScreen(appConfig);
+ splashScreen.Show();
logger.Log(string.Empty);
logger.Info("Initiating shutdown procedure...");
@@ -141,7 +142,7 @@ namespace SafeExamBrowser.Runtime
messageBox.Show(TextKey.MessageBox_ShutdownError, TextKey.MessageBox_ShutdownErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen);
}
- splashScreen?.Close();
+ splashScreen.Close();
}
private void StartSession(bool initial = false)
@@ -164,7 +165,7 @@ namespace SafeExamBrowser.Runtime
logger.Info("### --- Session Running --- ###");
runtimeWindow.HideProgressBar();
- runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning);
+ runtimeWindow.UpdateStatus(TextKey.RuntimeWindow_ApplicationRunning);
runtimeWindow.TopMost = configuration.CurrentSettings.KioskMode != KioskMode.None;
if (configuration.CurrentSettings.KioskMode == KioskMode.DisableExplorerShell)
@@ -270,7 +271,7 @@ namespace SafeExamBrowser.Runtime
private void BootstrapSequence_StatusChanged(TextKey status)
{
- splashScreen?.UpdateText(status);
+ splashScreen?.UpdateStatus(status, true);
}
private void ClientProcess_Terminated(int exitCode)
@@ -427,7 +428,7 @@ namespace SafeExamBrowser.Runtime
private void SessionSequence_StatusChanged(TextKey status)
{
- runtimeWindow?.UpdateText(status);
+ runtimeWindow?.UpdateStatus(status, true);
}
}
}
diff --git a/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml.cs b/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml.cs
index c46f22a5..5fc4d1ba 100644
--- a/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml.cs
@@ -58,6 +58,8 @@ namespace SafeExamBrowser.UserInterface.Classic
Dispatcher.Invoke(() =>
{
allowClose = true;
+ model.BusyIndication = false;
+
base.Close();
});
}
@@ -69,6 +71,7 @@ namespace SafeExamBrowser.UserInterface.Classic
public void HideProgressBar()
{
+ model.AnimatedBorderVisibility = Visibility.Visible;
model.ProgressBarVisibility = Visibility.Hidden;
}
@@ -108,18 +111,14 @@ namespace SafeExamBrowser.UserInterface.Classic
public void ShowProgressBar()
{
+ model.AnimatedBorderVisibility = Visibility.Hidden;
model.ProgressBarVisibility = Visibility.Visible;
}
- public void UpdateText(TextKey key, bool showBusyIndication = false)
+ public void UpdateStatus(TextKey key, bool busyIndication = false)
{
- model.StopBusyIndication();
model.Status = text.Get(key);
-
- if (showBusyIndication)
- {
- model.StartBusyIndication();
- }
+ model.BusyIndication = busyIndication;
}
public new void Show()
diff --git a/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml b/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml
index 6d1ab6f7..edc78d38 100644
--- a/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml
+++ b/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml
@@ -19,7 +19,7 @@
-
+
diff --git a/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml.cs b/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml.cs
index 8682ce84..b5719a09 100644
--- a/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Classic/SplashScreen.xaml.cs
@@ -63,6 +63,8 @@ namespace SafeExamBrowser.UserInterface.Classic
Dispatcher.Invoke(() =>
{
allowClose = true;
+ model.BusyIndication = false;
+
base.Close();
});
}
@@ -102,15 +104,10 @@ namespace SafeExamBrowser.UserInterface.Classic
model.CurrentProgress = value;
}
- public void UpdateText(TextKey key, bool showBusyIndication = false)
+ public void UpdateStatus(TextKey key, bool busyIndication = false)
{
- model.StopBusyIndication();
model.Status = text.Get(key);
-
- if (showBusyIndication)
- {
- model.StartBusyIndication();
- }
+ model.BusyIndication = busyIndication;
}
private void InitializeSplashScreen()
@@ -120,9 +117,6 @@ namespace SafeExamBrowser.UserInterface.Classic
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;
}
diff --git a/SafeExamBrowser.UserInterface.Classic/ViewModels/ProgressIndicatorViewModel.cs b/SafeExamBrowser.UserInterface.Classic/ViewModels/ProgressIndicatorViewModel.cs
index ce0b1259..ea632c40 100644
--- a/SafeExamBrowser.UserInterface.Classic/ViewModels/ProgressIndicatorViewModel.cs
+++ b/SafeExamBrowser.UserInterface.Classic/ViewModels/ProgressIndicatorViewModel.cs
@@ -13,14 +13,24 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
{
internal class ProgressIndicatorViewModel : INotifyPropertyChanged
{
+ private readonly object @lock = new object();
+
+ private Timer busyTimer;
private int currentProgress;
private bool isIndeterminate;
private int maxProgress;
private string status;
- private Timer busyTimer;
public event PropertyChangedEventHandler PropertyChanged;
+ public bool BusyIndication
+ {
+ set
+ {
+ HandleBusyIndication(value);
+ }
+ }
+
public int CurrentProgress
{
get
@@ -73,31 +83,35 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
}
}
- public virtual void StartBusyIndication()
- {
- StopBusyIndication();
-
- busyTimer = new Timer
- {
- AutoReset = true,
- Interval = 750
- };
-
- busyTimer.Elapsed += BusyTimer_Elapsed;
- busyTimer.Start();
- }
-
- public virtual void StopBusyIndication()
- {
- busyTimer?.Stop();
- busyTimer?.Close();
- }
-
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+ private void HandleBusyIndication(bool start)
+ {
+ lock (@lock)
+ {
+ if (busyTimer != null)
+ {
+ busyTimer.Elapsed -= BusyTimer_Elapsed;
+ busyTimer.Stop();
+ busyTimer.Close();
+ }
+
+ if (start)
+ {
+ busyTimer = new Timer
+ {
+ AutoReset = true,
+ Interval = 1500,
+ };
+ busyTimer.Elapsed += BusyTimer_Elapsed;
+ busyTimer.Start();
+ }
+ }
+ }
+
private void BusyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
var next = Status ?? string.Empty;
@@ -112,6 +126,7 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
}
Status = next;
+ busyTimer.Interval = 750;
}
}
}
diff --git a/SafeExamBrowser.UserInterface.Classic/ViewModels/RuntimeWindowViewModel.cs b/SafeExamBrowser.UserInterface.Classic/ViewModels/RuntimeWindowViewModel.cs
index e9dbb517..27ac559a 100644
--- a/SafeExamBrowser.UserInterface.Classic/ViewModels/RuntimeWindowViewModel.cs
+++ b/SafeExamBrowser.UserInterface.Classic/ViewModels/RuntimeWindowViewModel.cs
@@ -66,20 +66,6 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
}
}
- public override void StartBusyIndication()
- {
- base.StartBusyIndication();
-
- AnimatedBorderVisibility = Visibility.Hidden;
- }
-
- public override void StopBusyIndication()
- {
- base.StopBusyIndication();
-
- AnimatedBorderVisibility = Visibility.Visible;
- }
-
private void AppendLogMessage(ILogMessage message)
{
var time = message.DateTime.ToString("HH:mm:ss.fff");
diff --git a/SafeExamBrowser.UserInterface.Windows10/SplashScreen.xaml.cs b/SafeExamBrowser.UserInterface.Windows10/SplashScreen.xaml.cs
index d3a48787..473eb228 100644
--- a/SafeExamBrowser.UserInterface.Windows10/SplashScreen.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Windows10/SplashScreen.xaml.cs
@@ -100,15 +100,10 @@ namespace SafeExamBrowser.UserInterface.Windows10
model.CurrentProgress = value;
}
- public void UpdateText(TextKey key, bool showBusyIndication = false)
+ public void UpdateStatus(TextKey key, bool showBusyIndication = false)
{
- model.StopBusyIndication();
+ // TODO: Handle auto-start of busy indication
model.Status = text.Get(key);
-
- if (showBusyIndication)
- {
- model.StartBusyIndication();
- }
}
private void InitializeSplashScreen()