Igor do not think that because our tools do not use anything, we do not need good text support. Moose is struggling with the limits of the current textmodel. We should offer solutions to people not just to edit methods. Stef On Jan 13, 2013, at 9:51 PM, Igor Stasenko wrote:
Wow.. this is a huge progress! Sorry i was busy with other stuff and had no time to look at your code.
On 13 January 2013 20:54, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
I upload new version of TxText with new TxTextMorph which can show TxTextModel (http://www.smalltalkhub.com/#!/~sig/TxText ). See class side examples.
Implementation details:
TxTextMorph has textLayout instance variable which contains full precomputed information to draw text on screen. TxTextLayout contains collection of TxTextLine. TxTextLine contains collection of span objects (from text model) and offset with extent required for drawing lines (with right align for example). There are TxTextLayoutStrategy hierarchy responsible for building specific text layout objects:
TxSimpleTextLayoutStrategy build layout with actual text lines which text model contains TxWrapTextStrategy build layout with lines which satisfied preferredExtent (given from text morph bounds)
When text morph accepts new text model It asks layoutStrategy to build new layout. Then align selector applyed to layout. So text can be placed left to right, centered or right to left.
Morph drawing method very simple:
TxTextMorph>>drawOn: aCanvas textLayout drawTextOn: aCanvas at: self position
TxTextLayout>>drawTextOn: aCanvas at: aPoint | topOffset linePosition | topOffset := 0. lines do: [:eachLine | linePosition := aPoint x @ (aPoint y + topOffset). eachLine drawOn: aCanvas at: linePosition. topOffset := topOffset + eachLine height. ]
TxTextLine>>drawOn: aCanvas at: aPoint
spans do: [:each | each drawOn: aCanvas at: aPoint + offset ]
At the end TxCharactersSpan draw contents on canvas:
TxCharactersSpan >>drawOn: aCanvas at: aPoint aCanvas drawString: characters at: aPoint font: (self getAttribute: TxFontAttribute) color: (self getAttribute: TxColorAttribute)
And with Athens api text attributes can be not hardcoded:
TxCharactersSpan >>drawAthensOn: aCanvas at: aPoint attributes applyOn: aCanvas. aCanvas pathTransform translateX: aPoint x Y: aPoint y. aCanvas drawString: characters
Questions:
Now text alignment (like centering) is property of TxTextMorph. So it global property of full text layout. But how such attribute can be applied to specific line?
TxModel is list of spans. And each span object contains characters with same text attributes like font or color. Text alignment can be such attribute too. Do you think it should be attribute of all spans from single line? Or it should be only attribute of TxLineSeparator span? What your idea?
Well, there is two approaches: a per-line attribute can be a special span at the beginning at line, or it can be an attribute. Both has pros and cons, however. In case of span, it needs to be dealt properly with text editing/navigation. In case of attribute(s), this attribute is really per line (or better to say, per paragraph) and putting it into each span seems like superfluous.
IMO, i would go for a simplest model: the capability like text alignment (left/center/right) per line, is kind of overkill for our little world. I mean, it would be nice to have, but look at our tools: where are they used? Nowhere. So i would not focus on it right now, and having a global attribute seems like a good solution right now.
Future:
Next plan: cursor navigation, text selection and editing features. And of course tests, sorry I not start with tests now.
don't forget about tests. We started writing a model by implementing tests first, because we didn't wanted an implementation to dictate how things should be used.
I wait your comments , ideas and questions. Maybe you don't like my approach. I want to know why. I really want clean and object solution for text stuff in pharo.
-- Best regards, Igor Stasenko.