private void TilesetView_PaintTiles(object sender, TilesetViewPaintTilesEventArgs e)
        {
            Color highlightColor = Color.FromArgb(255, 255, 255);
            Color baseTileDrawColor = Color.FromArgb(255, 192, 128);
            Color externalDrawColor = Color.FromArgb(128, 192, 255);
            Color nonConnectedColor = Color.FromArgb(128, 0, 0, 0);
            Brush brushNonConnected = new SolidBrush(nonConnectedColor);
            TilesetAutoTileInput autoTile = this.SelectedAutoTile;

            // Early-out if there is nothing we can edit right now
            if (autoTile == null)
                return;

            // If we're in a special draw mode, switch highlight colors to indicate this.
            if (this.isExternalDraw)
                highlightColor = externalDrawColor;
            else if (this.isBaseTileDraw)
                highlightColor = baseTileDrawColor;

            // Set up shared working data
            TilesetAutoTileItem[] tileInput = autoTile.TileInput.Data;
            TilesetViewPaintTileData hoveredData = default(TilesetViewPaintTileData);
            TilesetAutoTileItem hoveredItem = default(TilesetAutoTileItem);
            GraphicsPath connectedOutlines = new GraphicsPath();
            GraphicsPath connectedRegion = new GraphicsPath();

            // Draw all the tiles that we're supposed to paint
            for (int i = 0; i < e.PaintedTiles.Count; i++)
            {
                TilesetViewPaintTileData paintData = e.PaintedTiles[i];

                // Prepare some data we'll need for drawing the per-tile info overlay
                bool tileHovered = this.TilesetView.HoveredTileIndex == paintData.TileIndex;
                bool isBaseTile = autoTile.BaseTileIndex == paintData.TileIndex;
                TilesetAutoTileItem item = (autoTile.TileInput.Count > paintData.TileIndex) ?
                    tileInput[paintData.TileIndex] :
                    default(TilesetAutoTileItem);

                // Remember hovered item data for later (post-overlay)
                if (tileHovered)
                {
                    hoveredData = paintData;
                    hoveredItem = item;
                }

                // Accumulate a shared region for displaying connectivity, as well as a path of all their outlines
                if (item.IsAutoTile)
                {
                    Rectangle centerRect = GetConnectivityRegionRect(TileConnection.None, paintData.ViewRect);
                    connectedRegion.AddRectangle(centerRect);
                    DrawConnectivityRegion(connectedRegion, item.Neighbours, paintData.ViewRect);
                    DrawConnectivityOutlines(connectedOutlines, item.Neighbours, paintData.ViewRect);
                }
                else if (item.ConnectsToAutoTile)
                {
                    connectedRegion.AddRectangle(paintData.ViewRect);
                }

                // Highlight base tile and external connecting tiles
                if (isBaseTile)
                    DrawTileHighlight(e.Graphics, paintData.ViewRect, baseTileDrawColor);
                else if (!item.IsAutoTile && item.ConnectsToAutoTile)
                    DrawTileHighlight(e.Graphics, paintData.ViewRect, externalDrawColor);
            }

            // Fill all non-connected regions with the overlay brush
            Region surroundingRegion = new Region();
            surroundingRegion.MakeInfinite();
            surroundingRegion.Exclude(connectedRegion);
            e.Graphics.IntersectClip(surroundingRegion);
            e.Graphics.FillRectangle(brushNonConnected, this.TilesetView.ClientRectangle);
            e.Graphics.ResetClip();

            // Draw connected region outlines
            e.Graphics.DrawPath(Pens.White, connectedOutlines);

            // Draw a tile-based hover indicator
            if (!hoveredData.ViewRect.IsEmpty && !this.isBaseTileDraw && !this.isExternalDraw)
                DrawHoverIndicator(e.Graphics, hoveredData.ViewRect, 64, highlightColor);

            // Draw a hover indicator for a specific hovered region
            if (!hoveredData.ViewRect.IsEmpty)
            {
                if (!this.isBaseTileDraw && !this.isExternalDraw)
                    DrawHoverIndicator(e.Graphics, GetConnectivityRegionRect(this.hoveredArea, hoveredData.ViewRect), 255, highlightColor);
                else
                    DrawHoverIndicator(e.Graphics, hoveredData.ViewRect, 255, highlightColor);

            }
        }
        private void TilesetView_PaintTiles(object sender, TilesetViewPaintTilesEventArgs e)
        {
            TileInput[] tileInput = e.Tileset.TileInput.Data;
            for (int i = 0; i < e.PaintedTiles.Count; i++)
            {
                TilesetViewPaintTileData paintData = e.PaintedTiles[i];
                int depthOffset = 0;
                bool isVertical = false;
                if (tileInput.Length > paintData.TileIndex)
                {
                    depthOffset = tileInput[paintData.TileIndex].DepthOffset;
                    isVertical = tileInput[paintData.TileIndex].IsVertical;
                }

                Bitmap overlayBitmap;
                int overlayAlpha;
                Color overlayColor;

                // Retrieve an overlay text bitmap that represents depth offset
                if (this.editMode == EditMode.Offset)
                {
                    string text = depthOffset.ToString();
                    overlayBitmap = this.GetDepthOverlayBitmap(text);

                    // Determine color and alpha for the text overlay
                    overlayAlpha =
                        (this.TilesetView.HoveredTileIndex == paintData.TileIndex ? 255 :
                        (depthOffset != 0 ? 192 :
                        64));
                    overlayColor =
                        (depthOffset > 0 ? Color.FromArgb(192, 255, 128) :
                        (depthOffset < 0 ? Color.FromArgb(255, 128, 128) :
                        Color.FromArgb(255, 255, 255)));
                }
                // Use the appropriate icon for vertical / flat tiles
                else
                {
                    overlayBitmap = isVertical ?
                        TilemapsResCache.IconTilesetDepthVerticalTile :
                        TilemapsResCache.IconTilesetDepthFlatTile;
                    overlayAlpha =
                        (this.TilesetView.HoveredTileIndex == paintData.TileIndex ? 255 :
                        (isVertical ? 192 :
                        64));
                    overlayColor =
                        (isVertical ? Color.FromArgb(128, 192, 255) :
                        Color.FromArgb(255, 255, 255));
                }

                // Draw the overlay image in the center of the current tile
                e.Graphics.DrawImageTint(
                    overlayBitmap,
                    Color.FromArgb(overlayAlpha, overlayColor),
                    paintData.ViewRect.X + (paintData.ViewRect.Width - overlayBitmap.Width) / 2,
                    paintData.ViewRect.Y + (paintData.ViewRect.Height - overlayBitmap.Height) / 2);

                // Draw a hover indicator
                if (paintData.TileIndex == this.TilesetView.HoveredTileIndex)
                {
                    Rectangle rect = paintData.ViewRect;
                    rect.Width -= 1;
                    rect.Height -= 1;
                    e.Graphics.DrawRectangle(Pens.Black, rect);
                    rect.Inflate(-1, -1);
                    e.Graphics.DrawRectangle(new Pen(overlayColor), rect);
                    rect.Inflate(-1, -1);
                    e.Graphics.DrawRectangle(Pens.Black, rect);
                }
            }
        }
        private void TilesetView_PaintTiles(object sender, TilesetViewPaintTilesEventArgs e)
        {
            Color colorFree = Color.White;
            Color colorCollision = Color.FromArgb(128, 192, 255);

            TileInput[] tileInput = e.Tileset.TileInput.Data;
            for (int i = 0; i < e.PaintedTiles.Count; i++)
            {
                TilesetViewPaintTileData paintData = e.PaintedTiles[i];

                // Prepare some data we'll need for drawing the tile collision info overlay
                TileCollisionShape collision = TileCollisionShape.Free;
                if (tileInput.Length > paintData.TileIndex)
                {
                    collision = tileInput[paintData.TileIndex].Collision[this.editLayerIndex];
                }
                bool tileHovered = this.TilesetView.HoveredTileIndex == paintData.TileIndex;
                bool simpleCollision =
                    collision == TileCollisionShape.Solid ||
                    collision == TileCollisionShape.Free;

                // Draw the center icon indicating the tiles simple solid / free state, as well as diagonal slopes
                {
                    bool centerIsCollision =
                        collision == TileCollisionShape.Solid ||
                        collision.HasFlag(TileCollisionShape.DiagonalUp) ||
                        collision.HasFlag(TileCollisionShape.DiagonalDown);

                    Bitmap centerImage;
                    if      (collision == TileCollisionShape.Solid)              centerImage = TilemapsResCache.TilesetCollisionBit;
                    else if (collision.HasFlag(TileCollisionShape.DiagonalUp))   centerImage = TilemapsResCache.TilesetCollisionDiagUp;
                    else if (collision.HasFlag(TileCollisionShape.DiagonalDown)) centerImage = TilemapsResCache.TilesetCollisionDiagDown;
                    else                                                         centerImage = TilemapsResCache.TilesetCollisionBit;

                    Color centerColor;
                    if (centerIsCollision) centerColor = colorCollision;
                    else                   centerColor = colorFree;

                    e.Graphics.DrawImageTint(
                        centerImage,
                        Color.FromArgb(GetCollisionIconAlpha(
                            tileHovered,
                            this.hoveredArea == TileHotSpot.Center,
                            centerIsCollision), centerColor),
                        paintData.ViewRect.X + (paintData.ViewRect.Width - centerImage.Width) / 2,
                        paintData.ViewRect.Y + (paintData.ViewRect.Height - centerImage.Height) / 2);
                }

                // Draw collision icons for specific directional passability.
                if (!simpleCollision || (tileHovered && (!this.isUserDrawing || !this.drawSimple)))
                {
                    e.Graphics.DrawImageTint(
                        TilemapsResCache.TilesetCollisionVertical,
                        Color.FromArgb(GetCollisionIconAlpha(
                            tileHovered,
                            this.hoveredArea == TileHotSpot.Right,
                            !simpleCollision && collision.HasFlag(TileCollisionShape.Right)),
                            collision.HasFlag(TileCollisionShape.Right) ? colorCollision : colorFree),
                        paintData.ViewRect.X + paintData.ViewRect.Width - TilemapsResCache.TilesetCollisionVertical.Width - 1,
                        paintData.ViewRect.Y + (paintData.ViewRect.Height - TilemapsResCache.TilesetCollisionVertical.Height) / 2);
                    e.Graphics.DrawImageTint(
                        TilemapsResCache.TilesetCollisionVertical,
                        Color.FromArgb(GetCollisionIconAlpha(
                            tileHovered,
                            this.hoveredArea == TileHotSpot.Left,
                            !simpleCollision && collision.HasFlag(TileCollisionShape.Left)),
                            collision.HasFlag(TileCollisionShape.Left) ? colorCollision : colorFree),
                        paintData.ViewRect.X + 1,
                        paintData.ViewRect.Y + (paintData.ViewRect.Height - TilemapsResCache.TilesetCollisionVertical.Height) / 2);
                    e.Graphics.DrawImageTint(
                        TilemapsResCache.TilesetCollisionHorizontal,
                        Color.FromArgb(GetCollisionIconAlpha(
                            tileHovered,
                            this.hoveredArea == TileHotSpot.Top,
                            !simpleCollision && collision.HasFlag(TileCollisionShape.Top)),
                            collision.HasFlag(TileCollisionShape.Top) ? colorCollision : colorFree),
                        paintData.ViewRect.X + (paintData.ViewRect.Width - TilemapsResCache.TilesetCollisionHorizontal.Width) / 2,
                        paintData.ViewRect.Y + 1);
                    e.Graphics.DrawImageTint(
                        TilemapsResCache.TilesetCollisionHorizontal,
                        Color.FromArgb(GetCollisionIconAlpha(
                            tileHovered,
                            this.hoveredArea == TileHotSpot.Bottom,
                            !simpleCollision && collision.HasFlag(TileCollisionShape.Bottom)),
                            collision.HasFlag(TileCollisionShape.Bottom) ? colorCollision : colorFree),
                        paintData.ViewRect.X + (paintData.ViewRect.Width - TilemapsResCache.TilesetCollisionHorizontal.Width) / 2,
                        paintData.ViewRect.Y + paintData.ViewRect.Height - TilemapsResCache.TilesetCollisionHorizontal.Height - 1);
                }
            }
        }