Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    [bug] mouseStillDownInitialDelay not honored

    SmartClient Version: SNAPSHOT_v11.1d_2016-12-15/Enterprise Development Only (built 2016-12-15)

    Chrome on OSX, Safari on iOS

    Hello, it seems that mouseStillDown fires immediately even if there's a mouseStillDownInitialDelay.

    It's apparent while running a simple test case:

    Code:
    isc.ListGrid.create({
        ID: "supplyList",
        width:500, height:300, alternateRecordStyles:true,
        dataSource: supplyItem,
        fields:[
            {name:"SKU"},
            {name:"itemName"},
            {name:"description"},
            {name:"category"}
        ],
        autoFetchData: true,
        showFilterEditor: true,
        filterOnKeypress: true,
        fetchDelay: 500,
        bodyProperties: {
            mouseStillDownInitialDelay:4000,
            mouseStillDown: function () {
                isc.logEcho('mouseStillDown')
            },
            mouseDown: function () {
                isc.logEcho('mouseDown')
            }
        }
    });
    This is what is logged while clicking records:

    Code:
    12:57:12.383:MDN9:WARN:Log:"mouseDown"
    12:57:12.384:MDN9:WARN:Log:"mouseStillDown"
    12:57:18.710:MDN2:WARN:Log:"mouseDown"
    12:57:18.711:MDN2:WARN:Log:"mouseStillDown"
    12:57:19.710:MDN2:WARN:Log:"mouseDown"
    12:57:19.711:MDN2:WARN:Log:"mouseStillDown"

    #2
    We've made a change to address this issue. Please try the next nightly build, dated December 19.

    Regards
    Isomorphic Software

    Comment


      #3
      SmartClient Version: SNAPSHOT_v11.1d_2016-12-19/Enterprise Development Only (built 2016-12-19)

      I can confirm it's fixed, thank you very much.

      Comment


        #4
        Hi Claudio
        Revisiting this issue we realize it's a case where this was actually working as designed, but our documentation didn't describe the behavior correctly.

        The intention with the mouseStillDown event was always that it would fire immediately on user mouse-down (along with the mouseDown event), then if the user held the mouse down there would be a pause of mouseStillDownInitialDelay, then the event would start firing repeatedly (every mouseStillDownDelay ms).

        This pattern is designed to handle the most common "repeated action" pattern, where a user can click a UI element to perform an action once, or click and hold to perform the action repeatedly.
        Examples of this include standard scrollbar button behavior and buttons to increase or decrease the value in a spinner type input element.
        (If the mouseStillDown event is not fired immediately on mouse down, the developer would have to implement a separate mouseDown or click handler in addition to the mouseStillDown handler to get this behavior).

        Modifying the behavior to avoid firing mouseStillDown has had undesirable impacts on various cases which relied on this behavior, and we will therefore be reverting this change and instead updating the documentation to make it clear how this actually behaves (and why).

        We do apologize for the confusion here.
        If you have a real use case which actually requires mouseStillDown *not* be fired immediately on mouse-down, do let us know and we'll be happy to advise on how best to achieve the end result you are actually looking for.

        Regards
        Isomorphic Software

        Comment


          #5
          Thanks for the clarification.
          My use case is a 'visual effect', on touch devices.
          I've got a 'floating' button, which 'floats' over a grid's body.
          The button is semi-transparent (opacity==40), and I call animateFade(80) when a record is selected (the button triggers an action on the selected record).
          When the user holds the finger on this grid's body (maybe while scrolling it a bit), I want to 'animateFade' the button to make it almost hidden (animateFade(10)).
          I don't want the animateFade(10) to trigger immediately because if the user is touching to select a record it has to change opacity from 40 to 80 or to stay to opacity==80, but there's a change in opacity because it starts to fade to 10, then re-starts to fade to 80. You may see the effect in this video https://www.youtube.com/watch?v=cqs6GsEc4rU
          With the previous change it was working with a code like this:
          Code:
          isc.ListGrid.create({
             .....
              bodyProperties: {
                      mouseStillDownInitialDelay: 400,
                      mouseStillDown: function () {
                          floatingButton.animateFade(10);
                      },
                      mouseUp: function () {
                          var selectedRecords = this.getParentCanvas().getSelectedRecords();
                          if (selectedRecords.isEmpty()) {
                              floatingButton.animateFade(40);
                          } else {
                              floatingButton.animateFade(80);
                          }
                      },
                      mouseOut: function () {
                          var selectedRecords = this.getParentCanvas().getSelectedRecords();
                          if (selectedRecords.isEmpty()) {
                              floatingButton.animateFade(40);
                          } else {
                              floatingButton.animateFade(80);
                          }
                      }
                  }
          });
          How it's now possible to achieve the previous behavior?

          Comment


            #6
            Thanks for the description / video.

            The mouseStillDown event isn't really appropriate for this even with the behavior of refusing to fire until mouseStillDownInitialDelay had expired, as it will fire repeatedly as long as the user holds the mouse down (or their finger down for a touch interface).
            What this means is the "animateFade()" method would fire repeatedly every 100ms or so as long as the mouse is down. That wouldn't have any real ill effects but it's not particularly desirable!

            What you want instead is a single notification after the mouse has been held down for your specified delay (400ms). Probably easiest just to set up a timer on mouseDown to do this.
            Something like this (and note - this is a conceptual demo rather than tested code):

            Code:
            isc.ListGrid.create({
               .....
                bodyProperties: {
                        ...
                        
                        mouseDown : function () {
                            this.delayedFadeTimer = this.delayCall("delayedFade", null, 400);
                        },
                        delayedFade : function () {
                            // Sanity check the mouse is still down, over us
                            // (Shouldn't be strictly necessary, since we clear the delayedFadeTimer on
                            // mouseOut / mouseUp)
                            if (isc.EventHandler.getTarget() == this && isc.EventHandler.leftButtonDown()) {
                                floatingButton.animateFade(10);
                            }
                        },
                        mouseUp: function () {
                            var selectedRecords = this.getParentCanvas().getSelectedRecords();
                            if (selectedRecords.isEmpty()) {
                                floatingButton.animateFade(40);
                            } else {
                                floatingButton.animateFade(80);
                            }
                            // Clear the delayedFade timer
                            if (this.delayedFadeTimer) isc.Timer.clear(this.delayedFadeTimer);
                        },
                        mouseOut: function () {
                            var selectedRecords = this.getParentCanvas().getSelectedRecords();
                            if (selectedRecords.isEmpty()) {
                                floatingButton.animateFade(40);
                            } else {
                                floatingButton.animateFade(80);
                            }
                            // Clear the delayedFade timer
                            if (this.delayedFadeTimer) isc.Timer.clear(this.delayedFadeTimer);
                        }
                    }
            });
            Hopefully this gives you enough to get things working how you need.

            Regards
            Isomorphic Software

            Comment


              #7
              Originally posted by Isomorphic View Post
              The mouseStillDown event isn't really appropriate for this even with the behavior of refusing to fire until mouseStillDownInitialDelay had expired, as it will fire repeatedly as long as the user holds the mouse down (or their finger down for a touch interface).
              What this means is the "animateFade()" method would fire repeatedly every 100ms or so as long as the mouse is down. That wouldn't have any real ill effects but it's not particularly desirable!
              Well, my actual code was a bit more complicated: it checked if the opacity was already that requested or if there was already an 'animateFade' in progress to that opacity, and called animateFade only if necessary.
              Anyway, your suggestion is working, thank you very much!

              Comment

              Working...
              X