Skip to main content
Participant
April 27, 2010
Question

RichEditableText.setFormatOfRange() resets scroll position

  • April 27, 2010
  • 1 reply
  • 715 views

Hi

I'm finding that calling setFormatOfRange() on a RichEditableText causes the scroll position to reset.  Is this the expected behaviour?

If so, how do I prevent it?

Regards

Marty

This topic has been closed for replies.

1 reply

Adobe Employee
April 27, 2010

Not sure what you mean by "resets".  It's expected that any operation can scroll the text to keep the selection in view.  I believe setFormatOfRange uses a TLF operation underneath.

Not sure of the exact way to do this with RichEditableText but if you can get the scrol position before the call you can set it back after the call.  The one caveat is that the scroll position will be clamped to its largest possible value based on the composed height of the content.

Hope that helps,

Richard

Participant
April 28, 2010

I've looked into this further.

As you mentioned, the setFormatOfRange() method invokes a ApplyFormatOperation.  This invokes (eventually) ParaEdit.setCharacterFormat() , which in turn calls ParaEdit.splitForChange() which eventually damages the textflow.

The RichEditableText has an event listener registered for this, which causes a call to invalidateSize().

This in turn causes measure() to fire, which causes the textFlow to reset the scroll position back to 0.

This seems highly problematic, because it means we can't edit text that is below the initial viewport's range without the RTE always returning back to a scroll position of 0.

While I understand the logic here (changing the font size can potentially change the measured size), it's pretty naff from a usability perspective.

In the end, I've subclassed RichEditableText, and overridden setFormatOfRange, hacking the invalidateSizeFlag back to false:

          override public function setFormatOfRange(format:TextLayoutFormat, anchorPosition:int=-1, activePosition:int=-1):void

          {

               super.setFormatOfRange(format,anchorPosition,activePosition);

               

               // HACK : Prevent measuring after setting the format,

               // as is triggers resetting the scrolling back to 0.

               invalidateSizeFlag = false;

          }

This could cause me problems if it genuinely has changed size.

I tried grabbing hold of the vertical scroll position, but didn't have huge success, largely because the scrolling happens later during validation rather than throughout the initial call, so hooking into this to change the scroll position back to it's non-zero value was pretty hacky. 

I'd love to find a more appropriate solution than the one I've posted -- any ideas?