Moving a Gadget with a Tablet?

Just starting out? Need help? Post your questions and find answers here.
Stefan
Posts: 248
Joined: Mon Feb 05, 2018 9:44 pm

Moving a Gadget with a Tablet?

Post by Stefan »

Click on the red gadget and then move the mouse.
This code works well with a PC, but unfortunately not with a tablet.
Is there a way to make it work with the tablet too? As a web app

Code: Select all


EnableExplicit



Enumeration
  
  #window
  #gadget
  #Timer
  
EndEnumeration


Declare Main()
Declare GadgetEvents()
Declare TimerEvents()

Main()

Procedure Main()
  Protected  pic
  
  OpenWindow(#window,0,0,800,600,"Test")
  
  pic=CreateImage(#PB_Any,100,60,32,RGB(200,0,0))
  ImageGadget(#gadget,20,20,ImageWidth(pic),ImageHeight(pic),ImageID(pic))
  
  BindEvent(#PB_Event_Gadget,       @GadgetEvents())
  BindEvent(#PB_Event_Timer,        @TimerEvents())
  
EndProcedure

Procedure GadgetEvents()
  
  If EventGadget()=#gadget
    AddTimer(#timer,50)
  EndIf
  
  
  
  
EndProcedure
Procedure TimerEvents()
  
  If EventTimer()=#Timer  
    
    
    Protected  mx,my
    
    
    mx=DesktopScaledX(WindowMouseX(#window))
    my=DesktopScaledY(WindowMouseY(#window))
    
    If my>0 And my>0
      ResizeGadget(#gadget,mx,my,#PB_Ignore,#PB_Ignore)
    EndIf
    
  EndIf
  
EndProcedure


User avatar
Peter
Posts: 1197
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Moving a Gadget with a Tablet?

Post by Peter »

You can use jQuery UI draggable():

Code: Select all

EnableExplicit

Enumeration
  
  #window
  #gadget
  
EndEnumeration

Declare Main()

Main()

Procedure Main()
  
  Protected  pic
  
  OpenWindow(#window, 0, 0, 800, 600, "Test")
  
  pic = CreateImage(#PB_Any, 100, 60, 32, RGB(200, 0, 0))
  
  ImageGadget(#gadget, 20, 20, ImageWidth(pic), ImageHeight(pic), ImageID(pic))
  
  Protected GID
  
  GID = GadgetID(#gadget)
  
  ! $(v_gid.gadget).draggable();
  
EndProcedure
More informations: https://jqueryui.com/draggable/
Stefan
Posts: 248
Joined: Mon Feb 05, 2018 9:44 pm

Re: Moving a Gadget with a Tablet?

Post by Stefan »

This works wonderfully with a PC, but unfortunately not with a tablet. (Android 12)

The example at https://jqueryui.com/draggable/
does not work with a tablet either
User avatar
Peter
Posts: 1197
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Moving a Gadget with a Tablet?

Post by Peter »

It seems that jQueryUI only recognises the mouse move event, but not the touch move event. Here you could use the jQuery UI Touch Punch library, which extends jQueryUI with the missing event:

Note: Please only open the code with a SpiderBasic version greater than 3.01, otherwise the JavaScript code will be changed.

Code: Select all

EnableExplicit

Enumeration
  
  #window
  #gadget
  
EndEnumeration

Procedure jQueryUITouchPunch()
  
  EnableJS

/*!
 * jQuery UI Touch Punch 0.2.3 (https://github.com/furf/jquery-ui-touch-punch)
 *
 * Copyright 2011–2014, Dave Furfero
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * Depends:
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 */
(function ($) {

  // Detect touch support
  $.support.touch = 'ontouchend' in document;

  // Ignore browsers without touch support
  if (!$.support.touch) {
    return;
  }

  var mouseProto = $.ui.mouse.prototype,
      _mouseInit = mouseProto._mouseInit,
      _mouseDestroy = mouseProto._mouseDestroy,
      touchHandled;

  /**
   * Simulate a mouse event based on a corresponding touch event
   * @param {Object} event A touch event
   * @param {String} simulatedType The corresponding mouse event
   */
  function simulateMouseEvent (event, simulatedType) {

    // Ignore multi-touch events
    if (event.originalEvent.touches.length > 1) {
      return;
    }

    event.preventDefault();

    var touch = event.originalEvent.changedTouches[0],
        simulatedEvent = document.createEvent('MouseEvents');
    
    // Initialize the simulated mouse event using the touch event's coordinates
    simulatedEvent.initMouseEvent(
      simulatedType,    // type
      true,             // bubbles                    
      true,             // cancelable                 
      window,           // view                       
      1,                // detail                     
      touch.screenX,    // screenX                    
      touch.screenY,    // screenY                    
      touch.clientX,    // clientX                    
      touch.clientY,    // clientY                    
      false,            // ctrlKey                    
      false,            // altKey                     
      false,            // shiftKey                   
      false,            // metaKey                    
      0,                // button                     
      null              // relatedTarget              
    );

    // Dispatch the simulated event to the target element
    event.target.dispatchEvent(simulatedEvent);
  }

  /**
   * Handle the jQuery UI widget's touchstart events
   * @param {Object} event The widget element's touchstart event
   */
  mouseProto._touchStart = function (event) {

    var self = this;

    // Ignore the event if another widget is already being handled
    if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
      return;
    }

    // Set the flag to prevent other widgets from inheriting the touch event
    touchHandled = true;

    // Track movement to determine if interaction was a click
    self._touchMoved = false;

    // Simulate the mouseover event
    simulateMouseEvent(event, 'mouseover');

    // Simulate the mousemove event
    simulateMouseEvent(event, 'mousemove');

    // Simulate the mousedown event
    simulateMouseEvent(event, 'mousedown');
  };

  /**
   * Handle the jQuery UI widget's touchmove events
   * @param {Object} event The document's touchmove event
   */
  mouseProto._touchMove = function (event) {

    // Ignore event if not handled
    if (!touchHandled) {
      return;
    }

    // Interaction was not a click
    this._touchMoved = true;

    // Simulate the mousemove event
    simulateMouseEvent(event, 'mousemove');
  };

  /**
   * Handle the jQuery UI widget's touchend events
   * @param {Object} event The document's touchend event
   */
  mouseProto._touchEnd = function (event) {

    // Ignore event if not handled
    if (!touchHandled) {
      return;
    }

    // Simulate the mouseup event
    simulateMouseEvent(event, 'mouseup');

    // Simulate the mouseout event
    simulateMouseEvent(event, 'mouseout');

    // If the touch interaction did not move, it should trigger a click
    if (!this._touchMoved) {

      // Simulate the click event
      simulateMouseEvent(event, 'click');
    }

    // Unset the flag to allow other widgets to inherit the touch event
    touchHandled = false;
  };

  /**
   * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
   * This method extends the widget with bound touch event handlers that
   * translate touch events to mouse events and pass them to the widget's
   * original mouse event handling methods.
   */
  mouseProto._mouseInit = function () {
    
    var self = this;

    // Delegate the touch handlers to the widget's element
    self.element.bind({
      touchstart: $.proxy(self, '_touchStart'),
      touchmove: $.proxy(self, '_touchMove'),
      touchend: $.proxy(self, '_touchEnd')
    });

    // Call the original $.ui.mouse init method
    _mouseInit.call(self);
  };

  /**
   * Remove the touch event handlers
   */
  mouseProto._mouseDestroy = function () {
    
    var self = this;

    // Delegate the touch handlers to the widget's element
    self.element.unbind({
      touchstart: $.proxy(self, '_touchStart'),
      touchmove: $.proxy(self, '_touchMove'),
      touchend: $.proxy(self, '_touchEnd')
    });

    // Call the original $.ui.mouse destroy method
    _mouseDestroy.call(self);
  };

})(jQuery);


  DisableJS
  
EndProcedure

Procedure Main()
  
  Protected  pic
  
  OpenWindow(#window, 0, 0, 800, 600, "Test")
  
  pic = CreateImage(#PB_Any, 100, 60, 32, RGB(200, 0, 0))
  
  ImageGadget(#gadget, 20, 20, ImageWidth(pic), ImageHeight(pic), ImageID(pic))
  
  Protected GID
  
  GID = GadgetID(#gadget)
  
  ! $(v_gid.gadget).draggable();
  
EndProcedure

jQueryUITouchPunch()

Main()
Fred
Site Admin
Posts: 1820
Joined: Mon Feb 24, 2014 10:51 am

Re: Moving a Gadget with a Tablet?

Post by Fred »

SpiderBasic uses another lib for movable, you can may be use it as well (I'm not at home now to check)
User avatar
Peter
Posts: 1197
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Moving a Gadget with a Tablet?

Post by Peter »

Fred wrote: Tue Sep 24, 2024 8:44 am SpiderBasic uses another lib for movable
at least Windows are extended in SpiderBasic with draggable(). Can you tell us the name of the other lib?
User avatar
Paul
Posts: 210
Joined: Wed Feb 26, 2014 6:46 pm
Location: Canada
Contact:

Re: Moving a Gadget with a Tablet?

Post by Paul »

Peter wrote: Wed Sep 25, 2024 11:54 am at least Windows are extended in SpiderBasic with draggable(). Can you tell us the name of the other lib?
Touchscreen ?
Stefan
Posts: 248
Joined: Mon Feb 05, 2018 9:44 pm

Re: Moving a Gadget with a Tablet?

Post by Stefan »

Why doesn't this work?

Code: Select all



EnableExplicit




Procedure jQueryUITouchPunch()
  
  EnableJS

/*!
 * jQuery UI Touch Punch 0.2.3 (https://github.com/furf/jquery-ui-touch-punch)
 *
 * Copyright 2011–2014, Dave Furfero
 * Dual licensed under the MIT Or GPL Version 2 licenses.
 *
 * Depends:
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 */
(function ($) {

  // Detect touch support
  $.support.touch = 'ontouchend' in document;

  // Ignore browsers without touch support
  If (!$.support.touch) {
    return;
  }

  var mouseProto = $.ui.mouse.Prototype,
      _mouseInit = mouseProto._mouseInit,
      _mouseDestroy = mouseProto._mouseDestroy,
      touchHandled;

  /**
   * Simulate a mouse event based on a corresponding touch event
   * @param {Object} event A touch event
   * @param {String} simulatedType The corresponding mouse event
   */
  function simulateMouseEvent (event, simulatedType) {

    // Ignore multi-touch events
    If (event.originalEvent.touches.length > 1) {
      return;
    }

    event.preventDefault();

    var touch = event.originalEvent.changedTouches[0],
        simulatedEvent = document.createEvent('MouseEvents');
    
    // Initialize the simulated mouse event using the touch event's coordinates
    simulatedEvent.initMouseEvent(
      simulatedType,    // type
      true,             // bubbles                    
      true,             // cancelable                 
      window,           // view                       
      1,                // detail                     
      touch.screenX,    // screenX                    
      touch.screenY,    // screenY                    
      touch.clientX,    // clientX                    
      touch.clientY,    // clientY                    
      false,            // ctrlKey                    
      false,            // altKey                     
      false,            // shiftKey                   
      false,            // metaKey                    
      0,                // button                     
      null              // relatedTarget              
    );

    // Dispatch the simulated event To the target element
    event.target.dispatchEvent(simulatedEvent);
  }

  /**
   * Handle the jQuery UI widget's touchstart events
   * @param {Object} event The widget element's touchstart event
   */
  mouseProto._touchStart = function (event) {

    var self = this;

    // Ignore the event If another widget is already being handled
    If (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
      return;
    }

    // Set the flag To prevent other widgets from inheriting the touch event
    touchHandled = true;

    // Track movement To determine If interaction was a click
    self._touchMoved = false;

    // Simulate the mouseover event
    simulateMouseEvent(event, 'mouseover');

    // Simulate the mousemove event
    simulateMouseEvent(event, 'mousemove');

    // Simulate the mousedown event
    simulateMouseEvent(event, 'mousedown');
  };

  /**
   * Handle the jQuery UI widget's touchmove events
   * @param {Object} event The document's touchmove event
   */
  mouseProto._touchMove = function (event) {

    // Ignore event If Not handled
    If (!touchHandled) {
      return;
    }

    // Interaction was Not a click
    this._touchMoved = true;

    // Simulate the mousemove event
    simulateMouseEvent(event, 'mousemove');
  };

  /**
   * Handle the jQuery UI widget's touchend events
   * @param {Object} event The document's touchend event
   */
  mouseProto._touchEnd = function (event) {

    // Ignore event If Not handled
    If (!touchHandled) {
      return;
    }

    // Simulate the mouseup event
    simulateMouseEvent(event, 'mouseup');

    // Simulate the mouseout event
    simulateMouseEvent(event, 'mouseout');

    // If the touch interaction did Not move, it should trigger a click
    If (!this._touchMoved) {

      // Simulate the click event
      simulateMouseEvent(event, 'click');
    }

    // Unset the flag To allow other widgets To inherit the touch event
    touchHandled = false;
  };

  /**
   * A duck punch of the $.ui.mouse _mouseInit method To support touch events.
   * This method extends the widget With bound touch event handlers that
   * translate touch events To mouse events And pass them To the widget's
   * original mouse event handling methods.
   */
  mouseProto._mouseInit = function () {
    
    var self = this;

    // Delegate the touch handlers To the widget's element
    self.element.bind({
      touchstart: $.proxy(self, '_touchStart'),
      touchmove: $.proxy(self, '_touchMove'),
      touchend: $.proxy(self, '_touchEnd')
    });

    // Call the original $.ui.mouse init method
    _mouseInit.call(self);
  };

  /**
   * Remove the touch event handlers
   */
  mouseProto._mouseDestroy = function () {
    
    var self = this;

    // Delegate the touch handlers To the widget's element
    self.element.unbind({
      touchstart: $.proxy(self, '_touchStart'),
      touchmove: $.proxy(self, '_touchMove'),
      touchend: $.proxy(self, '_touchEnd')
    });

    // Call the original $.ui.mouse destroy method
    _mouseDestroy.call(self);
  };

})(jQuery);


  DisableJS
  
EndProcedure


jQueryUITouchPunch()



OpenWindow(0,0,0,800,600,"main")
ButtonGadget (1,10,10,80,30,"test")



Define GID

GID = GadgetID(1)

! $(v_gid.gadget).draggable();



Stefan
Posts: 248
Joined: Mon Feb 05, 2018 9:44 pm

Re: Moving a Gadget with a Tablet?

Post by Stefan »

Can this perhaps be translated into Spiderbasic?

Code: Select all



<!DOCTYPE html>
<html>
<body>

<h1>DOM touchmove Event</h1>

<p id="myP">Touch this paragraph and move the finger to trigger a function that will write "Hello World".</p>

<p><strong>Note:</strong> This example is for touch devices only.</p>

<p id="demo"></p>

<script>
document.getElementById("myP").ontouchmove = myFunction;

function myFunction() {
  document.getElementById("demo").innerHTML = "Hello World";
}
</script>

</body>
</html>


Fred
Site Admin
Posts: 1820
Joined: Mon Feb 24, 2014 10:51 am

Re: Moving a Gadget with a Tablet?

Post by Fred »

Peter wrote: Wed Sep 25, 2024 11:54 am
Fred wrote: Tue Sep 24, 2024 8:44 am SpiderBasic uses another lib for movable
at least Windows are extended in SpiderBasic with draggable(). Can you tell us the name of the other lib?
we use 'interact':

Code: Select all

    // Use interact instead of jQuery draggable, as it's not mobile compliant and new TouchPunch which creates other issues.
    //
    interact(titleElement).draggable({
Post Reply