b...@openinworld.com wrote:
Benjamin wrote:
> Ben
>
> On Oct 11, 2013, at 9:24 AM, b...@openinworld.com wrote:
>
> >> b...@openinworld.com wrote: >> >>> I found it hard to find documentation on Spec beyond [1],[2],[3], some of which seem to have changed some syntax since they were written. I've been piecing things together to work out how to set the selected item with the simplest example I could. Even though it turns out pretty simple, I thought I'd share in case it was useful for others that haven't dipped their toes into Spec yet.
>>>
>>> ComposableModel subclass: #TestSpec
>>> instanceVariableNames: 'list text'
>>> classVariableNames: ''
>>> poolDictionaries: ''
>>> category: 'BTCPlay'
>>>
>>> TestSpec >> initializeWidgets
>>> self instantiateModels: #( #list #ListModel ).
>>>
>>> TestSpec >> getList
>>> ^list
>>>
>>> TestSpec class >> mySpecLayout
>>> <spec:#default>
>>> ^ SpecLayout composed
>>> add:#getList ;
>>> yourself.
>>>
>>> Then from Workspace
>>> x := (TestSpec new openWithSpec ; yourself).
>>> x getList items: { 1 . 2 . 3 . 4}.
>>> x getList setSelectedItem: 2.
>>>
>>> cheers -ben
>>>
>>> [1] hal.inria.fr/hal-00759030/PDF/Spec-IWST12-Final.pdf‎
>>> [2] https://ci.inria.fr/pharo-contribution/job/PharoForTheEnterprise/lastSuccessfulBuild/artifact/Spec/Spec.pier.pdf >>> [3] http://hal.inria.fr/docs/00/70/80/67/PDF/SpecTechReport.pdf
>>>
>>>
>>>
>>> >> So here is the same thing with TreeModel.
>>
>> ComposableModel subclass: #TestSpec2
>>   instanceVariableNames: 'tree'
>>   classVariableNames: ''
>>   poolDictionaries: ''
>>   category: 'BTCPlay'
>>
>> TestSpec2 >> initializeWidgets
>>   self instantiateModels: #( #tree #TreeModel ).      tree
>>       childrenBlock: [  :treeItem | self haltOnce. (treeItem isKindOf: 
Association) ifTrue: [ treeItem value ] ifFalse: [ {} ] ].
>>
>> TestSpec2 >> getTree
>>   ^tree
>>
>> TestSpec2 class >> mySpecLayout
>>   <spec:#default>
>>   ^ SpecLayout composed
>>       add:#getTree ;
>>       yourself.
>>
>> Then from Workspace (referring to attached pic)
>> x := (TestSpec2 new openWithSpec ; yourself).
>> x getTree roots: {  10 -> {  11. 12 } . 20 -> { 21 . 22 }  } .
>> x getTree selectedItem.  "<Print It> --> 21 "
>> x getTree selectedItem: ????
>>
>> Now how do I select a particular tree item at each level ?
>> eg. Select 10 and Select 12 ?
>>
>> cheers, ben
>> >
> There was something missing here at the two levels :)
> You can see case 11849[1] fixing the morphic issue
> and case 11850 [2] fixing the Spec problem :)
> Thanks. I'll try it. > Then your example make me think that using association > to describe the path may lead to an ambiguous situation > True. But to clarify things, ListModel suffers the same ambiguity as follows...
x := (TestSpec new openWithSpec ; yourself).
x getList items: { 1 . 2 . 3 . 2 . 4}.
x getList setSelectedItem: 2.

... ListModel and Treemodel should be consistent in this respect.
Musing further about this...
In the case of a multi-selection ListModel/TreeModel, it is probably reasonable to select all matching. For a single-selection, I'm not sure. Considering ListModel first, maybe defaulting to selecting the first matching is reasonable, perhaps with a backup method to select the Nth match. Then again, if the identical object appears in the list multiple times, then #setSelectedItem: might visually highlight all occurances while still reporting only a single object with #selectedItems. I think part of a test would go...

x getList items: { 1 . 2 . 3 . 2 . 4}.
x getList setSelectedItem: 2.
y := x getList selectedItem.
x getList setSelectedItem: y.
z := x getList selectedItem.
self assert: (y = z)

...which actually works so ListModel is cool in that regard - except maybe an option to visually highlight both 2s would be useful - but as a visual thing maybe that is a handled outside of ListModel.
Actually that should work the same with multi-selection.

x getList items: { 1 . 2 . 3 . 2 . 4}.
x getList setSelectedItems: { 2. 3 }.
y := x getList selectedItems.
x getList setSelectedItems: y.
z := x getList selectedItems.
self assert: (y = z)

Actually it seems there is no #setSelectedItems:.
How then do you save and restore a multi-selection.  e.g....
savedSelection := x getList selectedItems.
"other code that clears/modifies the selection - like refresh for additional 
items"
 x getList selectedItems: savedSelection.

cheers -ben

> Ben
>
> [1] https://pharo.fogbugz.com/default.asp?11849
> [2] https://pharo.fogbugz.com/default.asp?11850
>
> >>
>> <Spec-TreeModel-simple-example.png>
>> >
>
>
I installed your slices from Issues 11849 & 11850 and it looks mostly good.

Using a modified TreeModel example which I think provides a clearer/nicer example...

TestSpec2 >> initializeWidgets
self instantiateModels: #( #tree #TreeModel ). tree childrenBlock: [ :treeItem | (treeItem > 10000) ifTrue: [ #() ] ifFalse: [ (1 to: 3) collect: [ :i | treeItem * 10 + i ] ] ].

Then in Workspace...
x := (TestSpec2 new openWithSpec ; yourself).
x getTree roots: {  1. 2 . 1 . 11 }.
x getTree expandRoots.
x getTree selectedItem: 11.  "left side of attached pic"
x getTree selectedItem: (1 -> 11).   "right side of attached pic"

So the attached pic shows exhibits the behaviour I was musing about earlier - very cool. Before those slices there was no response to #selectedItem: from the widget.
However a couple of things...

1. x getTree selectedItem: 12.
   x getTree selectedItem.  "<PrintIt> --> 12"
while...
   x getTree selectedItem: ( 1 -> 13 ).
   x getTree selectedItem.  "<PrintIt> --> 1->13"

I think you really want #selectedItem to return the same thing each time regardless of how it was set. That is, just the object. Andn further, it would be better to have a separate accessors #selectedItem and #selectedPath

2. The following doesn't work...
   x getTree selectedItem:  { 1 -> 12 -> 121 }.

cheers -ben





<<inline: Issue-11849&11850.png>>

Reply via email to