A convenience for PluggableTextAttribute

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

A convenience for PluggableTextAttribute

Eliot Miranda-2
Hi All, Hi Marcel,

  let's imagine you want to emphasize a text with PluggableTextAttributes and you want to emphasize/print the text as quickly as possible and defer interpreting the text until later. Let's imagine that each substring you're emphasizing is a number that needs parsing to get the numeric value.  What you *don't* want to do is to create a PluggableTextAttribute for every different numeric substring.  What you'd like instead is use a single PlyggableTextAttribute for all such substrings and do the parsing when a particular numeric substring is selected.  To do this you'll need to change PluggableTextAttribute because by default if its actionBlock takes an argument the block is evaluated with the model.

This is exactly what I wanted today for inspecting objects in the VM simulator.  Here I want to click on an oop, which may be one of many in a large text, and have this result in a subsequent inspector pop up (actually an inform: which can be inspected or discarded.  Otherwise I have to create a different PluggableTextAttribute for every oop in the text, and that's slow and difficult.

So to be able to write this:

CogOopInspector>>text
^Text streamContents:
[:s| coInterpreter printOop: oop on: s oopAttribute: (PluggableTextAttribute evalBlock: [:myself :oopString| self interpretOopString: oopString])]

where each oop that printOop:on:oopAttribute: gets emphasized with one PluggableTextAttribute, deferring the costly parsing until the click (which is the right time, because that's the time when there's a costly UI action to perform),

I had to add this override to PluggableTextAttribute:

PluggableTextAttribute>>actOnClickFor: model in: aParagraph at: clickPoint
"Override to pass in the string with this attribute to the block if it takes two arguments."
| range |
(evalBlock notNil and: [evalBlock numArgs = 2]) ifFalse:
[^super actOnClickFor: model in: aParagraph at: clickPoint].
range := aParagraph text
rangeOf: self
startingAt: (aParagraph characterBlockAtPoint: clickPoint) stringIndex.
evalBlock value: model value: (aParagraph text string copyFrom: range first to: range last).
^true

For now I'll keep this as an extension in the VMMakerUI package.  But I think it is generally useful and should go in the base.  Do you agree?  If so, I'll try and remember ti add it after the release.
_,,,^..^,,,_
best, Eliot