public async void RefreshTiles() { // Cancel previous loads if (_tokenSource != null) { _tokenSource.Cancel(); while (_tokenSource != null) { await Task.Delay(1); } } Spinner spinner = null; Application.Invoke(() => { // Clear controls _buttons.Clear(); ClearTiles(); Content = spinner = new Spinner { Animate = true, MinHeight = 50, MinWidth = 50 }; }); while (spinner == null) { await Task.Delay(5); } _buttonsPerRow = CalculateButtonsPerRow((float)Size.Width); var i = 0; _tokenSource = new CancellationTokenSource(); try { var tiles = await LoadTiles(_tokenSource.Token); Application.Invoke(() => { foreach (var tile in tiles) { if (tile == null) { continue; } if (i >= _buttonsPerRow) { PushNewRow(); i = 0; } try { Xwt.Drawing.Image image = tile.Image?.ToXwtImage()?.ScaleToSize(100); Widget widget = null; if (ParkitectNexus.Data.Utilities.OperatingSystem.Detect() == SupportedOperatingSystem.Linux) { if (image != null) { Image lighterImage = image.WithAlpha(.7f); var clickableImage = new ImageView(image); clickableImage.ButtonPressed += (sender, args) => tile.ClickAction(); clickableImage.MouseEntered += (object sender, EventArgs e) => { ((ImageView)sender).Image = lighterImage; ((Widget)sender).BackgroundColor = Color.FromBytes(255, 255, 255); }; clickableImage.MouseExited += (object sender, EventArgs e) => { ((ImageView)sender).Image = image; ((Widget)sender).BackgroundColor = tile.BackgroundColor; }; widget = clickableImage; } else { var label = new Label(tile.Text); label.ButtonPressed += (sender, args) => tile.ClickAction(); label.Wrap = WrapMode.Word; label.TextAlignment = Alignment.Center; label.MouseEntered += (object sender, EventArgs e) => { ((Widget)sender).BackgroundColor = Color.FromBytes(255, 255, 255); }; label.MouseExited += (object sender, EventArgs e) => { ((Widget)sender).BackgroundColor = tile.BackgroundColor; }; widget = label; } } else { var button = new Button(image) { Label = tile.Image == null ? tile.Text : null, TooltipText = tile.Text, Style = ButtonStyle.Borderless, BackgroundColor = tile.BackgroundColor, ImagePosition = ContentPosition.Center }; Image lighterImage = image.WithAlpha(.7f); button.MouseEntered += (object sender, EventArgs e) => { ((Button)sender).Image = lighterImage; ((Widget)sender).BackgroundColor = Color.FromBytes(255, 255, 255); }; button.MouseExited += (object sender, EventArgs e) => { ((Button)sender).Image = image; ((Widget)sender).BackgroundColor = tile.BackgroundColor; }; button.Clicked += (sender, args) => tile.ClickAction(); widget = button; } widget.WidthRequest = 100; widget.HeightRequest = 100; widget.MinWidth = 0; widget.BackgroundColor = tile.BackgroundColor; _buttons.Add(widget); _rows.Peek().PackStart(widget); i++; } catch (Exception e) { _log.WriteLine("Failed to convert Tile object to UI"); _log.WriteException(e); } } Content = _box; }); } catch (TaskCanceledException) { } catch (OperationCanceledException) { } finally { _tokenSource?.Dispose(); _tokenSource = null; } }