private void ShowcaseView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var showcaseView = sender as SkiaSharp.Views.WPF.SKElement;
            var position     = DpiScaler.ScaleDown(e.GetPosition(showcaseView));
            var map          = Showcase.Maps[int.Parse(showcaseView.Tag.ToString())];
            var hoveredLoc   = GetHoveredLocation(map, position, true);

            if (hoveredLoc is null)
            {
                return;
            }

            var safeHoveredLoc = hoveredLoc.Value;
            var hoveredTile    = map.GetTile(safeHoveredLoc);
            var figure         = hoveredTile?.Parent;

            if (figure is null)
            {
                return;
            }

            Showcase.Pick(figure);
            showcaseView.InvalidateVisual();
            Captured = new(figure);

            DraggingView.Visibility = Visibility.Visible;
            DraggingView.InvalidateVisual();

            ShowcaseClickOffset = Point.Subtract(position, new Point());
            DraggingView_MouseMove(sender, e);
        }
        private void DraggingView_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (Captured is null || Lost)
            {
                return;
            }

            var draggableLoc = GetHoveredLocation(GameMap, DpiScaler.ScaleDown(Captured.Point), false);

            if (draggableLoc is not null)
            {
                var safeDraggableLoc = draggableLoc.Value;
                if (Captured.Figure.TryPutOnMap(GameMap, safeDraggableLoc))
                {
                    Showcase.Update();
                    Engine.Engine.Score += Captured.Figure.GetTiles().Count();
                    if (Engine.Engine.Score > Properties.Settings.Default.BestScore)
                    {
                        Properties.Settings.Default.BestScore = Engine.Engine.Score;
                        Properties.Settings.Default.Save();
                    }
                    Title = "Счёт: " + Engine.Engine.Score + " / " + Properties.Settings.Default.BestScore;

                    if (DidLose())
                    {
                        Lost          = true;
                        Captured      = null;
                        MouseLocation = new();
                        MapView.InvalidateVisual();
                        DraggingView.InvalidateVisual();
                        Showcase1View.InvalidateVisual();
                        Showcase2View.InvalidateVisual();
                        Showcase3View.InvalidateVisual();
                        return;
                    }
                }
                else
                {
                    Showcase.Return(Captured.Figure);
                }
            }
            else
            {
                Showcase.Return(Captured.Figure);
            }

            Captured                = null;
            MouseLocation           = new();
            DraggingView.Visibility = Visibility.Hidden;
            MapView.InvalidateVisual();
            DraggingView.InvalidateVisual();
            Showcase1View.InvalidateVisual();
            Showcase2View.InvalidateVisual();
            Showcase3View.InvalidateVisual();
        }
        private void MainView_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;

            canvas.Clear(SKColors.White);

            for (int x = 0; x < GameMap.Size; ++x)
            {
                for (int y = 0; y < GameMap.Size; ++y)
                {
                    var skRect = new SKRect(
                        (x * (float)TileSize.Width + TileMargin) * (float)DpiScaler.Scale.Value,
                        (y * (float)TileSize.Height + TileMargin) * (float)DpiScaler.Scale.Value,
                        ((x + 1) * (float)TileSize.Width) * (float)DpiScaler.Scale.Value,
                        ((y + 1) * (float)TileSize.Height) * (float)DpiScaler.Scale.Value);

                    var tile = GameMap.GetTile(x, y);
                    if (tile is null)
                    {
                        Paint.Color = new(0xffd6d6d6);
                    }
                    else
                    {
                        Paint.Color = new(tile.Color);
                    }

                    canvas.DrawRect(skRect, Paint);
                }
            }

            // debug
            if (Captured is not null && !Lost)
            {
                Paint.Color = new(0x44ffffff);

                var draggableLoc = GetHoveredLocation(GameMap, DpiScaler.ScaleDown(Captured.Point), false);
                if (draggableLoc is not null)
                {
                    foreach (var tile in Captured.Figure.GetTiles())
                    {
                        var safeDraggableLoc = draggableLoc.Value;
                        var skRect           = new SKRect(
                            ((safeDraggableLoc.X + tile.X) * (float)TileSize.Width + TileMargin) * (float)DpiScaler.Scale.Value,
                            ((safeDraggableLoc.Y + tile.Y) * (float)TileSize.Height + TileMargin) * (float)DpiScaler.Scale.Value,
                            ((safeDraggableLoc.X + tile.X + 1) * (float)TileSize.Width) * (float)DpiScaler.Scale.Value,
                            ((safeDraggableLoc.Y + tile.Y + 1) * (float)TileSize.Height) * (float)DpiScaler.Scale.Value);

                        canvas.DrawRect(skRect, Paint);
                    }
                }
            }
        }