Edit points of FreeShape

戏子无情 提交于 2019-12-31 03:12:07

问题


I'm having some GUI letting a user draw costimized GraphicsPath. I've created it using the GraphicsPath AddLine function.

Now I want to implement what you can see in the attached Microsoft Word image - "Edit Points".

I'm facing several problems:

  1. My path has hunders of "Lines"->each is only one pixel sized. I want to select only "key Points". How do I do that? It's kind of revers of "Flatten", couldn't find such a function.

  2. Is there an existing .Net function to draw the small blue rectangles, and the small green circle around the path? and what about the rectangles around each selected point?

Each help, even partial, would be appreciated.


回答1:


For the first part of your question do have a look at this post, which has a reduction function for a List<Point>. Note that the GraphicsPath.PathPoints collection is read-only, so you have to re-create the path from the reduced points list.

A few remarks on the second part:

  • There is no built-in routine to create the handles. Nor to make them do anything. So you need to code for them.

  • I append a simple class MoveLabel which can be used for this. It can be placed on a control or be added to its Controls collection. Then you can move it around. I have added a callback function MoveAction to process the result when the mouse is released.

You can either add a ..

public delegate void Moved(MoveLabel sender);

..to the form class, or, to avoid the Form1 reference, outside of the form class but in scope for the MoveLabel.

It can be used directly to move points in points list:

Create it on a panel:

var lab= new MoveLabel(Color.CadetBlue, 9, Point.Round(points[i]), i);
lab.Parent = panel;
lab.MoveAction = moved;

A simple processing function:

void moved(MoveLabel sender)
{
    points[sender.PointIndex] = 
            new Point(sender.Left - sender.Width / 2, sender.Top - sender.Height / 2);
    panel.Invalidate();
}

Note the the GraphicsPath.PathPoints are read-only, so we have to re-create the path from the new points list! Actually one can modify individual PathPoints in code, but the result do not stick; so one has to copy the PathPoints to a PointF[], modify them there and re-create the path. For complex paths best by using this overload..

If you want to implement a rotation (or other transformations) you can use the GraphicsPath.Transform function. You can use moveable labels to determine the rotation or scaling data.. Here is my minimal MoveLabel class:

public class MoveLabel : Label
{
    public Form1.Moved MoveAction { get; set; }
    public int PointIndex { get; set; }

    private Point mDown = Point.Empty;

    public MoveLabel()
    {
        MouseDown += (ss, ee) => { mDown = ee.Location; };
        MouseMove += (ss, ee) => {
            if (ee.Button.HasFlag(MouseButtons.Left))
            {
                Location = new Point(Left + ee.X - Width / 2, Top + ee.Y - Height / 2);
                mDown = Location;
            }
        };
        MouseUp += (ss, ee) => { if (MoveAction != null) MoveAction(this);  };
    }

    public MoveLabel(Color c, int size, Point location, int pointIndex) : this()
    {
        BackColor = Color.CadetBlue;
        Size = new Size(size, size);
        Location = location;
        PointIndex = pointIndex;
    }
}

This will also work fine to move points from bezier curves. By adding a call MoveAction(this); to the MouseMove linq code you can get live updates.. Make sure the Panels are DoubleBuffered for this :-)

Example:


Btw: I just came upon this post which shows how easily the curve or any other GDI+ vector drawing can be saved to emf, preserving the vector quality!


Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.



来源:https://stackoverflow.com/questions/50714327/edit-points-of-freeshape

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!