ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • WPF Interactive 2D Drawing
    .NET/WPF 2D 2013. 7. 11. 03:31
    반응형








    <Window x:Class="WpfApplication21.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Interactive 2D Drawing" Height="400" Width="400">
    <Window.Resources>
    <SolidColorBrush x:Key="MyGrayGridBrush" Color="YellowGreen"/>
    </Window.Resources>
    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition/>
    </Grid.RowDefinitions>
     
    <ToolBarTray Grid.Row="0">
    <ToolBar>
        <RadioButton x:Name="rbSquare" 
            IsChecked="True" ToolTip="Add Square">
            <Rectangle Width="15" Height="15" 
                Stroke="Blue" Fill="LightBlue"/>
        </RadioButton>
     
        <RadioButton x:Name="rbRectangle" 
            IsChecked="False" ToolTip="Add Rectangle">
            <Rectangle Width="20" Height="12"  
                Stroke="Blue" Fill="LightBlue"/>
        </RadioButton>
     
        <RadioButton x:Name="rbCircle" 
            IsChecked="False" ToolTip="Add Circle">
            <Ellipse Width="18" Height="18" 
                        Stroke="Blue" Fill="LightBlue"/>
        </RadioButton>
     
        <RadioButton x:Name="rbEllipse"  
            IsChecked="False" ToolTip="Add Ellipse">
            <Ellipse Width="22" Height="15" 
                        Stroke="Blue" Fill="LightBlue"/>
        </RadioButton>
     
        <RadioButton x:Name="rbCombine"  
            IsChecked="False" ToolTip="Combine shapes">
            <Path Fill="LightBlue" Stroke="Blue">
                <Path.Data>
                    <CombinedGeometry>
                        <CombinedGeometry.Geometry1>
                            <EllipseGeometry  
                                RadiusX="8" 
                                RadiusY="8" 
                                Center="8,8"/>
                        </CombinedGeometry.Geometry1>
                        <CombinedGeometry.Geometry2>
                            <EllipseGeometry 
                                RadiusX="8" 
                                RadiusY="8" 
                                Center="20,8"/>
                        </CombinedGeometry.Geometry2>
                    </CombinedGeometry>
                </Path.Data>
            </Path>
        </RadioButton>
     
        <RadioButton x:Name="rbSelect"  
            IsChecked="False" ToolTip="Select/Move">
            <Polygon  
            Points="6 1,10 1,10 10,14 10,8 16,2 10,6 10"  
                Fill="LightBlue" Stroke="Blue">
                <Polygon.RenderTransform>
                    <RotateTransform CenterX="8" 
                                        CenterY="8" 
                                        Angle="225"/>
                </Polygon.RenderTransform>
            </Polygon>
        </RadioButton>
     
        <RadioButton x:Name="rbDelete"  
            IsChecked="False" ToolTip="Delete">
            <Grid>
                <Line X1="2" Y1="2" X2="14"  
                        Y2="14" Stroke="Blue"/>
                <Line X1="2" Y1="14" X2="14"  
                        Y2="2" Stroke="Blue"/>
            </Grid>
        </RadioButton>
    </ToolBar>
    </ToolBarTray>
     
    <Viewbox Stretch="Uniform" Grid.Row="1">
    <Border Margin="5" BorderBrush="Black" 
            BorderThickness="1" Grid.Row="1" 
            HorizontalAlignment="Left">
        <Canvas Name="canvas1" Width="400" 
                Height="345" ClipToBounds="True" 
    Background="{StaticResource MyGrayGridBrush}" 
    MouseLeftButtonDown="OnMouseLeftButtonDown" 
    MouseLeftButtonUp="OnMouseLeftButtonUp"  
    MouseMove="OnMouseMove"/>
    </Border>
    </Viewbox>
    </Grid>
    </Window> 
    



    public partial class MainWindow : Window
    {
    private List<Path> paths = new List<Path>();
    private Point startPoint = new Point();
    private Shape rubberBand = null;
    Point currentPoint = new Point();
    private bool isDragging = false;
    private bool isDown = false;
    private Path originalElement = new Path();
    private Path movingElement = new Path();
    private Path path1 = new Path();
    private Path path2 = new Path();
    private SolidColorBrush fillColor =
                            new SolidColorBrush();
    private SolidColorBrush borderColor =
                            new SolidColorBrush();
    private SolidColorBrush selectFillColor =
                            new SolidColorBrush();
    private SolidColorBrush selectBorderColor =
                            new SolidColorBrush();
     
    public MainWindow()
    {
        InitializeComponent();
     
        fillColor.Color = Colors.LightGray;
        fillColor.Opacity = 0.5;
        borderColor.Color = Colors.Gray;
        selectFillColor.Color = Colors.LightCoral;
        selectFillColor.Opacity = 0.5;
        selectBorderColor.Color = Colors.Red;
    }
     
    private void OnMouseLeftButtonDown(object senderMouseButtonEventArgs e)
    {
        if (!canvas1.IsMouseCaptured)
        {
            startPoint = e.GetPosition(canvas1);
            canvas1.CaptureMouse();
     
            if (rbCombine.IsChecked == true)
            {
                SetCombineShapes(e);
            }
            else if (rbSelect.IsChecked == true)
            {
                if (canvas1 == e.Source)
                    return;
                isDown = true;
                originalElement = (Path)e.Source;
                e.Handled = true;
            }
            else if (rbDelete.IsChecked == true)
            {
                originalElement = (Path)e.Source;
                DeleteShape(originalElement);
            }
        }
    }
     
    private void OnMouseLeftButtonUp(object senderMouseButtonEventArgs e)
    {
        if (rbSquare.IsChecked == true)
            AddSquare(startPointcurrentPoint);
        else if (rbRectangle.IsChecked == true)
            AddRectangle(startPointcurrentPoint);
        else if (rbCircle.IsChecked == true)
            AddCircle(startPointcurrentPoint);
        else if (rbEllipse.IsChecked == true)
            AddEllipse(startPointcurrentPoint);
     
        if (rubberBand != null)
        {
            canvas1.Children.Remove(rubberBand);
            rubberBand = null;
            canvas1.ReleaseMouseCapture();
        }
     
        if (rbSelect.IsChecked == true)
        {
            if (isDown)
            {
                DragFinishing(false);
                e.Handled = true;
            }
        }
    }
     
    private void AddSquare(Point pointPoint currentPoint1)
    {
        Path path = new Path();
        path.Fill = fillColor;
        path.Stroke = borderColor;
        RectangleGeometry rg = new RectangleGeometry();
        double width = Math.Abs(point.X - currentPoint1.X);
        double height = Math.Abs(point.Y - currentPoint1.Y);
        double left = Math.Min(point.XcurrentPoint1.X);
        double top = Math.Min(point.YcurrentPoint1.Y);
        double side = width;
        if (width > height)
            side = height;
        rg.Rect = new Rect(lefttopsideside);
        path.Data = rg;
        paths.Add(path);
        canvas1.Children.Add(paths[paths.Count - 1]);
    }
     
    private void AddRectangle(Point pointPoint currentPoint1)
    {
        Path path = new Path();
        path.Fill = fillColor;
        path.Stroke = borderColor;
        RectangleGeometry rg = new RectangleGeometry();
        double width = Math.Abs(point.X - currentPoint1.X);
        double height = Math.Abs(point.Y - currentPoint1.Y);
        double left = Math.Min(point.XcurrentPoint1.X);
        double top = Math.Min(point.YcurrentPoint1.Y);
        rg.Rect = new Rect(lefttopwidthheight);
        path.Data = rg;
        paths.Add(path);
        canvas1.Children.Add(paths[paths.Count - 1]);
    }
     
    private void AddCircle(Point pointPoint currentPoint1)
    {
        Path path = new Path();
        path.Fill = fillColor;
        path.Stroke = borderColor;
        EllipseGeometry eg = new EllipseGeometry();
        double width = Math.Abs(point.X - currentPoint1.X);
        double height = Math.Abs(point.Y - currentPoint1.Y);
        double left = Math.Min(point.XcurrentPoint1.X);
        double top = Math.Min(point.YcurrentPoint1.Y);
        double side = width;
        if (width > height)
            side = height;
        eg.Center = new Point(left + side / 2,
            top + side / 2);
        eg.RadiusX = side / 2;
        eg.RadiusY = side / 2;
        path.Data = eg;
        paths.Add(path);
        canvas1.Children.Add(paths[paths.Count - 1]);
    }
     
    private void AddEllipse(Point pointPoint currentPoint1)
    {
        Path path = new Path();
        path.Fill = fillColor;
        path.Stroke = borderColor;
        EllipseGeometry eg = new EllipseGeometry();
        double width = Math.Abs(point.X - currentPoint1.X);
        double height = Math.Abs(point.Y - currentPoint1.Y);
        double left = Math.Min(point.XcurrentPoint1.X);
        double top = Math.Min(point.YcurrentPoint1.Y);
        eg.Center = new Point(left + width / 2,
            top + height / 2);
        eg.RadiusX = width / 2;
        eg.RadiusY = height / 2;
        path.Data = eg;
        paths.Add(path);
        canvas1.Children.Add(paths[paths.Count - 1]);
    }
     
    private void DragFinishing(bool cancel)
    {
        Mouse.Capture(null);
        if (isDragging)
        {
            if (!cancel)
            {
                currentPoint = Mouse.GetPosition(canvas1);
                TranslateTransform tt0 = new TranslateTransform();
                TranslateTransform tt = new TranslateTransform();
                tt.X = currentPoint.X - startPoint.X;
                tt.Y = currentPoint.Y - startPoint.Y;
                Geometry geometry =
                            (RectangleGeometry)new RectangleGeometry();
     
                string s = originalElement.Data.ToString();
     
                if (s == "System.Windows.Media.EllipseGeometry")
                    geometry = (EllipseGeometry)originalElement.Data;
                else if (s == "System.Windows.Media.RectangleGeometry")
                    geometry = (RectangleGeometry)originalElement.Data;
                else if (s == "System.Windows.Media.CombinedGeometry")
                    geometry = (CombinedGeometry)originalElement.Data;
     
                if (geometry.Transform.ToString() != "Identity")
                {
                    tt0 = (TranslateTransform)geometry.Transform;
                    tt.X += tt0.X;
                    tt.Y += tt0.Y;
                }
                geometry.Transform = tt;
                canvas1.Children.Remove(originalElement);
                originalElement = new Path();
                originalElement.Fill = fillColor;
                originalElement.Stroke = borderColor;
                originalElement.Data = geometry;
                canvas1.Children.Add(originalElement);
            }
     
            canvas1.Children.Remove(movingElement);
            movingElement = null;
        }
        isDragging = false;
        isDown = false;
    }
     
    private void OnMouseMove(object senderMouseEventArgs e)
    {
        if (canvas1.IsMouseCaptured)
        {
            currentPoint = e.GetPosition(canvas1);
            if (rubberBand == null)
            {
                rubberBand = new Rectangle();
                rubberBand.Stroke = Brushes.LightCoral;
                rubberBand.StrokeDashArray =
                    new DoubleCollection(new double[] { 42 });
                if (rbSquare.IsChecked == true ||
                    rbRectangle.IsChecked == true ||
                    rbCircle.IsChecked == true ||
                    rbEllipse.IsChecked == true)
                {
                    canvas1.Children.Add(rubberBand);
     
                }
            }
     
            double width = Math.Abs(
                startPoint.X - currentPoint.X);
            double height = Math.Abs(
                startPoint.Y - currentPoint.Y);
            double left = Math.Min(
                startPoint.XcurrentPoint.X);
            double top = Math.Min(
                startPoint.YcurrentPoint.Y);
     
            rubberBand.Width = width;
            rubberBand.Height = height;
            Canvas.SetLeft(rubberBandleft);
            Canvas.SetTop(rubberBandtop);
     
            if (rbSelect.IsChecked == true)
            {
                if (isDown)
                {
                    if (!isDragging && Math.Abs(currentPoint.X - startPoint.X>
                        SystemParameters.MinimumHorizontalDragDistance &&
                        Math.Abs(currentPoint.Y - startPoint.Y>
                        SystemParameters.MinimumVerticalDragDistance)
                        DragStarting();
                    if (isDragging)
                        DragMoving();
                }
            }
        }
    }
     
    private void DragMoving()
    {
        currentPoint = Mouse.GetPosition(canvas1);
        TranslateTransform tt = new TranslateTransform();
        tt.X = currentPoint.X - startPoint.X;
        tt.Y = currentPoint.Y - startPoint.Y;
        movingElement.RenderTransform = tt;
    }
     
    private void DragStarting()
    {
        isDragging = true;
        movingElement = new Path();
        movingElement.Data = originalElement.Data;
        movingElement.Fill = selectFillColor;
        movingElement.Stroke = selectBorderColor;
        canvas1.Children.Add(movingElement);
    }
     
    private void DeleteShape(Path path)
    {
        path.Stroke = selectBorderColor;
        string msg =
            "Do you really want to delete this shape?";
        string title = "Delete Shape?";
        MessageBoxButton buttons = MessageBoxButton.YesNo;
        MessageBoxImage icon = MessageBoxImage.Warning;
        MessageBoxResult result =
            MessageBox.Show(msgtitlebuttonsicon);
        if (result == MessageBoxResult.Yes)
            canvas1.Children.Remove(path);
        else
        {
            path.Stroke = borderColor;
            return;
        }
    }
     
    private void SetCombineShapes(MouseButtonEventArgs e)
    {
        if (path1.Name != "path1Selected")
        {
            path1 = (Path)e.Source;
            path1.Cursor = Cursors.Hand;
            path1.Stroke = selectBorderColor;
            path1.Name = "path1Selected";
        }
        else
        {
            if (path2 != null)
            {
                path2.Stroke = borderColor;
                path2.Cursor = Cursors.Arrow;
            }
            path2 = (Path)e.Source;
            path2.Cursor = Cursors.Hand;
            path2.Stroke = selectBorderColor;
     
            ContextMenu cm = new ContextMenu();
            path2.ContextMenu = cm;
            MenuItem mi = new MenuItem();
            mi.Header = "Union";
            mi.Click +=
                new RoutedEventHandler(Union_Click);
            cm.Items.Add(mi);
            mi = new MenuItem();
            mi.Header = "Xor";
            mi.Click +=
                new RoutedEventHandler(Xor_Click);
            cm.Items.Add(mi);
            mi = new MenuItem();
            mi.Header = "Intersect";
            mi.Click +=
                new RoutedEventHandler(Intersect_Click);
            cm.Items.Add(mi);
            mi = new MenuItem();
            mi.Header = "Exclude";
            mi.Click +=
                new RoutedEventHandler(Exclude_Click);
            cm.Items.Add(mi);
        }
    }
     
    private void Union_Click(
        object senderRoutedEventArgs e)
    {
        CombineShapes(path1path2"Union");
        path1.Name = "";
    }
     
    private void Xor_Click(object sender,
        RoutedEventArgs e)
    {
        CombineShapes(path1path2"Xor");
        path1.Name = "";
    }
     
    private void Intersect_Click(object sender,
        RoutedEventArgs e)
    {
        CombineShapes(path1path2"Intersect");
        path1.Name = "";
    }
     
    private void Exclude_Click(object sender,
        RoutedEventArgs e)
    {
        CombineShapes(path1path2"Exclude");
        path1.Name = "";
    }
     
    private void CombineShapes(Path p1Path p2string s)
    {
        Path myPath = new Path();
        myPath.Fill = fillColor;
        myPath.Stroke = borderColor;
        CombinedGeometry cg = new CombinedGeometry();
     
        if (s == "Union")
            cg.GeometryCombineMode =
                GeometryCombineMode.Union;
        else if (s == "Xor")
            cg.GeometryCombineMode =
                GeometryCombineMode.Xor;
        else if (s == "Intersect")
            cg.GeometryCombineMode =
                GeometryCombineMode.Intersect;
        else if (s == "Exclude")
            cg.GeometryCombineMode =
                GeometryCombineMode.Exclude;
        cg.Geometry1 = p1.Data;
        cg.Geometry2 = p2.Data;
        myPath.Data = cg;
        paths.Add(myPath);
        canvas1.Children.Add(paths[paths.Count - 1]);
        canvas1.Children.Remove(p1);
        canvas1.Children.Remove(p2);
    }
    }


    reference : Practical WPF Graphics Programming




    반응형

    '.NET > WPF 2D' 카테고리의 다른 글

    WPF 2D Geometry and Mini-Language  (0) 2013.07.11
    WPF 2D Bezier Curve  (0) 2013.07.11
    WPF 2D PathGeometry Class  (0) 2013.07.11
    WPF 2D Combined Geometry  (0) 2013.07.11
    WPF 2D Geometry Group  (0) 2013.07.11
    WPF Geometry and 2D Drawing  (0) 2013.07.11
    WPF 2D Composite Transforms  (0) 2013.07.04
    WPF 2D SkewTransform  (0) 2013.07.04

    댓글

Designed by Tistory.