6 Replies Latest reply on Dec 22, 2011 2:52 PM by msakrejda

    Have FXG shapes respond to mouse events, à la Degrafa

    msakrejda Level 4

      I'm trying to port a Flex 3 Degrafa-based component which used Degrafa GeometryGroups (each containing a single Degrafa Path) with mouseOver/mouseOut listeners to get interactive graphical objects that directly responded to mouse events. I can use the Spark Graphic and Path objects to do draw the same stuff on screen, but I haven't been able to get mouse events to work for just the path--the Path object does not allow me to add mouse listeners, and if I add them to the Graphic object, I get mouseOver/mouseOut for the entire Graphic object, which is the bounding box for the Path. Is this possible in FXG? Given that Degrafa does not support Flex 4, are there other approaches I could use?

        • 1. Re: Have FXG shapes respond to mouse events, à la Degrafa
          Chris Velevitch Level 1

          Yes it is possible. I'm using Flex 4.5 and putting on mouse events is straight forward. For example:-

          <asset:Close click="clickhandle(event)" mouseOver="mouseOverHandler(event)" mouseOut="mousOutHandler(event)"/>

          Just place the .fxg file (in this example "Close.fxg") somewhere and set the namespace (in this example "xmlns:assets='assetsdir'".

          • 2. Re: Have FXG shapes respond to mouse events, à la Degrafa
            msakrejda Level 4

            Thanks, Chris, but I think this is a somewhat different use case. What I'd like to be able to do is get mouseOver / mouseOut behavior for the individual paths, rather than the whole FXG graphic (for what it's worth, I'm constructing the FXG programatically at runtime, rather than reading it from an external file, but I don't think that's really relevant.

             

            Let me demonstrate with something more specific:

             

            <?xml version="1.0" encoding="utf-8"?>

            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"

                xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:example="com.truviso.example.*">

                <fx:Script>

                    <![CDATA[

             

                        private function handleOver(event:MouseEvent) : void {

                            overLbl.text = 'Hovering over ' + event.target.id;

                        }

                        private function handleOut(event:MouseEvent) : void {

                            overLbl.text = '';

                        }

             

                        private function handleClick(event:MouseEvent):void {

                            clickLbl.text = 'Clicked ' + event.target.id;

                        }

                    ]]>

                </fx:Script>

                <s:layout>

                    <s:VerticalLayout />

                </s:layout>

                <fx:Declarations>

                    <s:SolidColorStroke id="s1" color="red" weight="3"/>

                    <s:SolidColorStroke id="s2" color="black" weight="3"/>

                    <s:SolidColorStroke id="s3" color="green" weight="3"/>

                </fx:Declarations>

                <s:Label id="overLbl"/>

                <s:Label id="clickLbl"/>

                <s:Graphic id="paths" click="handleClick(event)" mouseOver="handleOver(event)" mouseOut="handleOut(event)"

                     width="800" height="800">

                    <s:Path id="p1" stroke="{s1}" data="M 100 100 L 200 200 L 200 100 z"/>

                    <s:Path id="p2" stroke="{s2}" data="M 300 300 L 350 350 L 200 350 z"/>

                    <s:Path id="p3" stroke="{s3}" data="M 10 10 L 15 20 L 20 25 L 20 10 z"/>

                </s:Graphic>

               

            </s:Application>

             

            In this application, I'd like to know when the user hovers over (or clicks on) the individual paths, rather than the whole graphic element. In Degrafa, I could achieve this by having each path in a separate GeometryGroup, because the GeometryGroup processed mouse events (but only within the boundaries of the defining shapes). If I try to do this if FXG (by having a separate Graphic wrapping each path), I get mouse events for the bounding boxes--there does not seem to be a way to get events directly related to the paths. I.e., I would like the clickLbl above to show "Clicked p1" (or p2, or p3) whenever you click specifically one of those triangles (especially since my actual shapes are far more complex).

            • 3. Re: Have FXG shapes respond to mouse events, à la Degrafa
              Chris Velevitch Level 1

              Although I haven't used the Graphic and Path tags yet so I don't know if this'll work. I can think of 2 possible solutions:-

              1. Put each path in separate Graphic tags and attach the event handlers to the the Graphic tag
              2. Create you own Path tag by extending the Path tag and defining your own events

              I hope these suggestions will work for you.

              • 4. Re: Have FXG shapes respond to mouse events, à la Degrafa
                msakrejda Level 4

                Thanks. (1) does not work--that's the bounding box issue I mentioned. That is, the Graphic responds to mouse events in a bounding box of the included path, so e.g., I can't have a mouseOver event fire precisely when the cursor crosses into the region bounded by the shape (unless the shape is a rectangle). I was able to do exactly this with the Degrafa approach I mentioned. I was afraid (2) may be the only answer--perhaps I can look into how they handled this.

                • 5. Re: Have FXG shapes respond to mouse events, à la Degrafa
                  Shongrunden Adobe Employee

                  Sounds like you want to set mouseEnabledWhereTransparent to false:

                    <s:Graphic click="trace('click')" mouseEnabledWhereTransparent="false">

                          <s:Ellipse width="100" height="100">

                              <s:fill>

                                  <s:SolidColor color="red" />

                              </s:fill>

                          </s:Ellipse>

                      </s:Graphic>

                  1 person found this helpful
                  • 6. Re: Have FXG shapes respond to mouse events, à la Degrafa
                    msakrejda Level 4

                    (sorry about the criminally late reply; I was on vacation when you responded and then I forgot about this till just now)

                     

                    Ooh, almost. Now what I need to do is to tell which sub-element within the Graphic the click belongs to--currently, in the example above, I only get the click notification for *paths*, not *p1*, *p2*, or *p3*. Is there a way to do that? Also, being able to find when clicks actually occur within the closed path, rather than on the path boundary itself, would be nice (although i can probably finagle that through existing algorithms).