[Pharo-project] [Pharo-Project] About new TxText text model
Hello. I look deep at TxText package where Igor and Camillo introduced new text model. Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position. I like design :). And I want use this package. And I have questions and suggestions: 1) Cursor is end of selection object. So now when you move cursor selection changed, because start of selection stay same. Am I right? I think cursor movement should always reset selection. It is what we see with basic text editors. But cursor now is just instance of TxPosition which implements simple position protocol (move left, up...). It just change current span and span position by movement. TxPosition knows nothing about TxSelection object. That's why I think Cursor class should be introduced here which alway reset text selection by any move. And if you want to change selection bounds just get explicitly start or end of selection and use position api. What do you think? 2) Next question about changes notification of text model. First I want Cursor and Selection objects are annnouncers. So I can implement CursorPresenter and SelectionPresenter to show such objects and handle changes. For example when CursorMovedAnnouncement happen I can move cursor caret morph at appropriate position. Another idea is make span objects announcers. Maybe it is not good idea but I want to subscribe at SpanAdded, SpanRemoved. SpanChanged, SpanSplitted. With such events I can make very simple implementation of TextEditor as list of SpanMorph's. Maybe it is not optimized solution but I think it is most simple thing. So I want to try it. 3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation. I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result. If you agree about such logic please suggest good name for such "restriction object" and instance variable where it will placed (at TxModel I think) Ok, now what do you think about all this? I want implement all my suggestions. But first I want listen your opinions. Best regards, Denis
On Nov 14, 2012, at 9:36 PM, Denis Kudriashov wrote:
Hello.
I look deep at TxText package where Igor and Camillo introduced new text model.
Excellent!
Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position.
If this is not in the class comments can you add it?
I like design :). And I want use this package. And I have questions and suggestions:
1) Cursor is end of selection object. So now when you move cursor selection changed, because start of selection stay same. Am I right? I think cursor movement should always reset selection. It is what we see with basic text editors. But cursor now is just instance of TxPosition which implements simple position protocol (move left, up...). It just change current span and span position by movement. TxPosition knows nothing about TxSelection object. That's why I think Cursor class should be introduced here which alway reset text selection by any move. And if you want to change selection bounds just get explicitly start or end of selection and use position api. What do you think?
2) Next question about changes notification of text model. First I want Cursor and Selection objects are annnouncers. So I can implement CursorPresenter and SelectionPresenter to show such objects and handle changes. For example when CursorMovedAnnouncement happen I can move cursor caret morph at appropriate position. Another idea is make span objects announcers. Maybe it is not good idea but I want to subscribe at SpanAdded, SpanRemoved. SpanChanged, SpanSplitted. With such events I can make very simple implementation of TextEditor as list of SpanMorph's. Maybe it is not optimized solution but I think it is most simple thing. So I want to try it.
3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation. I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result. If you agree about such logic please suggest good name for such "restriction object" and instance variable where it will placed (at TxModel I think)
Ok, now what do you think about all this? I want implement all my suggestions. But first I want listen your opinions.
Igor is traveling back from argentina today and camillo left yesterday.
Best regards, Denis
2012/11/16 Stéphane Ducasse <stephane.ducasse@inria.fr>
Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position.
If this is not in the class comments can you add it?
When I will have permissions
On 20 November 2012 21:31, Denis Kudriashov <dionisiydk@gmail.com> wrote:
2012/11/16 Stéphane Ducasse <stephane.ducasse@inria.fr>
Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position.
If this is not in the class comments can you add it?
When I will have permissions
once you will give me your username on smalltalk hub. :) -- Best regards, Igor Stasenko.
On 2012-11-14, at 17:36, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
I look deep at TxText package where Igor and Camillo introduced new text model.
Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position.
I like design :). And I want use this package. And I have questions and suggestions:
1) Cursor is end of selection object. So now when you move cursor selection changed, because start of selection stay same. Am I right?
yes
I think cursor movement should always reset selection. It is what we see with basic text editors. But cursor now is just instance of TxPosition which implements simple position protocol (move left, up...). It just change current span and span position by movement. TxPosition knows nothing about TxSelection object. That's why I think Cursor class should be introduced here which alway reset text selection by any move. And if you want to change selection bounds just get explicitly start or end of selection and use position api. What do you think?
Humm not so sure about this :). Your argument in favor of a default behavior which conforms to other editors is definitely something to consider. In the end it's not that much work to get the a decent default behavior. Somewhere in the view where you modify the mode you can do `text selection collapse`. If you want you can try to implement it ;) and we see how it feels to use it that way (most probably I will be in favor then..)
2) Next question about changes notification of text model. First I want Cursor and Selection objects are annnouncers. So I can implement CursorPresenter and SelectionPresenter to show such objects and handle changes. For example when CursorMovedAnnouncement happen I can move cursor caret morph at appropriate position.
this sounds like a good idea! I don't remember if we replace/create new instances of the cursors/selections... This might have an impact on where you want to listen for changes. But definitely we want something like that to decouple the model from any view.
Another idea is make span objects announcers. Maybe it is not good idea but I want to subscribe at SpanAdded, SpanRemoved. SpanChanged, SpanSplitted. With such events I can make very simple implementation of TextEditor as list of SpanMorph's. Maybe it is not optimized solution but I think it is most simple thing. So I want to try it.
3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation.
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model. For instance if you want to get the insertion point when clicking on some text view you have to take so many model-unrelated things into account (global transformation, font sizes).
I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result. If you agree about such logic please suggest good name for such "restriction object" and instance variable where it will placed (at TxModel I think)
Ok, now what do you think about all this? I want implement all my suggestions. But first I want listen your opinions.
Best regards, Denis
Hello. Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't. 2012/11/18 Camillo Bruni <camillobruni@gmail.com>
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model.
If such behaviour will be at view simple Cursor>>moveUp/moveDown will never work right from user perspective. So why you need cursor at text model which will never reflect state of visual cursor at screen? To me text model should completelly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph.
For instance if you want to get the insertion point when clicking on some text view you have to take so many model-unrelated things into account (global transformation, font sizes).
I think It can be solve easilly if text model will reflect visual lines of text. For example, imagine my simple idea where TextView is just list of SpanMorph's. When user click on text concrete span morph will handle it because TextView is just morph with submorphs (no special behaviour). So target SpanMorph should just compute span position under mouse and change text model cursor position appropriatelly. Then cursor will announce #changed event and CursorMorph will reflect this automatically. 3) What about auto wrap behaviour?
If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation. I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result.
Just remember two kinds of such line width restrictions: width in pixels and width in characters. First is usual text wrapping behaviour when line width restricted by view width. Last is when editor wrap lines which contains >100 characters for example.
On 20 November 2012 21:33, Denis Kudriashov <dionisiydk@gmail.com> wrote:
2012/11/21 Denis Kudriashov <dionisiydk@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done -- Best regards, Igor Stasenko.
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
On 25 November 2012 15:08, Denis Kudriashov <dionisiydk@gmail.com> wrote:
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
no idea, maybe Nicolas could help? http://www.smalltalkhub.com/#!/~sig/TxText/contributors -- Best regards, Igor Stasenko.
are you sure that you are using your account? Because it happened to me too. Stef On Nov 25, 2012, at 3:08 PM, Denis Kudriashov wrote:
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
When i got a 400 Bad request it's because of wrong password. Ben On Nov 25, 2012, at 8:05 PM, Stéphane Ducasse wrote:
are you sure that you are using your account? Because it happened to me too.
Stef
On Nov 25, 2012, at 3:08 PM, Denis Kudriashov wrote:
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
Yes. you are right. It was bad password. I not think about it because when I load code from smalltalkhub system was ask me for password. But It was not check it correctness. I uploaded version with class comment and refactored tests. 2012/11/25 Benjamin <benjamin.vanryseghem.pharo@gmail.com>
When i got a 400 Bad request it's because of wrong password.
Ben
On Nov 25, 2012, at 8:05 PM, Stéphane Ducasse wrote:
are you sure that you are using your account? Because it happened to me too.
Stef
On Nov 25, 2012, at 3:08 PM, Denis Kudriashov wrote:
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
On 25 November 2012 21:27, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Yes. you are right. It was bad password. I not think about it because when I load code from smalltalkhub system was ask me for password. But It was not check it correctness.
I uploaded version with class comment and refactored tests.
Good.! THanks a lot.
2012/11/25 Benjamin <benjamin.vanryseghem.pharo@gmail.com>
When i got a 400 Bad request it's because of wrong password.
Ben
On Nov 25, 2012, at 8:05 PM, Stéphane Ducasse wrote:
are you sure that you are using your account? Because it happened to me too.
Stef
On Nov 25, 2012, at 3:08 PM, Denis Kudriashov wrote:
2012/11/22 Igor Stasenko <siguctua@gmail.com>
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
My smalltalkhub nickname "dionisiy"
done
I try to commit version (with comment) but 400 bad request error raised. But I see myself as contributor at smalltalkhub project page. Any ideas?
-- Best regards, Igor Stasenko.
On 2012-11-20, at 17:30, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
2012/11/18 Camillo Bruni <camillobruni@gmail.com>
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model.
If such behaviour will be at view simple Cursor>>moveUp/moveDown will never work right from user perspective. So why you need cursor at text model which will never reflect state of visual cursor at screen?
it depends, I think the model should not take the view into account. First we implement the cursor movement as simple as possible, and that is for now on the model-base. If it will work properly or not depends on the view implementation.
To me text model should completly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph
Model IS the raw base model, the view is what you see, that are definitely two different things. For instance where would you deal with hyphenation? dynamic layouts? I don't think they belong in the model and I think we should stick to existing implementation schemes (M VC) and existing implementations like Cocoa...
"The font is then responsible for providing the drawing commands and metrics for the particular glyph when it's drawn." sounds like Cocoa delegates rendering to the font. On Nov 20, 2012, at 10:09 PM, Camillo Bruni wrote:
On 2012-11-20, at 17:30, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
2012/11/18 Camillo Bruni <camillobruni@gmail.com>
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model.
If such behaviour will be at view simple Cursor>>moveUp/moveDown will never work right from user perspective. So why you need cursor at text model which will never reflect state of visual cursor at screen?
it depends, I think the model should not take the view into account. First we implement the cursor movement as simple as possible, and that is for now on the model-base.
If it will work properly or not depends on the view implementation.
To me text model should completly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph
Model IS the raw base model, the view is what you see, that are definitely two different things. For instance where would you deal with hyphenation? dynamic layouts?
I don't think they belong in the model and I think we should stick to existing implementation schemes (M VC) and existing implementations like Cocoa...
On 21 November 2012 01:20, Sebastian Sastre <sebastian@flowingconcept.com> wrote:
"The font is then responsible for providing the drawing commands and metrics for the particular glyph when it's drawn."
sounds like Cocoa delegates rendering to the font.
Cocoa? I don't know where you took this citation from, but it is actually how Athens dealing with this stuff: it asks font to provide an instance of glyph renderer, suitable for rendering on athens surface. And yes, the glyph renderer is then responsible for delivering glyphs to surface by issuing appropriate drawing commands :) -- Best regards, Igor Stasenko.
2012/11/21 Camillo Bruni <camillobruni@gmail.com>
To me text model should completly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph
Model IS the raw base model, the view is what you see, that are definitely two different things. For instance where would you deal with hyphenation? dynamic layouts?
When I think about TextMorph model I think about object which can be used from tests or just workspace where no any view exists. And this is what you exactly implement with TxModel. You have TxModelTest where you move cursor, change selection, insert characters. And this is not depends on any possible text view. Great!. And without any thinking on text wrapping logic and others I can implement very SimpleTextMorph based on TxModel. You can imagine how simple can be implementation of multiline text view/editor based on such nice model. No crappy paragraphs and editors. Drawing morph can be just something like spans do: [:each | each drawOn: aCanvas] But now imagine that I want such morph with two options: autowrap by morph bounds and restrict lines by 10 characters. What should be changed for such behaviour? And maybe more clever question: what this options actually mean? In any case user just see list of text lines. And user can not know is this lines virtual (created by wrapping logic) or real (created by cr from source string). So logic of wrap lines is just splitting source string to visual lines by some restriction. (Same for hyphenation). But view just show list of lines (spans) and nothing more. And object which edit text (insert characters...) should know about "lines restrictions" and change span structure of text model appropriately. Now TxCharactersSpan implements full edit logic (#at:insert: method for example). To achive my suggestions new "restriction object" should be introduced and maybe special kind of spans. Maybe it should be called SpanBuilder (with WrappedTextSpanBuilder-like subclasses) Ok, this is my ideas. I try to implement it this weekend. What you mean by dynamic layouts? Best regards, Denis
On 20 November 2012 21:30, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
2012/11/18 Camillo Bruni <camillobruni@gmail.com>
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model.
If such behaviour will be at view simple Cursor>>moveUp/moveDown will never work right from user perspective. So why you need cursor at text model which will never reflect state of visual cursor at screen? To me text model should completelly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph.
because same model can have multiple different views. and each view can have different dimensions and show different portion(s) of model (text). The parts we implemented so far is about editing the model itself. Next step would be to implement text attribute(s) management, and then implement View(s) which will lay out the text for rendering it on screen. About cursor: The cursor is actually a convenience method in current model, to avoid using 'text selection end' every time. The selection/cursor in text model there because this should be is the only way how you can modify text: - you should not be able to modify text without using selection(s)/cursor. Any direct usage, like in existing Text , should be prohibited. Only high level operations via selection. And no illusions about that you can operate with text as with an ordinal Collection. If you want to turn text model into 'collection', you have to pay the price: use #asString. An way to treat text as a collection of characters is imo futile and falls short once you think how to introduce non-textual objects into text (images etc). More about selections: It is not necessary to have a direct correspondence between model selection and visual text editor selection/cursor. And often, actually would be counterproductive. Camillo may disagree, but i think the main purpose of selection/cursor objects and their protocol is to provide a convenient interface for editing the model. And the fact that you can have visual selection/cursor == model selection/cursoe is imo secondary to that, and completely unnecessary. Yes, we tried to map text navigation/selection protocol to look most natural, as if you editing the text in text editor. And tests which we have is actually telling that we're on the right way: we've been able to edit the text without having 'text editor' and without counting characters, but using high-level commands to cursor/selection. Which is IMO good.
For instance if you want to get the insertion point when clicking on some text view you have to take so many model-unrelated things into account (global transformation, font sizes).
I think It can be solve easilly if text model will reflect visual lines of text. For example, imagine my simple idea where TextView is just list of SpanMorph's. When user click on text concrete span morph will handle it because TextView is just morph with submorphs (no special behaviour). So target SpanMorph should just compute span position under mouse and change text model cursor position appropriatelly. Then cursor will announce #changed event and CursorMorph will reflect this automatically.
The decision to use spans was to denote a portion of text which has same attributes, so a rendering engine can set up all attributes once, at the start of span, and render all text characters in single pass, without need to do any other checks for attribute changes. I don't think representing spans with morphs will be a good idea.
3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation. I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result.
Just remember two kinds of such line width restrictions: width in pixels and width in characters. First is usual text wrapping behaviour when line width restricted by view width. Last is when editor wrap lines which contains >100 characters for example.
text wrapping is visual/layout information. The data flow when you rendering text is following: (Text) -> (Layout information) -> (Screen) The text , as a model , has nothing to do with layout information. More than that, don't forget about multiple views for same model, which can have different dimensions and different wrapping rules. So, it would be bad idea to mix layout information with text model itself. -- Best regards, Igor Stasenko.
Can you add part of this mail as class comment? Tx On Nov 21, 2012, at 10:58 PM, Igor Stasenko wrote:
On 20 November 2012 21:30, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
Can you add me as project contributor. I try to upload version with detailed comment from my first mail but can't.
2012/11/18 Camillo Bruni <camillobruni@gmail.com>
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model.
If such behaviour will be at view simple Cursor>>moveUp/moveDown will never work right from user perspective. So why you need cursor at text model which will never reflect state of visual cursor at screen? To me text model should completelly represent what user see at text view. Otherwise why you call it model? Otherwise it is just raw data like Text in current TextMorph.
because same model can have multiple different views. and each view can have different dimensions and show different portion(s) of model (text). The parts we implemented so far is about editing the model itself. Next step would be to implement text attribute(s) management, and then implement View(s) which will lay out the text for rendering it on screen.
About cursor: The cursor is actually a convenience method in current model, to avoid using 'text selection end' every time.
The selection/cursor in text model there because this should be is the only way how you can modify text: - you should not be able to modify text without using selection(s)/cursor. Any direct usage, like in existing Text , should be prohibited. Only high level operations via selection. And no illusions about that you can operate with text as with an ordinal Collection. If you want to turn text model into 'collection', you have to pay the price: use #asString. An way to treat text as a collection of characters is imo futile and falls short once you think how to introduce non-textual objects into text (images etc).
More about selections: It is not necessary to have a direct correspondence between model selection and visual text editor selection/cursor. And often, actually would be counterproductive.
Camillo may disagree, but i think the main purpose of selection/cursor objects and their protocol is to provide a convenient interface for editing the model. And the fact that you can have visual selection/cursor == model selection/cursoe is imo secondary to that, and completely unnecessary.
Yes, we tried to map text navigation/selection protocol to look most natural, as if you editing the text in text editor. And tests which we have is actually telling that we're on the right way: we've been able to edit the text without having 'text editor' and without counting characters, but using high-level commands to cursor/selection. Which is IMO good.
For instance if you want to get the insertion point when clicking on some text view you have to take so many model-unrelated things into account (global transformation, font sizes).
I think It can be solve easilly if text model will reflect visual lines of text. For example, imagine my simple idea where TextView is just list of SpanMorph's. When user click on text concrete span morph will handle it because TextView is just morph with submorphs (no special behaviour). So target SpanMorph should just compute span position under mouse and change text model cursor position appropriatelly. Then cursor will announce #changed event and CursorMorph will reflect this automatically.
The decision to use spans was to denote a portion of text which has same attributes, so a rendering engine can set up all attributes once, at the start of span, and render all text characters in single pass, without need to do any other checks for attribute changes. I don't think representing spans with morphs will be a good idea.
3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation. I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result.
Just remember two kinds of such line width restrictions: width in pixels and width in characters. First is usual text wrapping behaviour when line width restricted by view width. Last is when editor wrap lines which contains >100 characters for example.
text wrapping is visual/layout information. The data flow when you rendering text is following:
(Text) -> (Layout information) -> (Screen)
The text , as a model , has nothing to do with layout information. More than that, don't forget about multiple views for same model, which can have different dimensions and different wrapping rules. So, it would be bad idea to mix layout information with text model itself.
-- Best regards, Igor Stasenko.
On 18 November 2012 17:56, Camillo Bruni <camillobruni@gmail.com> wrote:
On 2012-11-14, at 17:36, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hello.
I look deep at TxText package where Igor and Camillo introduced new text model.
Text model based on sequence of span objects. There are now two kind of spans: CharacterSpan and LineSeparator. Each span has reference to next and previous spans. There is TxSelection object which contains cursor. So you can insert new text at cursor, you can cut selection, replace selection with another text. Such maniulation changes text model structure. It can create new span objects. It can split current span at cursor position, It can remove selected spans. Also you can move cursor up, down, left, right. Cursor always know about current span and span position.
I like design :). And I want use this package. And I have questions and suggestions:
1) Cursor is end of selection object. So now when you move cursor selection changed, because start of selection stay same. Am I right?
yes
I think cursor movement should always reset selection. It is what we see with basic text editors. But cursor now is just instance of TxPosition which implements simple position protocol (move left, up...). It just change current span and span position by movement. TxPosition knows nothing about TxSelection object. That's why I think Cursor class should be introduced here which alway reset text selection by any move. And if you want to change selection bounds just get explicitly start or end of selection and use position api. What do you think?
Humm not so sure about this :). Your argument in favor of a default behavior which conforms to other editors is definitely something to consider. In the end it's not that much work to get the a decent default behavior. Somewhere in the view where you modify the mode you can do `text selection collapse`.
If you want you can try to implement it ;) and we see how it feels to use it that way (most probably I will be in favor then..)
2) Next question about changes notification of text model. First I want Cursor and Selection objects are annnouncers. So I can implement CursorPresenter and SelectionPresenter to show such objects and handle changes. For example when CursorMovedAnnouncement happen I can move cursor caret morph at appropriate position.
this sounds like a good idea! I don't remember if we replace/create new instances of the cursors/selections... This might have an impact on where you want to listen for changes. But definitely we want something like that to decouple the model from any view.
i have only one question: - shall we do this surgery (with announcer stuff) in base model, or - shall we make a separate model which wraps around existing model,and then provides a notification(s). my main source of disdain about notifications is that in single class we will have to mix an action and notification about it i.e.. Selection>>cut self doThingsToCut. ... self announcer announce: IJustCutMyself. this is IMO a bit stinky. I would prefer a notification(s) to be in a separate layer: SelectionWatcher/Controller>>cut selection cut. ... self announcer announce: SelectionWasJustCut despite that it looks like more costly in terms of implementation. But i don't like mixing multiple concerns in single place.
Another idea is make span objects announcers. Maybe it is not good idea but I want to subscribe at SpanAdded, SpanRemoved. SpanChanged, SpanSplitted. With such events I can make very simple implementation of TextEditor as list of SpanMorph's. Maybe it is not optimized solution but I think it is most simple thing. So I want to try it.
3) What about auto wrap behaviour? If you have auto wrap option at text editors you have line width restriction. And you should spit real lines of text to visual lines which satisfed this restriction. And text mode should know about such restriction because any text insertion can require new visual lines creation.
I don't think the basic model should know about the visual lines. We discussed that for a while, but in the end that's purely a view on the basic model. For instance if you want to get the insertion point when clicking on some text view you have to take so many model-unrelated things into account (global transformation, font sizes).
I think insertion single line text at span position should be executed by special "restriction object". It should return new characters of span which satisfied that restriction. And it should return new span object (or just remains characters) which will present new visual lines. Then this "remains characters" should be inserted to next span at 0 position. When wrap behavior not needed "restriction object" just inserts new text into current characters at given position and returns result. If you agree about such logic please suggest good name for such "restriction object" and instance variable where it will placed (at TxModel I think)
Ok, now what do you think about all this? I want implement all my suggestions. But first I want listen your opinions.
Best regards, Denis
-- Best regards, Igor Stasenko.
I like the separation.
i have only one question: - shall we do this surgery (with announcer stuff) in base model, or - shall we make a separate model which wraps around existing model,and then provides a notification(s).
my main source of disdain about notifications is that in single class we will have to mix an action and notification about it i.e..
Selection>>cut self doThingsToCut. ... self announcer announce: IJustCutMyself.
this is IMO a bit stinky.
I would prefer a notification(s) to be in a separate layer:
ActiveText?
SelectionWatcher/Controller>>cut selection cut. ... self announcer announce: SelectionWasJustCut
despite that it looks like more costly in terms of implementation. But i don't like mixing multiple concerns in single place.
On 22 November 2012 08:11, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
I like the separation.
i have only one question: - shall we do this surgery (with announcer stuff) in base model, or - shall we make a separate model which wraps around existing model,and then provides a notification(s).
my main source of disdain about notifications is that in single class we will have to mix an action and notification about it i.e..
Selection>>cut self doThingsToCut. ... self announcer announce: IJustCutMyself.
this is IMO a bit stinky.
I would prefer a notification(s) to be in a separate layer:
ActiveText?
you suggest the name?
SelectionWatcher/Controller>>cut selection cut. ... self announcer announce: SelectionWasJustCut
despite that it looks like more costly in terms of implementation. But i don't like mixing multiple concerns in single place.
-- Best regards, Igor Stasenko.
I would prefer a notification(s) to be in a separate layer:
ActiveText?
you suggest the name? yes controller sucks
SelectionWatcher/Controller>>cut selection cut. ... self announcer announce: SelectionWasJustCut
despite that it looks like more costly in terms of implementation. But i don't like mixing multiple concerns in single place.
-- Best regards, Igor Stasenko.
On 22 November 2012 10:45, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
I would prefer a notification(s) to be in a separate layer:
ActiveText?
you suggest the name? yes controller sucks
hehe.. yes.. i didn't thought actually what name is better.. at that point i was use random name to indicate my intent. :) -- Best regards, Igor Stasenko.
participants (6)
-
Benjamin -
Camillo Bruni -
Denis Kudriashov -
Igor Stasenko -
Sebastian Sastre -
Stéphane Ducasse