Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
UiService.cs
1//#define PROFILING
2
3using IdApp.Cv;
5using Mopups.Pages;
6using Mopups.Services;
11using SkiaSharp;
12using Svg.Skia;
13using System.Collections.Concurrent;
14using System.Collections.ObjectModel;
15using System.Diagnostics;
16using System.Diagnostics.CodeAnalysis;
17using System.Text;
18using Waher.Events;
20
21#if PROFILING
23#endif
24
26{
28 [Singleton]
30 {
31 private readonly Dictionary<string, NavigationArgs> navigationArgsMap = [];
32 private readonly ConcurrentQueue<UiTask> taskQueue = new();
33 private readonly Stack<PopupPage?> popupStack = new();
34 private NavigationArgs? latestArguments = null;
35 private bool isExecutingUiTasks = false;
36 private bool isNavigating = false;
37
41 public UiService()
42 {
43 }
44
45 #region UI-tasks
46
47 private void AddTask(UiTask Task)
48 {
49 this.taskQueue.Enqueue(Task);
50
51 if (!this.isExecutingUiTasks)
52 {
53 this.isExecutingUiTasks = true;
54
55 MainThread.BeginInvokeOnMainThread(async () =>
56 {
57 await this.ProcessAllTasks();
58 });
59 }
60 }
61
62 private async Task ProcessAllTasks()
63 {
64 try
65 {
66 do
67 {
68 if (this.taskQueue.TryDequeue(out UiTask? Task))
69 await Task.Execute();
70 }
71 while (!this.taskQueue.IsEmpty);
72 }
73 finally
74 {
75 this.isExecutingUiTasks = false;
76 }
77 }
78
79 #endregion
80
81 #region DisplayAlert
82
84 public Task<bool> DisplayAlert(string Title, string Message, string? Accept = null, string? Cancel = null)
85 {
86 DisplayAlert Task = new(Title, Message, Accept, Cancel);
87 this.AddTask(Task);
88 return Task.CompletionSource.Task;
89 }
90
92 public Task DisplayException(Exception Exception, string? Title = null)
93 {
94 Exception = Log.UnnestException(Exception);
95
96 StringBuilder sb = new();
97
98 if (Exception is not null)
99 {
100 sb.AppendLine(Exception.Message);
101
102 while (Exception.InnerException is not null)
103 {
104 Exception = Exception.InnerException;
105 sb.AppendLine(Exception.Message);
106 }
107 }
108 else
109 sb.AppendLine(ServiceRef.Localizer[nameof(AppResources.ErrorTitle)]);
110
111 return this.DisplayAlert(
112 Title ?? ServiceRef.Localizer[nameof(AppResources.ErrorTitle)], sb.ToString(),
113 ServiceRef.Localizer[nameof(AppResources.Ok)]);
114 }
115
116 #endregion
117
118 #region DisplayPrompt
119
121 public Task<string?> DisplayPrompt(string Title, string Message, string? Accept = null, string? Cancel = null)
122 {
123 DisplayPrompt Task = new(Title, Message, Accept, Cancel);
124 this.AddTask(Task);
125 return Task.CompletionSource.Task;
126 }
127
128 #endregion
129
130 #region Screen shots
131
136 public async Task<ImageSource?> TakeBlurredScreenshotAsync()
137 {
138 try
139 {
140#if PROFILING
141 Profiler Profiler = new("Blur", ProfilerThreadType.Sequential);
142
143 Profiler.Start();
144 Profiler.NewState("Capture");
145#endif
146 IScreenshotResult? Screen = await Screenshot.CaptureAsync();
147 if (Screen is null)
148 return null;
149
150#if PROFILING
151 Profiler.NewState("PNG");
152#endif
153 //Read screenshot
154 using Stream PngStream = await Screen.OpenReadAsync(ScreenshotFormat.Png, 20);
155
156#if PROFILING
157 Profiler.NewState("SKBitmap");
158#endif
159 // Original SKBitmap from PNG stream
160 SKBitmap OriginalBitmap = SKBitmap.FromImage(SKImage.FromEncodedData(PngStream));
161
162#if PROFILING
163 Profiler.NewState("Scale");
164#endif
165 // Desired width and height for the downscaled image
166 int DesiredWidth = OriginalBitmap.Width / 4; //Reduce the width by a quarter
167 int DesiredHeight = OriginalBitmap.Height / 4; //Reduce the height by a quarter
168
169 // Create an SKImageInfo with the desired width, height, and color type of the original
170 SKImageInfo resizedInfo = new(DesiredWidth, DesiredHeight, SKColorType.Gray8);
171
172 // Create a new SKBitmap for the downscaled image
173 SKBitmap resizedBitmap = OriginalBitmap.Resize(resizedInfo, SKFilterQuality.Medium);
174
175#if PROFILING
176 Profiler.NewState("Prepare");
177#endif
178 //Blur image
179 IMatrix RezisedMatrix = Bitmaps.FromBitmap(resizedBitmap);
180 IMatrix GreyChannelMatrix = RezisedMatrix.GrayScale();
181
182#if PROFILING
183 Profiler.NewState("Blur 5x5");
184#endif
185 IMatrix NewMatrix = IdApp.Cv.Transformations.Convolutions.ConvolutionOperations.Blur(GreyChannelMatrix, 5);
186
187#if PROFILING
188 Profiler.NewState("Blur2");
189#endif
191
192#if PROFILING
193 Profiler.NewState("Encode");
194#endif
195 // Continue with the blurring and encoding to PNG as before
196 byte[] Blurred = Bitmaps.EncodeAsPng(NewMatrix);
197 ImageSource BlurredScreen = ImageSource.FromStream(() => new MemoryStream(Blurred));
198
199#if PROFILING
200 Profiler.Stop();
201
202 string TimingUml = Profiler.ExportPlantUml(TimeUnit.MilliSeconds);
203
204 await App.SendAlert("```uml\r\n" + TimingUml + "\r\n```", "text/markdown");
205#endif
206 return BlurredScreen;
207 }
208 catch (Exception ex)
209 {
210 ServiceRef.LogService.LogException(ex);
211 return null;
212 }
213 }
214
219 public async Task<ImageSource?> TakeScreenshotAsync()
220 {
221 try
222 {
223 IScreenshotResult? Result = await Screenshot.CaptureAsync();
224 if (Result is null)
225 return null;
226
227 // Read the stream into a memory stream or byte array
228 using Stream Stream = await Result.OpenReadAsync();
229 MemoryStream MemoryStream = new();
230 await Stream.CopyToAsync(MemoryStream);
231 byte[] Bytes = MemoryStream.ToArray();
232
233 // Return a new MemoryStream based on the byte array for each invocation
234 return ImageSource.FromStream(() => new MemoryStream(Bytes));
235 }
236 catch (Exception ex)
237 {
238 ServiceRef.LogService.LogException(ex);
239 return null;
240 }
241 }
242
243 #endregion
244
245 #region Navigation
246
247
248
250 public Page CurrentPage => Shell.Current.CurrentPage;
251
253 public override Task Load(bool IsResuming, CancellationToken CancellationToken)
254 {
255 if (this.BeginLoad(IsResuming, CancellationToken))
256 {
257 try
258 {
259 Application? Application = Application.Current;
260
261 if (Application is not null)
262 {
263 Application.PropertyChanging += this.OnApplicationPropertyChanging;
264 Application.PropertyChanged += this.OnApplicationPropertyChanged;
265 }
266
267 this.SubscribeToShellNavigatingIfNecessary(Application);
268
269 this.EndLoad(true);
270 }
271 catch (Exception ex)
272 {
273 ServiceRef.LogService.LogException(ex);
274 this.EndLoad(false);
275 }
276 }
277
278
279 return Task.CompletedTask;
280 }
281
283 public override Task Unload()
284 {
285 if (this.BeginUnload())
286 {
287 try
288 {
289 Application? Application = Application.Current;
290 if (Application is not null)
291 {
292 this.UnsubscribeFromShellNavigatingIfNecessary(Application);
293 Application.PropertyChanged -= this.OnApplicationPropertyChanged;
294 Application.PropertyChanging -= this.OnApplicationPropertyChanging;
295 }
296 }
297 catch (Exception ex)
298 {
299 ServiceRef.LogService.LogException(ex);
300 }
301
302 this.EndUnload();
303 }
304
305 return Task.CompletedTask;
306 }
307
308
310 public Task GoToAsync(string Route, BackMethod BackMethod = BackMethod.Inherited, string? UniqueId = null)
311 {
312 // No args navigation will create a default navigation arguments
313 return this.GoToAsync<NavigationArgs>(Route, null, BackMethod, UniqueId);
314 }
315
317 public async Task GoToAsync<TArgs>(string Route, TArgs? Args, BackMethod BackMethod = BackMethod.Inherited, string? UniqueId = null) where TArgs : NavigationArgs, new()
318 {
319 await MainThread.InvokeOnMainThreadAsync(async () =>
320 {
321 ServiceRef.PlatformSpecific.HideKeyboard();
322
323 // Get the parent's navigation arguments
324 NavigationArgs? ParentArgs = this.GetCurrentNavigationArgs();
325
326 // Create a default navigation arguments if Args are null
327 NavigationArgs NavigationArgs = Args ?? new();
328
329 NavigationArgs.SetBackArguments(ParentArgs, BackMethod, UniqueId);
330 this.PushArgs(Route, NavigationArgs);
331
332 if (!string.IsNullOrEmpty(UniqueId))
333 Route += "?UniqueId=" + UniqueId;
334
335 try
336 {
337 this.isNavigating = true;
338 await Shell.Current.GoToAsync(Route, NavigationArgs.Animated);
339 }
340 catch (Exception ex)
341 {
342 ex = Log.UnnestException(ex);
343 ServiceRef.LogService.LogException(ex);
344 string ExtraInfo = Environment.NewLine + ex.Message;
345
346 await ServiceRef.UiService.DisplayAlert(
347 ServiceRef.Localizer[nameof(AppResources.ErrorTitle)],
348 ServiceRef.Localizer[nameof(AppResources.FailedToNavigateToPage), Route, ExtraInfo]);
349 }
350 finally
351 {
352 this.isNavigating = false;
354 }
355 });
356 }
357
359 public async Task GoBackAsync(bool Animate = true)
360 {
361 try
362 {
363 NavigationArgs? NavigationArgs = this.GetCurrentNavigationArgs();
364
365 if (NavigationArgs is not null) // the main view?
366 {
367 string BackRoute = NavigationArgs.GetBackRoute();
368
369 this.isNavigating = true;
370 await Shell.Current.GoToAsync(BackRoute, Animate);
371 }
372 else
373 {
374 ShellNavigationState State = Shell.Current.CurrentState;
375 if (Uri.TryCreate(State.Location, "..", out Uri? BackLocation))
376 await Shell.Current.GoToAsync(BackLocation);
377 else
378 await Shell.Current.GoToAsync(Constants.Pages.MainPage);
379 }
380 }
381 catch (Exception ex)
382 {
383 ServiceRef.LogService.LogException(ex);
384
385 await ServiceRef.UiService.DisplayAlert(
386 ServiceRef.Localizer[nameof(AppResources.ErrorTitle)],
387 ServiceRef.Localizer[nameof(AppResources.FailedToClosePage)]);
388 }
389 finally
390 {
391 this.isNavigating = false;
392 }
393 }
394
400 public TArgs? PopLatestArgs<TArgs>()
401 where TArgs : NavigationArgs, new()
402 {
403 if (this.latestArguments is TArgs Result)
404 {
405 this.latestArguments = null;
406 return Result;
407 }
408 else
409 return null;
410 }
411
417 public TArgs? TryGetArgs<TArgs>(string? UniqueId = null)
418 where TArgs : NavigationArgs, new()
419 {
420 if (this.TryGetArgs(out TArgs? Result, UniqueId))
421 return Result;
422 else
423 return null;
424 }
425
431 public bool TryGetArgs<TArgs>([NotNullWhen(true)] out TArgs? Args, string? UniqueId = null)
432 where TArgs : NavigationArgs, new()
433 {
435
436 if (this.CurrentPage is Page Page)
437 {
438 NavigationArgs = this.TryGetArgs(Page.GetType().Name, UniqueId);
439 string Route = Routing.GetRoute(Page);
440 NavigationArgs ??= this.TryGetArgs(Route, UniqueId);
441
442 if ((NavigationArgs is null) && (UniqueId is null) &&
443 (Page is BaseContentPage BasePage) && (BasePage.UniqueId is not null))
444 {
445 return this.TryGetArgs(out Args, BasePage.UniqueId);
446 }
447 }
448
449 if (NavigationArgs is TArgs TArgsArgs)
450 Args = TArgsArgs;
451 else
452 Args = null;
453
454 return (Args is not null);
455 }
456
457 private NavigationArgs? GetCurrentNavigationArgs()
458 {
459 this.TryGetArgs(out NavigationArgs? Args);
460 return Args;
461 }
462
463 private void OnApplicationPropertyChanged(object? Sender, System.ComponentModel.PropertyChangedEventArgs Args)
464 {
465 if (Args.PropertyName == nameof(Application.MainPage))
466 this.SubscribeToShellNavigatingIfNecessary((Application?)Sender);
467 }
468
469 private void OnApplicationPropertyChanging(object? Sender, PropertyChangingEventArgs Args)
470 {
471 if (Args.PropertyName == nameof(Application.MainPage))
472 this.UnsubscribeFromShellNavigatingIfNecessary((Application?)Sender);
473 }
474
475 private void SubscribeToShellNavigatingIfNecessary(Application? Application)
476 {
477 if (Application?.MainPage is Shell Shell)
478 Shell.Navigating += this.Shell_Navigating;
479 }
480
481 private void UnsubscribeFromShellNavigatingIfNecessary(Application? Application)
482 {
483 if (Application?.MainPage is Shell Shell)
484 Shell.Navigating -= this.Shell_Navigating;
485 }
486
487 private void Shell_Navigating(object? Sender, ShellNavigatingEventArgs e)
488 {
489 try
490 {
491 if ((e.Source == ShellNavigationSource.Pop) && e.CanCancel && !this.isNavigating)
492 {
493 e.Cancel();
494
495 MainThread.BeginInvokeOnMainThread(async () =>
496 {
497 await this.GoBackAsync();
498 });
499 }
500 }
501 catch (Exception ex)
502 {
503 ServiceRef.LogService.LogException(ex);
504 }
505 }
506
507 private static bool TryGetPageName(string Route, [NotNullWhen(true)] out string? PageName)
508 {
509 PageName = null;
510
511 if (!string.IsNullOrWhiteSpace(Route))
512 {
513 PageName = Route.TrimStart('.', '/');
514 return !string.IsNullOrWhiteSpace(PageName);
515 }
516
517 return false;
518 }
519
520 private void PushArgs(string Route, NavigationArgs Args)
521 {
522 this.latestArguments = Args;
523
524 if (TryGetPageName(Route, out string? PageName))
525 {
526 if (Args is not null)
527 {
528 string? UniqueId = Args.UniqueId;
529
530 if (!string.IsNullOrEmpty(UniqueId))
531 PageName += "?UniqueId=" + UniqueId;
532
533 this.navigationArgsMap[PageName] = Args;
534 }
535 else
536 this.navigationArgsMap.Remove(PageName);
537 }
538 }
539
540 private NavigationArgs? TryGetArgs(string Route, string? UniqueId)
541 {
542 if (!string.IsNullOrEmpty(UniqueId))
543 Route += "?UniqueId=" + UniqueId;
544
545 if (TryGetPageName(Route, out string? PageName) &&
546 this.navigationArgsMap.TryGetValue(PageName, out NavigationArgs? Args))
547 {
548 return Args;
549 }
550
551 return null;
552 }
553
554 #endregion
555
556 #region Popups
557
561 public ReadOnlyCollection<PopupPage?> PopupStack => new(this.popupStack.ToList());
562
564 public Task PushAsync<TPage, TViewModel>() where TPage : BasePopup, new() where TViewModel : BasePopupViewModel, new()
565 {
566 TPage page = new();
567 TViewModel viewModel = new();
568 page.ViewModel = viewModel;
569
570 this.popupStack.Push(page);
571 return MopupService.Instance.PushAsync(page);
572 }
573
575 public Task PushAsync<TPage, TViewModel>(TPage page, TViewModel viewModel) where TPage : BasePopup where TViewModel : BasePopupViewModel
576 {
577 page.ViewModel = viewModel;
578
579 this.popupStack.Push(page);
580 return MopupService.Instance.PushAsync(page);
581 }
582
584 public Task PushAsync<TPage, TViewModel>(TPage page) where TPage : BasePopup where TViewModel : BasePopupViewModel, new()
585 {
586 TViewModel viewModel = new();
587 page.ViewModel = viewModel;
588
589 this.popupStack.Push(page);
590 return MopupService.Instance.PushAsync(page);
591 }
592
594 public Task PushAsync<TPage, TViewModel>(TViewModel viewModel) where TPage : BasePopup, new() where TViewModel : BasePopupViewModel
595 {
596 TPage page = new()
597 {
598 ViewModel = viewModel
599 };
600
601 this.popupStack.Push(page);
602 return MopupService.Instance.PushAsync(page);
603 }
604
606 public Task PushAsync<TPage>() where TPage : BasePopup, new()
607 {
608 TPage page = new();
609 this.popupStack.Push(page);
610 return MopupService.Instance.PushAsync(page);
611 }
612
614 public Task PushAsync<TPage>(TPage page) where TPage : BasePopup
615 {
616 BasePopupViewModel? viewModel = page.ViewModel;
617 this.popupStack.Push(page);
618 return MopupService.Instance.PushAsync(page);
619 }
620
622 public async Task<TReturn?> PushAsync<TPage, TViewModel, TReturn>() where TPage : BasePopup, new() where TViewModel : ReturningPopupViewModel<TReturn>, new()
623 {
624 TPage page = new();
625 TViewModel viewModel = new();
626 page.ViewModel = viewModel;
627
628 this.popupStack.Push(page);
629 await MopupService.Instance.PushAsync(page);
630 return await viewModel.Result;
631 }
632
634 public async Task<TReturn?> PushAsync<TPage, TViewModel, TReturn>(TPage page, TViewModel viewModel) where TPage : BasePopup where TViewModel : ReturningPopupViewModel<TReturn>
635 {
636 page.ViewModel = viewModel;
637
638 this.popupStack.Push(page);
639 await MopupService.Instance.PushAsync(page);
640 return await viewModel.Result;
641 }
642
644 public async Task<TReturn?> PushAsync<TPage, TViewModel, TReturn>(TPage page) where TPage : BasePopup
645 where TViewModel : ReturningPopupViewModel<TReturn>, new()
646 {
647 TViewModel viewModel = new();
648 page.ViewModel = viewModel;
649
650 this.popupStack.Push(page);
651 await MopupService.Instance.PushAsync(page);
652 return await viewModel.Result;
653 }
654
656 public async Task<TReturn?> PushAsync<TPage, TViewModel, TReturn>(TViewModel viewModel) where TPage : BasePopup, new() where TViewModel : ReturningPopupViewModel<TReturn>
657 {
658 TPage page = new()
659 {
660 ViewModel = viewModel
661 };
662
663 this.popupStack.Push(page);
664 await MopupService.Instance.PushAsync(page);
665
666 return await viewModel.Result;
667 }
668
670 public async Task PopAsync()
671 {
672 if (this.popupStack.Count == 0)
673 return;
674 try
675 {
676 object? vm = this.popupStack.Pop()?.BindingContext;
677 if (vm is not null)
678 (vm as BasePopupViewModel)?.OnPop();
679
680 await MopupService.Instance.PopAsync();
681 }
682 catch (Exception ex)
683 {
684 ServiceRef.LogService.LogException(ex);
685 }
686 }
687
688 #endregion
689
690 #region Image
692 public async Task<ImageSource?> ConvertSvgUriToImageSource(string svgUri)
693 {
694 try
695 {
696 //Fetch image
697 using HttpClient httpClient = new();
698 using HttpResponseMessage response = await httpClient.GetAsync(svgUri);
699 if (!response.IsSuccessStatusCode)
700 return null;
701
702 // Load SVG image
703 byte[] contentBytes = await response.Content.ReadAsByteArrayAsync();
704 SKSvg svg = new();
705 using (MemoryStream stream = new(contentBytes))
706 {
707 svg.Load(stream);
708 }
709
710 //Check that the svg was parsed correct
711 if (svg.Picture is null)
712 return null;
713
714 using (MemoryStream stream = new())
715 {
716 if (svg.Picture.ToImage(stream, SKColor.Parse("#00FFFFFF"), SKEncodedImageFormat.Png, 100, 1, 1, SKColorType.Rgba8888, SKAlphaType.Premul, SKColorSpace.CreateSrgb()))
717 return ImageSource.FromStream(() => new MemoryStream(stream.ToArray()));
718 return null;
719 }
720 }
721 catch (Exception ex)
722 {
723 ServiceRef.LogService.LogException(ex);
724 return null;
725 }
726
727 }
728 #endregion
729 }
730}
Static methods managing conversion to and from bitmap representations.
Definition: Bitmaps.cs:12
static byte[] EncodeAsPng(IMatrix M)
Encodes an image in a matrix using PNG.
Definition: Bitmaps.cs:318
static IMatrix FromBitmap(SKBitmap Bmp)
Craetes a matrix from a bitmap.
Definition: Bitmaps.cs:66
Static class for Convolution Operations, implemented as extensions.
Definition: Blur.cs:9
static Matrix< float > Blur(this Matrix< float > M)
Blurs an image.
Definition: Blur.cs:15
The Application class, representing an instance of the Neuro-Access app.
Definition: App.xaml.cs:69
Absolute paths to important pages.
Definition: Constants.cs:733
const string MainPage
Path to main page.
Definition: Constants.cs:737
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
bool BeginLoad(bool IsResuming, CancellationToken CancellationToken)
Sets the IsLoading flag if the service isn't already loading.
void EndLoad(bool isLoaded)
Sets the IsLoading and IsLoaded flags and fires an event representing the current load state of the s...
bool IsResuming
If App is resuming service.
bool BeginUnload()
Sets the IsLoading flag if the service isn't already unloading.
void EndUnload()
Sets the IsLoading and IsLoaded flags and fires an event representing the current load state of the s...
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ILogService LogService
Log service.
Definition: ServiceRef.cs:91
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:55
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
An base class holding page specific navigation parameters.
string? UniqueId
An unique view identifier used to search the args of similar view types.
readonly TaskCompletionSource< bool > NavigationCompletionSource
The completion source for the navigation task. Will return true when the navigation and transitions a...
void SetBackArguments(NavigationArgs? ParentArgs, BackMethod BackMethod=BackMethod.Inherited, string? UniqueId=null)
Sets the reference to the main parent's NavigationArgs.
string GetBackRoute()
Get the route used for the IUiService.GoBackAsync method.
bool Animated
Is the navigation animated
Abstract base class for UI tasks.
Definition: UiTask.cs:7
abstract Task Execute()
Executes the task.
UiService()
Creates a new instance of the UiService class.
Definition: UiService.cs:41
Task PushAsync< TPage >()
Pushes a popup, without any viewmodel binding, onto the current view
Definition: UiService.cs:606
override Task Unload()
Unloads the specified service.
Definition: UiService.cs:283
async Task GoToAsync< TArgs >(string Route, TArgs? Args, BackMethod BackMethod=BackMethod.Inherited, string? UniqueId=null)
Navigates the AppShell to the specified route, with page arguments to match.
Definition: UiService.cs:317
TArgs? TryGetArgs< TArgs >(string? UniqueId=null)
Returns the page's arguments from the (one-level) deep navigation stack.
Definition: UiService.cs:417
Task< bool > DisplayAlert(string Title, string Message, string? Accept=null, string? Cancel=null)
Displays an alert/message box to the user. If Accept or Cancel was pressed
Definition: UiService.cs:84
TArgs? PopLatestArgs< TArgs >()
Pops the latests navigation arguments. Can only be used once to get the navigation arguments....
Definition: UiService.cs:400
Task DisplayException(Exception Exception, string? Title=null)
Displays an alert/message box to the user.
Definition: UiService.cs:92
override Task Load(bool IsResuming, CancellationToken CancellationToken)
Loads the specified service.
Definition: UiService.cs:253
Task GoToAsync(string Route, BackMethod BackMethod=BackMethod.Inherited, string? UniqueId=null)
Navigates the AppShell to the specified route, with page arguments to match.
Definition: UiService.cs:310
async Task< ImageSource?> ConvertSvgUriToImageSource(string svgUri)
Fetches a SVG and converts it to a PNG image source. An image Source representing the SVG file or nul...
Definition: UiService.cs:692
async Task GoBackAsync(bool Animate=true)
Returns to the previous page/route.
Definition: UiService.cs:359
ReadOnlyCollection< PopupPage?> PopupStack
The current stack of popup pages.
Definition: UiService.cs:561
async Task< ImageSource?> TakeScreenshotAsync()
Takes a screen-shot.
Definition: UiService.cs:219
async Task< ImageSource?> TakeBlurredScreenshotAsync()
Takes a blurred screen shot
Definition: UiService.cs:136
Task PushAsync< TPage, TViewModel >()
Pushes a popup onto the current view
Definition: UiService.cs:564
Task< string?> DisplayPrompt(string Title, string Message, string? Accept=null, string? Cancel=null)
Prompts the user for some input. User input
Definition: UiService.cs:121
async Task< TReturn?> PushAsync< TPage, TViewModel, TReturn >()
Pushes a popup onto the current view Return value, or null if cancelled.
Definition: UiService.cs:622
async Task PopAsync()
Closes the current popup.
Definition: UiService.cs:670
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static Exception UnnestException(Exception Exception)
Unnests an exception, to extract the relevant inner exception.
Definition: Log.cs:818
Class that keeps track of events and timing.
Definition: Profiler.cs:67
void Stop()
Stops measuring time.
Definition: Profiler.cs:210
void NewState(string State)
Main Thread changes state.
Definition: Profiler.cs:247
string ExportPlantUml(TimeUnit TimeUnit)
Exports events to PlantUML.
Definition: Profiler.cs:510
void Start()
Starts measuring time.
Definition: Profiler.cs:200
Interface for matrices.
Definition: IMatrix.cs:9
Service serializing and managing UI-related tasks.
Definition: IUiService.cs:14
Definition: Abs.cs:2
Definition: Abs.cs:2
BackMethod
Navigation Back Method
Definition: BackMethod.cs:7
TimeUnit
Options for presenting time in reports.
Definition: Profiler.cs:16
ProfilerThreadType
Type of profiler thread.