private void HandleLoopBoundsChanges(BoundsChangeMerger <Loop> boundsChanges) { foreach (var change in boundsChanges) { SMRect oldBounds = change.OldBounds; SMRect newBounds = change.NewBounds; // Don't move things on structure move. if (!change.IsResize) { continue; } var element = change.TargetElement; float leftDiff = newBounds.Left - oldBounds.Left; float topDiff = newBounds.Top - oldBounds.Top; foreach (BorderNode node in element.BorderNodes) { if (BorderNode.GetBorderNodeDockingAxis(node.Docking) == BorderNodeDockingAxis.Horizontal) { node.Left -= leftDiff; } else { node.Top -= topDiff; } } ViewElementOverlapHelper.PreventBorderNodeOverlap(element, g => ViewElementOverlapHelper.PreventBorderNodeOverlap(g)); element.BorderNodes.ForEach(bn => bn.EnsureDocking()); } }
protected override void SetIconViewGeometry() { Bounds = new SMRect(Left, Top, StockDiagramGeometries.GridSize * 4, StockDiagramGeometries.GridSize * 4); var terminals = FixedTerminals.OfType <NodeTerminal>().ToArray(); terminals[0].Hotspot = new SMPoint(0, StockDiagramGeometries.GridSize * 1); }
public TerminateLifetimeTunnelGuide(SMRect r, LoopTerminateLifetimeTunnel rightRegister, SMThickness border, IEnumerable <SMRect> avoidRects) { // go ahead and coerce rect, because we can't go over borders. _rect = r; _rect.Y += border.Top; _rect.Height = Math.Max(_rect.Height - border.Top - border.Bottom, 0); _terminateLifetimeTunnel = rightRegister; _avoidRects = avoidRects ?? new List <SMRect>(); }
private void SetIconViewGeometry() { int inputTerminalCount = FixedTerminals.Count - 1, height = StockDiagramGeometries.GridSize * 2 * Math.Max(2, inputTerminalCount); Bounds = new SMRect(Left, Top, StockDiagramGeometries.GridSize * 4, height); var terminals = FixedTerminals.OfType <NodeTerminal>().ToArray(); terminals[0].Hotspot = new SMPoint(StockDiagramGeometries.GridSize * 4, StockDiagramGeometries.GridSize * 1); int index = 0; foreach (Terminal terminal in FixedTerminals.Skip(1)) { terminal.Hotspot = new SMPoint(0, StockDiagramGeometries.GridSize * (2 * index + 1)); ++index; } }
private bool IsInBounds(SMRect leftRect, SMRect rightRect) { // To handle collision, we need to fake out our rect size // to add the EdgeOverflow, else contains will fail and we'll land // on top of other avoid zones SMRect leftAdjustedRect = _rect; SMRect rightAdjustedRect = _rect; rightAdjustedRect.X -= EdgeOverflow; rightAdjustedRect.Width += EdgeOverflow * 2; IBorderNodeGuide guide = AdornedStructure.GetGuide(PairedBeginLifetimeTunnel); leftAdjustedRect.X -= guide.EdgeOverflow; leftAdjustedRect.Width += guide.EdgeOverflow * 2; return(leftAdjustedRect.Contains(leftRect) && rightAdjustedRect.Contains(rightRect)); }
private bool IsGood(SMRect leftRect, SMRect rightRect) { if (!IsInBounds(leftRect, rightRect)) { return(false); } else if (_avoidRects.Any(r => r.Overlaps(rightRect) || ((PairedBeginLifetimeTunnel.Owner != null) && r.Overlaps(leftRect)))) { // We need to check PairedLeftShiftRegister.Owner above because when you convert a tunnel to a right shift register, the // paired left shift register gets added then removed immediately from the structure. The final left shift register doesn't // actually get created/added until the user left clicks on an existing tunnel to replace it or somewhere else to create a // new left shift register. However, if we don't exclude the non-parented left shift register in our calculation, we might // end up moving the right shift register when we don't need to. We don't need to worry about doing the same thing for the // left shift register because movement of both shift registers is tied to the right shift register. return(false); } return(true); }
protected override void SetIconViewGeometry() { int maxSideTerminals = Math.Max(InputTerminals.Count(), OutputTerminals.Count()); Bounds = new SMRect(Left, Top, StockDiagramGeometries.GridSize * 4, StockDiagramGeometries.GridSize * Math.Max(maxSideTerminals, 2) * 2); int i = 0; foreach (var inputTerminal in InputTerminals) { inputTerminal.Hotspot = new SMPoint(0, StockDiagramGeometries.GridSize * (i * 2 + 1)); ++i; } i = 0; foreach (var outputTerminal in OutputTerminals) { outputTerminal.Hotspot = new SMPoint(StockDiagramGeometries.GridSize * 4, StockDiagramGeometries.GridSize * (i * 2 + 1)); ++i; } }
public static void FindBorderNodePositions(StructureViewModel structureViewModel, out SMRect leftRect, out SMRect rightRect) { var view = structureViewModel.View; double top = 0; #if FALSE var contextMenuInfo = parameter.QueryService <ContextMenuInfo>().FirstOrDefault(); if (contextMenuInfo != null && !view.IsEmpty) { top = contextMenuInfo.ClickPosition.GetPosition(view).Y; } #endif Structure model = (Structure)structureViewModel.Model; top -= (top - model.OuterBorderThickness.Top) % StockDiagramGeometries.GridSize; top = Math.Max(top, model.OuterBorderThickness.Top); top = Math.Min(top, model.Height - model.OuterBorderThickness.Bottom - StockDiagramGeometries.StandardTunnelHeight); SMRect l = new SMRect(-StockDiagramGeometries.StandardTunnelOffsetForStructures, top, StockDiagramGeometries.StandardTunnelWidth, StockDiagramGeometries.StandardTunnelHeight); SMRect r = new SMRect(model.Width - StockDiagramGeometries.StandardTunnelWidth + StockDiagramGeometries.StandardTunnelOffsetForStructures, top, StockDiagramGeometries.StandardTerminalWidth, StockDiagramGeometries.StandardTunnelHeight); while ( model.BorderNodes.Any( node => node.Bounds.Overlaps(l) || node.Bounds.Overlaps(r))) { l.Y += StockDiagramGeometries.GridSize; r.Y += StockDiagramGeometries.GridSize; } // If we ran out of room looking for a place to put Shift Register, we need to grow our Loop if (l.Bottom > model.Height - model.OuterBorderThickness.Bottom) { model.Height = l.Bottom + StockDiagramGeometries.StandardTunnelHeight; } leftRect = l; rightRect = r; }
/// <summary> /// Called to rubber band select this visual. /// The entire wire is selected since we do not have any segments. testRect can /// be ignored since we do not have segment calculations. /// </summary> public override bool RubberBandSelect(SMRect testRect) { ((SplineWireControl)this.View.AsFrameworkElement).Stroke = Brushes.Orange; return(true); }
public BorderNodeGeometry ConstrainBounds(BorderNodeGeometry geom, RectDifference oldMinusNew) { // ShiftRegisters cannot change docking, so first force the geometry to dock, this coerces crazy X values SMRect coercedInput = EnforceDocking(geom); // Now we are going to iterate up and down the side of the structure, looking for a location in which // both the left and the right registers are clear. We start with the right being the coerced input // and the left being the actual left shift register's bounds _except_ it's Y, which we want to move in sync with it's pair SMRect rightBounds = coercedInput; SMRect leftBounds = PairedBeginLifetimeTunnel.Bounds; leftBounds.Y = rightBounds.Y; // Before we start scanning, make sure our current location doesn't just work, if it does we're done if (IsGood(leftBounds, rightBounds)) { return(new BorderNodeGeometry(rightBounds, BorderNodeDocking.Right)); } const float DistanceToIterateBy = StockDiagramGeometries.GridSize; SMRect rightSideUpIteration = rightBounds; rightSideUpIteration.Y -= DistanceToIterateBy; SMRect leftSideUpIteration = leftBounds; leftSideUpIteration.Y -= DistanceToIterateBy; SMRect rightSideDownIteration = rightBounds; rightSideDownIteration.Y += DistanceToIterateBy; SMRect leftSideDownIteration = leftBounds; leftSideDownIteration.Y += DistanceToIterateBy; bool favorUp = oldMinusNew.Y > 0 || oldMinusNew.X > 0; bool favorDown = oldMinusNew.Y < 0 || oldMinusNew.X < 0; bool favorNeither = !favorUp && !favorDown; // prevent overlap. Starting from our bounds calculation, move outward to find closest. Make sure we don't leave structure. while (true) { if (favorUp || favorNeither) { if (IsGood(leftSideUpIteration, rightSideUpIteration)) { return(new BorderNodeGeometry(rightSideUpIteration, BorderNodeDocking.Right)); } if (!IsInBounds(leftSideUpIteration, rightSideUpIteration)) { favorUp = false; } rightSideUpIteration.Y -= DistanceToIterateBy; leftSideUpIteration.Y -= DistanceToIterateBy; } if (favorDown || favorNeither) { if (IsGood(leftSideDownIteration, rightSideDownIteration)) { return(new BorderNodeGeometry(rightSideDownIteration, BorderNodeDocking.Right)); } if (!IsInBounds(leftSideDownIteration, rightSideDownIteration)) { favorDown = false; } rightSideDownIteration.Y += DistanceToIterateBy; leftSideDownIteration.Y += DistanceToIterateBy; } if (favorNeither && !IsInBounds(leftSideUpIteration, rightSideUpIteration) && !IsInBounds(leftSideDownIteration, rightSideDownIteration)) { // Give up, neither is within bounds. break; } favorNeither = !favorUp && !favorDown; } return(new BorderNodeGeometry(rightBounds, BorderNodeDocking.Right)); }
/// <inheritdoc /> protected override SMRect CalculateBoundsForJointChange(SMRect originalBounds, SMPoint modifiedJointPosition, bool jointAdded, out bool boundsModified, out bool needsBoundsCompute) { throw new NotImplementedException(); }