Exemplo n.º 1
0
        /// <summary>
        /// Helper method that constrains packet data within
        /// a specified input rectangle.
        /// </summary>
        /// <param name="data">The data to modify.</param>
        private void ModifyPacketData(StylusDataBase data)
        {
            // For each packet in the packet data, check whether
            // its x,y values fall outside of the specified rectangle.
            // If so, replace them with the nearest point that still
            // falls within the rectangle.
            for (int i = 0; i < data.Count; i += data.PacketPropertyCount)
            {
                // packet data always has x followed by y followed by the rest
                int x = data[i];
                int y = data[i + 1];

                // Constrain points to the input rectangle
                x = Math.Max(x, rectangle.Left);
                x = Math.Min(x, rectangle.Right);
                y = Math.Max(y, rectangle.Top);
                y = Math.Min(y, rectangle.Bottom);

                // If necessary, modify the x,y packet data
                if (x != data[i])
                {
                    data[i] = x;
                }
                if (y != data[i + 1])
                {
                    data[i + 1] = y;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Modifies packet data according to the current <see cref="Transform">transform matrix</see>.
        /// </summary>
        /// <param name="data">The data to modify.</param>
        private void ModifyPacketData(StylusDataBase data)
        {
            // Create an array of points, one for each packet.
            Point[] points = new Point[data.Count / data.PacketPropertyCount];
            int     i, j; // Declare outside the loop for the Debug.Assert below.

            // Convert the X and Y coordinates from the packet data into Points.
            for (i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++)
            {
                // X and Y are always the first two elements in a packet.
                points[j] = new Point(data[i], data[i + 1]);
            }

            // We should have exactly as many points as there were packets in the array.
            Debug.Assert(i == data.Count);
            Debug.Assert(j == points.Length);

            // Apply the transformation to the points.
            this.m_InverseTransform.TransformPoints(points);

            // Store the modified X and Y coordinates back into the data.
            // The new values will be seen by all subsequent IStylus(A)SyncPlugins.
            for (i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++)
            {
                data[i]     = points[j].X;
                data[i + 1] = points[j].Y;
            }
        }
Exemplo n.º 3
0
     IEnumerable <TouchEventArgs> GetEvents(StylusDataBase data)
     {
         for (int i = 0; i < data.Count; i += data.PacketPropertyCount)
         {
             float x = data[i];
             float y = data[i + 1];
             if (data.Stylus.Name != "Mouse") // TODO: hack
             {
                 yield return new TouchEventArgs
                        {
                            Index = data.Stylus.Id,
                            X     = Math.Floor(x * _dpiX / 2540.0F),
                            Y     = Math.Floor(y * _dpiY / 2540.0F)
                        }
             }
             ;
         }
     }
 }
Exemplo n.º 4
0
        private void Interpret(StylusDataBase data, int index)
        {
            Point offset = attachedControl.PointToScreen(new Point(0, 0));
            PointF relativePosition = HimetricToPointF(data[index], data[index + 1]);
            PointF position = subject.ScreenToDocument(new PointF(relativePosition.X + offset.X, relativePosition.Y + offset.Y));
            float pressure = (data.PacketPropertyCount > 3 ? data[index + 2] : 255.0f) / 255.0f;
            int status = data[index + data.PacketPropertyCount - 1];
            MouseButtons button = StatusToMouseButtons(status);

            bool didMouseMove = false;

            if (lastbutton != button) 
            {
                //if a button was previously down, MouseUp it.
                if (lastbutton != MouseButtons.None) 
                {
                    subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
                    subject.PerformDocumentMouseUp(lastbutton, 1, position.X, position.Y, 0, pressure);
                    didMouseMove = true;
                }

                //if a new button was pushed, MouseDown it.
                if (button != MouseButtons.None) 
                {
                    subject.PerformDocumentMouseDown(button, 1, position.X, position.Y, 0, pressure);
                    subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
                    didMouseMove = true;
                }
            }

            if (!didMouseMove)
            {
                //regardless of the button states, send a new MouseMove
                subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
            }

            lastbutton = button;
        }
Exemplo n.º 5
0
        private void Interpret(StylusDataBase data, int index)
        {
            Point        offset           = attachedControl.PointToScreen(new Point(0, 0));
            PointF       relativePosition = HimetricToPointF(data[index], data[index + 1]);
            PointF       position         = subject.ScreenToDocument(new PointF(relativePosition.X + offset.X, relativePosition.Y + offset.Y));
            float        pressure         = (data.PacketPropertyCount > 3 ? data[index + 2] : 255.0f) / 255.0f;
            int          status           = data[index + data.PacketPropertyCount - 1];
            MouseButtons button           = StatusToMouseButtons(status);

            bool didMouseMove = false;

            if (lastbutton != button)
            {
                //if a button was previously down, MouseUp it.
                if (lastbutton != MouseButtons.None)
                {
                    subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
                    subject.PerformDocumentMouseUp(lastbutton, 1, position.X, position.Y, 0, pressure);
                    didMouseMove = true;
                }

                //if a new button was pushed, MouseDown it.
                if (button != MouseButtons.None)
                {
                    subject.PerformDocumentMouseDown(button, 1, position.X, position.Y, 0, pressure);
                    subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
                    didMouseMove = true;
                }
            }

            if (!didMouseMove)
            {
                //regardless of the button states, send a new MouseMove
                subject.PerformDocumentMouseMove(button, 1, position.X, position.Y, 0, pressure);
            }

            lastbutton = button;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Erases strokes that overlap the cursor.
        /// </summary>
        /// <param name="sender">The real time stylus associated with the notification</param>
        /// <param name="data">The notification data</param>
        /// <seealso cref="EraserPlugin.StylusDown"/>
        /// <seealso cref="EraserPlugin.Packets"/>
        /// <seealso cref="EraserPlugin.StylusUp"/>
        private void HandlePackets(RealTimeStylus sender, StylusDataBase data)
        {
            using (Synchronizer.Lock(this)) {
                // Ignore the strokes if the eraser stylus is not selected,
                // and if the stylus is not inverted.
                if (this.Eraser == null && !data.Stylus.Inverted)
                    return;

                // Ignore if a touch input
                if (m_TouchSupported) {
                    try {
                        if (sender.GetTabletFromTabletContextId(data.Stylus.TabletContextId).DeviceKind == TabletDeviceKind.Touch)
                            return;
                    }
                    catch {
                        m_TouchSupported = false;
                    }
                }

                // Ignore the strokes if no ink sheet is selected.
                InkSheetModel sheet = this.InkSheetModel;
                if (sheet == null)
                    return;

                // Convert the X and Y coordinates of the data,
                // which are defined to be at offsets [i] and [i+1],
                // to an array of Points.
                Debug.Assert(data.Count % data.PacketPropertyCount == 0);
                Point[] points = new Point[data.Count / data.PacketPropertyCount];
                for (int i = 0, j = 0, il = data.Count, inc = data.PacketPropertyCount; i < il; i += inc, j++)
                    points[j] = new Point(data[i], data[i + 1]);

                // Convert the ink points to pixels so we can
                // ignore the ones that are outside the slide view area.
                // This is done all at once to conserve resources used by the Graphics object.
                Point[] pixels = points;
                using (Synchronizer.Lock(this.m_Display.SyncRoot))
                    using (Graphics g = this.m_Display.CreateGraphics())
                        this.m_Renderer.InkSpaceToPixel(g, ref pixels);

                // Prevent anyone else from accessing the ink concurrently.
                using (Synchronizer.Lock(this.InkSheetModel.Ink.Strokes.SyncRoot)) {
                    // Iterate through each point through which the cursor has passed.
                    for(int i = 0, il = points.Length; i < il; i++) {
                        // Don't erase anything when the cursor is outside of the
                        // slide viewing area.  This prevents users from accidentally
                        // erasing strokes they can't see, especially when using the
                        // slide zoom feature.
                        if (!this.m_DisplayBounds.Contains(pixels[i]))
                            continue;

                        // Find all strokes within some radius from the cursor.
                        Strokes erased = sheet.Ink.HitTest(points[i], ERASER_RADIUS);

                        // If any strokes were found, erase them.
                        if (erased.Count > 0) {
                            // Get the list of stroke IDs in order to send an event
                            int[] ids = new int[erased.Count];
                            for (int j = 0; j < ids.Length; j++)
                                ids[j] = erased[j].Id;

                            // We must first warn listeners that the strokes are about to
                            // be deleted, because after they're deleted, no information
                            // about them can be recovered.  This is used to send
                            // network events and to store undo information.
                            sheet.OnInkDeleting(new StrokesEventArgs(ids));

                            // Delete the erased strokes.
                            sheet.Ink.DeleteStrokes(erased);

                            // Inform listeners that the strokes have actually been deleted.
                            // This causes slide displays to refresh.
                            sheet.OnInkDeleted(new StrokesEventArgs(ids));
                        }
                    }
                }
            }
        }
Exemplo n.º 7
0
        private void HandlePackets(StylusDataBase data)
        {
            using(Synchronizer.Lock(this)) {
                GraphicsPath boundary = ((GraphicsPath) this.m_SelectionBoundaryTable[data.Stylus.Id]);
                ArrayList collected = ((ArrayList) this.m_SelectionPointsTable[data.Stylus.Id]);
                Debug.Assert((boundary == null) == (collected == null));
                if(boundary == null) return;

                using(Graphics g = this.m_Display.CreateGraphics()) {
                    g.IntersectClip(this.m_DisplayBounds);

                    Debug.Assert(data.Count % data.PacketPropertyCount == 0);
                    Point[] points = new Point[data.Count / data.PacketPropertyCount];
                    for(int i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++) {
                        // Create a Point using the X and Y coordinates of the data, which are defined to be at offsets [i] and [i+1].
                        points[j] = new Point(data[i], data[i+1]);
                    }

                    // Add the points to the list of collected points, *before* they are converted to pixel coordinates.
                    collected.AddRange(points);

                    this.m_Renderer.InkSpaceToPixel(g, ref points);

                    PointF previous;
                    int start;
                    if(this.m_SelectionPreviousPointTable.ContainsKey(data.Stylus.Id)) {
                        previous = ((PointF) this.m_SelectionPreviousPointTable[data.Stylus.Id]);
                        start = 0;
                    } else {
                        m_SelectionPreviousPointTable[data.Stylus.Id] = previous =
                            (boundary.PointCount > 0) ? Point.Round(boundary.PathPoints[boundary.PointCount - 1])
                            : points.Length > 0 ? points[0] : Point.Empty;
                        start = (boundary.PointCount > 0) ? 0 : 1;
                    }

                    RectangleF bounds = new RectangleF(previous, SizeF.Empty);

                    for(int i = start; i < points.Length; i++) {
                        PointF point = points[i];
                        boundary.AddLine(previous, (previous = point));
                        ExpandRectangle(ref bounds, previous);
                    }

                    if(points.Length > 0)
                        this.m_SelectionPreviousPointTable[data.Stylus.Id] = previous;

                    int inflate = ((int) Math.Ceiling(SelectionBoundaryPenOuter.Width));
                    bounds.Inflate(inflate, inflate);
                    g.IntersectClip(bounds);
                    DrawSelectionBoundary(g, boundary);
                }
            }
        }
        /// <summary>
        /// Modifies packet data according to the current <see cref="Transform">transform matrix</see>.
        /// </summary>
        /// <param name="data">The data to modify.</param>
        private void ModifyPacketData(StylusDataBase data)
        {
            // Create an array of points, one for each packet.
            Point[] points = new Point[data.Count / data.PacketPropertyCount];
            int i, j; // Declare outside the loop for the Debug.Assert below.

            // Convert the X and Y coordinates from the packet data into Points.
            for(i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++) {
                // X and Y are always the first two elements in a packet.
                points[j] = new Point(data[i], data[i+1]);
            }

            // We should have exactly as many points as there were packets in the array.
            Debug.Assert(i == data.Count);
            Debug.Assert(j == points.Length);

            // Apply the transformation to the points.
            this.m_InverseTransform.TransformPoints(points);

            // Store the modified X and Y coordinates back into the data.
            // The new values will be seen by all subsequent IStylus(A)SyncPlugins.
            for(i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++) {
                data[i] = points[j].X;
                data[i+1] = points[j].Y;
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Erases strokes that overlap the cursor.
        /// </summary>
        /// <param name="sender">The real time stylus associated with the notification</param>
        /// <param name="data">The notification data</param>
        /// <seealso cref="EraserPlugin.StylusDown"/>
        /// <seealso cref="EraserPlugin.Packets"/>
        /// <seealso cref="EraserPlugin.StylusUp"/>
        private void HandlePackets(RealTimeStylus sender, StylusDataBase data)
        {
            using (Synchronizer.Lock(this)) {
                // Ignore the strokes if the eraser stylus is not selected,
                // and if the stylus is not inverted.
                if (this.Eraser == null && !data.Stylus.Inverted)
                {
                    return;
                }

                // Ignore if a touch input
                if (m_TouchSupported)
                {
                    try {
                        if (sender.GetTabletFromTabletContextId(data.Stylus.TabletContextId).DeviceKind == TabletDeviceKind.Touch)
                        {
                            return;
                        }
                    }
                    catch {
                        m_TouchSupported = false;
                    }
                }

                // Ignore the strokes if no ink sheet is selected.
                InkSheetModel sheet = this.InkSheetModel;
                if (sheet == null)
                {
                    return;
                }

                // Convert the X and Y coordinates of the data,
                // which are defined to be at offsets [i] and [i+1],
                // to an array of Points.
                Debug.Assert(data.Count % data.PacketPropertyCount == 0);
                Point[] points = new Point[data.Count / data.PacketPropertyCount];
                for (int i = 0, j = 0, il = data.Count, inc = data.PacketPropertyCount; i < il; i += inc, j++)
                {
                    points[j] = new Point(data[i], data[i + 1]);
                }

                // Convert the ink points to pixels so we can
                // ignore the ones that are outside the slide view area.
                // This is done all at once to conserve resources used by the Graphics object.
                Point[] pixels = points;
                using (Synchronizer.Lock(this.m_Display.SyncRoot))
                    using (Graphics g = this.m_Display.CreateGraphics())
                        this.m_Renderer.InkSpaceToPixel(g, ref pixels);

                // Prevent anyone else from accessing the ink concurrently.
                using (Synchronizer.Lock(this.InkSheetModel.Ink.Strokes.SyncRoot)) {
                    // Iterate through each point through which the cursor has passed.
                    for (int i = 0, il = points.Length; i < il; i++)
                    {
                        // Don't erase anything when the cursor is outside of the
                        // slide viewing area.  This prevents users from accidentally
                        // erasing strokes they can't see, especially when using the
                        // slide zoom feature.
                        if (!this.m_DisplayBounds.Contains(pixels[i]))
                        {
                            continue;
                        }

                        // Find all strokes within some radius from the cursor.
                        Strokes erased = sheet.Ink.HitTest(points[i], ERASER_RADIUS);

                        // If any strokes were found, erase them.
                        if (erased.Count > 0)
                        {
                            // Get the list of stroke IDs in order to send an event
                            int[] ids = new int[erased.Count];
                            for (int j = 0; j < ids.Length; j++)
                            {
                                ids[j] = erased[j].Id;
                            }

                            // We must first warn listeners that the strokes are about to
                            // be deleted, because after they're deleted, no information
                            // about them can be recovered.  This is used to send
                            // network events and to store undo information.
                            sheet.OnInkDeleting(new StrokesEventArgs(ids));

                            // Delete the erased strokes.
                            sheet.Ink.DeleteStrokes(erased);

                            // Inform listeners that the strokes have actually been deleted.
                            // This causes slide displays to refresh.
                            sheet.OnInkDeleted(new StrokesEventArgs(ids));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Helper method that constrains packet data within
        /// a specified input rectangle.
        /// </summary>
        /// <param name="data">The data to modify.</param>
        private void ModifyPacketData(StylusDataBase data)
        {
            // For each packet in the packet data, check whether
            // its x,y values fall outside of the specified rectangle.
            // If so, replace them with the nearest point that still
            // falls within the rectangle.
            for (int i = 0; i < data.Count ; i += data.PacketPropertyCount)
            {
                // packet data always has x followed by y followed by the rest
                int x = data[i];
                int y = data[i+1];

                // Constrain points to the input rectangle
                x = Math.Max(x, rectangle.Left);
                x = Math.Min(x, rectangle.Right);
                y = Math.Max(y, rectangle.Top);
                y = Math.Min(y, rectangle.Bottom);

                // If necessary, modify the x,y packet data
                if (x != data[i])
                {
                    data[i] = x;
                }
                if (y != data[i+1])
                {
                    data[i+1] = y;
                }
            }
        }
Exemplo n.º 11
0
        private void HandlePackets(StylusDataBase data)
        {
            using (Synchronizer.Lock(this)) {
                GraphicsPath boundary  = ((GraphicsPath)this.m_SelectionBoundaryTable[data.Stylus.Id]);
                ArrayList    collected = ((ArrayList)this.m_SelectionPointsTable[data.Stylus.Id]);
                Debug.Assert((boundary == null) == (collected == null));
                if (boundary == null)
                {
                    return;
                }

                using (Graphics g = this.m_Display.CreateGraphics()) {
                    g.IntersectClip(this.m_DisplayBounds);

                    Debug.Assert(data.Count % data.PacketPropertyCount == 0);
                    Point[] points = new Point[data.Count / data.PacketPropertyCount];
                    for (int i = 0, j = 0; i < data.Count; i += data.PacketPropertyCount, j++)
                    {
                        // Create a Point using the X and Y coordinates of the data, which are defined to be at offsets [i] and [i+1].
                        points[j] = new Point(data[i], data[i + 1]);
                    }

                    // Add the points to the list of collected points, *before* they are converted to pixel coordinates.
                    collected.AddRange(points);

                    this.m_Renderer.InkSpaceToPixel(g, ref points);

                    PointF previous;
                    int    start;
                    if (this.m_SelectionPreviousPointTable.ContainsKey(data.Stylus.Id))
                    {
                        previous = ((PointF)this.m_SelectionPreviousPointTable[data.Stylus.Id]);
                        start    = 0;
                    }
                    else
                    {
                        m_SelectionPreviousPointTable[data.Stylus.Id] = previous =
                            (boundary.PointCount > 0) ? Point.Round(boundary.PathPoints[boundary.PointCount - 1])
                            : points.Length > 0 ? points[0] : Point.Empty;
                        start = (boundary.PointCount > 0) ? 0 : 1;
                    }

                    RectangleF bounds = new RectangleF(previous, SizeF.Empty);

                    for (int i = start; i < points.Length; i++)
                    {
                        PointF point = points[i];
                        boundary.AddLine(previous, (previous = point));
                        ExpandRectangle(ref bounds, previous);
                    }

                    if (points.Length > 0)
                    {
                        this.m_SelectionPreviousPointTable[data.Stylus.Id] = previous;
                    }

                    int inflate = ((int)Math.Ceiling(SelectionBoundaryPenOuter.Width));
                    bounds.Inflate(inflate, inflate);
                    g.IntersectClip(bounds);
                    DrawSelectionBoundary(g, boundary);
                }
            }
        }