SEBWIN-141: Touch-optimized main elements of mobile user interface, next up: Custom message box implementation.

This commit is contained in:
dbuechel 2019-03-22 10:09:51 +01:00
parent b7167d35f6
commit ca939f045c
12 changed files with 72 additions and 47 deletions

View file

@ -44,6 +44,8 @@ using SafeExamBrowser.Monitoring.Processes;
using SafeExamBrowser.Monitoring.Windows; using SafeExamBrowser.Monitoring.Windows;
using SafeExamBrowser.SystemComponents; using SafeExamBrowser.SystemComponents;
using SafeExamBrowser.WindowsApi; using SafeExamBrowser.WindowsApi;
using Desktop = SafeExamBrowser.UserInterface.Desktop;
using Mobile = SafeExamBrowser.UserInterface.Mobile;
namespace SafeExamBrowser.Client namespace SafeExamBrowser.Client
{ {
@ -293,9 +295,9 @@ namespace SafeExamBrowser.Client
switch (uiMode) switch (uiMode)
{ {
case UserInterfaceMode.Mobile: case UserInterfaceMode.Mobile:
return new UserInterface.Mobile.ActionCenter(); return new Mobile.ActionCenter();
default: default:
return new UserInterface.Desktop.ActionCenter(); return new Desktop.ActionCenter();
} }
} }
@ -304,9 +306,9 @@ namespace SafeExamBrowser.Client
switch (uiMode) switch (uiMode)
{ {
case UserInterfaceMode.Mobile: case UserInterfaceMode.Mobile:
return new UserInterface.Mobile.MessageBox(text); return new Mobile.MessageBox(text);
default: default:
return new UserInterface.Desktop.MessageBox(text); return new Desktop.MessageBox(text);
} }
} }
@ -315,9 +317,9 @@ namespace SafeExamBrowser.Client
switch (uiMode) switch (uiMode)
{ {
case UserInterfaceMode.Mobile: case UserInterfaceMode.Mobile:
return new UserInterface.Mobile.Taskbar(new ModuleLogger(logger, nameof(UserInterface.Mobile.Taskbar))); return new Mobile.Taskbar(new ModuleLogger(logger, nameof(Mobile.Taskbar)));
default: default:
return new UserInterface.Desktop.Taskbar(new ModuleLogger(logger, nameof(UserInterface.Desktop.Taskbar))); return new Desktop.Taskbar(new ModuleLogger(logger, nameof(Desktop.Taskbar)));
} }
} }
@ -326,9 +328,9 @@ namespace SafeExamBrowser.Client
switch (uiMode) switch (uiMode)
{ {
case UserInterfaceMode.Mobile: case UserInterfaceMode.Mobile:
return new UserInterface.Mobile.UserInterfaceFactory(text); return new Mobile.UserInterfaceFactory(text);
default: default:
return new UserInterface.Desktop.UserInterfaceFactory(text); return new Desktop.UserInterfaceFactory(text);
} }
} }

View file

@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
mc:Ignorable="d" Title="BrowserWindow" Background="#FFF0F0F0" Height="500" Width="750" MinHeight="250" MinWidth="250" Icon=".\Images\SafeExamBrowser.ico"> mc:Ignorable="d" Title="BrowserWindow" Background="#FFF0F0F0" FontSize="16" Height="500" Width="750" MinHeight="250" MinWidth="250" Icon=".\Images\SafeExamBrowser.ico">
<Window.Resources> <Window.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
@ -29,18 +29,18 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BackwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" /> <Button Grid.Column="0" x:Name="BackwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ForwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" /> <Button Grid.Column="1" x:Name="ForwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="2" x:Name="ReloadButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" /> <Button Grid.Column="2" x:Name="ReloadButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Grid Grid.Column="3" Height="25" Margin="5,0"> <Grid Grid.Column="3" Height="50" Margin="5,0">
<TextBox x:Name="UrlTextBox" HorizontalAlignment="Stretch" Padding="5,0" VerticalContentAlignment="Center" /> <TextBox x:Name="UrlTextBox" HorizontalAlignment="Stretch" Margin="5" Padding="8" VerticalContentAlignment="Center" />
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" HorizontalAlignment="Right" Icon="Spinner" Margin="5,3" SpinDuration="1.5" Visibility="Collapsed" /> <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" HorizontalAlignment="Right" Icon="Spinner" Margin="12,10" SpinDuration="1.5" Visibility="Collapsed" />
</Grid> </Grid>
<Button Grid.Column="4" x:Name="MenuButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" /> <Button Grid.Column="4" x:Name="MenuButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}"> <Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}">
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="250"> <Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="350">
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<Grid Height="40"> <Grid Height="55">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />

View file

@ -27,8 +27,8 @@
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock x:Name="TimeTextBlock" Grid.Row="0" Text="{Binding Path=Time}" Foreground="White" HorizontalAlignment="Center" /> <TextBlock x:Name="TimeTextBlock" Grid.Row="0" Text="{Binding Path=Time}" FontSize="15" Foreground="White" HorizontalAlignment="Center" />
<TextBlock x:Name="DateTextBlock" Grid.Row="1" Text="{Binding Path=Date}" Foreground="White" HorizontalAlignment="Center" /> <TextBlock x:Name="DateTextBlock" Grid.Row="1" Text="{Binding Path=Date}" FontSize="15" Foreground="White" HorizontalAlignment="Center" />
</Grid> </Grid>
</Grid> </Grid>
</Button> </Button>

View file

@ -30,7 +30,7 @@
<RowDefinition Height="3*" /> <RowDefinition Height="3*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<fa:ImageAwesome Grid.Row="0" Foreground="Black" Icon="KeyboardOutline" Margin="2" VerticalAlignment="Center" /> <fa:ImageAwesome Grid.Row="0" Foreground="Black" Icon="KeyboardOutline" Margin="2" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" x:Name="Text" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" /> <TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
</Grid> </Grid>
</Button> </Button>
</Grid> </Grid>

View file

@ -21,7 +21,7 @@
<RowDefinition Height="3*" /> <RowDefinition Height="3*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ContentControl Grid.Row="0" x:Name="Icon" VerticalAlignment="Center" /> <ContentControl Grid.Row="0" x:Name="Icon" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" x:Name="Text" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" /> <TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
</Grid> </Grid>
</Button> </Button>
</Grid> </Grid>

View file

@ -21,7 +21,7 @@
<RowDefinition Height="3*" /> <RowDefinition Height="3*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ContentControl Grid.Row="0" x:Name="Icon" Foreground="Black" VerticalAlignment="Center" /> <ContentControl Grid.Row="0" x:Name="Icon" Foreground="Black" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" x:Name="Text" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" /> <TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
</Grid> </Grid>
</Button> </Button>
</Grid> </Grid>

View file

@ -35,7 +35,7 @@
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" /> <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
<Image x:Name="NetworkStatusIcon" Height="8" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" /> <Image x:Name="NetworkStatusIcon" Height="8" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" />
</Grid> </Grid>
<TextBlock Grid.Row="1" x:Name="Text" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" /> <TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
</Grid> </Grid>
</Button> </Button>
</Grid> </Grid>

View file

@ -14,7 +14,8 @@
</ResourceDictionary> </ResourceDictionary>
</Window.Resources> </Window.Resources>
<Grid> <Grid>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Auto" Padding="5,5,5,0" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}"> <ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Auto" Padding="5,5,5,0" PanningMode="Both" VerticalScrollBarVisibility="Auto"
Template="{StaticResource SmallBarScrollViewer}">
<TextBlock x:Name="LogContent" FontFamily="Consolas" /> <TextBlock x:Name="LogContent" FontFamily="Consolas" />
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>

View file

@ -5,7 +5,7 @@
xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile"
mc:Ignorable="d" Height="200" Width="450" ResizeMode="NoResize" Topmost="True"> mc:Ignorable="d" Background="Transparent" Height="750" Width="1000" FontSize="16" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStyle="None">
<Window.Resources> <Window.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
@ -13,32 +13,35 @@
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Window.Resources> </Window.Resources>
<Grid FocusManager.FocusedElement="{Binding ElementName=Password}"> <Grid Background="#66000000" FocusManager.FocusedElement="{Binding ElementName=Password}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="2*" /> <RowDefinition Height="*" />
<RowDefinition Height="1*" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid Grid.Row="0"> <Grid Grid.Row="0" />
<Grid> <Grid Grid.Row="1" Background="White">
<Grid Margin="25">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<fa:ImageAwesome Grid.Column="0" x:Name="NoAdapterIcon" Foreground="LightGray" Icon="Key" Margin="25" Rotation="90" Width="50" /> <fa:ImageAwesome Grid.Column="0" x:Name="NoAdapterIcon" Foreground="LightGray" Icon="Key" Margin="25" Rotation="90" Width="75" />
<Grid Grid.Column="1" Margin="0,0,25,25"> <Grid Grid.Column="1" Margin="25,0,25,25">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" x:Name="Message" Margin="0,0,0,5" TextWrapping="WrapWithOverflow" VerticalAlignment="Bottom" /> <TextBlock Grid.Row="0" x:Name="Message" Margin="12,20" TextWrapping="WrapWithOverflow" VerticalAlignment="Bottom" />
<PasswordBox Grid.Row="1" x:Name="Password" Height="25" VerticalContentAlignment="Center" /> <PasswordBox Grid.Row="1" x:Name="Password" Padding="12" VerticalContentAlignment="Center" />
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
<Grid Grid.Row="1" Background="{StaticResource BackgroundBrush}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid Grid.Row="2" Background="{StaticResource BackgroundBrush}">
<WrapPanel Orientation="Horizontal" Margin="25,0" HorizontalAlignment="Right" VerticalAlignment="Center"> <WrapPanel Orientation="Horizontal" Margin="50,25" HorizontalAlignment="Right" VerticalAlignment="Center">
<Button x:Name="ConfirmButton" Cursor="Hand" Margin="10,0" Padding="10,5" MinWidth="75" /> <Button x:Name="ConfirmButton" Cursor="Hand" Margin="20,0" Padding="20,10" MinWidth="100" />
<Button x:Name="CancelButton" Cursor="Hand" Padding="10,5" MinWidth="75" /> <Button x:Name="CancelButton" Cursor="Hand" Padding="20,10" MinWidth="100" />
</WrapPanel> </WrapPanel>
</Grid> </Grid>
</Grid> </Grid>

View file

@ -47,9 +47,10 @@ namespace SafeExamBrowser.UserInterface.Mobile
if (parent is Window) if (parent is Window)
{ {
Owner = parent as Window; Owner = parent as Window;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
} }
InitializeBounds();
if (ShowDialog() is true) if (ShowDialog() is true)
{ {
result.Password = Password.Password; result.Password = Password.Password;
@ -60,11 +61,20 @@ namespace SafeExamBrowser.UserInterface.Mobile
}); });
} }
private void InitializeBounds()
{
Left = 0;
Top = 0;
Height = SystemParameters.PrimaryScreenHeight;
Width = SystemParameters.PrimaryScreenWidth;
}
private void InitializePasswordDialog(string message, string title) private void InitializePasswordDialog(string message, string title)
{ {
InitializeBounds();
Message.Text = message; Message.Text = message;
Title = title; Title = title;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
CancelButton.Content = text.Get(TextKey.PasswordDialog_Cancel); CancelButton.Content = text.Get(TextKey.PasswordDialog_Cancel);
CancelButton.Click += CancelButton_Click; CancelButton.Click += CancelButton_Click;
@ -74,6 +84,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
Closing += (o, args) => closing?.Invoke(); Closing += (o, args) => closing?.Invoke();
Password.KeyUp += Password_KeyUp; Password.KeyUp += Password_KeyUp;
SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged;
} }
private void CancelButton_Click(object sender, RoutedEventArgs e) private void CancelButton_Click(object sender, RoutedEventArgs e)
@ -97,6 +108,14 @@ namespace SafeExamBrowser.UserInterface.Mobile
} }
} }
private void SystemParameters_StaticPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(SystemParameters.WorkArea))
{
Dispatcher.InvokeAsync(InitializeBounds);
}
}
private class PasswordDialogResult : IPasswordDialogResult private class PasswordDialogResult : IPasswordDialogResult
{ {
public string Password { get; set; } public string Password { get; set; }

View file

@ -5,24 +5,24 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile"
mc:Ignorable="d" mc:Ignorable="d"
Title="SplashScreen" Background="White" Height="200" Width="350" WindowStyle="None" WindowStartupLocation="CenterScreen" Title="SplashScreen" Background="White" FontSize="16" Height="250" Width="500" WindowStyle="None" WindowStartupLocation="CenterScreen"
Cursor="Wait" Icon="./Images/SafeExamBrowser.ico" ResizeMode="NoResize" Topmost="True"> Cursor="Wait" Icon="./Images/SafeExamBrowser.ico" ResizeMode="NoResize" Topmost="True">
<Border BorderBrush="DodgerBlue" BorderThickness="1"> <Border BorderBrush="DodgerBlue" BorderThickness="1">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="25" /> <RowDefinition Height="50" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid Grid.Row="0"> <Grid Grid.Row="0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="155" /> <ColumnDefinition Width="225" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/SplashScreen.png" /> <Image Grid.Column="0" Grid.ColumnSpan="2" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/SplashScreen.png" />
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" Margin="10,75,10,10" TextWrapping="Wrap" /> <TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" Margin="10,85,10,10" TextWrapping="Wrap" />
</Grid> </Grid>
<ProgressBar x:Name="ProgressBar" Grid.Row="1" Minimum="0" Maximum="{Binding Path=MaxProgress}" Value="{Binding Path=CurrentProgress}" IsIndeterminate="{Binding Path=IsIndeterminate}" BorderThickness="0" /> <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" /> <TextBlock x:Name="StatusTextBlock" Grid.Row="1" Text="{Binding Path=Status}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid> </Grid>
</Border> </Border>
</Window> </Window>

View file

@ -125,7 +125,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
InfoTextBlock.Inlines.Add(new Run($"Version {appConfig.ProgramVersion}") { FontStyle = FontStyles.Italic }); 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 LineBreak()); InfoTextBlock.Inlines.Add(new LineBreak());
InfoTextBlock.Inlines.Add(new Run(appConfig.ProgramCopyright) { FontSize = 10 }); InfoTextBlock.Inlines.Add(new Run(appConfig.ProgramCopyright) { FontSize = 12 });
} }
} }
} }