fin-hypergrid / core

A canvas-based super high performant grid renderer API
MIT License
897 stars 144 forks source link

Can't scroll on touch screens #792

Open AmirF27 opened 5 years ago

AmirF27 commented 5 years ago

The grid doesn't seem to respond to scrolling events on touch screens. I can tap without any issues, but scrolling doesn't seem to work. This in turn doesn't also allow resizing or moving columns. The grid doesn't seem to respond to touch events.

This is a bit of an urgent issue, as we are currently in the process of moving our entire application to Hypergrid. We would like to know if it's just a matter of configuration or if Hypergrid doesn't support touch screens, and if not, if it's possible to request this feature.

joneit commented 5 years ago

Touch screen support was never completed. I will look into this today and assess the amount of work involved and I'll post here my findings and when I think I could get it done.

(Of course, contributions are always welcome! Is there any chance you have the bandwidth to contribute a solution to this issue?)

AmirF27 commented 5 years ago

@joneit Of course! I'd be more than happy to contribute a solution (or at least try). If you could just give me a heads up as to where to start, that would be great (if not that's fine too). Also, is there a way to contact you in case I have any questions?

joneit commented 5 years ago

@AmirF27 That would be great!

Look in ./src/lib/Canvas.js at the way "click" events are implemented. We need to implement Touch events similarly (see also Using Touch Events), including how they are consumed.

How Hypergrid sets up events

The way events are handled in Hypergrid is a little heavy handed:

  1. In ./src/Hypergird/index.js, for each grid instance (let's call it grid) the constructor (Hypergrid.prototype.initialize) calls this.initCanvas to instantiate its own Canvas object (grid.canvas)
  2. In ./src/lib/Canvas.js, the constructor (Canvas.prototype.initialize)
    1. Creates the <canvas> element (this.canvas === grid.canvas.canvas)
    2. Calls its own this.addEventListener to set up listeners on the actual for each mouse event type (e.g., click) to be handled by specific this.fin______ class methods (e.g., this.finclick)
    3. The this.fin______ handlers call dispatchNewMouseKeysEvent to rethrow the DOM event as a fin-canvas- custom event (e.g., fin-canvas-click) (dispatchNewMouseKeysEvent may or may not suffice for touch events; if not, add a new method)
  3. grid.initCanvas then calls this.delegateCanvasEvents (in ./src/Hypergrid/events.js) for each such fin-canvas- event, which calls this.addInternalEventListener with a handler (an anonymous function) which:
    1. May include state maintenance logic specific to the event
    2. Calls this.delegate______ method (e.g., this.delegateClick)
      • These methods merely call a this.behavior.on________ method (e.g., this.behavior.onClick)
    3. Calls this.fireSynthetic_______Event (e.g., this.fireSyntheticClickEvent)
      • These methods all call dispatchGridEvent with specific event details
      • This is what calls any listeners the application developer may have added to the grid (via grid.addEventListener)
      • Note that besides the primitive synthetic events for click, mousedown, etc., there are also semantic synthetic events called from the feature chain (e.g., fireSyntheticEditorKeyPressEvent)

Setting up dev environment

  1. We will be doing some dev work on the Hypergrid core repo, so step 1 is to clone it:
    cd ~
    mkdir repos
    cd repos
    git clone https://github.com/fin-hypergrid/core fin-hypergrid

    This creates a new directory ~/repos/fin-hypergrid containing the clone of the core repo. (It is currently not necessary to run npm build on core unless you are changing the built-in stylesheet or images. Important: You should however, run npm lint before committing your changes.)

  2. I usually develop with the "dev testbench" (build/demo/index.html), so let's clone that too:
    git clone https://github.com/fin-hypergrid/build

    This creates a new directory ~/repos/build.

  3. Before running npm install, which would install fin-hypergrid@3.2.0(among other items) from the npm registry, you need to point that dependency to your local core clone:
    cd build
    npm install ../fin-hypergrid

    This does two things:

    1. Installs the fin-hypergrid dependency as a simple symlink instead of a folder in node_modules/fin-hypergrid
    2. Changes package.json'sfin-hypergirddependency from=3.2.0tofile:../fin-hypergrid`.

      Important: Do not commit this change! You will want to change it some new version number such as =3.4.0 or whatever; we will decide when the time comes which version. (Your build PR is in addition to your core PR; it adds listeners to ./testbench/events.js to demonstrate your new events in the testbench.)

  4. Now run the rest of the install (this will ignore the fin-hypergird dependency because it is already installed):
    npm install
  5. Between editing the core files and refreshing the browser, you must rebuild the test bench:

    sh bundle-demo.sh

    NOTE: This actually does two builds: The regular file with source map; and the min file without source map. In practice, I just do the first of the two (browserify testbench/index.js -do demo/build/testbench.js) because the min build is slow and is not even used in testing.

    NOTE: This just builds testbench.js. To build fin-hypergrid.js, used by the other demos, run sh core-bundle.sh.

  6. To test on a touch device
    1. From a new console session, issue the following commands from the ~/repos/build directory:
      npm install --global http-server # first time only
      http-server demo
    2. From your device, go to browser and enter the URL displayed in the console:
      192.168.x.y:8080

User Interaction

Now we get to how exactly are we going to define touches.

Issues

There are several problems here:

  1. Scrolling doesn't work
  2. There's no way to make multiple selections (usually accomplished with click + drag)
  3. There's no way to invoke a cell editor.

Proposed UI solution

I believe you are only interested in the first item above.

For scrolling, what would feel natural to me is a single touch (i.e., one finger) + drag.

My contact info

If you want to ask me questions privately, my email address is on my user page.

AmirF27 commented 5 years ago

@joneit Thank you for the explanations! I will get started as soon as I'm able. Should I fork the repository or can I clone this one and work directly on it?

Regarding the issues, my team and I are indeed only interested in the first item for the moment. Should I try to work on the other two or can I focus only on the first item for now?

AmirF27 commented 5 years ago

Hi @joneit. I've got a couple questions regarding this feature. I've sent you an email. Please let me know when you see it or if you see this comment. If there is anyone else I can ask it would be great too.

AmirF27 commented 5 years ago

Hi @joneit. I've sent you an email regarding opening a pull request for this issue. I'm ready to open a pull request. Would you be able to look at it?

RandomFractals commented 5 years ago

@joneit & @AmirF27 I'd love to see this merged in this repo & added to perspectiveJS grid eventually to get touch screen support for the vscode ext. data viz tools I've built with your grid: https://github.com/RandomFractals/vscode-data-preview

any ETA on this PR being approved and released?