/// <summary> /// Undo action. /// </summary> virtual public void Undo() { if (History <ShapeCollection> .IsAtStart()) { return; } _shapes.Clear(); _shapes.AddRange(History <ShapeCollection> .Undo()); Invalidate(); }
public void SelectUIShape(UIShapeBase shape) { if (m_bCopying == true) { return; } if (m_selectedShapeList.Contains(shape) == false) { m_selectedShapeList.Add(shape); // 선택에 넣음 } if (shape == m_baseDialog || shape.Parent == m_baseDialog) // 작업 다이얼로그는 그대로 { m_UIShapeList.Clear(); foreach (ShapeBase child in m_baseDialog.ChildCollection) { if (child is UIShapeBase) { m_UIShapeList.Add(child as UIShapeBase); } } m_UIShapeList.Add(m_baseDialog); // 다이얼로그는 제일 마지막에 추가 ( 나중에 검색할때 가장 나중에 검색되도록 ) return; } // 작업 다이얼로그가 변경됨 if (shape is UIShapeDialog) { m_baseDialog = shape as UIShapeDialog; } else if (shape.Parent is UIShapeDialog) { m_baseDialog = shape.Parent as UIShapeDialog; } else { return; } m_UIShapeList.Clear(); foreach (ShapeBase child in m_baseDialog.ChildCollection) { if (child is UIShapeBase) { m_UIShapeList.Add(child as UIShapeBase); } } m_UIShapeList.Add(m_baseDialog); // 다이얼로그는 제일 마지막에 추가 ( 나중에 검색할때 가장 나중에 검색되도록 ) }
public override bool OnMouseUp(MouseEventArgs e, KeyModifier eKeyMod, int iOldX, int iOldY) { if (Dragmode == MOUSE_MODE.UI_AREA_SELECT) { // 범위내의 Shape 들을 전부 Select } if (Dragmode == MOUSE_MODE.UI_MOVE || Dragmode == MOUSE_MODE.UI_COPY) { foreach (UIShapeBase shape in m_selectedShapeList) { EditorManager.Actions.Add(new SetPropertyAction(shape, "PosX", shape.PosX)); EditorManager.Actions.Add(new SetPropertyAction(shape, "PosY", shape.PosY)); } } else if (Dragmode == MOUSE_MODE.UI_SIZE) { foreach (UIShapeBase shape in m_selectedShapeList) { EditorManager.Actions.Add(new SetPropertyAction(shape, "SizeX", shape.SizeX)); EditorManager.Actions.Add(new SetPropertyAction(shape, "SizeY", shape.SizeY)); } } else { // bool addSelection = false; // bool toggleSelection = false; // // if ((eKeyMod & KeyModifier.Ctrl) > 0 && (eKeyMod & KeyModifier.Shift) > 0) // addSelection = true; // // UIShapeBase hitShape = this.GetUIShape(e.X, e.Y); // // if (addSelection) // View.Gizmo.AddShape(hitShape, false); // else if (toggleSelection) // View.Gizmo.AddShape(hitShape, true); // else // View.Gizmo.SetSingleShape(hitShape); } // m_selectedShapeList.Clear(); m_UICopyShapeList.Clear(); Dragmode = MOUSE_MODE.UI_NONE; m_bCopying = false; //m_selectedShape = null; return(false); }
public static void LoadShapeCollection(string fileName) { bool replace = true; if (replace) { mShapeCollection.RemoveFromManagers(); mShapeCollection.Clear(); mShapeCollection = FlatRedBallServices.Load <ShapeCollection>(fileName, ContentManagerName); mShapeCollection.AddToManagers(); LastLoadedFile = fileName; } }
public override bool OnMouseDown(MouseEventArgs e, KeyModifier eKeyMod, int iOldX, int iOldY) { // 1. 현재 마우스 포지션의 UI 를 가지고 온다 // 2. UI 가 있고, 커서가 경계에 겹칠 경우 - Select 해주고 마우스 커서 변경 , Move Mode 로 Position 변경 // 3. UI 가 있고, 커서가 경계 안에 있을 경우 - 사이즈 변경 if (e.Button == MouseButtons.Left) { UIShapeBase selectedShape = null; if (View.Cursor == Cursors.Arrow) // 화살표일 경우 선택 모드 { m_selectedShapeList.Clear(); selectedShape = this.GetUIShape(e.X, e.Y, false); } else if (View.Cursor == Cursors.Cross) { selectedShape = this.GetUIShape(e.X, e.Y, false); } else// 화살표가 아니면 선택된 아이템중에 선택 { selectedShape = this.GetUIShapeFromSelection(e.X, e.Y); } if (eKeyMod == KeyModifier.Shift) // Shift 누르면 복사 { m_bCopying = true; Dragmode = MOUSE_MODE.UI_COPY; } if (selectedShape != null) { if (m_selectedShapeList.Contains(selectedShape) == false) { m_selectedShapeList.Add(selectedShape); } } } // if (EditorManager.SelectedShapes.Contains(m_selectedShape) == false ) // { // EditorManager.SelectedShapes = new CSharpFramework.ShapeCollection(); // EditorManager.SelectedShapes.Add(m_selectedShape); // } if (m_selectedShapeList.Count >= 1) { if (View.Cursor == Cursors.SizeAll) { if (eKeyMod == KeyModifier.Shift && Dragmode == MOUSE_MODE.UI_COPY) // 시프트키 눌리고 , 셀렉티드 쉐입에 , Move Mode 이면 복사 { m_bCopying = true; foreach (UIShapeBase shape in m_selectedShapeList) { if (shape != null) { UIShapeBase copyShape = CreateNewShape(shape, m_baseDialog, shape.PosX, shape.PosY); m_UICopyShapeList.Add(copyShape); } } m_selectedShapeList.Clear(); m_selectedShapeList.AddRange(m_UICopyShapeList); m_UIShapeList.AddRange(m_UICopyShapeList); // // foreach (UIShapeBase shape in m_UICopyShapeList) // { // EditorManager.Actions.Add(new AddShapeAction(shape, m_baseDialog, shape.ParentLayer, true)); // } // // EditorManager.SelectedShapes.Clear(); // 기존 선택된 UI 들 지우고 // EditorManager.SelectedShapes.AddRange(m_UICopyShapeList); // 복사된거만 선택 m_bCopying = false; //UIShapeBase copyShape = CreateNewShape(m_selectedShape, m_baseDialog, m_selectedShape.PosX, m_selectedShape.PosY); //m_selectedShape = copyShape; //UIShapeBase copyShape = (UIShapeBase)m_selectedShape.Clone(); //m_UICopyShapeList.Add(copyShape); } else { Dragmode = MOUSE_MODE.UI_MOVE; } } else if (View.Cursor == Cursors.Arrow) { } else { Dragmode = MOUSE_MODE.UI_SIZE; } } if (Dragmode == MOUSE_MODE.UI_COPY) { ShapeCollection collection = new CSharpFramework.ShapeCollection(); collection.AddRange(m_UICopyShapeList); EditorManager.SelectedShapes = collection; } else { ShapeCollection collection = new CSharpFramework.ShapeCollection(); collection.AddRange(m_selectedShapeList); EditorManager.SelectedShapes = collection; } return(false); }
/// <summary> /// Modifies the first Polygon so that it is the result of both merged polygons. /// This method assumes that the polygons collide and that both are drawn /// clockwise. /// </summary> /// <param name="polygon">The first polygon. This one will be modified.</param> /// <param name="otherPolygon">The second polygon which will not be modified.</param> #endregion public static void Merge(Polygon polygon, Polygon otherPolygon) { // Vic says: This is useful for debugging merging. Don't remove it!!! bool shouldDebug = false; Segment[] firstSegments; Segment[] secondSegments; List<ContactPoint> contactPoints = GetContactPoints(polygon, otherPolygon, out firstSegments, out secondSegments); #if !SILVERLIGHT && !WINDOWS_PHONE && !XBOX360 && !IOS && !MONODROID if (shouldDebug) { ShapeCollection sc = new ShapeCollection(); sc.Polygons.Add(polygon); sc.Polygons.Add(otherPolygon); for (int i = 0; i < contactPoints.Count; i++) { Circle circle = new Circle(); circle.Radius = .5f; circle.Position = contactPoints[i].Position; if (contactPoints[i].ContactType == ContactType.SegmentIntersection) { circle.Color = Color.Orange; } else { circle.Color = Color.Green; } sc.Circles.Add(circle); } FlatRedBall.Content.Math.Geometry.ShapeCollectionSave scs = new FlatRedBall.Content.Math.Geometry.ShapeCollectionSave(); scs.AddPolygonList(sc.Polygons); scs.AddCircleList(sc.Circles); string fileName = FlatRedBall.IO.FileManager.MyDocuments + "mergeTest.shcx"; scs.Save(fileName); sc.Clear(); } #endif int firstPointToStartAt = GetPointToStartAt(polygon, otherPolygon); if (firstPointToStartAt == -1) { throw new NotImplementedException(); // return a polygon that is the same shape as the rectangle } List<Vector3> thisVertices = GetAbsoluteVertices(firstSegments); List<Vector3> otherVertices = GetAbsoluteVertices(secondSegments); SetPointsFromContactPointsAndVertices(polygon, otherPolygon, contactPoints, firstPointToStartAt, thisVertices, otherVertices); }
/// <summary> /// Exports the part of the diagram that encloses all given shapes (plus margin on each side) to an image of the given format. /// Pass null/Nothing for Parameter shapes in order to expor the whole diagram area. /// </summary> /// <param name="imageFormat">Specifies the format of the graphics file.</param> /// <param name="shapes">The shapes that should be drawn. If null/Nothing, the whole diagram area will be exported.</param> /// <param name="margin">Specifies the thickness of the margin around the exported diagram area.</param> /// <param name="withBackground">Specifies whether the diagram's background should be exported to the graphics file.</param> /// <param name="backgroundColor">Specifies a color for the exported image's background. /// If the diagram is exported with background, the diagram's background will be drawn over the specified background color.</param> /// <param name="dpi">Specifies the resolution for the export file. Only applies to pixel based image file formats.</param> public Image CreateImage(ImageFileFormat imageFormat, IEnumerable<Shape> shapes, int margin, bool withBackground, Color backgroundColor, int dpi) { Image result = null; // Get/Create info graphics bool disposeInfoGfx; Graphics infoGraphics; if (DisplayService != null) { infoGraphics = DisplayService.InfoGraphics; disposeInfoGfx = false; } else { infoGraphics = Graphics.FromHwnd(IntPtr.Zero); disposeInfoGfx = true; } try { // If dpi value is not valid, get current dpi from display service if (dpi <= 0) dpi = (int)Math.Round((infoGraphics.DpiX + infoGraphics.DpiY) / 2f); // Get bounding rectangle around the given shapes Rectangle imageBounds = Rectangle.Empty; if (shapes == null) { imageBounds.X = imageBounds.Y = 0; imageBounds.Width = Width; imageBounds.Height = Height; } else { int left, top, right, bottom; left = top = int.MaxValue; right = bottom = int.MinValue; // Calculate the bounding rectangle of the given shapes Rectangle boundingRect = Rectangle.Empty; foreach (Shape shape in shapes) { boundingRect = shape.GetBoundingRectangle(true); if (boundingRect.Left < left) left = boundingRect.Left; if (boundingRect.Top < top) top = boundingRect.Top; if (boundingRect.Right > right) right = boundingRect.Right; if (boundingRect.Bottom > bottom) bottom = boundingRect.Bottom; } if (Geometry.IsValid(left, top, right, bottom)) imageBounds = Rectangle.FromLTRB(left, top, right, bottom); } imageBounds.Inflate(margin, margin); imageBounds.Width += 1; imageBounds.Height += 1; bool originalQualitySetting = this.HighQualityRendering; HighQualityRendering = true; UpdateBrushes(); float scaleX = 1, scaleY = 1; switch (imageFormat) { case ImageFileFormat.Svg: throw new NotImplementedException(); case ImageFileFormat.Emf: case ImageFileFormat.EmfPlus: // Create MetaFile and graphics context IntPtr hdc = infoGraphics.GetHdc(); try { Rectangle bounds = Rectangle.Empty; bounds.Size = imageBounds.Size; result = new Metafile(hdc, bounds, MetafileFrameUnit.Pixel, (imageFormat == ImageFileFormat.Emf) ? EmfType.EmfOnly : EmfType.EmfPlusDual, Name); } finally { infoGraphics.ReleaseHdc(hdc); } break; case ImageFileFormat.Bmp: case ImageFileFormat.Gif: case ImageFileFormat.Jpeg: case ImageFileFormat.Png: case ImageFileFormat.Tiff: int imgWidth = imageBounds.Width; int imgHeight = imageBounds.Height; if (dpi > 0 && dpi != infoGraphics.DpiX || dpi != infoGraphics.DpiY) { scaleX = dpi / infoGraphics.DpiX; scaleY = dpi / infoGraphics.DpiY; imgWidth = (int)Math.Round(scaleX * imageBounds.Width); imgHeight = (int)Math.Round(scaleY * imageBounds.Height); } result = new Bitmap(Math.Max(1, imgWidth), Math.Max(1, imgHeight)); ((Bitmap)result).SetResolution(dpi, dpi); break; default: throw new NShapeUnsupportedValueException(typeof(ImageFileFormat), imageFormat); } // Draw diagram using (Graphics gfx = Graphics.FromImage(result)) { GdiHelpers.ApplyGraphicsSettings(gfx, RenderingQuality.MaximumQuality); // Fill background with background color if (backgroundColor.A < 255) { if (imageFormat == ImageFileFormat.Bmp || imageFormat == ImageFileFormat.Jpeg) { // For image formats that do not support transparency, fill background with the RGB part of // the given backgropund color gfx.Clear(Color.FromArgb(255, backgroundColor)); } else if (backgroundColor.A > 0) { // Skip filling background for meta files if transparency is 100%: // Filling Background with Color.Transparent causes graphical glitches with many applications gfx.Clear(backgroundColor); } } else { // Graphics.Clear() does not work as expected for classic EMF (fills only the top left pixel // instead of the whole graphics context). if (imageFormat == ImageFileFormat.Emf) { using (SolidBrush brush = new SolidBrush(backgroundColor)) gfx.FillRectangle(brush, gfx.ClipBounds); } else gfx.Clear(backgroundColor); } // Transform graphics (if necessary) gfx.TranslateTransform(-imageBounds.X, -imageBounds.Y, MatrixOrder.Prepend); if (scaleX != 1 || scaleY != 1) gfx.ScaleTransform(scaleX, scaleY, MatrixOrder.Append); // Draw diagram background if (withBackground) DrawBackground(gfx, imageBounds); // Draw diagram shapes if (shapes == null) { foreach (Shape shape in diagramShapes.BottomUp) shape.Draw(gfx); } else { // Add shapes to ShapeCollection (in order to maintain zOrder while drawing) int cnt = (shapes is ICollection) ? ((ICollection)shapes).Count : -1; ShapeCollection shapeCollection = new ShapeCollection(cnt); foreach (Shape s in shapes) { // Sort out duplicate references to shapes (as they can occur in the result of Diagram.FindShapes()) if (shapeCollection.Contains(s)) continue; shapeCollection.Add(s, s.ZOrder); } // Draw shapes foreach (Shape shape in shapeCollection.BottomUp) shape.Draw(gfx); shapeCollection.Clear(); } // Reset transformation gfx.ResetTransform(); } // Restore original graphics settings HighQualityRendering = originalQualitySetting; UpdateBrushes(); return result; } finally { if (disposeInfoGfx) GdiHelpers.DisposeObject(ref infoGraphics); } }
/// <summary> /// Modifies the first Polygon so that it is the result of both merged polygons. /// This method assumes that the polygons collide and that both are drawn /// clockwise. /// </summary> /// <param name="polygon">The first polygon. This one will be modified.</param> /// <param name="otherPolygon">The second polygon which will not be modified.</param> #endregion public static void Merge(Polygon polygon, Polygon otherPolygon) { // Vic says: This is useful for debugging merging. Don't remove it!!! bool shouldDebug = false; Segment[] firstSegments; Segment[] secondSegments; List <ContactPoint> contactPoints = GetContactPoints(polygon, otherPolygon, out firstSegments, out secondSegments); #if !MONOGAME if (shouldDebug) { ShapeCollection sc = new ShapeCollection(); sc.Polygons.Add(polygon); sc.Polygons.Add(otherPolygon); for (int i = 0; i < contactPoints.Count; i++) { Circle circle = new Circle(); circle.Radius = .5f; circle.Position = contactPoints[i].Position; if (contactPoints[i].ContactType == ContactType.SegmentIntersection) { circle.Color = Color.Orange; } else { circle.Color = Color.Green; } sc.Circles.Add(circle); } FlatRedBall.Content.Math.Geometry.ShapeCollectionSave scs = new FlatRedBall.Content.Math.Geometry.ShapeCollectionSave(); scs.AddPolygonList(sc.Polygons); scs.AddCircleList(sc.Circles); string fileName = FlatRedBall.IO.FileManager.MyDocuments + "mergeTest.shcx"; scs.Save(fileName); sc.Clear(); } #endif int firstPointToStartAt = GetPointToStartAt(polygon, otherPolygon); if (firstPointToStartAt == -1) { throw new NotImplementedException(); // return a polygon that is the same shape as the rectangle } List <Vector3> thisVertices = GetAbsoluteVertices(firstSegments); List <Vector3> otherVertices = GetAbsoluteVertices(secondSegments); SetPointsFromContactPointsAndVertices(polygon, otherPolygon, contactPoints, firstPointToStartAt, thisVertices, otherVertices); }