private void UpdateExternalDrawMode() { TilesetAutoTileInput autoTile = this.currentAutoTile; if (autoTile == null) { return; } bool lastExternalDraw = this.isExternalDraw; int hoveredTile = this.TilesetView.HoveredTileIndex; TilesetAutoTileItem item = (hoveredTile >= 0 && hoveredTile < autoTile.TileInput.Count) ? autoTile.TileInput[hoveredTile] : default(TilesetAutoTileItem); this.isExternalDraw = Control.ModifierKeys.HasFlag(Keys.Shift) || item.ConnectsToAutoTile; if (lastExternalDraw != this.isExternalDraw) { this.TilesetView.InvalidateTile(this.TilesetView.HoveredTileIndex, 0); } }
private void PerformUserDrawAction() { Tileset tileset = this.SelectedTileset.Res; if (tileset == null) { return; } TilesetAutoTileInput autoTile = this.currentAutoTile; if (autoTile == null) { return; } int tileIndex = this.TilesetView.HoveredTileIndex; if (tileIndex < 0 || tileIndex > tileset.TileCount) { return; } // Determine data before the operation, and set up data for afterwards bool lastIsBaseTile = autoTile.BaseTileIndex == tileIndex; bool newIsBaseTile = lastIsBaseTile; TilesetAutoTileItem lastInput = (autoTile.TileInput.Count > tileIndex) ? autoTile.TileInput[tileIndex] : default(TilesetAutoTileItem); TilesetAutoTileItem newInput = lastInput; // Determine how data is modified due to our user operation if (this.userDrawMode == AutoTileDrawMode.Add) { if (this.isExternalDraw) { newInput.Neighbours = TileConnection.None; newInput.ConnectsToAutoTile = true; newInput.IsAutoTile = false; newIsBaseTile = false; } else if (this.isBaseTileDraw) { newInput.Neighbours = TileConnection.All; newInput.IsAutoTile = true; newInput.ConnectsToAutoTile = false; newIsBaseTile = true; } else { newInput.Neighbours |= this.hoveredArea; newInput.IsAutoTile = true; newInput.ConnectsToAutoTile = false; } } else if (this.userDrawMode == AutoTileDrawMode.Remove) { if (this.isExternalDraw || this.isBaseTileDraw || this.hoveredArea == TileConnection.None) { newInput.Neighbours = TileConnection.None; newInput.ConnectsToAutoTile = false; newInput.IsAutoTile = false; newIsBaseTile = false; } else { newInput.Neighbours &= ~this.hoveredArea; newInput.IsAutoTile = (newInput.Neighbours != TileConnection.None); } } // Apply the new, modified data to the actual data using an UndoRedo operation if (newIsBaseTile != lastIsBaseTile) { UndoRedoManager.Do(new EditPropertyAction( null, TilemapsReflectionInfo.Property_TilesetAutoTileInput_BaseTile, new object[] { autoTile }, new object[] { newIsBaseTile?tileIndex: -1 })); } if (!object.Equals(lastInput, newInput)) { UndoRedoManager.Do(new EditTilesetAutoTileItemAction( tileset, autoTile, tileIndex, newInput)); } }
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.currentAutoTile; // 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); } } }
public EditTilesetAutoTileItemAction(Tileset tileset, TilesetAutoTileInput autoTile, int tileIndex, TilesetAutoTileItem tileInput) { if (tileset == null) { throw new ArgumentNullException("tileset"); } if (autoTile == null) { throw new ArgumentNullException("autoTile"); } this.tileset = tileset; this.autoTile = autoTile; this.tileInput = new RawList <TilesetAutoTileItem>(tileIndex + 1); this.tileInput.Count = tileIndex + 1; this.tileInput.Data[tileIndex] = tileInput; this.tileInputMask = new RawList <bool>(tileIndex + 1); this.tileInputMask.Count = tileIndex + 1; this.tileInputMask.Data[tileIndex] = true; }