/// <summary> /// What happens when we release the mouse button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CurrentEditor_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { CurrentEditor.ReleaseMouseCapture(); CurrentStatus = ""; if (IsDrawing) { var newAtomPos = e.GetPosition(CurrentEditor); //first get the current active visuals var landedGroupVisual = CurrentEditor.GetTargetedVisual(newAtomPos) as GroupVisual; var landedAtomVisual = CurrentEditor.GetTargetedVisual(newAtomPos) as AtomVisual; var landedBondVisual = CurrentEditor.GetTargetedVisual(newAtomPos) as BondVisual; //check to see whether or not we've clicked and released on the same atom bool sameAtom = landedAtomVisual == _currentAtomVisual; //check to see whether the target is in the same molecule bool sameMolecule = landedAtomVisual?.ParentAtom.Parent == _currentAtomVisual?.ParentAtom.Parent; if (landedGroupVisual != null) { ClearTemporaries(); return; } //check bonds first - we can't connect to a bond so we need to simply do some stuff with it if (landedBondVisual != null) { //clicking on a stereo bond should just invert it var parentBond = landedBondVisual.ParentBond; if (parentBond.Stereo == BondStereo.Hatch & EditViewModel.CurrentStereo == BondStereo.Hatch | parentBond.Stereo == BondStereo.Wedge & EditViewModel.CurrentStereo == BondStereo.Wedge) { EditViewModel.SwapBondDirection(parentBond); } else { //modify the bond attribute (order, stereo, whatever's selected really) EditViewModel.SetBondAttributes(parentBond); } } else //we clicked on empty space or an atom { Atom parentAtom = _currentAtomVisual?.ParentAtom; if (landedAtomVisual == null) //no atom hit { if (parentAtom != null) { if (_currentAtomVisual != null) { //so just sprout a chain off it at two-o-clock EditViewModel.AddAtomChain( parentAtom, _angleSnapper.SnapBond(newAtomPos, e), ClockDirections.II); } else { //otherwise create a singleton EditViewModel.AddAtomChain(null, newAtomPos, ClockDirections.II); } } else { //create a singleton //otherwise create a singleton EditViewModel.AddAtomChain(null, newAtomPos, ClockDirections.II); } } else //we went mouse-up on an atom { Atom lastAtom = landedAtomVisual.ParentAtom; if (sameAtom) //both are the same atom { if (lastAtom.Element.Symbol != EditViewModel.SelectedElement.Symbol) { EditViewModel.SetElement(EditViewModel.SelectedElement, new List <Atom> { lastAtom }); } else { var atomMetrics = GetNewChainEndPos(landedAtomVisual); EditViewModel.AddAtomChain(lastAtom, atomMetrics.NewPos, atomMetrics.sproutDir); parentAtom.UpdateVisual(); } } else //we must have hit a different atom altogether { if (parentAtom != null) { //already has a bond to the target atom var existingBond = parentAtom.BondBetween(lastAtom); if (existingBond != null) //it must be in the same molecule { EditViewModel.IncreaseBondOrder(existingBond); } else //doesn't have a bond to the target atom { if (sameMolecule) { EditViewModel.AddNewBond(parentAtom, lastAtom, parentAtom.Parent); } else { EditViewModel.JoinMolecules(parentAtom, lastAtom, EditViewModel.CurrentBondOrder, EditViewModel.CurrentStereo); } parentAtom.UpdateVisual(); lastAtom.UpdateVisual(); } } } } } } ClearTemporaries(); }