using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Drawing; namespace SketchAssistant { public class MVP_Presenter { /// /// The View of the MVP-Model, in this case Form1. /// Form1 programView; /// /// The Model of the MVP-Model. /// MVP_Model programModel; /*******************/ /*** ENUMERATORS ***/ /*******************/ public enum MouseAction { Click, Down, Up, Move } /***********************/ /*** CLASS VARIABLES ***/ /***********************/ /// /// A dialog responsible for opening files. /// OpenFileDialog openFileDialog; /// /// Instance of FileImporter to handle drawing imports. /// private FileImporter fileImporter; public MVP_Presenter(Form1 form) { programView = form; programModel = new MVP_Model(this); //Initialize Class Variables openFileDialog = new OpenFileDialog(); fileImporter = new FileImporter(); } /***********************************/ /*** FUNCTIONS VIEW -> PRESENTER ***/ /***********************************/ public void Resize(Tuple leftPBS,Tuple rightPBS) { programView.Refresh(); programModel.leftImageBoxWidth = leftPBS.Item1; programModel.leftImageBoxHeight = leftPBS.Item2; programModel.rightImageBoxWidth = rightPBS.Item1; programModel.rightImageBoxHeight = rightPBS.Item2; programModel.UpdateSizes(); } /// /// Display a new FileDialog to load an image. /// public void LoadToolStripMenuItemClick() { openFileDialog.Filter = "Image|*.jpg;*.png;*.jpeg"; if (openFileDialog.ShowDialog() == DialogResult.OK) { ProgramView.SetToolStripLoadStatus(openFileDialog.SafeFileName); ProgramModel leftImage = Image.FromFile(openFileDialog.FileName); pictureBoxLeft.Image = leftImage; //Refresh the left image box when the content is changed this.Refresh(); } UpdateButtonStatus(); } /// /// Display a new FileDialog to load a collection of lines. /// public void ExamplePictureToolStripMenuItemClick() { if (ProgramModel.CheckSavedStatus()) { openFileDialog.Filter = "Interactive Sketch-Assistant Drawing|*.isad"; if (openFileDialog.ShowDialog() == DialogResult.OK) { ProgramView.SetToolStripLoadStatus(openFileDialog.SafeFileName); try { (int, int, List) values = fileImporter.ParseISADInputFile(openFileDialog.FileName); DrawEmptyCanvasLeft(values.Item1, values.Item2); BindAndDrawLeftImage(values.Item3); //Match The right canvas to the left historyOfActions = new ActionHistory(lastActionTakenLabel); DrawEmptyCanvasRight(); isFilledMatrix = new bool[rightImage.Width, rightImage.Height]; linesMatrix = new HashSet[rightImage.Width, rightImage.Height]; rightLineList = new List>(); //Start the redraw mode redrawAss = new RedrawAssistant(leftLineList); UpdateSizes(); overlayItems = redrawAss.Tick(currentCursorPosition, rightLineList, -1, false); RedrawRightImage(); this.Refresh(); } catch (FileImporterException ex) { ShowInfoMessage(ex.ToString()); } } } UpdateButtonStatus(); } public void ChangeState(bool NowDrawing) { programModel.ChangeState(NowDrawing); } public void Undo() { } public void Redo() { } public void NewCanvas() { } public void Tick() { } public void MouseEvent(MouseAction mouseAction, MouseEventArgs e) { switch (mouseAction) { case MouseAction.Click: break; case MouseAction.Down: break; case MouseAction.Up: break; case MouseAction.Move: programModel.SetCurrentCursorPosition(ConvertCoordinates(new Point(e.X, e.Y))); break; } } /************************************/ /*** FUNCTIONS MODEL -> PRESENTER ***/ /************************************/ /// /// Called by the model when the state of the Program changes. /// Changes the look of the UI according to the current state of the model. /// /// If the model is in Drawing Mode /// If actions in the model can be undone /// If actions in the model can be redone /// If an image is loaded in the model public void UpdateUIState(bool inDrawingMode, bool canUndo, bool canRedo, bool imageLoaded) { Dictionary dict = new Dictionary { {"canvasButton", Form1.ButtonState.Disabled }, {"drawButton", Form1.ButtonState.Disabled}, {"deleteButton",Form1.ButtonState.Disabled } {"undoButton", Form1.ButtonState.Disabled },{"redoButton", Form1.ButtonState.Disabled}}; if (imageLoaded) { if (inDrawingMode) { dict["drawButton"] = Form1.ButtonState.Active; dict["deleteButton"] = Form1.ButtonState.Enabled; } else { dict["drawButton"] = Form1.ButtonState.Enabled; dict["deleteButton"] = Form1.ButtonState.Active; } if (canUndo){dict["undoButton"] = Form1.ButtonState.Enabled;} if (canRedo){dict["redoButton"] = Form1.ButtonState.Enabled;} } foreach(KeyValuePair entry in dict) { programView.SetToolStripButtonStatus(entry.Key, entry.Value); } } /// /// Is called by the model when the left image is changed. /// /// The new image. public void UpdateLeftImage(Image img) { programView.DisplayInLeftPictureBox(img); } /// /// Is called by the model when the right image is changed. /// /// The new image. public void UpdateRightImage(Image img) { programView.DisplayInRightPictureBox(img); } public void PassMessageToView(String msg) { programView.ShowInfoMessage(msg); } /*************************/ /*** HELPING FUNCTIONS ***/ /*************************/ /// /// A function that calculates the coordinates of a point on a zoomed in image. /// /// The position of the mouse cursor /// The real coordinates of the mouse cursor on the image private Point ConvertCoordinates(Point cursorPosition) { var rightImageDimensions = programModel.GetRightImageDimensions(); Point realCoordinates = new Point(0, 0); int widthImage = rightImageDimensions.Item1; int heightImage = rightImageDimensions.Item2; int widthBox = programModel.rightImageBoxWidth; int heightBox = programModel.rightImageBoxHeight; if (heightImage == 0 && widthImage == 0) { return cursorPosition; } float imageRatio = (float)widthImage / (float)heightImage; float containerRatio = (float)widthBox / (float)heightBox; if (imageRatio >= containerRatio) { //Image is wider than it is high float zoomFactor = (float)widthImage / (float)widthBox; float scaledHeight = heightImage / zoomFactor; float filler = (heightBox - scaledHeight) / 2; realCoordinates.X = (int)(cursorPosition.X * zoomFactor); realCoordinates.Y = (int)((cursorPosition.Y - filler) * zoomFactor); } else { //Image is higher than it is wide float zoomFactor = (float)heightImage / (float)heightBox; float scaledWidth = widthImage / zoomFactor; float filler = (widthBox - scaledWidth) / 2; realCoordinates.X = (int)((cursorPosition.X - filler) * zoomFactor); realCoordinates.Y = (int)(cursorPosition.Y * zoomFactor); } return realCoordinates; } } }