SEBWIN-221: Changed IProgressIndicator implementation to automatically show busy indication after a delay. All application controllers now create new splash screens before executing an operation sequence.
This commit is contained in:
parent
ed43534e5b
commit
7a57cdf93b
10 changed files with 62 additions and 76 deletions
|
@ -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()
|
||||
|
|
|
@ -42,8 +42,7 @@ namespace SafeExamBrowser.Contracts.UserInterface
|
|||
|
||||
/// <summary>
|
||||
/// 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!
|
||||
/// </summary>
|
||||
void UpdateText(TextKey key, bool showBusyIndication = false);
|
||||
void UpdateStatus(TextKey key, bool busyIndication = false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IConfigurationRepository> configuration;
|
||||
private Mock<ISessionData> session;
|
||||
private Settings settings;
|
||||
private Mock<IProgressIndicator> progressIndicator;
|
||||
private ServiceOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
|
@ -38,7 +36,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
configuration = new Mock<IConfigurationRepository>();
|
||||
session = new Mock<ISessionData>();
|
||||
settings = new Settings();
|
||||
progressIndicator = new Mock<IProgressIndicator>();
|
||||
|
||||
configuration.SetupGet(c => c.CurrentSession).Returns(session.Object);
|
||||
configuration.SetupGet(c => c.CurrentSettings).Returns(settings);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<ColumnDefinition Width="155" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Classic;component/Images/SplashScreen.png" />
|
||||
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Margin="10,75,10,10" TextWrapping="Wrap" />
|
||||
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" 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}" BorderThickness="0" />
|
||||
<TextBlock x:Name="StatusTextBlock" Grid.Row="1" Text="{Binding Path=Status}" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue