Customizing the Caret of a PluggableTextMorph

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Customizing the Caret of a PluggableTextMorph

Sean P. DeNigris
Administrator
For VimPharo, I want to have a different cursor depending on whether a tool is in insert or normal mode.

I tried a handful of ways, but they all failed or worked partially/inconsistently. Here's some of them:
* add the state to the paragraph, but the entire paragraph gets replaced during the life of the tool, so the state gets lost
* add the state to the editor, but the situation is the same
* add the state to PluggableTextMorph, override and access it from TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got me very acquainted with the emergency evaluator. It "worked", but only after using the arrows a bit.

Does anyone have any idea where I might hook in?

<rant>I find the whole text system very confusing. What the heck does a paragraph know about insertion points?? A view has one paragraph object, even if there are several paragraphs (as understood by the rest of humanity as a block of text with breaks between the adjoining ones. Editors and Paragraphs are thrown out and replaced on a whim. I'm finding it very hard to understand and modify</rant>

Thanks,
Sean
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Marcus Denker-4

On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:

>
> <rant>I find the whole text system very confusing.

:-) It's a mess of epic proportion. If you know take into account that the orignal plan
of Squeak was to be the Medium to re-invent all Media...

        Marcus


--
Marcus Denker -- http://marcusdenker.de


Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

philippeback
In reply to this post by Sean P. DeNigris
I am also spending a hell of a lot of time on Text, Paragraph, Styler and other things like that (TextAttribute and subclasses).

Very complicated indeed. It was worse before I have been told.

Phil

2012/7/16 Sean P. DeNigris <[hidden email]>
For VimPharo, I want to have a different cursor depending on whether a tool
is in insert or normal mode.

I tried a handful of ways, but they all failed or worked
partially/inconsistently. Here's some of them:
* add the state to the paragraph, but the entire paragraph gets replaced
during the life of the tool, so the state gets lost
* add the state to the editor, but the situation is the same
* add the state to PluggableTextMorph, override and access it from
TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
me very acquainted with the emergency evaluator. It "worked", but only after
using the arrows a bit.

Does anyone have any idea where I might hook in?

<rant>I find the whole text system very confusing. What the heck does a
paragraph know about insertion points?? A view has one paragraph object,
even if there are several paragraphs (as understood by the rest of humanity
as a block of text with breaks between the adjoining ones. Editors and
Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
to understand and modify</rant>

Thanks,
Sean

--
View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
Sent from the Pharo Smalltalk mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Benjamin Van Ryseghem (Pharo)
Indeed it was :)

Alain Plantec did a great job about that :)

Ben
On Jul 16, 2012, at 10:27 PM, [hidden email] wrote:

I am also spending a hell of a lot of time on Text, Paragraph, Styler and other things like that (TextAttribute and subclasses).

Very complicated indeed. It was worse before I have been told.

Phil

2012/7/16 Sean P. DeNigris <[hidden email]>
For VimPharo, I want to have a different cursor depending on whether a tool
is in insert or normal mode.

I tried a handful of ways, but they all failed or worked
partially/inconsistently. Here's some of them:
* add the state to the paragraph, but the entire paragraph gets replaced
during the life of the tool, so the state gets lost
* add the state to the editor, but the situation is the same
* add the state to PluggableTextMorph, override and access it from
TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
me very acquainted with the emergency evaluator. It "worked", but only after
using the arrows a bit.

Does anyone have any idea where I might hook in?

<rant>I find the whole text system very confusing. What the heck does a
paragraph know about insertion points?? A view has one paragraph object,
even if there are several paragraphs (as understood by the rest of humanity
as a block of text with breaks between the adjoining ones. Editors and
Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
to understand and modify</rant>

Thanks,
Sean

--
View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
Sent from the Pharo Smalltalk mailing list archive at Nabble.com.



Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Stéphane Ducasse
In reply to this post by Sean P. DeNigris

On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:

> For VimPharo, I want to have a different cursor depending on whether a tool
> is in insert or normal mode.
>
> I tried a handful of ways, but they all failed or worked
> partially/inconsistently. Here's some of them:
> * add the state to the paragraph, but the entire paragraph gets replaced
> during the life of the tool, so the state gets lost
> * add the state to the editor, but the situation is the same
> * add the state to PluggableTextMorph, override and access it from
> TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
> me very acquainted with the emergency evaluator. It "worked", but only after
> using the arrows a bit.
>
> Does anyone have any idea where I might hook in?
>
> <rant>I find the whole text system very confusing. What the heck does a
> paragraph know about insertion points?? A view has one paragraph object,
> even if there are several paragraphs (as understood by the rest of humanity
> as a block of text with breaks between the adjoining ones. Editors and
> Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
> to understand and modify</rant>

I got burned by that when I worked on my botanics env….
it was terrible.

>
> Thanks,
> Sean
>
> --
> View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Fernando olivero-2
In reply to this post by Sean P. DeNigris
Hi Sean, you can take a look at Athens-PangoCairo (in squeaksource).

Using NativeBoost, i'm using the Pango layout library [1], and the
Pango-Cairo binding [2],  to avoid laying out text using the outdated
(and messy) stuff in the image.

Check out the classes: ParagraphDescription & AthensPangoCairoParagraph.

I'm using them as the basis for the TextShape,LabelShape, and
EditableTextShape in Shapes / Gaucho ( using TextEditor,
SingleLineEditor ).

Maybe somebody can do the same for Morphic? use Pango to layout the
text, and code a new TextMorph on top of it?

Fernando

[1] http://developer.gnome.org/pango/stable/pango-Layout-Objects.html
[2] http://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html
On Wed, Jul 18, 2012 at 7:28 AM, Stéphane Ducasse
<[hidden email]> wrote:

>
> On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:
>
>> For VimPharo, I want to have a different cursor depending on whether a tool
>> is in insert or normal mode.
>>
>> I tried a handful of ways, but they all failed or worked
>> partially/inconsistently. Here's some of them:
>> * add the state to the paragraph, but the entire paragraph gets replaced
>> during the life of the tool, so the state gets lost
>> * add the state to the editor, but the situation is the same
>> * add the state to PluggableTextMorph, override and access it from
>> TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
>> me very acquainted with the emergency evaluator. It "worked", but only after
>> using the arrows a bit.
>>
>> Does anyone have any idea where I might hook in?
>>
>> <rant>I find the whole text system very confusing. What the heck does a
>> paragraph know about insertion points?? A view has one paragraph object,
>> even if there are several paragraphs (as understood by the rest of humanity
>> as a block of text with breaks between the adjoining ones. Editors and
>> Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
>> to understand and modify</rant>
>
> I got burned by that when I worked on my botanics env….
> it was terrible.
>
>>
>> Thanks,
>> Sean
>>
>> --
>> View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
>> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

philippeback
In reply to this post by Stéphane Ducasse
Ah, the morass into which I am currently digging...

Well, if we look at it for a while, it becomes a tad clearer.

PluggableTextMorph is just a shell for a TextMorph.

The TextMorph basically displays a Text (which can be styled with TextAttributes)

When moving into edition, there is an editor known by the TextMorph but this is not an editor like I understood it, but rather a helper object that will come handy with TextMorph>>handleInteraction: interactionBlock

Inside handleInteraction, there is that editor and paragraph and then a call to interaction blockValue.

And the interactionBlock is containing a bunch of various things that delegate the real editing work to the editor.

Like in aTextMorph>>handleInteraction: [editor mouseUp: evt]

If you then look into the editor (mostly SmalltalkEditor right now in the image), you see a quite large method for that mouseUp: evt handling. And lots of other things.

There should be a cleanup occuring in the Editor -> TextEditor -> SmalltalkEditor hierarchy.

The TextEditor knows a bit too much and I am currently implementing a child of TextEditor to have a simple, clean editor that does only the basics for my purpose. Once I am please with it, it may become an interesting child of Editor (maybe the TextEditor itself, with TextEditor renamed to something else (for example, TextEditor has something with codeCompletionAround).

TextEditor and friends do have a ton of class side methods with all the commands, keystrokes, and menu entries. Very important to grasp how that works.

The TextMorph>>editorClass returns the editor class to use. Currently the SmalltalkEditor (yikes!)

If gets taken in TextMorph>>installEditorToReplace: priorEditor, where we get editor := self editorClass forMorph: self.

digging further, we get TextEditor>>forMorph: aMorph returning

^self basicNew initWithMorph: aMorph.

and ... we'll get there! ... TextEditor>>initWithMorph: aMorph

super initialize.
morph := aMorph.
self resetState.

So, we now have both linked. 

That dance occurs everytime we get something occuring to the TextMorph.

>>handleEvent: anEvent will do anEvent sendTo: self and then the usual:

evt sendTo: anObject, which will handle the event with ^anObjject handleMouseUp, donw, ...

That is where we get back to the self handleInteraction: evt which calls the [editor mouseUp: evt]  through the TextMorph handleInteraction.

An interesting bit occurs with the TextMorph>>yellowActivity; shiftKeyState for the menus (and the PragmaMenuBuilder and strings like 'smalltalkMenu' looking into SmallTalk editor for menu entries (Class side, yellowButtonMenu and shifted friend).

That's it for editor, except we need to say a word on its lifecyle:

It gets created and destroyed all the time: created with TextMorph>>hasFocus, going away with keyBoardFocusChange


Then for Paragraph, just realize that Paragraphis something to be used like;

Paragraph new
  compose: text "Coming from the TextMorph"
  style: textStyle copy "always copy these beasties"
  from: 1
  in (0@0 extent: extX@extY);
  adjustRightX;
  ...

So, the Paragraph is composing the text into an area, taking into account the styles that are in the text The TextStyle is the default style, it can be overriden by some TextAttribute.

And that's where the TextMorph>>drawOn: aCanvas comes into play.

if will invoke Canvas>>paragraph: which will draw the text.

This will lead us to CharacterScanner and friends (CompositionScanner) and TextComposer depending on it.

look for composeLineFrom: to: .... or composeAllLines.

This will call Paragraph>>composeAll

^self multiComposeLinesFrom: firstCharIndex
to: text size
delta: 0
into: OrderedCollection new "Ah, there we will end up into"
priorLines: Array new
atY: container top.


So, it may be interesting to see how Paragraph works, but paragraph has nothing to do with Editor.

Paragraph renders the text if an editing change has to be shown display wise. But doesn't know about the Editor.

TextMorph uses TextMorph>>updateFromParagraph and >>fit to do the stuff.

In CharacterScanner you can find interesting display code:

CharacterScanner>>basicScanCharactersFrom: startIndex
  to: stopIndex
  in: sourceString
  rightX: rightX
  stopConditions: stops "this one still a tad foggy to me"
  kern: kernDelta

There is a primitive rendering a char down there. This is all for StrikeFont. I don't know how TrueType is supported but there are 

As you are doing Vim keystrokes, check TextMorph>>basicKeyStroke that does the same dance as the mouse events but invokes 

self handleInteraction: [editor keystroke evt] 
self updateFromParagraph.
super keystroke: evt.

So, hope this makes it all a bit clearer.

All of the PluggableTextMorph story builds upon all of the above to ensure a scrolling window and widget pluggability. Which I do not care at this point since I am designing a specific UI for a game.

Phil

2012/7/18 Stéphane Ducasse <[hidden email]>

On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:

> For VimPharo, I want to have a different cursor depending on whether a tool
> is in insert or normal mode.
>
> I tried a handful of ways, but they all failed or worked
> partially/inconsistently. Here's some of them:
> * add the state to the paragraph, but the entire paragraph gets replaced
> during the life of the tool, so the state gets lost
> * add the state to the editor, but the situation is the same
> * add the state to PluggableTextMorph, override and access it from
> TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
> me very acquainted with the emergency evaluator. It "worked", but only after
> using the arrows a bit.
>
> Does anyone have any idea where I might hook in?
>
> <rant>I find the whole text system very confusing. What the heck does a
> paragraph know about insertion points?? A view has one paragraph object,
> even if there are several paragraphs (as understood by the rest of humanity
> as a block of text with breaks between the adjoining ones. Editors and
> Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
> to understand and modify</rant>

I got burned by that when I worked on my botanics env….
it was terrible.

>
> Thanks,
> Sean
>
> --
> View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>





Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

philippeback
In reply to this post by Fernando olivero-2
I wouldn't do that for basic morphs as it would make Cairo necessary and then make completely ununderstandable what happens for laying out text for someone who wants to understand it (which is an important aspect of an open smalltalk image).

TextMorph>>onBlinkCursor leads you to Paragraph (of course since it deals with the display)

onBlinkCursor
"Blink the cursor"
| para |
para := self paragraph ifNil:[^nil].
Time millisecondClockValue < self blinkStart ifTrue:[
"don't blink yet"
^para showCaret: para focused.
].
para showCaret: para showCaret not.
para caretRect ifNotNil:[:r| self invalidRect: r].

so, para>>focused if where to look (but it is only a variable change so, you'll need to track the usage)

Phil

2012/7/20 Fernando Olivero <[hidden email]>
Hi Sean, you can take a look at Athens-PangoCairo (in squeaksource).

Using NativeBoost, i'm using the Pango layout library [1], and the
Pango-Cairo binding [2],  to avoid laying out text using the outdated
(and messy) stuff in the image.

Check out the classes: ParagraphDescription & AthensPangoCairoParagraph.

I'm using them as the basis for the TextShape,LabelShape, and
EditableTextShape in Shapes / Gaucho ( using TextEditor,
SingleLineEditor ).

Maybe somebody can do the same for Morphic? use Pango to layout the
text, and code a new TextMorph on top of it?

Fernando

[1] http://developer.gnome.org/pango/stable/pango-Layout-Objects.html
[2] http://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html
On Wed, Jul 18, 2012 at 7:28 AM, Stéphane Ducasse
<[hidden email]> wrote:
>
> On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:
>
>> For VimPharo, I want to have a different cursor depending on whether a tool
>> is in insert or normal mode.
>>
>> I tried a handful of ways, but they all failed or worked
>> partially/inconsistently. Here's some of them:
>> * add the state to the paragraph, but the entire paragraph gets replaced
>> during the life of the tool, so the state gets lost
>> * add the state to the editor, but the situation is the same
>> * add the state to PluggableTextMorph, override and access it from
>> TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
>> me very acquainted with the emergency evaluator. It "worked", but only after
>> using the arrows a bit.
>>
>> Does anyone have any idea where I might hook in?
>>
>> <rant>I find the whole text system very confusing. What the heck does a
>> paragraph know about insertion points?? A view has one paragraph object,
>> even if there are several paragraphs (as understood by the rest of humanity
>> as a block of text with breaks between the adjoining ones. Editors and
>> Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
>> to understand and modify</rant>
>
> I got burned by that when I worked on my botanics env….
> it was terrible.
>
>>
>> Thanks,
>> Sean
>>
>> --
>> View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
>> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Denis Kudriashov
In reply to this post by Fernando olivero-2
Hello

2012/7/20 Fernando Olivero <[hidden email]>
Hi Sean, you can take a look at Athens-PangoCairo (in squeaksource).

Using NativeBoost, i'm using the Pango layout library [1], and the
Pango-Cairo binding [2],  to avoid laying out text using the outdated
(and messy) stuff in the image.

Check out the classes: ParagraphDescription & AthensPangoCairoParagraph.

I'm using them as the basis for the TextShape,LabelShape, and
EditableTextShape in Shapes / Gaucho ( using TextEditor,
SingleLineEditor ).

Maybe somebody can do the same for Morphic? use Pango to layout the
text, and code a new TextMorph on top of it?

How I can try your code?
Do you have ready image to play with it?

I am very interested with clean and simple alternative to morphic. I want it for Presenty framework.

(But I really like morphic as live user interface environment)

Best regards,
Denis



Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

philippeback
So, there is the damn caret drawing code:

Paragraph>>displaySelectionInLine: line on: aCanvas 
| leftX rightX w caretColor |
selectionStart ifNil: [^self]. "No selection"
aCanvas isShadowDrawing ifTrue: [ ^self ]. "don't draw selection with shadow"
selectionStart = selectionStop 
ifTrue: 
["Only show caret on line where clicked"

selectionStart textLine ~= line ifTrue: [^self]]
ifFalse: 
["Test entire selection before or after here"

(selectionStop stringIndex < line first 
or: [selectionStart stringIndex > (line last + 1)]) ifTrue: [^self]. "No selection on this line"
(selectionStop stringIndex = line first 
and: [selectionStop textLine ~= line]) ifTrue: [^self]. "Selection ends on line above"
(selectionStart stringIndex = (line last + 1) 
and: [selectionStop textLine ~= line]) ifTrue: [^self]]. "Selection begins on line below"
leftX := (selectionStart stringIndex < line first 
ifTrue: [line ]
ifFalse: [selectionStart ])left.
rightX := (selectionStop stringIndex > (line last + 1) or: 
[selectionStop stringIndex = (line last + 1) 
and: [selectionStop textLine ~= line]]) 
ifTrue: [line right]
ifFalse: [selectionStop left].
selectionStart = selectionStop 
ifTrue: 
[rightX := rightX + 1.
w := self caretWidth.
caretRect := (leftX-w) @ line top corner: (rightX+w)@ line bottom.
self showCaret ifFalse:[^self].
caretColor := self insertionPointColor.
1 to: w
do: 
[:i | 
"Draw caret triangles at top and bottom"

aCanvas fillRectangle: ((leftX - w + i - 1) @ (line top + i - 1) 
extent: ((w - i) * 2 + 3) @ 1)
color: caretColor.
aCanvas fillRectangle: ((leftX - w + i - 1) @ (line bottom - i) 
extent: ((w - i) * 2 + 3) @ 1)
color: caretColor].
aCanvas fillRectangle: (leftX @ line top corner: rightX @ line bottom)
color: caretColor]
ifFalse: 
[caretRect := nil.
aCanvas fillRectangle: (leftX @ line top corner: rightX @ line bottom)
color: self selectionColor]




Paragraph class>>insertionPointColor has the color. I was fed up of blue, turned it red :-)
This one is hardcoded and could take a hint from the selection color twiceDarker for example.

Phil

2012/7/20 Denis Kudriashov <[hidden email]>
Hello

2012/7/20 Fernando Olivero <[hidden email]>
Hi Sean, you can take a look at Athens-PangoCairo (in squeaksource).

Using NativeBoost, i'm using the Pango layout library [1], and the
Pango-Cairo binding [2],  to avoid laying out text using the outdated
(and messy) stuff in the image.

Check out the classes: ParagraphDescription & AthensPangoCairoParagraph.

I'm using them as the basis for the TextShape,LabelShape, and
EditableTextShape in Shapes / Gaucho ( using TextEditor,
SingleLineEditor ).

Maybe somebody can do the same for Morphic? use Pango to layout the
text, and code a new TextMorph on top of it?

How I can try your code?
Do you have ready image to play with it?

I am very interested with clean and simple alternative to morphic. I want it for Presenty framework.

(But I really like morphic as live user interface environment)

Best regards,
Denis






--
Philippe Back
Dramatic Performance Improvements
Mob: +32(0) 478 650 140 | Fax: +32 (0) 70 408 027 Mail: [hidden email] | Web: http://philippeback.eu | Blog: http://philippeback.be

High Octane SPRL
rue cour Boisacq 101
1301 Bierges
Belgium
Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Fernando olivero-2
In reply to this post by Denis Kudriashov
Hi Phil. Excellent summary of the current mess!

Yes, TextMorphs are the "views" , Editors handle the
insertion/selection/menu logic, and Paragraphs lay out the text.

I've replaced Paragraph, with Pango Layouts to reuse a more
customizable layout engine, until some kind soul rewrites completely
Paragraph (and friends) to be as easy to use (and powerfull) as Pango
(which i doubt it will happen in the next decade).


Denis, unfortunately i had to handle other stuff related to my phd,
and still couldn't release Gaucho/Shapes, I'm working on it now again.
Here's a presentation i gave @ the pharo conf [1]. Glad to hear that
you want to try to use it for Presently, will be out soon.

[1] http://app.sliderocket.com:80/app/FullPlayer.aspx?id=fcff251e-29cd-49eb-89b3-e33349139ddf




On Fri, Jul 20, 2012 at 4:26 PM, [hidden email] <[hidden email]> wrote:

> So, there is the damn caret drawing code:
>
> Paragraph>>displaySelectionInLine: line on: aCanvas
> | leftX rightX w caretColor |
> selectionStart ifNil: [^self]. "No selection"
> aCanvas isShadowDrawing ifTrue: [ ^self ]. "don't draw selection with shadow"
> selectionStart = selectionStop
> ifTrue:
> ["Only show caret on line where clicked"
>
> selectionStart textLine ~= line ifTrue: [^self]]
> ifFalse:
> ["Test entire selection before or after here"
>
> (selectionStop stringIndex < line first
> or: [selectionStart stringIndex > (line last + 1)]) ifTrue: [^self]. "No selection on this line"
> (selectionStop stringIndex = line first
> and: [selectionStop textLine ~= line]) ifTrue: [^self]. "Selection ends on line above"
> (selectionStart stringIndex = (line last + 1)
> and: [selectionStop textLine ~= line]) ifTrue: [^self]]. "Selection begins on line below"
> leftX := (selectionStart stringIndex < line first
> ifTrue: [line ]
> ifFalse: [selectionStart ])left.
> rightX := (selectionStop stringIndex > (line last + 1) or:
> [selectionStop stringIndex = (line last + 1)
> and: [selectionStop textLine ~= line]])
> ifTrue: [line right]
> ifFalse: [selectionStop left].
> selectionStart = selectionStop
> ifTrue:
> [rightX := rightX + 1.
> w := self caretWidth.
> caretRect := (leftX-w) @ line top corner: (rightX+w)@ line bottom.
> self showCaret ifFalse:[^self].
> caretColor := self insertionPointColor.
> 1 to: w
> do:
> [:i |
> "Draw caret triangles at top and bottom"
>
> aCanvas fillRectangle: ((leftX - w + i - 1) @ (line top + i - 1)
> extent: ((w - i) * 2 + 3) @ 1)
> color: caretColor.
> aCanvas fillRectangle: ((leftX - w + i - 1) @ (line bottom - i)
> extent: ((w - i) * 2 + 3) @ 1)
> color: caretColor].
> aCanvas fillRectangle: (leftX @ line top corner: rightX @ line bottom)
> color: caretColor]
> ifFalse:
> [caretRect := nil.
> aCanvas fillRectangle: (leftX @ line top corner: rightX @ line bottom)
> color: self selectionColor]
>
>
>
>
> Paragraph class>>insertionPointColor has the color. I was fed up of blue, turned it red :-)
> This one is hardcoded and could take a hint from the selection color twiceDarker for example.
>
> Phil
>
> 2012/7/20 Denis Kudriashov <[hidden email]<mailto:[hidden email]>>
> Hello
>
> 2012/7/20 Fernando Olivero <[hidden email]<mailto:[hidden email]>>
> Hi Sean, you can take a look at Athens-PangoCairo (in squeaksource).
>
> Using NativeBoost, i'm using the Pango layout library [1], and the
> Pango-Cairo binding [2],  to avoid laying out text using the outdated
> (and messy) stuff in the image.
>
> Check out the classes: ParagraphDescription & AthensPangoCairoParagraph.
>
> I'm using them as the basis for the TextShape,LabelShape, and
> EditableTextShape in Shapes / Gaucho ( using TextEditor,
> SingleLineEditor ).
>
> Maybe somebody can do the same for Morphic? use Pango to layout the
> text, and code a new TextMorph on top of it?
>
> How I can try your code?
> Do you have ready image to play with it?
>
> I am very interested with clean and simple alternative to morphic. I want it for Presenty framework.
>
> (But I really like morphic as live user interface environment)
>
> Best regards,
> Denis
>
>
>
>
>
>
> --
> Philippe Back
> Dramatic Performance Improvements
> Mob: +32(0) 478 650 140 | Fax: +32 (0) 70 408 027 Mail: [hidden email]<mailto:[hidden email]> | Web: http://philippeback.eu | Blog: http://philippeback.be
>
> High Octane SPRL
> rue cour Boisacq 101
> 1301 Bierges
> Belgium

Reply | Threaded
Open this post in threaded view
|

Re: Customizing the Caret of a PluggableTextMorph

Stéphane Ducasse
In reply to this post by philippeback
Phil

Sorry for the state of the system. We are cleaning slowly.
Now what would be good is that if you could enhance the class comments.
Igor started to write a new paragraph (or text representation) I guess that he needs some help/feedback.
Igor should be back from holiday so ping him please :).

Stef

> Ah, the morass into which I am currently digging...
>
> Well, if we look at it for a while, it becomes a tad clearer.
>
> PluggableTextMorph is just a shell for a TextMorph.
>
> The TextMorph basically displays a Text (which can be styled with TextAttributes)
>
> When moving into edition, there is an editor known by the TextMorph but this is not an editor like I understood it, but rather a helper object that will come handy with TextMorph>>handleInteraction: interactionBlock
>
> Inside handleInteraction, there is that editor and paragraph and then a call to interaction blockValue.
>
> And the interactionBlock is containing a bunch of various things that delegate the real editing work to the editor.
>
> Like in aTextMorph>>handleInteraction: [editor mouseUp: evt]
>
> If you then look into the editor (mostly SmalltalkEditor right now in the image), you see a quite large method for that mouseUp: evt handling. And lots of other things.
>
> There should be a cleanup occuring in the Editor -> TextEditor -> SmalltalkEditor hierarchy.
>
> The TextEditor knows a bit too much and I am currently implementing a child of TextEditor to have a simple, clean editor that does only the basics for my purpose. Once I am please with it, it may become an interesting child of Editor (maybe the TextEditor itself, with TextEditor renamed to something else (for example, TextEditor has something with codeCompletionAround).
>
> TextEditor and friends do have a ton of class side methods with all the commands, keystrokes, and menu entries. Very important to grasp how that works.
>
> The TextMorph>>editorClass returns the editor class to use. Currently the SmalltalkEditor (yikes!)
>
> If gets taken in TextMorph>>installEditorToReplace: priorEditor, where we get editor := self editorClass forMorph: self.
>
> digging further, we get TextEditor>>forMorph: aMorph returning
>
> ^self basicNew initWithMorph: aMorph.
>
> and ... we'll get there! ... TextEditor>>initWithMorph: aMorph
>
> super initialize.
> morph := aMorph.
> self resetState.
>
> So, we now have both linked.
>
> That dance occurs everytime we get something occuring to the TextMorph.
>
> >>handleEvent: anEvent will do anEvent sendTo: self and then the usual:
>
> evt sendTo: anObject, which will handle the event with ^anObjject handleMouseUp, donw, ...
>
> That is where we get back to the self handleInteraction: evt which calls the [editor mouseUp: evt]  through the TextMorph handleInteraction.
>
> An interesting bit occurs with the TextMorph>>yellowActivity; shiftKeyState for the menus (and the PragmaMenuBuilder and strings like 'smalltalkMenu' looking into SmallTalk editor for menu entries (Class side, yellowButtonMenu and shifted friend).
>
> That's it for editor, except we need to say a word on its lifecyle:
>
> It gets created and destroyed all the time: created with TextMorph>>hasFocus, going away with keyBoardFocusChange
>
>
> Then for Paragraph, just realize that Paragraphis something to be used like;
>
> Paragraph new
>   compose: text "Coming from the TextMorph"
>   style: textStyle copy "always copy these beasties"
>   from: 1
>   in (0@0 extent: extX@extY);
>   adjustRightX;
>   ...
>
> So, the Paragraph is composing the text into an area, taking into account the styles that are in the text The TextStyle is the default style, it can be overriden by some TextAttribute.
>
> And that's where the TextMorph>>drawOn: aCanvas comes into play.
>
> if will invoke Canvas>>paragraph: which will draw the text.
>
> This will lead us to CharacterScanner and friends (CompositionScanner) and TextComposer depending on it.
>
> look for composeLineFrom: to: .... or composeAllLines.
>
> This will call Paragraph>>composeAll
>
> ^self multiComposeLinesFrom: firstCharIndex
> to: text size
> delta: 0
> into: OrderedCollection new "Ah, there we will end up into"
> priorLines: Array new
> atY: container top.
>
>
> So, it may be interesting to see how Paragraph works, but paragraph has nothing to do with Editor.
>
> Paragraph renders the text if an editing change has to be shown display wise. But doesn't know about the Editor.
>
> TextMorph uses TextMorph>>updateFromParagraph and >>fit to do the stuff.
>
> In CharacterScanner you can find interesting display code:
>
> CharacterScanner>>basicScanCharactersFrom: startIndex
>   to: stopIndex
>   in: sourceString
>   rightX: rightX
>   stopConditions: stops "this one still a tad foggy to me"
>   kern: kernDelta
>
> There is a primitive rendering a char down there. This is all for StrikeFont. I don't know how TrueType is supported but there are
>
> As you are doing Vim keystrokes, check TextMorph>>basicKeyStroke that does the same dance as the mouse events but invokes
>
> self handleInteraction: [editor keystroke evt]
> self updateFromParagraph.
> super keystroke: evt.
>
> So, hope this makes it all a bit clearer.
>
> All of the PluggableTextMorph story builds upon all of the above to ensure a scrolling window and widget pluggability. Which I do not care at this point since I am designing a specific UI for a game.
>
> Phil
>
> 2012/7/18 Stéphane Ducasse <[hidden email]>
>
> On Jul 16, 2012, at 9:38 PM, Sean P. DeNigris wrote:
>
> > For VimPharo, I want to have a different cursor depending on whether a tool
> > is in insert or normal mode.
> >
> > I tried a handful of ways, but they all failed or worked
> > partially/inconsistently. Here's some of them:
> > * add the state to the paragraph, but the entire paragraph gets replaced
> > during the life of the tool, so the state gets lost
> > * add the state to the editor, but the situation is the same
> > * add the state to PluggableTextMorph, override and access it from
> > TextMorphForEditView>>updateFromParagraph. This was an extreme PITA and got
> > me very acquainted with the emergency evaluator. It "worked", but only after
> > using the arrows a bit.
> >
> > Does anyone have any idea where I might hook in?
> >
> > <rant>I find the whole text system very confusing. What the heck does a
> > paragraph know about insertion points?? A view has one paragraph object,
> > even if there are several paragraphs (as understood by the rest of humanity
> > as a block of text with breaks between the adjoining ones. Editors and
> > Paragraphs are thrown out and replaced on a whim. I'm finding it very hard
> > to understand and modify</rant>
>
> I got burned by that when I worked on my botanics env….
> it was terrible.
>
> >
> > Thanks,
> > Sean
> >
> > --
> > View this message in context: http://forum.world.st/Customizing-the-Caret-of-a-PluggableTextMorph-tp4640245.html
> > Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
> >
>
>
>
>
>