Question

I'm working on skinning the Spark:TabBar, but am running into a snag with my custom skin used for the tabbar's buttons. Here is a diagram of what I am trying to accomplish:

_______________________
|                     |
|  Label            X |
|_____________________|

So we have a button (I'm using a custom skin on the spark:ButtonBarButton component) that has a label and a secondary button for removing said item from the list. The X button should only be displayed when the user hovers over the main button.

The issue I have is that I am completely unable to interact with the X button, because it is a button within a button. It does not respond to hover states, and any click handlers I attach to it do not fire - instead the parent button's click events fire.

I'm currently toying around with using stopPropagation, but that won't (or rather I don't expect it to) fix the hover state issues, and am looking for a more feasible solution.

Here are some examples of my code:

VerticalPillBarSkin - hostComponent: spark.components.TabBar

<s:DataGroup id="dataGroup" width="100%" height="100%" clipAndEnableScrolling="true">
    <s:layout>
        <s:VerticalLayout paddingRight="3" gap="3"/>
    </s:layout>
    <s:itemRenderer>
        <fx:Component>
            <s:ButtonBarButton skinClass="{VerticalPillBarButtonSkin}" width="120"/>
        </fx:Component>
    </s:itemRenderer>
</s:DataGroup>

VerticalPillBarButtonSkin - note that SymbolButton is a custom component extending ButtonBase.

<s:Label id="labelDisplay" color="0x000000"
         textAlign="left" verticalAlign="middle"
         horizontalCenter="0" verticalCenter="1"
         left="0" right="12" top="6" bottom="6" />

<s:Spacer width="100%" />

<x:SymbolButton  id="removeButton" 
                  includeIn="overStates"
                  icon="{REMOVE}"
                  iconRollover="{REMOVE_OVER}"
                  right="5" verticalCenter="0" click="closeHandler()" />

Does anyone know of a good way around this issue? I had played with using something other than s:ButtonBarButton as the VerticalPillBarButton, but that doesn't seem to be a working option. If there is any other information I can provide, please feel free to ask.

Was it helpful?

Solution 3

My question is actually two pretty related questions, and I'll answer them both here.

  1. 'X' button's hover state is ignored

This was the slightly more involved solution, but the gist is that I had to create a custom itemRenderer instead of skinning ButtonBarButton.

  1. 'X' button click event is ignored

While my question seems to make this the main issue, the solution is actually quite simple. The reason that neither @Zeus or @Josh solutions worked for me was because there was not a down state in the itemrenderer skin. Because the X button is set to be included only in hover states, it was actually being removed from the view onclick, and therefore never firing its click event. Pretty big facepalm moment.

TL;DR - Don't forget the down state!

OTHER TIPS

A few suggestions,

  • I would set the buttonMode property on the child button and see if that works.
  • Also, when the user hits on X the event handler(parent button) can know the target and the current target, since the user hits the X, the target will be button X. You can do an If else to figure out the action to take.

Attach a MouseEvent.CLICK handler to the secondary button and call event.stopImmediatePropagation(). That will prevent it from firing bubbling the event any further.

private function secondaryClickHandler( e:MouseEvent ):void {
    e.stopImmediatePropagation();

    // run click code here
}

So basically, the click originates from the secondary button and bubbles up to the main button which then fires another handler. This will make sure it doesn't hit that main button if it originates from the secondary button.

You may need to do that to MouseEvent.MOUSE_UP as well/instead. I believe the order is down->up->click, but I can't remember for sure.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top