5

I have a Spark List with my own custom renderer. When the user rolls over an item in the list, left and right buttons appear in the row allowing the user to change the value of a value being rendered. For example, if there are 5 priorities (1 to 5), the left button decreases the value and the right button increases it.

Quick note: they're not really buttons, but s:Images designed to work like buttons.

Now this works fine, except under one particular condition: If the user selects the row, then moves the cursor out of the row, then back into the row, when the user clicks on either button, nothing happens. Even though this scenario sounds convoluted it's something the test users do all the time! It's really frustrating for them.

I have discovered the reason for this behaviour: The buttons are only displayed in the hover and selected states of the item renderer. This is what I want to happen - the buttons should not be visible unless the user's pointer is capable of pressing them. When an item is selected in the list the state of the renderer goes to selected. Clicking again doesn't change the state. Moving the pointer out of the row, then back in again and clicking (on the already selected row) makes the row's state go from selected, to normal (when mouse-down) and back to selected (on mouse-up). I find this very odd! It means that the button actually disappears when in state normal (which it should) thus isn't being clicked).

I had considered that somehow I could have the images "higher up" in the Z-order on the item renderer and thus they intercept the click event before the item renderer gets it, but I can't get this to work.

Can anyone help?

If it helps, a snippet from the ItemRenderer is below:

<s:HGroup width="150" verticalAlign="middle" verticalCenter="0">
  <s:Image id="previousItemButton" buttonMode="true" source="{_leftArrow}" width="16" height="16" visible.normal="false" visible.hovered="true" visible.selected="true" click="previousClicked(event)"/>
  <s:Label text="{data.outputFormat.value}" width="100%" click="nextClicked(event)"/>
  <s:Image id="nextItemButton" buttonMode="true" source="{_rightArrow}" width="16" height="16" visible.normal="false" visible.hovered="true" visible.selected="true" click="nextClicked(event)"/>
</s:HGroup>

UPDATE:

The issue was caused by a spurious rollOut event on the highest level of the components that made up the ItemRenderer. This rollOut called a method which consisted of:

protected function hgroup1_rollOutHandler(event:MouseEvent):void {
  if (this.selected) {
    this.selected = false;
  }
}

This was causing the problem and removing the rollOut and the method fixed the issue. Quite why a roll-out is being activated on mouseDown I don't know.

Steven Magana-Zook
  • 2,751
  • 27
  • 41
Phil
  • 1,897
  • 4
  • 25
  • 48
  • Have you tried it with a real button, and not just an image? – J_A_X Feb 22 '12 at 20:59
  • No. I'd imagine the same thing would occur since the 2 Images disappear since they are not visible in the "normal" state. – Phil Feb 22 '12 at 21:16
  • Try it. Having a click event on an image is different than having an actual button. They have different behaviours which can impact your application. It's also hard to comment properly on your problem since you're not showing much of what's actually happening and the small amount of code. – J_A_X Feb 22 '12 at 21:31
  • Exactly the same behaviour with Spark Buttons. The Mouse-down event on the row makes the ItemRenderer state "Normal" so the buttons disappear (see the visible.normal="false" in the code above). With the buttons gone they can't be clicked on. On Mouse Release the Item Renderer state returns to "selected" and the buttons reappear. – Phil Feb 22 '12 at 22:12
  • 1
    GAH! I've figured out the problem and it's nothing to do with images / clicks or buttons! Looking at my ItemRenderer the highest component had a rollOut listener on it. When this was activated a function which performed: if (this.selected) this.selected = false; . This was old redundant code which should have been removed! Argh! Quite why it did, what it did on a Mouse Down I don't know. 2 things learned from this: always clean up pointless code and create a simple example to demonstrate your problem! Thank J_A_X for looking into this - sorry to waste your time. – Phil Feb 22 '12 at 22:37
  • The reason a rollout event is fired is this: when the button is clicked it steals the focus from its parent component and hence triggers a rollout. You could disable this by setting the itemrenderers' `mouseChildren` to `false`, but then you couldn't click the button anymore. At least not directly: you could still listen for clicks on the itemrenderer and use `target` to see whether the button was clicked or something else. I've been forced to use this approach at times, but most of the times you can do what you need by using the states properly (as you did). – RIAstar Feb 23 '12 at 09:58

0 Answers0