private void ButtonAtom_Click(object sender, EventArgs e) { SelectedTool = DiagramAction.PlaceAtom; MessageBoxText = "Atom tool selected."; AtomSelectionForm sForm = new AtomSelectionForm(); sForm.ShowDialog(); var par = CurrentObject.GetInternalParameters(); MessageBoxText = par["Symbol"] + " selected."; }
// When clicking on the diagram. private void DiagramView_Click(object sender, EventArgs e) { MouseEventArgs args = (MouseEventArgs)e; Point clickLocation = args.Location; // Grid snap for atoms and texts. if (GridSettingForm.Settings.GridWidth > 0 && GridSettingForm.Settings.GridHeight > 0 && (new DiagramAction[] { DiagramAction.PlaceAtom, DiagramAction.PlaceText, DiagramAction.PlaceAtomCarbon, DiagramAction.PlaceAtomHydrogen, DiagramAction.PlaceAtomNitrogen, DiagramAction.PlaceAtomOxygen }.Contains(SelectedTool))) { // Get grid settings from settings object. int w = GridSettingForm.Settings.GridWidth, h = GridSettingForm.Settings.GridHeight; int xo = GridSettingForm.Settings.GridXOffset, yo = GridSettingForm.Settings.GridYOffset; int ux = clickLocation.X - xo, uy = clickLocation.Y - yo; // Find closest grid intersections. int[][] pairs = { new int[] { ux - (ux % w), uy - (uy % h) }, new int[] { ux + (w - (ux % w)), uy - (uy % h) }, new int[] { ux - (ux % w), uy + (h - (uy % h)) }, new int[] { ux + (w - (ux % w)), uy + (h - (uy % h)) } }; // Get distances to intersections. double[] distances = new double[pairs.Length]; for (int i = 0; i < pairs.Length; i++) { int dx, dy; dx = pairs[i][0] - ux; dy = pairs[i][1] - uy; distances[i] = Math.Sqrt(dx * dx + dy * dy); // via Pythagoras' Theorem. } // Get minimum distance and index of minimum distance. int mindex; double minstance; mindex = 0; minstance = distances[0]; for (int i = 1; i < distances.Length; i++) { if (distances[i] < minstance) { minstance = distances[i]; mindex = i; } } // Move selection to placement. clickLocation.X = pairs[mindex][0] + xo; clickLocation.Y = pairs[mindex][1] + yo; } // Finding nearby objects for object anchoring. List <DiagramObject> objects = new List <DiagramObject>(); List <DiagramObject> atoms = new List <DiagramObject>(); List <DiagramObject> texts = new List <DiagramObject>(); foreach (DiagramObject obj in CurrentDiagram.Objects) { if (obj.IsMouseIntersect(clickLocation)) { objects.Add(obj); } } foreach (DiagramObject obj in objects) { if (obj.ObjectID == DiagramObject.ObjectTypeID.Atom) { atoms.Add(obj); } } foreach (DiagramObject obj in objects) { if (obj.ObjectID == DiagramObject.ObjectTypeID.Text) { texts.Add(obj); } } int anchor = -1; // For object anchoring. try { // CurrentDiagram.AddDiagramObject(new Atom("C", clickLocation.X, clickLocation.Y)); switch (SelectedTool) { case DiagramAction.Select: foreach (DiagramObject obj in objects) { if (args.Button == MouseButtons.Right) { CurrentDiagram.RemoveDiagramObject(obj.DiagramID); MessageBoxText = $"Object of ID {obj.DiagramID} deleted."; break; } else { if (SelectedObject != obj) { SelectedObject = obj; EditingForm eForm = new EditingForm(obj); eForm.Show(); break; } } } break; case DiagramAction.PlaceAtom: var par = CurrentObject.GetInternalParameters(); par["X"] = (float)clickLocation.X; par["Y"] = (float)clickLocation.Y; Atom a = new Atom(); a.EditInternalParameters(par); CurrentDiagram.AddDiagramObject(a); break; case DiagramAction.PlaceAtomCarbon: CurrentDiagram.AddDiagramObject(new Atom("C", clickLocation.X, clickLocation.Y)); break; case DiagramAction.PlaceAtomNitrogen: CurrentDiagram.AddDiagramObject(new Atom("N", clickLocation.X, clickLocation.Y, new SKColor(0, 128, 0))); break; case DiagramAction.PlaceAtomOxygen: CurrentDiagram.AddDiagramObject(new Atom("O", clickLocation.X, clickLocation.Y, new SKColor(255, 0, 0))); break; case DiagramAction.PlaceAtomHydrogen: CurrentDiagram.AddDiagramObject(new Atom("H", clickLocation.X, clickLocation.Y, new SKColor(128, 128, 128))); break; case DiagramAction.PlaceSingleBond: if (atoms.Count > 0) { anchor = atoms[0].DiagramID; } CurrentObject = new Bond(clickLocation.X, clickLocation.Y, 0, 0, 1.5f, null, Bond.BondType.Single, Bond.BondStyle.Plain, anchor); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceBondEnd; break; case DiagramAction.PlaceDoubleBond: if (atoms.Count > 0) { anchor = atoms[0].DiagramID; } CurrentObject = new Bond(clickLocation.X, clickLocation.Y, 0, 0, 1.5f, null, Bond.BondType.Double, Bond.BondStyle.Plain, anchor); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceBondEnd; break; case DiagramAction.PlaceTripleBond: if (atoms.Count > 0) { anchor = atoms[0].DiagramID; } CurrentObject = new Bond(clickLocation.X, clickLocation.Y, 0, 0, 1.5f, null, Bond.BondType.Triple, Bond.BondStyle.Plain, anchor); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceBondEnd; break; case DiagramAction.PlaceAromaticBond: if (atoms.Count > 0) { anchor = atoms[0].DiagramID; } CurrentObject = new Bond(clickLocation.X, clickLocation.Y, 0, 0, 1.5f, null, Bond.BondType.Aromatic, Bond.BondStyle.Plain, anchor); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceBondEnd; break; case DiagramAction.PlaceBondEnd: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Bond) { int ach = ((Bond)CurrentObject).AnchorID1; if (atoms.Count > 0) { foreach (var atom in atoms) { if (atom.DiagramID != ach) { anchor = atom.DiagramID; break; } else { anchor = -1; } } } var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; parameters["AnchorID2"] = anchor; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; switch (((Bond)CurrentObject).TypeOfBond) { case Bond.BondType.Single: SelectedTool = DiagramAction.PlaceSingleBond; break; case Bond.BondType.Double: SelectedTool = DiagramAction.PlaceDoubleBond; break; case Bond.BondType.Triple: SelectedTool = DiagramAction.PlaceTripleBond; break; case Bond.BondType.Aromatic: SelectedTool = DiagramAction.PlaceAromaticBond; break; } // CurrentObject = null; } break; case DiagramAction.PlaceLineStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Line); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceLineEnd; break; case DiagramAction.PlaceLineEnd: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; SelectedTool = DiagramAction.PlaceLineStart; // CurrentObject = null; } break; case DiagramAction.PlaceCurveStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Curve, Line.LineStyle.Plain); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceCurveControlPoint; break; case DiagramAction.PlaceCurveControlPoint: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); List <float[]> cpts = (List <float[]>)parameters["ControlPoints"]; cpts.Add(new float[] { clickLocation.X, clickLocation.Y }); CurrentObject.EditInternalParameters(parameters); if (cpts.Count == 2) { SelectedTool = DiagramAction.PlaceCurveEnd; } } break; case DiagramAction.PlaceCurveEnd: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; SelectedTool = DiagramAction.PlaceCurveStart; // CurrentObject = null; } break; case DiagramAction.PlaceStraightArrowStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Line, Line.LineStyle.Plain, Line.EndType.Plain, Line.EndType.Arrow); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceStraightArrowEnd; break; case DiagramAction.PlaceStraightArrowEnd: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; SelectedTool = DiagramAction.PlaceStraightArrowStart; // CurrentObject = null; } break; case DiagramAction.PlaceCurvedArrowStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Curve, Line.LineStyle.Plain, Line.EndType.Plain, Line.EndType.Arrow); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceCurvedArrowControlPoint; break; case DiagramAction.PlaceCurvedArrowControlPoint: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); List <float[]> cpts = (List <float[]>)parameters["ControlPoints"]; cpts.Add(new float[] { clickLocation.X, clickLocation.Y }); CurrentObject.EditInternalParameters(parameters); if (cpts.Count == 2) { SelectedTool = DiagramAction.PlaceCurvedArrowEnd; } } break; case DiagramAction.PlaceCurvedArrowEnd: if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; SelectedTool = DiagramAction.PlaceCurvedArrowStart; // CurrentObject = null; } break; case DiagramAction.ChargeIncrease: foreach (DiagramObject obj in objects) { if (obj.ObjectID == DiagramObject.ObjectTypeID.Atom) { var p = ((Atom)obj).GetInternalParameters(); p["Charge"] = (int)p["Charge"] + 1; obj.EditInternalParameters(p); break; } } break; case DiagramAction.ChargeDecrease: foreach (DiagramObject obj in objects) { if (obj.ObjectID == DiagramObject.ObjectTypeID.Atom) { var p = ((Atom)obj).GetInternalParameters(); p["Charge"] = (int)p["Charge"] - 1; obj.EditInternalParameters(p); break; } } break; case DiagramAction.PlaceSharpLineStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Sharp, Line.LineStyle.Plain); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceSharpLineControlPoint; break; case DiagramAction.PlaceSharpLineControlPoint: if (args.Button == MouseButtons.Right) { if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; } SelectedTool = DiagramAction.PlaceSharpLineStart; } else { if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); List <float[]> cpts = (List <float[]>)parameters["ControlPoints"]; cpts.Add(new float[] { clickLocation.X, clickLocation.Y }); CurrentObject.EditInternalParameters(parameters); } } break; case DiagramAction.PlaceSharpArrowStart: CurrentObject = new Line(clickLocation.X, clickLocation.Y, 0, 0, null, 1.5f, null, Line.LineType.Sharp, Line.LineStyle.Plain, Line.EndType.Plain, Line.EndType.Arrow); ToolGroup.Enabled = false; SelectedTool = DiagramAction.PlaceSharpArrowControlPoint; break; case DiagramAction.PlaceSharpArrowControlPoint: if (args.Button == MouseButtons.Right) { if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); parameters["X2"] = (float)clickLocation.X; parameters["Y2"] = (float)clickLocation.Y; CurrentObject.EditInternalParameters(parameters); CurrentDiagram.AddDiagramObject(CurrentObject); ToolGroup.Enabled = true; } SelectedTool = DiagramAction.PlaceSharpArrowStart; } else { if (CurrentObject.ObjectID == DiagramObject.ObjectTypeID.Line) { var parameters = CurrentObject.GetInternalParameters(); List <float[]> cpts = (List <float[]>)parameters["ControlPoints"]; cpts.Add(new float[] { clickLocation.X, clickLocation.Y }); CurrentObject.EditInternalParameters(parameters); } } break; case DiagramAction.PlaceText: CurrentDiagram.AddDiagramObject(new Text("Edit object to edit text.", clickLocation.X, clickLocation.Y)); break; default: break; } UpdateScreen(true); } catch (Exception err) { ErrorLogger.ShowErrorMessageBox(err); } }