public void Draw(EditView view) { Graph graph = view.Graph; TetrisTemplate template = graph.MetaData.TetrisTemplate; double scale = view.TetrisTemplateScale; Vector origin = view.TetrisTemplateOrigin; graphics.Clear(graph.MetaData.BackgroundColor); if (template.Shapes.Count == 0) { return; } using (Brush activatedBrush = new SolidBrush(Color.Yellow), deactivatedBrush = new SolidBrush(graph.MetaData.ForegroundColor)) { for (int k = 0; k < template.Shapes.Count; ++k) { List <Node> shape = template.Shapes[k]; graphics.FillClosedCurve(view.SelectedTetrisShapes[k] ? activatedBrush : deactivatedBrush, shape.Select(node => new Vector(node.X, node.Y).MapToScreen(scale, origin).ToPoint()).ToArray(), System.Drawing.Drawing2D.FillMode.Alternate, 0.0f); } } float penWidth = (float)(borderPercent * scale); using (Pen pen = new Pen(graph.MetaData.BackgroundColor, penWidth)) { for (int k = 0; k < template.Shapes.Count; ++k) { List <Node> shape = template.Shapes[k]; graphics.DrawClosedCurve(pen, shape.Select(node => new Vector(node.X, node.Y).MapToScreen(scale, origin).ToPoint()).ToArray(), 0.0f, System.Drawing.Drawing2D.FillMode.Alternate); } } }
internal void ExportToFile(string savePath) { EditView exportView = new EditView(Graph, Graph.MetaData.ExportWidth, Graph.MetaData.ExportHeight, (int)tetrisTemplateEditorSize.X, (int)tetrisTemplateEditorSize.Y); Bitmap bitmap = new Bitmap(Convert.ToInt32(Graph.MetaData.ExportWidth), Convert.ToInt32(Graph.MetaData.ExportHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(bitmap); PuzzleGraphRenderer renderer = new PuzzleGraphRenderer(g); renderer.Draw(exportView); bitmap.Save(savePath, ImageFormat.Png); }
private void FlipVerticallyToolStripMenuItem_Click(object sender, EventArgs e) { if (editView != null) { editView.GraphEditManager.BeforePreformEdit(editView.Graph, "Flip Vertically"); Graph graph = Graph.FlipGraph(editView.Graph, Graph.FlipType.Vertical); editView = new EditView(graph, editorPictureBox.Width, editorPictureBox.Height, tetrisTemplatePictureBox.Width, tetrisTemplatePictureBox.Height); UpdateGraphDrawing(); UpdateTetrisTemplateDrawing(); ToolkitListView.SelectedItems.Clear(); } }
public MainForm(string[] args) { InitializeComponent(); // Init graph drawing Graphics graphTargetGraphics = editorPictureBox.CreateGraphics(); graphBuffer = BufferedGraphicsManager.Current.Allocate(graphTargetGraphics, new Rectangle(0, 0, Screen.FromControl(this).Bounds.Width, Screen.FromControl(this).Bounds.Height)); graphBuffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; graphRenderer = new PuzzleGraphRenderer(graphBuffer.Graphics); // Init tetris template drawing Graphics tetrisTemplateTargetGraphics = tetrisTemplatePictureBox.CreateGraphics(); tetrisTemplateBuffer = BufferedGraphicsManager.Current.Allocate(tetrisTemplateTargetGraphics, new Rectangle(0, 0, Screen.FromControl(this).Bounds.Width, Screen.FromControl(this).Bounds.Height)); tetrisTemplateBuffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; tetrisTemplateRenderer = new TetrisTemplateRenderer(tetrisTemplateBuffer.Graphics); // Init preview graph box Graphics decoratorPreviewGraphics = decoratorPreviewPictureBox.CreateGraphics(); decoratorPreviewBuffer = BufferedGraphicsManager.Current.Allocate(decoratorPreviewGraphics, new Rectangle(0, 0, Screen.FromControl(this).Bounds.Width, Screen.FromControl(this).Bounds.Height)); decoratorPreviewBuffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // Init other stuff editorPictureBox.MouseWheel += EditorPictureBox_MouseWheel; decoratorPreviewPictureBox.MouseWheel += DecoratorPreviewPictureBox_MouseWheel; InitToolkit(); UpdateToolkitListView(); if (args.Length >= 1) { string fileName = args[0]; try { Graph graph = Graph.LoadFromFile(fileName); if (ObsolateFormatFixer.FixObsoletedTetrisFormat(graph)) { Console.WriteLine("[Info] We have automatically upgraded the obsoleted file format. Please remember to save."); } editView = new EditView(graph, editorPictureBox.Width, editorPictureBox.Height, tetrisTemplatePictureBox.Width, tetrisTemplatePictureBox.Height); UpdateGraphDrawing(); UpdateTetrisTemplateDrawing(); savePath = fileName; } catch { MessageBox.Show(Resources.Lang.Warnings_FailToLoad + fileName); savePath = null; editView = null; } } }
public void DrawSelectionBoxes(EditView view, List <GraphElement> selectedObjects, Color color, bool skew = false) { Vector skewVector = skew ? new Vector(2.0, 2.0) : Vector.Zero; float width = skew ? 2.5f : 2f; float lineWidth = (float)(view.Scale * 0.175); using (Pen pen = new Pen(color, width)) { foreach (object obj in selectedObjects) { if (obj is Node node) { Vector screenPosition = new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin) + skewVector; graphics.DrawRectangle(pen, (float)screenPosition.X - lineWidth / 2, (float)screenPosition.Y - lineWidth / 2, lineWidth, lineWidth); } else if (obj is Edge edge) { Vector screenPosition1 = new Vector(edge.Start.X, edge.Start.Y).MapToScreen(view.Scale, view.Origin); Vector screenPosition2 = new Vector(edge.End.X, edge.End.Y).MapToScreen(view.Scale, view.Origin); Vector direction = screenPosition2 - screenPosition1; if (direction.Length() < 1e-6) { graphics.DrawRectangle(pen, (float)screenPosition1.X - lineWidth / 2, (float)screenPosition1.Y - lineWidth / 2, lineWidth, lineWidth); } else { direction = direction / direction.Length(); Vector crossDir = new Vector(direction.Y, -direction.X); Vector p1 = screenPosition1 - (+crossDir) * lineWidth / 2 + skewVector; Vector p2 = screenPosition1 - (-crossDir) * lineWidth / 2 + skewVector; Vector p3 = screenPosition2 + (+crossDir) * lineWidth / 2 + skewVector; Vector p4 = screenPosition2 + (-crossDir) * lineWidth / 2 + skewVector; graphics.DrawLines(pen, new PointF[] { p1.ToPoint(), p2.ToPoint(), p3.ToPoint(), p4.ToPoint(), p1.ToPoint() }); } } else if (obj is Face face) { graphics.DrawClosedCurve(pen, face.Nodes.Select(item => (new Vector(item.X, item.Y).MapToScreen(view.Scale, view.Origin) + skewVector).ToPoint()).ToArray(), 0.0f, System.Drawing.Drawing2D.FillMode.Alternate); } else { throw new NotSupportedException(); } } } }
void DrawEdge(EditView view, Edge edge, Pen pen) { Vector screenPosition1 = new Vector(edge.Start.X, edge.Start.Y).MapToScreen(view.Scale, view.Origin); Vector screenPosition2 = new Vector(edge.End.X, edge.End.Y).MapToScreen(view.Scale, view.Origin); if (edge.Decorator is PuzzleGraph.Decorators.BrokenDecorator) { Vector screenPosition3 = screenPosition1 * 0.6 + screenPosition2 * 0.4; Vector screenPosition4 = screenPosition1 * 0.4 + screenPosition2 * 0.6; graphics.DrawLine(pen, (float)screenPosition1.X, (float)screenPosition1.Y, (float)screenPosition3.X, (float)screenPosition3.Y); graphics.DrawLine(pen, (float)screenPosition2.X, (float)screenPosition2.Y, (float)screenPosition4.X, (float)screenPosition4.Y); } else { graphics.DrawLine(pen, (float)screenPosition1.X, (float)screenPosition1.Y, (float)screenPosition2.X, (float)screenPosition2.Y); } }
private void OpenToolStripMenuItem_Click(object sender, EventArgs e) { openInfoFileDialog.InitialDirectory = Path.Combine(Application.StartupPath, "Puzzles"); if (openInfoFileDialog.ShowDialog() == DialogResult.Cancel) { return; } savePath = openInfoFileDialog.FileName; Graph graph = Graph.LoadFromFile(savePath); if (ObsolateFormatFixer.FixObsoletedTetrisFormat(graph)) { Console.WriteLine("[Info] We have automatically upgraded the obsoleted file format. Please remember to save."); } editView = new EditView(graph, editorPictureBox.Width, editorPictureBox.Height, tetrisTemplatePictureBox.Width, tetrisTemplatePictureBox.Height); UpdateGraphDrawing(); UpdateTetrisTemplateDrawing(); ToolkitListView.SelectedItems.Clear(); }
private void DrawCreatingModeLines(EditView view, Color color, bool skew) { Vector skewVector = skew ? new Vector(2.0, 2.0) : Vector.Zero; float width = skew ? 2.5f : 2f; float selectionIconSize = 5; List <Node> drawNodes = new List <Node>(); drawNodes.AddRange(view.CreatingNodes); if (view.HoveredCreatingNode != null) { drawNodes.Add(view.HoveredCreatingNode); } PointF[] points = drawNodes.Select(node => (new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin) + skewVector).ToPoint()).ToArray(); using (Pen pen = new Pen(color, width) { LineJoin = System.Drawing.Drawing2D.LineJoin.Round }) { foreach (Node node in drawNodes) { RectangleF boundingBox = (new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin) + skewVector).ToCircleBoundingBox(selectionIconSize); graphics.DrawEllipse(pen, boundingBox); } if (points.Length > 1) { graphics.DrawPolygon(pen, points); } } if (points.Length > 2 && !skew) { using (Brush brush = new SolidBrush(Color.FromArgb(50, color))) { graphics.FillPolygon(brush, points); } } }
public void Draw(EditView view) { Graph graph = view.Graph; float lineWidth = (float)(view.Scale * graph.MetaData.EdgeWidth); float faceCircleSize = (float)(view.Scale * (1 - graph.MetaData.EdgeWidth * 2) * 0.3); graphics.Clear(graph.MetaData.BackgroundColor); using (Pen edgePen = new Pen(graph.MetaData.ForegroundColor, lineWidth)) using (Brush pointBrush = new SolidBrush(graph.MetaData.ForegroundColor)) { foreach (Face face in graph.Faces) { Vector sum = Vector.Zero; foreach (Node node in face.Nodes) { sum += new Vector(node.X, node.Y); } Vector screenPosition = (sum / face.Nodes.Count).MapToScreen(view.Scale, view.Origin); if (face.GraphElementColor != Color.Transparent) { using (Brush brush = new SolidBrush(face.GraphElementColor)) { graphics.FillPolygon(brush, face.Nodes.Select(node => new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin).ToPoint()).ToArray()); } } if (face.Decorator is null) { if (view.IsDragging) // Debug paint { graphics.FillEllipse(pointBrush, new RectangleF((float)screenPosition.X - faceCircleSize / 2, (float)screenPosition.Y - faceCircleSize / 2, faceCircleSize, faceCircleSize)); } } else { double scale = face.Decorator is IUnifiedScaleDecorator ? view.Scale : view.Scale * (1 - graph.MetaData.EdgeWidth) * graph.MetaData.FaceDecorationScale; DrawDecorator(face.Decorator, screenPosition, scale, view.Graph.MetaData, face.GraphElementColor, true); } } foreach (Node node in graph.Nodes) { if (view.IsDragging || !node.Hidden) { DrawNode(view, node, pointBrush, lineWidth); } } foreach (Edge edge in graph.Edges) { if (edge.GraphElementColor == Color.Transparent) { DrawEdge(view, edge, edgePen); } } } foreach (Node node in graph.Nodes) { if (node.Decorator is PuzzleGraph.Decorators.StartDecorator || node.Decorator is PuzzleGraph.Decorators.EndDecorator) { Vector screenPosition = new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin); double scale = node.Decorator is IUnifiedScaleDecorator ? view.Scale : view.Scale * graph.MetaData.EdgeWidth; DrawDecorator(node.Decorator, screenPosition, scale, view.Graph.MetaData, view.Graph.MetaData.BackgroundColor, false); } } foreach (Edge edge in graph.Edges) { if (edge.Decorator is PuzzleGraph.Decorators.StartDecorator || edge.Decorator is PuzzleGraph.Decorators.EndDecorator) { Vector screenPosition = new Vector((edge.Start.X + edge.End.X) / 2, (edge.Start.Y + edge.End.Y) / 2).MapToScreen(view.Scale, view.Origin); double scale = edge.Decorator is IUnifiedScaleDecorator ? view.Scale : view.Scale * graph.MetaData.EdgeWidth; DrawDecorator(edge.Decorator, screenPosition, scale, view.Graph.MetaData, view.Graph.MetaData.BackgroundColor, false); } } // Draw solutions foreach (Edge edge in graph.Edges) { if (edge.GraphElementColor != Color.Transparent) { using (Pen edgePen = new Pen(edge.GraphElementColor, lineWidth)) using (Brush pointBrush = new SolidBrush(edge.GraphElementColor)) { DrawEdge(view, edge, edgePen); DrawNode(view, edge.Start, pointBrush, lineWidth); DrawNode(view, edge.End, pointBrush, lineWidth); } } } foreach (Node node in graph.Nodes) { if (node.Decorator != null && !(node.Decorator is PuzzleGraph.Decorators.EndDecorator) && !(node.Decorator is PuzzleGraph.Decorators.StartDecorator)) { Vector screenPosition = new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin); double scale = node.Decorator is IUnifiedScaleDecorator ? view.Scale : view.Scale * graph.MetaData.EdgeWidth; DrawDecorator(node.Decorator, screenPosition, scale, view.Graph.MetaData, view.Graph.MetaData.BackgroundColor, false); } } foreach (Edge edge in graph.Edges) { if (edge.Decorator != null && !(edge.Decorator is PuzzleGraph.Decorators.BrokenDecorator) && !(edge.Decorator is PuzzleGraph.Decorators.EndDecorator) && !(edge.Decorator is PuzzleGraph.Decorators.StartDecorator)) { Vector screenPosition = new Vector((edge.Start.X + edge.End.X) / 2, (edge.Start.Y + edge.End.Y) / 2).MapToScreen(view.Scale, view.Origin); double scale = edge.Decorator is IUnifiedScaleDecorator ? view.Scale : view.Scale * graph.MetaData.EdgeWidth; DrawDecorator(edge.Decorator, screenPosition, scale, view.Graph.MetaData, view.Graph.MetaData.BackgroundColor, false); } } DrawSelectionBoxes(view, view.HoveredObjects, Color.DarkGreen, true); DrawSelectionBoxes(view, view.HoveredObjects, Color.LightGreen); DrawSelectionBoxes(view, view.SelectedObjects, Color.DarkGoldenrod, true); DrawSelectionBoxes(view, view.SelectedObjects, Color.Yellow); if (view.IsCreatingMode) { DrawCreatingModeLines(view, Color.DarkRed, false); DrawCreatingModeLines(view, Color.Red, false); } }
void DrawNode(EditView view, Node node, Brush brush, float lineWidth) { Vector screenPosition = new Vector(node.X, node.Y).MapToScreen(view.Scale, view.Origin); graphics.FillEllipse(brush, new RectangleF((float)screenPosition.X - lineWidth / 2, (float)screenPosition.Y - lineWidth / 2, lineWidth, lineWidth)); }