Skip to main content
Participating Frequently
March 13, 2010
Question

Preserving position of highlighted text lines during scrolling

  • March 13, 2010
  • 1 reply
  • 1127 views

I'm building an editor and I want to highlight lines that are selected by mouse click. I cannot use background color since I want to highlight the whole line from one end of the container to the other. This is straightforward to implement using the x-y coordinates from the mouse event to locate the line, and then draw a highlight box as a sprite on top of the container. Thanks for the ParagraphBorder sample that helped me figure out how to get this done right away.

However, when the user scrolls via mousewheel or vertical scrollbar, the highlight box must be redrawn. I thought this would be easy by storing the current highlighted line index and accessing the textflowline by index within the corresponding event handler to redraw the box using the bounds of this line. Yet, even after updating all controllers, I seem to retrieve the wrong line by index since the box drawn using the bounds of this line is incorrect.

As another approach, I thought I could use the mousewheel delta and shift the horizontal box sprite accordingly, but this doesn't work either. The box ends up jumping all around the container - it seems like the values returned by the mousewheel are erratic. Plus the box also ends up in positions that are not properly aligned with the text lines.

Any suggestions?

I am using the latest stable build (4.0.0.13875) for Adobe Flex  Gumbo.

Thanks for your time and help.

P.S. I understand that there some bugs related to mousewheel behavior. So if necessary, is it possible to disable scrolling of the textflow due to mousewheel?

This topic has been closed for replies.

1 reply

saviesAuthor
Participating Frequently
March 24, 2010

I probably didn't get any reply because this is more of a Flex question rather than TLF. Since I was not successful implementing the approach outlined above, I have been trying a purely TLF approach now. I hope I can get an answer regarding my current problem with this approach.

I'm capturing the TextLayoutEvent which lets me know whenever the textflow is scrolled. This works fine, but the event does not provide any information on the delta distance scrolled. I can keep track and calculate this amount for each event, but with this approach I ended up having similar problems as described above.

As an alternative, I decided to redraw the highlight box based on the new coordinates of the textline rather than moving it relative to the scroll amount. This seemed really easy since the selection had not changed and all I had to do was use findLineAtPosition to get the textflowline corresponding to current selection. My highlight function then uses the rect bounds of the specified textflowline to draw the box.

The problem is that the bounds of the textflowline corresponding to the current selection are the old bounds - the position has not been updated after scrolling. I tried functions such as updateAllControllers, composeToPosition, but failed to get the updated values for the scrolled layout. I checked for damage, line validity, and there is no damage, the line is valid, hence explaining why compose or update functions don't make a difference. I can see that each time I receive a new TextLayoutEvent, the computed bounds are correct for the previous scroll event, so the coordinates are being updated at some point after my textlayoutevent handler. So I tried moving my logic to handlers for updateComplete or flowOperationEnd, and still I get the incorrect bounds.

I assume it should be possible to get the updated coordinates/bounds of a textline following scrolling, so what am I doing wrong?

Thanks for your time.

Adobe Employee
March 24, 2010

Have you looked at verticalScrollPostion and horizontalScrollPosition variables on the ContainerController.  I think that's the adjustment you need.

Hope that helps,

Richard

saviesAuthor
Participating Frequently
March 30, 2010

Thanks a lot - that certainly helped. I was calculating the delta using the vertical scroll position of the parent text area. Using the properties that you pointed out, the delta works out fine.

I still need to control the behavior of the highlight box when the highlighted line scrolls off screen, i.e. remove the highlight and highlight again when the selected line scrolls back into the visible area of the container. To this end, I need to know the index of the topmost visible textflowline in the container. However, I don't see any straightforward way of getting this information. The content bounds can be accessed as pixels but not as an indexed range of visible lines.

If I understand correctly, lines that are not visible are marked invalid. So I could iterate and the index of the first valid line would be the topmost visible line in the container. Yet, even if I could, this is not a good way of finding this line due to performance - the larger the text, the more I would have to iterate.

Is there a property or method that provides access to visible/valid lines only? Or is there another recommended way to find visible line indexes within a container?

Thanks again for your time.

P.S. I know my problem with the scroll delta is solved, but I would still like to understand why I can't access updated coordinates in the textlayout/scroll event handler? Shouldn't this be possible or am I misunderstanding how it should work? If you don't mind, I would greatly appreciate some enlightment.