locked
Ink and PointerPressed

    Question

  • I've created a user control that puts a shape on the screen and then allows you to write on that shape.  I also wanted it to be moveable so it responds to pointer pressed and allows drag etc.

    My problem is that if you move the shape before writing you can do so easily.  After it has ink on it the shape will not respond if you attempt to drag it starting at the point where there is some ink.  I'm assuming I need to pass through the PointerPressed event but cannot figure out where that would be for the Ink.

    Feels like I'm missing something really obvious but if someone feels like pointing me in the right direction I would be really grateful.

    Sunday, August 03, 2014 6:49 PM

Answers

  • I suspect that setting the Lines' HitTestVisible property to false will fix your problem.

    If not, can you please share on OneDrive a buildable sample that demonstrates the problem?

    --Rob

    Thursday, August 07, 2014 11:34 PM
    Owner

All replies

  • What language are you using so we can help you f find the right forum? This will be different for HTML, Xaml, and DirectX.

    If you can provide a minimal sample demonstrating what you are doing that will help as well.

    Your app needs to explicitly pass pointer input to the InkManager so it can intercept it before then to handle manipulations.

    Sunday, August 03, 2014 10:15 PM
    Owner
  • I'm using C# and Xaml.  I'm at work at the moment and don't have access to the code however I essentially lifted the functionality from this example

    http://msdn.microsoft.com/en-gb/library/windows/apps/xaml/hh974457.aspx

    The caveat is that I applied this to a shape object on my canvas as opposed to a canvas i.e. my version has a Shape in the place of InkCanvas.  The control is simply a canvas object with one shape in it at this point.

    When I get home I can post the code but hope this gives some idea of where I am going.

    Monday, August 04, 2014 8:34 AM
  • I'm not sure what "After it has ink on it the shape will not respond if you attempt to drag it starting at the point where there is some ink." means. If you can share via OneDrive a minimal project demonstrating what you're doing and a clear description of the repro steps and expected vs. actual behavior I'd be happy to take a look.

    Monday, August 04, 2014 8:05 PM
    Owner
  • Okay this is the code for the Sticky user control.  

    When you run this you get a circle usercontrol that you can write on.  If you use touch to drag the circle it will drag fine.  However if you first scribble all over the circle with ink and then try to drag it you will find it won't drag unless you find a bit with no ink where you can touch the underlying shape.  

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Input;
    using Windows.UI.Input.Inking;
    using Windows.UI.Xaml.Shapes;
    using Windows.UI;

    using System.Diagnostics;

    // The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

    namespace OneBan
    {
        public sealed partial class Sticky : UserControl
        {
            private Windows.UI.Input.GestureRecognizer GestureProc;


            private TransformGroup Cumulative=new TransformGroup();
            private MatrixTransform Previous=new MatrixTransform() {Matrix=Matrix.Identity};
            private CompositeTransform Delta=new CompositeTransform();
            private InkManager inkManager = new InkManager();
            private uint PenId = 0;
            private Point PreviousPoint;

            public Sticky()
            {
                this.InitializeComponent();

                GestureProc = new Windows.UI.Input.GestureRecognizer();

                GestureProc.GestureSettings =
                    Windows.UI.Input.GestureSettings.ManipulationTranslateX |
                    Windows.UI.Input.GestureSettings.ManipulationTranslateY;

                MyShape.PointerPressed += Sticky_PointerPressed;    //only move if you are holding the shape of the note
                this.PointerCanceled += Sticky_PointerCanceled;
                this.PointerReleased += Sticky_PointerReleased;
                this.PointerMoved += Sticky_PointerMoved;

                this.GestureProc.ManipulationStarted += GestureProc_ManipulationStarted;
                this.GestureProc.ManipulationUpdated += GestureProc_ManipulationUpdated;
                this.GestureProc.ManipulationCompleted += GestureProc_ManipulationCompleted;

                Cumulative.Children.Add(Previous);
                Cumulative.Children.Add(Delta);



                RenderTransform = Cumulative;
            }


            #region Manipulation gesture support functions
            void GestureProc_ManipulationCompleted(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.ManipulationCompletedEventArgs e)
            {
                //currently nothing to do here
            }

            void GestureProc_ManipulationUpdated(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.ManipulationUpdatedEventArgs e)
            {
                this.Previous.Matrix = this.Cumulative.Value;

                Point center = new Point(e.Position.X, e.Position.Y);

                this.Delta.CenterX = center.X;
                this.Delta.CenterY = center.Y;

                this.Delta.Rotation = e.Delta.Rotation;
                this.Delta.ScaleX = Delta.ScaleY = e.Delta.Scale;
                this.Delta.TranslateX = e.Delta.Translation.X;
                this.Delta.TranslateY = e.Delta.Translation.Y;
            }

            void GestureProc_ManipulationStarted(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.ManipulationStartedEventArgs e)
            {
                //no action here yet
            }

            void Sticky_PointerMoved(object sender, PointerRoutedEventArgs e)
            {
                if(e.Pointer.PointerId==PenId)
                {
                    PointerPoint pt = e.GetCurrentPoint(StickyPaper);
                    Point CurrentContactPoint = pt.Position;
                    if (Distance(CurrentContactPoint, PreviousPoint) > 2)
                    {
                        Line line = new Line()
                        {
                            X1 = PreviousPoint.X,
                            Y1 = PreviousPoint.Y,
                            X2 = CurrentContactPoint.X,
                            Y2 = CurrentContactPoint.Y,
                            StrokeThickness = 5,
                            Stroke = new SolidColorBrush(Windows.UI.Colors.Red)
                        };

                        PreviousPoint = CurrentContactPoint;

                        // Draw the line on the canvas by adding the Line object as
                        // a child of the Canvas object.
                        StickyPaper.Children.Add(line);

                        // Pass the pointer information to the InkManager.
                        inkManager.ProcessPointerUpdate(pt);
                    }
                }
                else
                    this.GestureProc.ProcessMoveEvents(e.GetIntermediatePoints(null));

                e.Handled = true;
            }

            private double Distance(Point currentContact, Point previousContact)
            {
                return Math.Sqrt(Math.Pow(currentContact.X - previousContact.X, 2) +
                        Math.Pow(currentContact.Y - previousContact.Y, 2));
            }

            void Sticky_PointerReleased(object sender, PointerRoutedEventArgs e)
            {
                if (e.Pointer.PointerId == PenId)
                {
                    PointerPoint pt = e.GetCurrentPoint(StickyPaper);
                    inkManager.ProcessPointerUp(pt);
                    PenId = 0;
                }
                else
                    this.GestureProc.ProcessUpEvent(e.GetCurrentPoint(null));
                e.Handled = true;
            }

            void Sticky_PointerCanceled(object sender, PointerRoutedEventArgs e)
            {

                this.GestureProc.CompleteGesture();
                e.Handled = true;
            }

            void Sticky_PointerPressed(object sender, PointerRoutedEventArgs e)
            {
                switch(e.Pointer.PointerDeviceType)
                {
                    case Windows.Devices.Input.PointerDeviceType.Pen:
                        PointerPoint pt = e.GetCurrentPoint(StickyPaper);
                        inkManager.ProcessPointerDown(pt);
                        PenId = pt.PointerId;
                        PreviousPoint = pt.Position;

                        e.Handled = true;
                        break;
                    default:
                        // Route the events to the gesture recognizer
                        // The points are in the reference frame of the canvas that contains the rectangle element.
                        this.GestureProc.ProcessDownEvent(e.GetCurrentPoint(null));
                        // Set the pointer capture to the element being interacted with
                        this.CapturePointer(e.Pointer);
                        // Mark the event handled to prevent execution of default handlers
                        e.Handled = true;
                        break;
                }

                Debug.WriteLine("Pointer pressed");
            }

        }

    }

    XAML

    <UserControl
        x:Class="OneBan.Sticky"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:OneBan"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="300">

        <Canvas Name="StickyPaper"  ManipulationMode="None" Canvas.Left="300" Canvas.Top="100" RequestedTheme="Light">
            <Ellipse Name="MyShape" Width="300"  Height="300" Fill="#FFF3F32B" StrokeThickness="2">
                <Ellipse.Stroke>
                    <SolidColorBrush Color="Black" Opacity="0.5"/>
                </Ellipse.Stroke>
            </Ellipse>
        </Canvas>
    </UserControl>

                
    Monday, August 04, 2014 9:13 PM
  • I suspect that setting the Lines' HitTestVisible property to false will fix your problem.

    If not, can you please share on OneDrive a buildable sample that demonstrates the problem?

    --Rob

    Thursday, August 07, 2014 11:34 PM
    Owner
  • Hi Rob,

    You are a genius.  Many thanks this fixed the problem nice and simply.

    Many thanks for your help.

    Trevor

    Friday, August 08, 2014 7:43 PM