private void updatePropAttachment(Attachment att, InteractionState ist) { if (!(mainObj is Node)) { return; } Node mainNode = mainObj as Node; RectangleF rc = followMasterRotation ? mainNode.getRotatedBounds() : mainNode.getBoundingRect(); float w = rc.Right - rc.Left; float h = rc.Bottom - rc.Top; RectangleF perc = att.percents; RectangleF rcNew = RectangleF.FromLTRB( rc.Left + w * perc.Left / 100, rc.Top + h * perc.Top / 100, rc.Left + w * perc.Right / 100, rc.Top + h * perc.Bottom / 100); if (!flowChart.DisabledGroups) { att.node.setRect(rcNew); } }
internal override void updateModify(PointF current, InteractionState ist) { base.updateModify(current, ist); PointF pt1 = flowChart.InteractionStartPoint; PointF pt2 = current; PointF ptTLA = new PointF(rcSaved.Left, rcSaved.Top); ptTLA.X += pt2.X - pt1.X; ptTLA.Y += pt2.Y - pt1.Y; ptTLA = flowChart.AlignPointToGrid(ptTLA); base.modifyDX = ptTLA.X - ptLastTopLeft.X; base.modifyDY = ptTLA.Y - ptLastTopLeft.Y; ptLastTopLeft = ptTLA; if (base.modifyHandle == 8) { // translate all points of arrows having both their ends selected foreach (Arrow arrow in arrowsToMove) arrow.translatePoints(base.modifyDX, base.modifyDY); // modify selected objects foreach (ChartObject obj in selectedItems) if (!ignoreItem(obj, ist) && obj.canModify(base.modifyHandle) && !(obj is Arrow && arrowsToMove.Contains(obj))) obj.modifyTranslate(base.modifyDX, base.modifyDY, true); rect.Offset(base.modifyDX, base.modifyDY); } }
internal virtual void completeModify(PointF end, InteractionState ist) { modifyDX = end.X - ptMdfLast.X; modifyDY = end.Y - ptMdfLast.Y; ptMdfLast = end; modifying = false; }
internal virtual void cancelModify(InteractionState ist) { rect = rcSaved; ptOrg = ptSavedOrg; ptEnd = ptSavedEnd; modifyDX = modifyDY = 0; modifying = false; }
// ************ modification ************ internal virtual void startModify(PointF org, int handle, InteractionState ist) { flowChart.UndoManager.onModifyItem(this); modifyHandle = handle; ptMdfLast = org; modifyDX = modifyDY = 0; ptSavedOrg = ptOrg; ptSavedEnd = ptEnd; rcSaved = rect; modifying = true; }
internal override void cancelModify(InteractionState ist) { base.cancelModify(ist); relatedInteraction = null; // call CancelModify method of all selected objects foreach (ChartObject obj in selectedItems) { if (obj.getModifying()) { obj.cancelModify(ist); } } }
internal void beginModification(InteractionState ist) { if (cycleProtect) { return; } cycleProtect = true; Point pt = new Point(0, 0); for (int i = 0; i < attachments.Count; ++i) { ((Attachment)attachments[i]).node.startModify(pt, 0, ist); } getArrowsToMove(ist); cycleProtect = false; }
private bool updateToSegmentAttachment(Attachment att, InteractionState ist) { int segment = att.attData; int n1 = 0, n2 = 0; if (((Arrow)mainObj).SegmentCount <= segment) { cycleProtect = false; new RemoveGroupCmd(MainObject, this).Execute(); return(false); } switch (((Arrow)mainObj).Style) { case ArrowStyle.Bezier: n1 = segment * 3 + 1; n2 = n1 + 1; break; case ArrowStyle.Polyline: case ArrowStyle.Cascading: n1 = segment; n2 = segment + 1; break; } PointF ptPrev = Utilities.midPoint( prevPoints[n1], prevPoints[n2]); PointF ptCurr = Utilities.midPoint( ((Arrow)mainObj).Points[n1], ((Arrow)mainObj).Points[n2]); if (flowChart.DisabledGroups) { ptCurr = ptPrev; } att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); return(true); }
internal override void completeModify(PointF end, InteractionState ist) { base.completeModify(end, ist); relatedInteraction = null; RectangleF rcBounding = new RectangleF(0, 0, 0, 0); if (modifyHandle == 8) { MethodCallVisitor visitor = new MethodCallVisitor( new VisitOperation(updateNSARect)); visitHierarchy(visitor); foreach (ChartObject obj in selectedItems) { RectangleF rcObj = obj.getRotatedBounds(); rcBounding = Utilities.unionNonEmptyRects(rcBounding, rcObj); } rect = rcBounding; // beware of arrow routing; obj.completeModify invokations // might route many arrows repetitively flowChart.DontRouteForAwhile = true; // call EndModify method of all selected objects foreach (ChartObject obj in selectedItems) { if (obj.getModifying() && obj.canModify(modifyHandle)) { obj.completeModify(); } } // now that would route an arrow only once flowChart.DontRouteForAwhile = false; flowChart.routeAllArrows(this); // fire SelectionMoved event, for that was exactly what happened flowChart.fireSelectionMoved(); } }
// ************ modification ************ internal override void startModify(PointF org, int handle, InteractionState ist) { base.startModify(org, handle, ist); relatedInteraction = ist; ptLastTopLeft.X = rect.Left; ptLastTopLeft.Y = rect.Top; ptLastTopLeft = flowChart.AlignPointToGrid(ptLastTopLeft); if (handle == 8 && selectedItems.Count > 0) { foreach (ChartObject obj in selectedItems) if (!obj.getModifying() && obj.canModify(handle)) obj.startModify(org, 0, ist); } // find arrows whose both ends are selected arrowsToMove.Clear(); MethodCallVisitor visitor = new MethodCallVisitor( new VisitOperation(HV_TranslateArrow)); visitHierarchy(visitor); }
private bool updateToPointAttachment(Attachment att, InteractionState ist) { int point = att.attData; if (((Arrow)mainObj).Points.Count <= point) { cycleProtect = false; new RemoveGroupCmd(MainObject, this).Execute(); return(false); } PointF ptPrev = prevPoints[point]; PointF ptCurr = ((Arrow)mainObj).Points[point]; if (flowChart.DisabledGroups) { ptCurr = ptPrev; } att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); return(true); }
internal override void updateModify(PointF current, InteractionState ist) { base.updateModify(current, ist); PointF pt1 = flowChart.InteractionStartPoint; PointF pt2 = current; PointF ptTLA = new PointF(rcSaved.Left, rcSaved.Top); ptTLA.X += pt2.X - pt1.X; ptTLA.Y += pt2.Y - pt1.Y; ptTLA = flowChart.AlignPointToGrid(ptTLA); base.modifyDX = ptTLA.X - ptLastTopLeft.X; base.modifyDY = ptTLA.Y - ptLastTopLeft.Y; ptLastTopLeft = ptTLA; if (base.modifyHandle == 8) { // translate all points of arrows having both their ends selected foreach (Arrow arrow in arrowsToMove) { arrow.translatePoints(base.modifyDX, base.modifyDY); } // modify selected objects foreach (ChartObject obj in selectedItems) { if (!ignoreItem(obj, ist) && obj.canModify(base.modifyHandle) && !(obj is Arrow && arrowsToMove.Contains(obj))) { obj.modifyTranslate(base.modifyDX, base.modifyDY, true); } } rect.Offset(base.modifyDX, base.modifyDY); } }
private void getArrowsToMove(InteractionState ist) { arrowsToMove.Clear(); // translate arrows if attachment type is 'to corner' if (mainObj is Node) { // get arrows of nodes attached 'to corner' ArrowCollection arrowsToCheck = new ArrowCollection(); foreach (Attachment att in Attachments) { if (att.type == AttachTo.FixedCorner || att.type == AttachTo.SideMiddle) { Node node = att.node; node.getAllIncomingArrows(arrowsToCheck); node.getAllOutgoingArrows(arrowsToCheck); } } // check if arrow points must be translated by this group foreach (Arrow a in arrowsToCheck) { if (mustTranslateArrow(a) && !arrowsToMove.Contains(a) && !ist.affectedArrows.Contains(a)) { arrowsToMove.Add(a); ist.affectedArrows.Add(a); } } } }
internal override void startModify(PointF org, int handle, InteractionState ist) { if (cycleProtect) { cycleDetected = true; return; } else cycleDetected = false; cycleProtect = true; base.startModify(org, handle, ist); // save the state of segments so it can be restored from cancelModify savedSegments = saveSegments(); if (subordinateGroup != null) subordinateGroup.beginModification(ist); cycleProtect = false; }
/// <summary> /// checks whether an item shouldn't be moved by the Selection object itself, either because /// its group master moves it, or if it's an arrow whose origin or dest. nodes aren't modified; /// this method is intended to be called only from updateModify /// </summary> private bool ignoreItem(ChartObject item, InteractionState ist) { if (item is Node && item.MasterGroup != null) { // ignore the item if its group master is already moving if (item.MasterGroup.MainObject.getModifying() && !ist.cycleRoots.Contains(item)) return true; } // ignore arrows whose source and destination aren't modified Arrow arrow = item as Arrow; if (arrow != null) { if (!arrow.Origin.getModifying() && !arrow.Destination.getModifying()) return true; } return parentSelected(item, false); }
internal void updateObjects(InteractionState ist) { if (cycleProtect) { return; } cycleProtect = true; if (!flowChart.DisabledGroups) { foreach (Arrow arrow in arrowsToMove) { arrow.translatePoints( mainObj.getBoundingRect().X - prevRect.X, mainObj.getBoundingRect().Y - prevRect.Y); } } for (int i = 0; i < attachments.Count; i++) { Attachment att = (Attachment)attachments[i]; switch (att.type) { case AttachTo.FixedCorner: updateToCornerAttachment(att, ist); break; case AttachTo.SideMiddle: updateSideMiddleAttachment(att, ist); break; case AttachTo.Proportional: updatePropAttachment(att, ist); break; case AttachTo.ArrowPoint: if (!updateToPointAttachment(att, ist)) { return; } break; case AttachTo.ArrowSegment: if (!updateToSegmentAttachment(att, ist)) { return; } break; case AttachTo.LongestHSegment: updateLongestSegmAttachment(att, ist); break; } } if (mainObj.getType() == ItemType.Arrow) { prevPoints = ((Arrow)mainObj).Points.Clone(); } else { prevRect = mainObj.getBoundingRect(); prevRotation = (mainObj as Node).rotation(); } cycleProtect = false; }
protected void AV_Cancel(ChartObject obj, InteractionState ist) { Arrow arrow = (Arrow)obj; arrow.cancelModify(ist); }
internal override void cancelModify(InteractionState ist) { base.cancelModify(ist); relatedInteraction = null; // call CancelModify method of all selected objects foreach (ChartObject obj in selectedItems) if (obj.getModifying()) obj.cancelModify(ist); }
internal override void completeModify(PointF end, InteractionState ist) { if (cycleProtect) return; cycleProtect = true; base.completeModify(end, ist); if (modifyHandle != 9) rect = updateRect(rect, end, modifyHandle); rect = Utilities.normalizeRect(rect); onRectUpdate(); modifying = true; visitArrows( new MethodCallVisitor(new VisitOperation(AV_EndModOutgoing)), new MethodCallVisitor(new VisitOperation(AV_EndModIncoming))); if (subordinateGroup != null) { subordinateGroup.updateObjects(ist); subordinateGroup.endModification(); } modifying = false; flowChart.routeAllArrows(this); flowChart.fireObjModified(this, end, modifyHandle); cycleProtect = false; }
protected override void OnMouseDown(MouseEventArgs e) { if (Enabled) try { this.Focus(); } catch (SecurityException) {}; focusLost = false; endInplaceEdit(true); base.OnMouseDown(e); if (!Enabled) return; if (focusLost) return; if (panMode) return; // get mouse position in document coordinates Graphics g = this.CreateGraphics(); setTransforms(g); PointF ptMousePos = Utilities.deviceToDoc(g, e.X, e.Y); g.Dispose(); if (manipulatorEnacted(ptMousePos)) return; if (e.Clicks > 1) { ChartObject objUnderMouse = GetObjectAt(ptMousePos, false); if (objUnderMouse != null) { fireDblClickedEvent(objUnderMouse, ptMousePos, e.Button); } else { if (DocDblClicked != null) { DocDblClicked(this, new MousePosArgs( e.Button, ptMousePos.X, ptMousePos.Y)); } } if (this.Capture) { this.Capture = false; if (docBuffer != null) { docBuffer.Dispose(); docBuffer = null; } interaction = null; } return; } int btn = btnNum(e.Button); buttonDown[btn] = true; downPos[btn] = new Point(e.X, e.Y); ptStartDragDev = new Point(e.X, e.Y); if (interaction == null) { // enter pan mode if a modifier key is pressed or a mouse button is mapped to panning panMode = ((middleButtonAction == MouseButtonAction.Pan && e.Button == MouseButtons.Middle) || ((_modifierKeyActions.GetKeys(ModifierKeyAction.Pan) & ModifierKeys) != 0 && e.Button == MouseButtons.Left)); if (panMode) { try { Capture = true; } catch (SecurityException) {}; panPoint = new PointF(ScrollX, ScrollY); Cursor = panCursor; return; } } // or start drawing - we care only for left-button clicks if (e.Button == MouseButtons.Left && Behavior != BehaviorType.DoNothing) { userAction = true; // get mouse position in document coordinates g = this.CreateGraphics(); setTransforms(g); ptStartDrag = Utilities.deviceToDoc(g, e.X, e.Y); // start dragging try {this.Capture = true; } catch (SecurityException) {}; mouseMoved = false; // create or modify an item interaction = currentBehavior.startDraw(ptStartDrag, g); interaction.start(ptStartDrag, this); // save the control background docBuffer = createBackBuffer(ClientRectangle, g); drawFlowChart(docBuffer, ClientRectangle, true); // cleanup g.Dispose(); userAction = false; } }
internal override void startModify(PointF org, int handle, InteractionState ist) { if (cycleProtect) { cycleDetected = true; ist.cycleRoots.Add(this); return; } else cycleDetected = false; cycleProtect = true; base.startModify(org, handle, ist); visitArrows( new MethodCallVisitor(new VisitOperationIntr(AV_StartModOutgoing), ist), new MethodCallVisitor(new VisitOperationIntr(AV_StartModIncoming), ist)); if (subordinateGroup != null) subordinateGroup.beginModification(ist); cycleProtect = false; }
internal virtual void updateModify(PointF current, InteractionState ist) { modifyDX = current.X - ptMdfLast.X; modifyDY = current.Y - ptMdfLast.Y; ptMdfLast = current; }
internal void startModifyEnd(InteractionState ist) { if (cycleProtect) return; cycleProtect = true; base.startModify(points[points.Count-1], points.Count-1, ist); // save the state of segments so it can be restored from cancelModify savedSegments = saveSegments(); if (subordinateGroup != null) subordinateGroup.beginModification(ist); cycleProtect = false; }
protected void AV_StartModOutgoing(ChartObject obj, InteractionState ist) { Arrow arrow = (Arrow)obj; arrow.startModifyOrg(ist); }
internal void updateObjects(InteractionState ist) { if(cycleProtect) return; cycleProtect = true; if (!flowChart.DisabledGroups) { foreach (Arrow arrow in arrowsToMove) arrow.translatePoints( mainObj.getBoundingRect().X - prevRect.X, mainObj.getBoundingRect().Y - prevRect.Y); } for (int i = 0; i < attachments.Count; i++) { Attachment att = (Attachment)attachments[i]; switch(att.type) { case AttachTo.FixedCorner: updateToCornerAttachment(att, ist); break; case AttachTo.SideMiddle: updateSideMiddleAttachment(att, ist); break; case AttachTo.Proportional: updatePropAttachment(att, ist); break; case AttachTo.ArrowPoint: if (!updateToPointAttachment(att, ist)) return; break; case AttachTo.ArrowSegment: if (!updateToSegmentAttachment(att, ist)) return; break; case AttachTo.LongestHSegment: updateLongestSegmAttachment(att, ist); break; } } if (mainObj.getType() == ItemType.Arrow) { prevPoints = ((Arrow)mainObj).Points.Clone(); } else { prevRect = mainObj.getBoundingRect(); prevRotation = (mainObj as Node).rotation(); } cycleProtect = false; }
private void updateRelatedPoints(PointF current, InteractionState ist) { // when the arrow style is asBezier it has two kinds of control points // 1. the points through which the curve go, when they are moved the adjacent // points of the second type are moved with the same translation vector // 2. the points controlling the bend of the curve, the line that goes through // them and the point of type 1 between them is tangent in this type 1 point. // when any of the points in type 2 pair is modified, its corresponding // point is moved so they maintain there symmetry in relation to the type 1 point if (style == ArrowStyle.Bezier) { if ((modifyHandle+1) % 3 == 0 && modifyHandle < points.Count-3) { points[modifyHandle+2] = Utilities.symmetricPt(points[modifyHandle], points[modifyHandle+1]); } if ((modifyHandle-1) % 3 == 0 && modifyHandle > 3) { points[modifyHandle-2] = Utilities.symmetricPt(points[modifyHandle], points[modifyHandle-1]); } if ((modifyHandle%3 == 0) && modifyHandle > 0 && modifyHandle < points.Count-1) { points[modifyHandle-1] = new PointF( points[modifyHandle-1].X + modifyDX, points[modifyHandle-1].Y + modifyDY); points[modifyHandle+1] = new PointF( points[modifyHandle+1].X + modifyDX, points[modifyHandle+1].Y + modifyDY); } } // in case of a cascading arrow, when a point is moved the two // points adjacent to it are moved too, so the lines connecting them // maintain their horizontal / vertical orientation if (style == ArrowStyle.Cascading) { int h = modifyHandle; int ip = modifyHandle - 1; int ix = modifyHandle + 1; float dX = points[points.Count - 1].X - points[0].X; float dY = points[points.Count - 1].Y - points[0].Y; // when dragging an end point, change the start segment orientation // if the dx/dy ratio does not correspond to the current orientation if (cascadeOrientation == Orientation.Auto && (h == 0 || h == points.Count - 1) && ((cascadeStartHorizontal && Math.Abs(dX) < Math.Abs(dY)) || (!cascadeStartHorizontal && Math.Abs(dX) > Math.Abs(dY)))) { cascadeStartHorizontal = Math.Abs(dX) > Math.Abs(dY); arrangePrpSegments(dX, dY); } else { // let users change the segment orientation using a mouse gesture // while dragging a point next to the first or last one float mouseDX = current.X - ist.StartPoint.X; float mouseDY = current.Y - ist.StartPoint.Y; if (cascadeOrientation == Orientation.Auto) { bool transpose = false; if (h == 1) { float segmentDX = points[2].X - points[1].X; float segmentDY = points[2].Y - points[1].Y; float pointDX = current.X - points[0].X; float pointDY = current.Y - points[0].Y; transpose = CascadeStartHorizontal ? Math.Abs(pointDY) > Math.Abs(pointDX) && mouseDY * segmentDY > 0 : Math.Abs(pointDX) > Math.Abs(pointDY) && mouseDX * segmentDX > 0; } else if (h == points.Count - 2) { float segmentDX = points[points.Count - 2].X - points[points.Count - 1].X; float segmentDY = points[points.Count - 2].Y - points[points.Count - 1].Y; float pointDX = current.X - points[points.Count - 1].X; float pointDY = current.Y - points[points.Count - 1].Y; transpose = CascadeEndHorizontal ? Math.Abs(pointDY) > Math.Abs(pointDX) && mouseDY * segmentDY > 0 : Math.Abs(pointDX) > Math.Abs(pointDY) && mouseDX * segmentDX > 0; } if (transpose) { if (flowChart.AllowSplitArrows) { if (ist.splitToChangeOrient) { // insert a new segment and change only the orientation of the one at the end segmentCount++; if (h == 1) { cascadeStartHorizontal = !cascadeStartHorizontal; points[1] = points[2]; points.Insert(1, current); } else if (h == points.Count - 2) { points[points.Count - 2] = points[points.Count - 3]; points.Insert(points.Count - 1, current); h++; ip++; ix++; modifyHandle++; ist.setHandleIndex(ist.SelectionHandle + 1); } } else { // remove the segment that was added for the previous change of orientation segmentCount--; if (h == 1) { cascadeStartHorizontal = !cascadeStartHorizontal; points.RemoveAt(1); } else if (h == points.Count - 2) { points.RemoveAt(points.Count - 2); h--; ip--; ix--; modifyHandle--; ist.setHandleIndex(ist.SelectionHandle - 1); } } ist.splitToChangeOrient = !ist.splitToChangeOrient; } else { cascadeStartHorizontal = !cascadeStartHorizontal; // change the orientation of all segments PointF start = points[0]; for (int i = 1; i < points.Count - 1; ++i) { PointF point = points[i]; point.X = (point.X - start.X) / dX * 100; point.Y = (point.Y - start.Y) / dY * 100; points[i] = new PointF( start.X + point.Y * dX / 100, start.Y + point.X * dY / 100); } points[h] = current; } } } alignCascadingSegments(h); } } }
protected override void OnMouseUp(MouseEventArgs e) { #if VERTIGO if (!DesignMode && !loadedFromVertigoAssembly()) throw new Exception("This FlowChart.NET version can be used only " + "with the CodePlex Vertigo project."); #endif base.OnMouseUp(e); // stop autoscrolling if (scrollTimer != null) { scrollTimer.Enabled = false; scrollTimer = null; } // stop pan mode if it's active now if (panMode) { panMode = mouseMoved = false; buttonDown[btnNum(e.Button)] = false; if (Capture) Capture = false; Cursor = curPointer; return; } if (!Enabled) return; userAction = true; Graphics g = this.CreateGraphics(); setTransforms(g); // get mouse position in document coordinates PointF ptCurr = Utilities.deviceToDoc(g, e.X, e.Y); PointF ptMousePos = ptCurr; if (interaction != null && Behavior != BehaviorType.DoNothing && this.Capture && buttonDown[0]) { ChartObject currObject = interaction.CurrentObject; RectangleF rcInv = interaction.InvalidRect; // should the operation be performed? if (e.Button != MouseButtons.Left || !mouseMoved || !interaction.isAllowed(ptCurr)) { // cancel the operation interaction.cancel(this); // if the mouse wasn't moved, select the object under cursor if (!mouseMoved && (interaction.Action == Action.Create || interaction.Action == Action.Split)) { ChartObject obj = GetObjectAt(ptCurr, true); if (obj == null || confirmSelect(obj)) { RectangleF rcOld = calcSelectionRect(activeObject, ptCurr); rcInv = Utilities.unionRects(rcInv, rcOld); rcInv = Utilities.unionNonEmptyRects( rcInv, selection.getRepaintRect(false)); int oldSelCount = selection.GetSize(); // change selection if ((_modifierKeyActions.GetKeys(ModifierKeyAction.Select) & ModifierKeys) != 0) selection.Toggle(obj); else selection.Change(obj); int newSelCount = selection.GetSize(); rcInv = Utilities.unionRects(rcInv, selection.getRepaintRect(false)); rcInv = Utilities.unionRects(rcInv, calcSelectionRect(activeObject, ptCurr)); rcInv.Inflate(selHandleSize, selHandleSize); if (!(oldSelCount == 0 && newSelCount == 0)) dirty = true; } // if confirmSelect() } // if !mouseMoved } // if (e.Button != MouseButtons.Left) else { // complete operation interaction.complete(ptCurr, this); rcInv = interaction.InvalidRect; // update document size if needed if (autoSizeDoc != MindFusion.FlowChartX.AutoSize.None) sizeDocForItem(currObject); } Rectangle rcInvDev = Utilities.docToDevice(g, rcInv); rcInvDev.Inflate(2, 2); this.Invalidate(rcInvDev, false); this.Capture = false; docBuffer.Dispose(); docBuffer = null; interaction = null; } g.Dispose(); int btn = btnNum(e.Button); if (buttonDown[btn] && Math.Abs(downPos[btn].X - e.X) <= 2 && Math.Abs(downPos[btn].Y - e.Y) <= 2) { ChartObject objUnderMouse = GetObjectAt(ptMousePos, false); if (objUnderMouse != null) { fireClickedEvent(objUnderMouse, ptMousePos, e.Button); } else { if (DocClicked != null) { DocClicked(this, new MousePosArgs( e.Button, ptMousePos.X, ptMousePos.Y)); } } } buttonDown[btn] = false; userAction = false; }
private void updateSideMiddleAttachment(Attachment att, InteractionState ist) { int side; PointF ptPrev = new PointF(0, 0); PointF ptCurr = new PointF(0, 0); RectangleF rc; side = att.attData; switch(side) { case 0: ptPrev.X = prevRect.Left + prevRect.Width / 2; ptPrev.Y = prevRect.Top; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left + rc.Width / 2; ptCurr.Y = rc.Top; break; case 1: ptPrev.X = prevRect.Right; ptPrev.Y = prevRect.Top + prevRect.Height / 2; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Right; ptCurr.Y = rc.Top + rc.Height / 2; break; case 2: ptPrev.X = prevRect.Left + prevRect.Width / 2; ptPrev.Y = prevRect.Bottom; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left + rc.Width / 2; ptCurr.Y = rc.Bottom; break; case 3: ptPrev.X = prevRect.Left; ptPrev.Y = prevRect.Top + prevRect.Height / 2; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left; ptCurr.Y = rc.Top + rc.Height / 2; break; } if (followMasterRotation && ist.SelectionHandle == 9 && mainObj is Node) { Node mainNode = mainObj as Node; float newAngle = mainNode.rotation(); if (newAngle != prevRotation) { PointF pivot = mainNode.getCenter(); PointF center = att.node.getCenter(); float a = 0, r = 0; Geometry.Geometry2D.Convert.DekartToPolar( pivot, center, ref a, ref r); a -= newAngle - prevRotation; ptPrev = ptCurr = center; Geometry.Geometry2D.Convert.PolarToDekart( pivot, a,r, ref ptCurr); } } if (flowChart.DisabledGroups) ptCurr = ptPrev; att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); }
internal override void updateModify(PointF current, InteractionState ist) { if (cycleProtect) return; cycleProtect = true; base.updateModify(current, ist); if (modifyHandle != 9) rect = updateRect(rect, current, modifyHandle); onRectUpdate(); visitArrows( new MethodCallVisitor(new VisitOperation(AV_UpdateOutgoing)), new MethodCallVisitor(new VisitOperation(AV_UpdateIncoming)), getExcludedArrows()); if (subordinateGroup != null) subordinateGroup.updateObjects(ist); cycleProtect = false; }
private void updatePropAttachment(Attachment att, InteractionState ist) { if (!(mainObj is Node)) return; Node mainNode = mainObj as Node; RectangleF rc = followMasterRotation ? mainNode.getRotatedBounds() : mainNode.getBoundingRect(); float w = rc.Right - rc.Left; float h = rc.Bottom - rc.Top; RectangleF perc = att.percents; RectangleF rcNew = RectangleF.FromLTRB( rc.Left + w * perc.Left / 100, rc.Top + h * perc.Top / 100, rc.Left + w * perc.Right / 100, rc.Top + h * perc.Bottom / 100); if (!flowChart.DisabledGroups) att.node.setRect(rcNew); }
internal override void cancelModify(InteractionState ist) { if (cycleProtect) return; cycleProtect = true; base.cancelModify(ist); visitArrows( new MethodCallVisitor(new VisitOperationIntr(AV_Cancel), ist)); onRectUpdate(); if (subordinateGroup != null) subordinateGroup.cancelModification(ist); cycleProtect = false; }
private bool updateToPointAttachment(Attachment att, InteractionState ist) { int point = att.attData; if (((Arrow)mainObj).Points.Count <= point) { cycleProtect = false; new RemoveGroupCmd(MainObject, this).Execute(); return false; } PointF ptPrev = prevPoints[point]; PointF ptCurr = ((Arrow)mainObj).Points[point]; if(flowChart.DisabledGroups) ptCurr = ptPrev; att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); return true; }
protected void AV_StartModIncoming(ChartObject obj, InteractionState ist) { Arrow arrow = (Arrow)obj; arrow.startModifyEnd(ist); }
internal override void completeModify(PointF end, InteractionState ist) { base.completeModify(end, ist); relatedInteraction = null; RectangleF rcBounding = new RectangleF(0, 0, 0, 0); if (modifyHandle == 8) { MethodCallVisitor visitor = new MethodCallVisitor( new VisitOperation(updateNSARect)); visitHierarchy(visitor); foreach (ChartObject obj in selectedItems) { RectangleF rcObj = obj.getRotatedBounds(); rcBounding = Utilities.unionNonEmptyRects(rcBounding, rcObj); } rect = rcBounding; // beware of arrow routing; obj.completeModify invokations // might route many arrows repetitively flowChart.DontRouteForAwhile = true; // call EndModify method of all selected objects foreach (ChartObject obj in selectedItems) if (obj.getModifying() && obj.canModify(modifyHandle)) obj.completeModify(); // now that would route an arrow only once flowChart.DontRouteForAwhile = false; flowChart.routeAllArrows(this); // fire SelectionMoved event, for that was exactly what happened flowChart.fireSelectionMoved(); } }
private void updateLongestSegmAttachment(Attachment att, InteractionState ist) { int segment = ((Arrow)mainObj).getLongestHorzSegment(); int n1 = 0, n2 = 0; switch (((Arrow)mainObj).Style) { case ArrowStyle.Bezier: n1 = segment * 3 + 1; n2 = n1 + 1; break; case ArrowStyle.Polyline: case ArrowStyle.Cascading: n1 = segment; n2 = segment + 1; break; } PointF ptCurr = Utilities.midPoint( ((Arrow)mainObj).Points[n1], ((Arrow)mainObj).Points[n2]); if (!flowChart.DisabledGroups) { float dx = ptCurr.X - att.node.getCenter().X; float dy = ptCurr.Y - att.node.getCenter().Y; att.node.modifyTranslate(dx, dy, true); } }
internal void beginModification(InteractionState ist) { if (cycleProtect) return; cycleProtect = true; Point pt = new Point(0, 0); for (int i = 0; i < attachments.Count; ++i) ((Attachment)attachments[i]).node.startModify(pt, 0, ist); getArrowsToMove(ist); cycleProtect = false; }
internal void cancelModification(InteractionState ist) { if (cycleProtect) return; cycleProtect = true; for (int i = 0; i < attachments.Count; ++i) ((Attachment)attachments[i]).node.cancelModify(ist); if (mainObj.getType() == ItemType.Arrow) { prevPoints = ((Arrow)mainObj).Points.Clone(); } else { prevRect = mainObj.getBoundingRect(); prevRotation = (mainObj as Node).rotation(); } cycleProtect = false; }
private bool updateToSegmentAttachment(Attachment att, InteractionState ist) { int segment = att.attData; int n1 = 0, n2 = 0; if (((Arrow)mainObj).SegmentCount <= segment) { cycleProtect = false; new RemoveGroupCmd(MainObject, this).Execute(); return false; } switch (((Arrow)mainObj).Style) { case ArrowStyle.Bezier: n1 = segment * 3 + 1; n2 = n1 + 1; break; case ArrowStyle.Polyline: case ArrowStyle.Cascading: n1 = segment; n2 = segment + 1; break; } PointF ptPrev = Utilities.midPoint( prevPoints[n1], prevPoints[n2]); PointF ptCurr = Utilities.midPoint( ((Arrow)mainObj).Points[n1], ((Arrow)mainObj).Points[n2]); if (flowChart.DisabledGroups) ptCurr = ptPrev; att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); return true; }
private void updateSideMiddleAttachment(Attachment att, InteractionState ist) { int side; PointF ptPrev = new PointF(0, 0); PointF ptCurr = new PointF(0, 0); RectangleF rc; side = att.attData; switch (side) { case 0: ptPrev.X = prevRect.Left + prevRect.Width / 2; ptPrev.Y = prevRect.Top; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left + rc.Width / 2; ptCurr.Y = rc.Top; break; case 1: ptPrev.X = prevRect.Right; ptPrev.Y = prevRect.Top + prevRect.Height / 2; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Right; ptCurr.Y = rc.Top + rc.Height / 2; break; case 2: ptPrev.X = prevRect.Left + prevRect.Width / 2; ptPrev.Y = prevRect.Bottom; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left + rc.Width / 2; ptCurr.Y = rc.Bottom; break; case 3: ptPrev.X = prevRect.Left; ptPrev.Y = prevRect.Top + prevRect.Height / 2; rc = mainObj.getBoundingRect(); ptCurr.X = rc.Left; ptCurr.Y = rc.Top + rc.Height / 2; break; } if (followMasterRotation && ist.SelectionHandle == 9 && mainObj is Node) { Node mainNode = mainObj as Node; float newAngle = mainNode.rotation(); if (newAngle != prevRotation) { PointF pivot = mainNode.getCenter(); PointF center = att.node.getCenter(); float a = 0, r = 0; Geometry.Geometry2D.Convert.DekartToPolar( pivot, center, ref a, ref r); a -= newAngle - prevRotation; ptPrev = ptCurr = center; Geometry.Geometry2D.Convert.PolarToDekart( pivot, a, r, ref ptCurr); } } if (flowChart.DisabledGroups) { ptCurr = ptPrev; } att.node.modifyTranslate( ptCurr.X - ptPrev.X, ptCurr.Y - ptPrev.Y, true); }