Repairing enyo.Panels wrapping functionality

Hey all,

I've noticed there has been a long-time todo in the enyo.Panels implementation regarding the 'wrap' setting.
I'm currently creating a panels sub-kind that supports wrapping taking into account the direction of drag interactions and such. While I'm implementing this for enyo 2.4 at the moment, I don't think it should be too difficult to extract a patch for enyo 2.5 to fix some of the issues.

Besides just implementing the required infrastructure in the enyo.Panels and enyo.Arranger components though, there is the considerably more complicated matter of actually implementing directional wrapping support in the various arrangers.

If I were to make a pull-request for direction-aware wrapping of panels, would such a pull-request necessarily need to update *all* arrangers to be able to use it while maintaining full backward compatibility of all their current features? Or is it enough to simply patch what's needed in the enyo.Arranger and supply maybe one example Arranger that makes use of it?


  • Allright, I'll share the code when I have something that works well. Like I said, it'll initially be implemented for 2.4. The 2.5 panels source has seen some changes, but I don't think it will be problematic to port the changes if they're good enough to roll into enyo 2.5.x or 2.6 or such.
  • Hey Derek,

    Sorry for taking so long to get back with more info on this, I've been out with the flu for a few days. I've currently got an enyo.Panels and enyo.Arranger superkind that implement some changes to make wrapping easier as well as a CarouselArranger that makes use of the added wrapping infrastructure.

    So far, the idea is basically to use a set of fromIndex, toIndex and direction parameters any time a new index is set with the setter, or when a drag transition is triggered. This then provides all the info an arranger needs to position panels such that you always have something ready to slide into view etc. The extra direction parameters should allow (almost?) any arranger to get rid of the long-standing fix-me comment in the source regarding assumptions about the direction of a drag interaction.

    Because my extended panels implementation includes a new 'direction' parameter for transitions, arrangements are named not just by the id of the active panel, but a combination of the transition direction and the id of the active panel. This doubles the possible amount of stored arrangements, but I think it's worth it considering it provides arrangers with the ability to calculate the optimal set of arrangements for any given transition.

    If this sounds good enough, I can try to migrate the code to the current master branch and create a pull-request.
  • By the way, there is one small item I don't completely understand. In the enyo.Arranger.measureArrangementDelta method there's the following line of code: s = s * (this.container.fromIndex > this.container.toIndex ? -1 : 1);. I seem to never run into a case where s actually needs to be multiplied by -1.

    Do you know of any scenarios where one of the current arrangers requires this line of code? I have the feeling that particular line of code is entirely obsolete in my current code, but I'd hate to accidentally break other people's code by blindly remove it without understanding why it was there in the first place
  • I'm still working on an updated implementation of panels, I was wondering, what's the general idea behind the transition events? It seems the behaviour is a bit different between enyo 2.4 and the current master.

    In enyo 2.4, it seems events fire only if the transition info is different form the last time it fired. This can lead to inconsistencies where a transitionStart fires without a transitionFinish event. Also, enyo 2.4 does not fire the events at all in case of a refresh.

    In the current master, it seems there is considerably more complicated logic around firing transition events but it's not really obvious what the desired behaviour is. Then, in contrast with enyo 2.4, when refreshing, the transitionstart event is never fired, but the transitionfinish event is still allowed to fire.

    It's all rather complicated and has me wondering if things couldn't be a bit simpler. If I think about transition events, the main goal seems to be to notify other components of the following information:
    - The fact that the panels component has started a particular transition, along with the parameters of the transition (fromIndex, toIndex, direction).
    - The fact that the panels component has finished a particular transition, along with the parameters of the transition (fromIndex, toIndex, direction).
    - The fact that an already transitioning panels component has altered the parameters of it's transition.

    Would it be okay to alter the transition events such that:
    - Panels *always* fires a transitionStart event if the panels instance goes from not transitioning to transitioning state.
    - Panels *always* fires a transitionFinish event if the panels instance goes from transitioning to not transitioning state.
    - Panels *always* fires a transitionChanged event if an already transitioning panels instance alters it's transition parameters before the already started transition has finished.

    That leaves us with one last scenario:
    What to do with a refresh and/or a direct transition differently than an animated/dragged transition?

    If we treat them the same, a refresh or direct transition should fire both a transitionStart and a transitionFinish event. Pro's of this are consistency and fewer event types. The con is this means firing 2 events almost immediately after each other.

    If we treat them as different scenario's, we should perhaps simply include a new event that properly describes what actually happened (before state, after state). Pro's are only one event fires and we gain the ability for other components to respond to this particular scenario in an optimized manner. Con is, more events means potentially more complexity for components that need to handle these events.
  • Hey, no problem, I know times are busy. If it takes a bit of time to get a good answer together, that's okay.

    A little update from my side. I've tried to set up my panels kind such that it doesn't break the current panels API, but the transition events are a bit more predictable.

    First of all, any transition comes with the following set of parameters that describe the transition state: fromIndex, toIndex, direction, transitionPoints, fraction.
    Any transition event passes on the values of those parameters.

    Next, I now have three events:
    • transitionStart, which fires when:
      • The panels are not yet transitioning and the startTransition method starts a new transition.
      • Any time a dragTransition starts, even if the panels component is already transitioning.
    • transitionReverse, this new event fires when:
      • verifyDragTransition determines that the drag direction indicates the user would like to reverse the direction of the current drag transition.
    • transitionFinish, this event fires when:
      • A animated transition finishes.
      • A direct transition finishes.
      • When a dragTransition reaches a transition boundary
    The main reason to add the new transitionReversed event, is to express more precisely what is happening. This is important when implementing - for instance - a pager, which can display many items using only a limited amount of panels. In such cases, the indexes of items in the list, and the indexes of a panels in the panels component don't always line up in exactly the same way. Instead, the transitions describe the users intent much more accurately.

    There is one tricky thing about the above setup. If a user tries to swipe through multiple panel arrangements in quick succession, each newly started dragTransition fires a new transitionStart event and the previous transition is essentially discarded. This means the previous transition never actually finishes and thus never fires a transitionFinish event, yet the index did get updated by dragfinishTransition.

    I currently cannot think of a particular scenario where the lack of a transitionFinish event would cause problems, particularly because the transition really does not get finished. However, if desired, I could implement a transitionCanceled event or something like that in case of a discarded transition.
  • Panel transitions have always had a lot of strangeness to them. I'm not sure whether you'll be happy to hear that we've reworked it again for 2.6.
  • Haha, yeah I saw there has been a lot going on over at github. I've decided to use our in-house solution for now and see where things are going with 2.6.

    Do the reworked panels have some sense of directionality?
  • I think there was some additional work around the direction of the transition but I didn't work on it myself.
Sign In or Register to comment.