Friday, July 16, 2010

Spark TextArea with Line Numbers

Here is a skin that you can use on the Spark TextArea class to show line numbers down the left side of the text.
The line numbers use the same size font as the TextArea.

It is very simply to use, simply set the skinClass property in mxml like this:
<s:TextArea skinClass="flex.utils.spark.TextAreaLineNumbersSkin"/>

If you want a horizontal scroll bar on the TextArea, then set lineBreak="explicit" and the horizontal scrollbar will appear.

Here is an example of it in action (right click to view source).

It would be very easy to modify this skin to make it resizable by adding a resize handle in the bottom right corner. Look at the source code from my previous blog post on Resizable Controls, specifically the flex.utils.spark.resize.ResizableTextAreaSkin class, it uses a custom skin for the Scroller, which adds the resize handle.


JabbyPanda said...

"textDisplay.mx_internal::textContainerManager.numLines" - this was really painful to get the number of lines displayed in s:TextArea :(

Although, cool demo in overall!

Chris Callendar said...

Yeah I agree, surprisingly complicated just to get at the number of lines.

Softweb Solutions said...

Really Nice Demo i really like this post flex developer

MotionMaker said...

Nice example. I wanted to take it another step and stop the scrolling to display only on explicit breaks lineBreak="{LineBreak.EXPLICIT}" on the RichEditableText

and add a horizontal scroller just on the RichEditableText

I found I needed to put the RichEditableText into a Group to get the lineBreak to work but have not figured how to get a horizontal scroll just for the content RichEditableText.

Chris Callendar said...

Hi MotionMaker,

I made a slight adjustment to the skin, so now if you specify on the TextArea lineBreak="explicit" the horizontal scrollbars will show up when needed. By default the lineBreak property is set to "toFit" which means the horizontal scrollbar will not appear.

Thanks for the comment,

DK said...

Any ideas on how to get the Scroller to automatically follow the cursor when you use the arrow key to move the cursor beyond the edge of the textarea? E.g., hit "Random string" to fill the textarea, focus the cursor in the textarea, and then repeatedly hit arrow down beyond line 20. If this were the default skin, the textarea would scroll with the cursor, but since we've wrapped the RichEditableText element in an HGroup, that behavior no longer works.

Any ideas?

DK said...

Answered my own question. You just need to restructure the skin a little bit and put the scroller back around the RichEditableText element, and bind the scroll position of the "gutter" to the scroll position of the text editing area:

<s:HGroup id="textGroup"
<s:HGroup id="gutter" clipAndEnableScrolling="true" minWidth="25" height="100%"
<s:Label id="lineNumbersLabel"
<s:Line width="1"
yTo="{Math.max(textGroup.height-1, textDisplay.height-1)}">
<s:SolidColorStroke color="#EDEDED"
<s:Scroller height="100%" width="100%" id="editorScroller">
<s:RichEditableText id="textDisplay"
valueCommit="updateLineNumbers(event)" />

Chris Callendar said...

That's awesome DK, thanks for contributing. I was thinking that the "gutter" should actually be outside the scroller too, that is how most text editors do it I think.

I've updated my example above to include your work, and added one more change - a gray box that covers up the line numbers at the bottom when the horizontal scrollbar is present (when lineBreak="explicit").


Mario Junior said...

Good stuff! This may be very useful for some projects. Thanks by share it with us.

Kim said...

Great work - Thanks for posting this :)

Ric.Far said...

Whith text with > then 5000 lines, we have a delay ....

Anonymous said...

Very good sample. But it has some size problems. The height of the numbers and scrollbar are same, not same as the height of the text part, and results strange behavior.tex stops with number 38 on line, but the the numbers scroll more with empty lines.