private void SetActiveAdorner(ChemicalVisual value) { switch (value) { case GroupVisual gv: _highlightAdorner = new GroupHoverAdorner(this, gv); break; case FunctionalGroupVisual fv: _highlightAdorner = new AtomHoverAdorner(this, fv); break; case AtomVisual av: _highlightAdorner = new AtomHoverAdorner(this, av); break; case BondVisual bv: _highlightAdorner = new BondHoverAdorner(this, bv); break; default: _highlightAdorner = null; break; } }
public ChemicalVisual GetTargetedVisual(Point p) { _visuals.Clear(); // Re-Populate _visuals via ResultCallback with *ALL* ChemicalVisual's which are under the mouse cursor // GroupVisual's seem to be added first (with outermost first) one for each Group // Next are any BondVisual's one for each Bond // Next is the AtomVisual for the Atom VisualTreeHelper.HitTest(this, null, ResultCallback, new PointHitTestParameters(p)); // First try to get a GroupVisual // HACK: What guarantees that the first one found is the "top level" group? ChemicalVisual result = _visuals.FirstOrDefault(v => v is GroupVisual); // If not successful try to get an AtomVisual (should only ever be one!) if (result == null) { result = _visuals.FirstOrDefault(v => v is AtomVisual | v is FunctionalGroupVisual); } // Finally get first ChemicalVisual which ought to be a BondVisual if (result == null) { result = _visuals.FirstOrDefault(); } return(result); }
private HitTestResultBehavior ResultCallback(HitTestResult result) { _visualHit = result.VisualHit as ChemicalVisual; if (_visualHit != null) { _visuals.Add(_visualHit); } return(HitTestResultBehavior.Continue); }
private void CurrentEditor_MouseMove(object sender, MouseEventArgs e) { Clashing = false; CurrentPoint = e.GetPosition(CurrentEditor); //check to see whether we've dragged off the target first if (MouseIsDown && IsDrawing) { CurrentStatus = "Drag along arrow to size ring: [Esc] to cancel"; double xamlBondSize = EditViewModel.Model.XamlBondLength; if (Target != null && GetTargetedVisual(e) != Target) //dragging off a bond or atom { //first, work out how far we've dragged the mouse switch (Target) { case AtomVisual av: RingSize = GetRingSize(av, CurrentPoint, xamlBondSize); IdentifyPlacements(av.ParentAtom, xamlBondSize, out _preferredPlacements, RingSize); if (_preferredPlacements != null) { Vector parallelToBV = GetProjection(av.ParentAtom.BalancingVector(), av.Position, CurrentPoint); Point endPoint = av.Position + parallelToBV; CurrentAdorner = new NRingAdorner(CurrentEditor, EditViewModel.EditBondThickness, _preferredPlacements, av.Position, endPoint); } break; case BondVisual bv: RingSize = GetRingSizeFromEdge(bv, CurrentPoint); Vector perpToBV = GetProjection(bv.ParentBond.BondVector.Perpendicular(), bv.ParentBond.MidPoint, CurrentPoint); IdentifyPlacements(bv.ParentBond, out _preferredPlacements, RingSize, perpToBV); if (_preferredPlacements != null) { Vector?perpToAV = bv.ParentBond.GetUncrowdedSideVector(); if (perpToAV != null) { var parentBondMidPoint = bv.ParentBond.MidPoint; Vector parallelToPerp = GetProjection(perpToAV.Value, parentBondMidPoint, CurrentPoint); Point endPoint = parentBondMidPoint + parallelToPerp; CurrentAdorner = new NRingAdorner(CurrentEditor, EditViewModel.EditBondThickness, _preferredPlacements, parentBondMidPoint, endPoint); } else { CurrentAdorner = null; } } else { CurrentAdorner = null; } break; } } else if (Target == null) //dragging in empty space { RingSize = GetRingSize(FirstPoint, CurrentPoint, xamlBondSize); _preferredPlacements = MarkOutAtoms(FirstPoint, CurrentPoint - FirstPoint, xamlBondSize, RingSize); //need to check whether the user is trying to fuse without //having the pencil directly over the object! foreach (Point p in _preferredPlacements) { ChemicalVisual cv = CurrentEditor.GetTargetedVisual(p); if (cv != null) { //user is trying to fuse wrongly Clashing = true; break; } } if (Clashing) { CurrentStatus = "Can't draw ring here - drag over atom or bond to draw fused ring"; } CurrentAdorner = new NRingAdorner(CurrentEditor, EditViewModel.EditBondThickness, _preferredPlacements, FirstPoint, CurrentPoint, Clashing); } else { switch (CurrentEditor.ActiveVisual) { case AtomVisual av: CurrentStatus = "Drag from atom to size ring."; break; case BondVisual bv: CurrentStatus = "Drag from bond to size ring."; break; default: CurrentStatus = DefaultStatusText; break; } } } }