/// file: Project.cs /// Author: Maxime Rohmer /// Brief: A controller that manipulates that gives the view all the info it needs and controlls the layers and tools /// Version: 0.1.0 /// Date: 17/06/2022 using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace Paint_2 { public class Project { const string DEFAULT_FILEPATH = "C:/Paint2/Drawings/"; readonly Color DEFAULT_COLOR = Color.Firebrick; const int DEFAULT_WIDTH = 0; private List _avaibleTools; private List _selectedLayers; private Guid uniqIdGenerator; private List _layers; private bool _eyedropping; private bool _randomColor; private Size _canvasSize; private Random _random; private bool _drawing; private string _name; public List AvaibleTools { get => _avaibleTools; set => _avaibleTools = value; } //public Sketch CurrentLayer { get => _currentSketch; set => _currentSketch = value; } public List Layers { get => _layers; set => _layers = value; } public bool Eyedropping { get => _eyedropping; set => _eyedropping = value; } public bool RandomColor { get => _randomColor; set => _randomColor = value; } public Size CanvasSize { get => _canvasSize; set => _canvasSize = value; } public Random Random { get => _random; set => _random = value; } public bool Drawing { get => _drawing; set => _drawing = value; } public string Name { get => _name; set => _name = value; } public List LayersToPrint { get => _selectedLayers; set => _selectedLayers = value; } public Project(string name, Size canvasSize) { Name = name; CanvasSize = canvasSize; Random = new Random(); //We set all the avaible tools at first AvaibleTools = new List(); AvaibleTools.Add(new Pencil("Default Pencil")); AvaibleTools.Add(new DotPencil("Dotted Line")); AvaibleTools.Add(new BezierPencil("Bezier Generator")); AvaibleTools.Add(new RectanglePencil("Box tool")); AvaibleTools.Add(new RectangleBorderPencil("Rectangle tool")); AvaibleTools.Add(new EllipsePencil("Ball tool")); AvaibleTools.Add(new EllipseBorderPencil("Ellipse tool")); //We create a single first layer with the default toolSet Layers = new List(); LayersToPrint = new List(); AddLayer(); LayersToPrint.Add(Layers[0].Id); } public string AddLayer() { List newTools = new List(); foreach (PaintTool tool in AvaibleTools) { newTools.Add((PaintTool)tool.Clone()); } uniqIdGenerator = Guid.NewGuid(); string test = uniqIdGenerator.ToString(); Sketch newSketch = new Sketch(String.Concat("Layer_", Layers.Count + 1), CanvasSize, newTools, uniqIdGenerator.ToString()); Layers.Add(newSketch); LayersToPrint.Add(newSketch.Id); RestoreLayerNames(); return (newSketch.Id); } private void RestoreLayerNames() { //resets all the names to not have multiple layer 3 for example for (int i = 0; i < Layers.Count; i++) { Layers[i].Name = "Layer_" + (i + 1); } } public bool RemoveLayer(string layerId) { Sketch layer = FindSketch(Layers, layerId); if (layer != null) { Layers.Remove(layer); RestoreLayerNames(); return true; } else { return false; } } public Sketch FindSketch(List layers, string id) { foreach (Sketch layer in layers) { if (layer.Id == id) { return layer; } } return null; } public bool IsSketchPresent (List layers, string id) { foreach (string layer in layers) { if (layer == id) { return true; } } return false; } public List GetAllLayers() { return Layers; } public void SwitchLayer(string idLayer) { bool present = IsSketchPresent(LayersToPrint,idLayer); if (present) { LayersToPrint.Remove(idLayer); } else { LayersToPrint.Add(idLayer); } } public void MouseDown(List selectedLayers, Color hoveringColor, Point mousePosition, int toolWidth) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { if (Eyedropping) { Color pointedColor = hoveringColor; if (layer.CurrentTool.Color != pointedColor) { layer.ChangePaintToolColor(pointedColor); } } else { Drawing = true; if (RandomColor) { layer.StartDrawing(mousePosition, Color.FromArgb(Random.Next(0, 256), Random.Next(0, 256), Random.Next(0, 256)), toolWidth); } else { layer.StartDrawing(mousePosition, layer.CurrentTool.Color, toolWidth); } } } } } public void MouseUp(List selectedLayers, Point mousePosition) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { if (!Eyedropping) { layer.AddDrawingPoint(mousePosition); Drawing = false; layer.StopDrawing(); } } } } public void TimerTick(List selectedLayers, Point mousePosition) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { if (Drawing) { layer.AddDrawingPoint(mousePosition); } } } } public void ChangeColor(List selectedLayers, Color newColor) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { layer.ChangePaintToolColor(newColor); } } } public void ChangeWidth(List selectedLayers, int width) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { layer.ChangePaintToolWidth(width); } } } public void ChangeTool(List selectedLayers, int toolId) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { layer.ChangeTool(toolId); } } } public Bitmap ForcePaintAllLayers() { Bitmap result = new Bitmap(CanvasSize.Width, CanvasSize.Height); Graphics gr = Graphics.FromImage(result); foreach (Sketch layer in Layers) { gr.DrawImage(layer.ForcePaint(), Point.Empty); } return result; } public Bitmap ForcePaintLayers() { Bitmap result = new Bitmap(CanvasSize.Width, CanvasSize.Height); Graphics gr = Graphics.FromImage(result); foreach (string layerId in LayersToPrint) { Sketch layer = FindSketch(Layers, layerId); if (layer != null) { gr.DrawImage(layer.ForcePaint(), Point.Empty); } } return result; } public Bitmap PaintAllLayers() { Bitmap result = new Bitmap(CanvasSize.Width, CanvasSize.Height); Graphics gr = Graphics.FromImage(result); foreach (Sketch layer in Layers) { gr.DrawImage(layer.Paint(), Point.Empty); } return result; } public Bitmap PaintLayers() { Bitmap result = null; if (CanvasSize.Width != 0 && CanvasSize.Height != 0) { result = new Bitmap(CanvasSize.Width, CanvasSize.Height); Graphics gr = Graphics.FromImage(result); foreach (string layerId in LayersToPrint) { Sketch layer = FindSketch(Layers, layerId); if (layer != null) { gr.DrawImage(layer.Paint(), Point.Empty); } } } return result; } public void Clear() { foreach (Sketch layer in Layers) { layer.Clear(); } } public PaintTool GetCurrentTool(List selectedLayers) { if (Layers.Count == 0 || selectedLayers.Count == 0) { return null; } else { Sketch CurrentLayer = FindSketch(Layers, selectedLayers[0]); return CurrentLayer.CurrentTool; } } public Color GetCurrentToolColor(List selectedLayers) { if (Layers.Count == 0 || selectedLayers.Count == 0) { return DEFAULT_COLOR; } else { //Sketch CurrentLayer = Layers[selectedLayers[0]; Sketch CurrentLayer = FindSketch(Layers,selectedLayers[0]); return CurrentLayer.CurrentTool.Color; } } public int GetCurrentToolWidth(List selectedLayers) { if (selectedLayers.Count == 0) { return DEFAULT_WIDTH; } Sketch CurrentLayer = FindSketch(Layers, selectedLayers[0]); return CurrentLayer.CurrentTool.Width; } public List GetLayerColorHistory(List selectedLayers, int colorsCount) { if (selectedLayers.Count == 0) { List result = new List(); for (int i = 0; i < colorsCount; i++) { result.Add(DEFAULT_COLOR); } return result; } Sketch CurrentLayer = FindSketch(Layers, selectedLayers[0]); return CurrentLayer.CurrentTool.GetLastColors(colorsCount); } public void Save(string fileName, Bitmap image) { if (!Directory.Exists(DEFAULT_FILEPATH)) { Directory.CreateDirectory(DEFAULT_FILEPATH); } if (!Directory.Exists(DEFAULT_FILEPATH + fileName)) { Directory.CreateDirectory(DEFAULT_FILEPATH + fileName); } image.Save(DEFAULT_FILEPATH + fileName + "/" + fileName + ".png", System.Drawing.Imaging.ImageFormat.Png); } public void SaveCopy(string fileName, Bitmap image) { int version = 1; if (!Directory.Exists(DEFAULT_FILEPATH)) { Directory.CreateDirectory(DEFAULT_FILEPATH); } if (!Directory.Exists(DEFAULT_FILEPATH + fileName)) { Directory.CreateDirectory(DEFAULT_FILEPATH + fileName); } while (File.Exists(DEFAULT_FILEPATH + fileName + "/" + fileName + version + ".png")) { version += 1; } image.Save(DEFAULT_FILEPATH + fileName + "/" + fileName + version + ".png", System.Drawing.Imaging.ImageFormat.Png); } public void Resize(Size newSize) { CanvasSize = newSize; foreach (Sketch layer in Layers) { layer.Resize(CanvasSize); } } public void SwitchRandom() { RandomColor = !RandomColor; } public void SwitchEyeDrop() { Eyedropping = !Eyedropping; } public void Undo(List selectedLayers) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { layer.Undo(); } } } public void Redo(List selectedLayers) { foreach (string id in selectedLayers) { Sketch layer = FindSketch(Layers, id); if (layer != null) { layer.Redo(); } } } public string PrintAllLayers() { string result = ""; foreach (Sketch layer in Layers) { result += layer.Name; result += Environment.NewLine; } return result; } public void CtrlDown() { foreach (Sketch layer in Layers) { layer.CtrlDown(); } } public void CtrlUp() { foreach (Sketch layer in Layers) { layer.CtrlUp(); } } public void ShiftDown() { foreach (Sketch layer in Layers) { layer.ShiftDown(); } } public void ShiftUp() { foreach (Sketch layer in Layers) { layer.ShiftUp(); } } public string ConvertToSVG() { string fileContent = ""; string newLine = Environment.NewLine; fileContent += ""; fileContent += newLine; foreach (Sketch layer in Layers) { fileContent += ""; fileContent += newLine; fileContent += layer.PaintSVG(); } fileContent += newLine; fileContent += ""; return fileContent; } public bool SaveSvg(string path,string fileName) { bool result = false; if (Directory.Exists(path)) { using (StreamWriter sw = File.CreateText(path + "\\" + fileName + ".svg")) { sw.WriteLine(ConvertToSVG()); result = true; } } return result; } } }