Touch Support

Topics: WPF
Sep 13, 2010 at 10:49 AM

Hi radioman,

add following code to GMapControl in WindowsPresentation, will be able move the map with a finger in a multitouch app (no zooming only moving)

      protected override void OnStylusDown(StylusDownEventArgs e)
      {
          if (CanDragMap)
          {
              Stylus.Capture(this);

              System.Windows.Point p = e.GetPosition(this);

              if (MapRenderTransform != null)
              {
                  p = MapRenderTransform.Inverse.Transform(p);
              }

              Core.mouseDown.X = Convert.ToInt32(p.X);
              Core.mouseDown.Y = Convert.ToInt32(p.Y);
              if (true)
              {
                  Cursor = Cursors.SizeAll;
                  Core.BeginDrag(Core.mouseDown);
              }
              InvalidateVisual();
          }
          else
          {
              if (!isSelected)
              {
                  System.Windows.Point p = e.GetPosition(this);
                  isSelected = true;
                  SelectedArea = RectLatLng.Empty;
                  selectionEnd = PointLatLng.Empty;
                  selectionStart = FromLocalToLatLng(Convert.ToInt32(p.X), Convert.ToInt32(p.Y));
              }
          }
          base.OnStylusDown(e);
      }

      protected override void OnStylusUp(StylusEventArgs e)
      {
          if (isSelected)
          {
              isSelected = false;
          }

          if (Core.IsDragging)
          {
              Mouse.Capture(null);

              if (isDragging)
              {
                  isDragging = false;
                  Debug.WriteLine("IsDragging = " + isDragging);
              }
              Core.EndDrag();
              Cursor = Cursors.Arrow;

              if (BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(CurrentPosition))
              {
                  if (Core.LastLocationInBounds.HasValue)
                  {
                      CurrentPosition = Core.LastLocationInBounds.Value;
                  }
              }
          }
          else
          {
              if (!selectionEnd.IsEmpty && !selectionStart.IsEmpty)
              {
                  if (!SelectedArea.IsEmpty)
                  {
                      SetZoomToFitRect(SelectedArea);
                  }
              }
              else
              {
                  InvalidateVisual();
              }
          }

          base.OnStylusUp(e);
      }

      protected override void OnStylusMove(StylusEventArgs e)
      {
          if (Core.IsDragging)
          {
              if (!isDragging)
              {
                  isDragging = true;
                  Debug.WriteLine("IsDragging = " + isDragging);
              }

              // ...
              if (BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(CurrentPosition))
              {
              }
              else
              {
                  System.Windows.Point p = e.GetPosition(this);

                  if (MapRenderTransform != null)
                  {
                      p = MapRenderTransform.Inverse.Transform(p);
                  }

                  Core.mouseCurrent.X = Convert.ToInt32(p.X);
                  Core.mouseCurrent.Y = Convert.ToInt32(p.Y);
                  if (true)
                  {
                      Core.Drag(Core.mouseCurrent);
                  }

                  UpdateMarkersOffset();
              }
              InvalidateVisual();
          }
          else
          {
              if (isSelected && !selectionStart.IsEmpty)
              {
                  System.Windows.Point p = e.GetPosition(this);
                  selectionEnd = FromLocalToLatLng(Convert.ToInt32(p.X), Convert.ToInt32(p.Y));
                  if (true)
                  {
                      GMap.NET.PointLatLng p1 = selectionStart;
                      GMap.NET.PointLatLng p2 = selectionEnd;

                      double x1 = Math.Min(p1.Lng, p2.Lng);
                      double y1 = Math.Max(p1.Lat, p2.Lat);
                      double x2 = Math.Max(p1.Lng, p2.Lng);
                      double y2 = Math.Min(p1.Lat, p2.Lat);

                      SelectedArea = new RectLatLng(y1, x1, x2 - x1, y1 - y2);
                  }
              }
          }

          base.OnStylusMove(e);
      }

Coordinator
Sep 13, 2010 at 11:10 AM

great! I'll include it, still can't test in real ;/ ..and do you leave selection code on purpose or i can remove it?

Sep 13, 2010 at 11:32 AM

Hi radioman,

first of all, sorry for my bad english, i am from germany. i experimenting with your great library on multitouch monitor systems under win7. OnStylusDown (OnStylusMove...etc) is the same as OnMouseDown, only that this event fired the digitizer of a multitouch monitor. This Code works for me fine, i can move the map with one finger in every direction. The problem is, if you are using two ore more fingers the mapcontrol begins to shaking. normally, two fingers are for zooming or rotate. this i dont have implementet to this time. now i work on zooming, rotating function when the the digitizer get more as one finger.

daniel

Coordinator
Sep 13, 2010 at 11:39 AM

i see, ..keep in mind, that rotation center isn't in the center somehow, can't find why... and is it possible to get Touch working on windows forms?

Sep 13, 2010 at 11:51 AM

Stylus digitizer events are a part of a uielement in wpf since .net 4. theese events are not available in winforms controls. but i think its possible on other way.

Coordinator
Sep 13, 2010 at 12:01 PM

you mean there are no such events in 3.5?

Sep 13, 2010 at 12:12 PM

 

i have looked into an older test app of me with target framework 3.5. stylus events also available. my mistake. but if you want to implement touch support into winforms you need WM_Gesture handling of Windows Touch API i think.