1. #1
    Sencha User
    Join Date
    Mar 2013
    Posts
    15
    Vote Rating
    0
    shashank_a is on a distinguished road

      0  

    Default Answered: Handling events on Sencha GXT sprite

    Hi All,

    Can anyone tell me how to handle a mouse over event on a sprite like (RectangleSprite) in GXT 3.0.
    I could not find a proper documentation or example on how to handle the event.

    Can anyone share a link or documentation on event handling in GXT 3.0.


    Thanks in advance.

  2. If I use event.getSource() it is returning the an XML format data in which I can find both the sprite values, I could not differentiate the actual sprite where the event is triggered or fired.
    Calling event.getSource() returns the widget itself - yes, that will show the widget's structure if you .toString() it, but you don't need to do that to make changes to it. If you check the type of that source, it will be DrawComponent (in your case, maybe Chart in some other cases), so you could cast to that type and call specific methods.

    Code:
    DrawComponent surface = new DrawComponent();
    // X,Y,height and width values and ZIndex value
    
    final ReactangleSprite main = new RectangleSprite();
    //X,Y,Height,Width  values
    surface.addSprite(main);
    
    final RectangleSprite rect1 = new RectangleSprite();
    // X,Y,height and width values 
    surface.addSprite(rect1);
    
    final RectangleSprite rect2 = new RectangleSprite();
    // X,Y,height and width values and Zindex value
    surface.addSprite(rect2);
    
    surface.addSpriteOverHandler(new SpriteOverHandler() {
      public void onSpriteOver(SpriteOverEvent event) {
        if (rect1 == event.getSprite()) {
          Window.alert("Over rect1");
        } else if (rect2 == event.getSprite()) {
          Window.alert("Over rect2");
        }
      }
    });
    Is this what you mean? Just like any other object, you can ask if the sprite from the event is the same as some other sprite. You could also store them in a Map<Sprite, String> or something to label each one, or give each an index in a List<Sprite> - they are just objects that you can store like any other object.

    Sprite *shouldn't* have some other way for you to add extra fields/properties - that is like wanting to know how to tell the difference between two Lists other than their size and their values - the List *is* that data, just as the RectangleSprite *is* just that x/y, height/width, plus a few other details on how to draw it.

  3. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,736
    Vote Rating
    92
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default

    Just like with Elements, there is no way to ask a single Sprite for events that happen to it. Sprites are actually not even directly drawn to the screen - they are cross-browser ways to talk about drawing, which in some browsers will use SVG elements, and VML elements in others. We may build a Canvas implementation which will not draw each sprite using an element at all!

    As in the rest of GWT, you ask the containing widget about events, not the element (or sprite in this case) at all. DrawComponent (the superclass of Chart) has several sprite-specific mouse handlers to help abstract out this behavior no matter what implementation (SVG/VML/Canvas) you happen to be using.

    Code:
    widget.addSpriteOverHandler(new SpriteOverHandler() {
         public void onSpriteOver(SpriteOverEvent event) {
             //handle the event
      }
    });
    The other add*Handler methods like addSpriteOutHandler, etc may also be helpful for this.

  4. #3
    Sencha User
    Join Date
    Mar 2013
    Posts
    15
    Vote Rating
    0
    shashank_a is on a distinguished road

      0  

    Default

    Hi Colin Alworth.

    Thanks for the reply.

    Above code works as fine if we want to have a common functionality to be applied to all the sprites on a draw component instance.

    In the above case if we have multiple instances of the same sprite for example we have draw component and two rectangles sprites added to the draw component instance.

    In this case if we want to add some functionality in a sprite event for example SpriteOver event, this functionality should be applied to only one of the two instances of the two rectangle sprites added to the draw component instance. we cannot achieve such functionality if we add events to the draw component itself.

    Is their a way to handle such a case. Is their a parameter which helps in differentiating two similar sprite instances apart from X,Y,width and Height parameters of the sprite.

  5. #4
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,736
    Vote Rating
    92
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default

    In the above case if we have multiple instances of the same sprite for example we have draw component and two rectangles sprites added to the draw component instance.
    You cannot use the same Sprite in two different draw components, in the same way that you cannot use the same Element in two different widgets. These cases are slightly different in that the Element is the actual thing which the browser uses to draw, whereas the sprite is just an abstraction, but if you break the rules of that abstraction, you probably will encounter problems later.

    In this case if we want to add some functionality in a sprite event for example SpriteOver event, this functionality should be applied to only one of the two instances of the two rectangle sprites added to the draw component instance. we cannot achieve such functionality if we add events to the draw component itself.
    And that is one of the ways that you will run into issues. There probably are ways, but they will be implementation specific, so will break if something in the underlying implementation changes (such as adding Canvas support). I do not suggest you do this.

    Instead, Sprite has a copy() method which will duplicate the object for use in the same or a different draw component. That will probably be the cleanest way to tell which is which - does that help answer your question?

    This is akin to drawing two normal Widgets and wanting to listen to events on both - you need to base the details of the handler on the context that the event occurred in. This raises another way you could do this - ask the event object for its source - that will tell you which DrawComponent object the event came from.

  6. #5
    Sencha User
    Join Date
    Mar 2013
    Posts
    15
    Vote Rating
    0
    shashank_a is on a distinguished road

      0  

    Default

    Colin I think I did not make my point clear. Here is what I'm trying to explain you.

    DrawComponent surface = new DrawComponent();
    // X,Y,height and width values and ZIndex value

    ReactangleSprite main = new RectangleSprite();
    //X,Y,Height,Width values
    surface.addSprite(main);

    RectangleSprite rect1 = new RectangleSprite();
    // X,Y,height and width values
    surface.addSprite(rect1);

    RectangleSprite rect2 = new RectangleSprite();
    // X,Y,height and width values and Zindex value
    surface.addSprite(rect2);

    surface is added to the root panel at the end.

    Now in a SpriteOverEvent I would like to change for example say stoke of the rect1 sprite and it should not apply to rect2 sprite.

    If I use event.getSource() it is returning the an XML format data in which I can find both the sprite values, I could not differentiate the actual sprite where the event is triggered or fired.

    I even tried using event.getSprite() method which is returning the x,y,height and width values of the sprite on which the event has fired(I don't want depend on the those values for differentiating the sprites).

  7. #6
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,736
    Vote Rating
    92
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default

    If I use event.getSource() it is returning the an XML format data in which I can find both the sprite values, I could not differentiate the actual sprite where the event is triggered or fired.
    Calling event.getSource() returns the widget itself - yes, that will show the widget's structure if you .toString() it, but you don't need to do that to make changes to it. If you check the type of that source, it will be DrawComponent (in your case, maybe Chart in some other cases), so you could cast to that type and call specific methods.

    Code:
    DrawComponent surface = new DrawComponent();
    // X,Y,height and width values and ZIndex value
    
    final ReactangleSprite main = new RectangleSprite();
    //X,Y,Height,Width  values
    surface.addSprite(main);
    
    final RectangleSprite rect1 = new RectangleSprite();
    // X,Y,height and width values 
    surface.addSprite(rect1);
    
    final RectangleSprite rect2 = new RectangleSprite();
    // X,Y,height and width values and Zindex value
    surface.addSprite(rect2);
    
    surface.addSpriteOverHandler(new SpriteOverHandler() {
      public void onSpriteOver(SpriteOverEvent event) {
        if (rect1 == event.getSprite()) {
          Window.alert("Over rect1");
        } else if (rect2 == event.getSprite()) {
          Window.alert("Over rect2");
        }
      }
    });
    Is this what you mean? Just like any other object, you can ask if the sprite from the event is the same as some other sprite. You could also store them in a Map<Sprite, String> or something to label each one, or give each an index in a List<Sprite> - they are just objects that you can store like any other object.

    Sprite *shouldn't* have some other way for you to add extra fields/properties - that is like wanting to know how to tell the difference between two Lists other than their size and their values - the List *is* that data, just as the RectangleSprite *is* just that x/y, height/width, plus a few other details on how to draw it.

  8. #7
    Sencha User
    Join Date
    Mar 2013
    Posts
    15
    Vote Rating
    0
    shashank_a is on a distinguished road

      0  

    Default

    Yeah that is helping in differentiating the sprites on the draw component instance.

    One more thing in event handling concept.

    For the above example only if I add a image sprite and then I SpriteOver and SpriteOut events order will be effected?

    I mean to say
    1) SpriteOver on ParentRectangle.
    2) Now I do a SpriteOver event on to the ChildRectangle which should also fire the SpriteOut event on parent rectangle.
    3) Now I have a ImageSprite on the ChildRectangle so from above step I do SpriteOver event on to the ImageSprite which should also fire a SpriteOut event on the ChildRectangle.

    When I start to come back out of the DrawComponent area in reverse order events should be fired in the following order

    SpriteOut event on ImageSprite and SpriteOver on ChildRectangle and SpriteOut on ChildRectangle and then SpriteOver on ParentRectangle and then finally SpriteOut event on the ParentRectangle.

    Does the above order of events is correct?
    Because I could see the above event order in one of my examples.

  9. #8
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,736
    Vote Rating
    92
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default

    You should not make assumptions about the order of events for over or out. In a tree of DOM elements, the events fire first from the sub-element, then from the parent, but all sprites are just added directly to the DrawComponent, with no hierarchy. Additionally, two sprites might be drawn with an overlapping region, so you cannot assume that because the user has left one sprite that they have left both.

    If you look at the internals of how DrawComponent.onMouseMove works, you'll see that it iterates over the sprites in the order they are in the surface. This too varies - in one of the implementations (VML or SVG, I forget for now) this collection is sorted by z-index, so lower sprites will end up firing first.

    But in general you should not assume which order events are firing in. It might be working for your current sample, but that won't cover all possible cases.

Thread Participants: 1