Skip to main content
Participating Frequently
November 16, 2010
Question

Problem with links when paginating

  • November 16, 2010
  • 3 replies
  • 907 views

Hello, I've been struggling with this for two weeks now without being able to find a solution, so any help would be hugely appreciated.

I wrote a subclass (relevant code below) of Sprite which contains a TextFlow and a variable number of child sprites (each one of them is linked to a ContainerController in the TextFlow's flowComposer). When there's just one page everything works fine: the cursor changes when you hover over a link and it opens the browser when you click on it. The problem comes when there's more than one page: neither cursor change nor click behavior in any page.

I observed something similar happening in the Pagination example contained in the latest build anounced on the blog, except for the fact that links in the first page worked.

After reading this discussion I downloaded the latest build, copied textLayout.swc into the frameworks/libs directory of my local copy of Flex SDK 4.1 (replacing the old one) and updated the project's build path reference to that file (I'm still talking about the Pagination example) and things started to work there.

So I repeated this last step for my project, but no luck. I even rebuilt the SDK using ant after copying the new file. By the way, how can I know which version of textLayout.swc my project is using? When I expand the swc in my build path it says "textLayout_1.1.0.604.swz", but the 2.0 readme says the current build is 200... so I'm a bit confused about that.

So, here's the code for the problematic method, I would like to know if this is a bug or it's just my code is messed up. Please tell me if you need to know something else. (The comments are in Spanish, but I leave the just in case )

private function refreshPages() : void
{
            //Si se estaba viendo alguna página, guardar la posición absoluta de su primer caracter
            //para después poder seguir desde ahí.
            this.savePosition();
          
            //Limpiar la lista de páginas.
            this._textFlow.flowComposer.removeAllControllers();
          
            var i : int
            for (i = 0; i < this.numChildren; i++)
            {
                //this.getChildAt(i) = null;
                this.removeChildAt(i);
            }
          
            //Se lleva la cuenta de la posición sobre x de la página actual.
            var currentX : Number = 0;
          
            var container : Sprite; //Sprite donde se va a mostrar el texto de una página.
            var controller : ContainerController; //Controlador que maneja el sprite de una página.
            while (true)
            {
                //Se crea y posiciona una nueva página.
                container = new Sprite();
              
                controller = new ContainerController(container, this._width, this._height);
                controller.horizontalScrollPolicy = ScrollPolicy.OFF;
                controller.verticalScrollPolicy = ScrollPolicy.OFF;
                this._textFlow.flowComposer.addController(controller);
                this._textFlow.flowComposer.compose();
              
                container.x = currentX;
              
                currentX += this._width;
              
                //Se corta cuando ya todo el texto está cubierto por los ContainerControllers creados.
                if (controller.textLength == 0 ||
                    controller.textLength + controller.absoluteStart > this._textFlow.textLength)
                    break;
            }
            //Se sacan los controladores vacíos, y se agregan los containers válidos al componente.
            for (i = 0; i < this._textFlow.flowComposer.numControllers; i++)
            {
                var currentController : ContainerController = this._textFlow.flowComposer.getControllerAt(i);
                if (currentController.textLength == 0)
                    this._textFlow.flowComposer.removeControllerAt(i);
                else
                    this.addChild(currentController.container);
            }


            //Se redibujan los controladores.

            this._textFlow.flowComposer.updateAllControllers();
          
            //Se trata de ir a la página en la que está el contenido que el
            //usuario estaba probablemente leyendo.
            this.restorePage();
}

Thanks.

This topic has been closed for replies.

3 replies

latamykAuthor
Participating Frequently
December 10, 2010

Problem solved. In the last example I just replaced

this.controllerTwo.setCompositionSize(width - 24, this.stage.stageHeight);

for

this.controllerTwo.setCompositionSize(width, this.stage.stageHeight);

I tried to see what happened with things like

this.controllerTwo.setCompositionSize(width + 2, this.stage.stageHeight);

And in that case links didn't work at startup.

In the original example, the problem was in another class, and it was associated with dinamycally changing the columnCount property of the TextFlow object.

latamykAuthor
Participating Frequently
December 7, 2010

Sorry for insisting so much with this, but now I've come up with a very simple piece of code that seems to be one step from solving the problem, but I still can't figure it out.

Right after the app loads, before resizing it, you hover over or try to click the links but nothing happens. If you resize the window, it doesn't matter how much, the links magically start working.


The full code:

<?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"
               applicationComplete="init()">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
   
    <mx:Canvas id="canvasOne" x="0" y="0"/>
   
    <fx:Script>
        <![CDATA[
            import fl.transitions.Tween;
            import fl.transitions.TweenEvent;
            import fl.transitions.easing.Regular;
           
            import flashx.textLayout.container.ContainerController;
            import flashx.textLayout.container.ScrollPolicy;
            import flashx.textLayout.conversion.TextConverter;
            import flashx.textLayout.elements.TextFlow;
           
            import mx.core.UIComponent;
            import mx.events.ResizeEvent;
           
            private var markup : String =
                "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>" +
                "<p>Say It Ain't So is a song by the American rock band <a href='http://en.wikipedia.org/wiki/Weezer_(1994_album)'>Weezer</a>. It was released as the third single from their debut album, Weezer (The Blue Album)." +
                "Written (like most Weezer songs) by frontman Rivers Cuomo, the song came to be after he had all the music finished and one line, Say it ain't so. [1] Cuomo made a connection to an incident in high school where he came home and saw a bottle of beer in the fridge. He believed his mother and father\'s marriage ended because his father was an alcoholic and this made him fear the marriage between his mother and step-father would end this way as well.[2]" +
                "In 2008, Rolling Stone ranked Say It Ain\'t So #72 on The 100 Greatest Guitar Songs of All Time. [3] Pitchfork Media included the song at number 10 on their Top 200 Tracks of the 90s.[4]" +
                "Say It Ain\'t So was featured as a playable track in the 2007 music video game <a href='http://en.wikipedia.org/wiki/Rock_Band_(video_game)'>Rock Band</a>.</p>" +
                "<p>The music video for Say It Ain't So, directed by Sophie Muller, met with less success than the previous two Weezer videos directed by Spike Jonze, however the song still successfully climbed to the top 10 of the Modern Rock Tracks chart." +
                "As noted in the Weezer DVD collection Video Capture Device and the slip cover of the re-released special edition of their debut album, they filmed the music video at the house where the band used to rehearse and record. The video also features a cameo by the band's webmaster/band photographer/archivist and close friend for many years, Karl Koch." +
                "A small poster of Mercyful Fate/King Diamond frontman King Diamond is visible several times throughout the video, most clearly during the final chorus, just as Rivers Cuomo turns his mic around.</p>" +
                "* The band Further Seems Forever covered the song on the Weezer tribute album Rock Music: A Tribute to Weezer." +
                "* An episode of One Tree Hill featured a cover by MoZella." +
                "* Juliana Hatfield covered the song at a concert in 1995.[5]" +
                "* Asher Roth sampled this song for his debut rap single I Love College. After the song leaked onto the internet, Rivers Cuomo reportedly refused to clear sample, which prompted Roth to debut a remixed version of his song as his official debut single.[6]" +
                "* Chiptune artist Inverse Phase wrote a Commodore 64 cover and titled it Say It Ain't Sixty-FO[7]" +
                "* The Deftones have covered this song live in concert." +
                "* The Sleeping have covered this song live in concert." +
                "* Young Guns covered this song and released it on their EP Sons of Apathy." +
                "* Finch (American band) also covered this song live/" +
                "</TextFlow>";
           
            private var flow : TextFlow;
           
            private var containerOne : Sprite;
            private var controllerOne : ContainerController;
            private var containerTwo : Sprite;
            private var controllerTwo : ContainerController;
           
            private var currentPage : int = 0;
            private var pageCount : int = 2;
           
            private function init() : void
            {
                //Load Text Layout Markup
                flow = TextConverter.importToFlow(this.markup, TextConverter.TEXT_LAYOUT_FORMAT);
                flow.columnCount = 2;
               
                //Container One set up
                this.containerOne = new Sprite();
                this.controllerOne = new ContainerController(containerOne,
                    this.stage.stageWidth, this.stage.stageHeight);
                this.controllerOne.verticalScrollPolicy = ScrollPolicy.OFF;
                this.flow.flowComposer.addController(controllerOne);
                this.containerOne.x = 0;
                this.containerOne.y = 0;
               
                //Container Two set up
                this.containerTwo = new Sprite();
                this.controllerTwo = new ContainerController(containerTwo,
                    this.stage.stageWidth, this.stage.stageHeight);
                this.controllerTwo.verticalScrollPolicy = ScrollPolicy.OFF;
                this.flow.flowComposer.addController(controllerTwo);
               
                this.containerTwo.x = this.stage.stageWidth;
                this.containerTwo.y = 0;
               
                this.flow.flowComposer.compose();
                this.flow.flowComposer.updateAllControllers();
               
                this.containerOne.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
               
                var uiOne : UIComponent = new UIComponent();
                uiOne.addChild(this.containerOne);
                this.canvasOne.addChild(uiOne);
               
                var uiTwo : UIComponent = new UIComponent();
                uiTwo.addChild(this.containerTwo);
                this.canvasOne.addChild(uiTwo);
            }
           
            private function onAddedToStage(event : Event) : void
            {
                this.removeEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
                this.addEventListener(ResizeEvent.RESIZE, this.onResize);
               
                this.onResize(null);
            }
           
            private function onResize(event : Event) : void
            {
                var width : Number = this.stage.stageWidth;
               
                this.controllerOne.setCompositionSize(width, this.stage.stageHeight);
                this.controllerTwo.setCompositionSize(width - 24, this.stage.stageHeight);
               
                this.containerTwo.x = this.stage.stageWidth;
               
                this.flow.flowComposer.compose();
                this.flow.flowComposer.updateAllControllers();
            }
        ]]>
    </fx:Script>
</s:Application>

Adobe Employee
November 17, 2010

In your code it looks like the sprites are all added to the parent as if they are overlapping.

There have been some recent fixes to links in 2.0.  I made a modified version of the Alice example and was able to work the links.  Source is here:

http://blogs.adobe.com/tlf/files/2010/11/PaginationWithSelection.zip

I'm using TLF build 201

Hope that helps,

Richard

latamykAuthor
Participating Frequently
November 17, 2010

Hi Richard, thanks for your answer. I had suspicions about Sprite overlapping, but the way I'm removing the old children before adding the new ones, and setting each Sprite's x should avoid that (I'll try adding a couple of pixels between them just in case). Before doing it this way I had just one child at a time in the parent container, but it neither worked (could there be any gotcha in the Sprite's removeChildAt method?).

Anyway, I'll recheck that and try your example. Hopefully there will be a ticked star next to this thread's title by this afternoon