Indeed,  it was just a first try to have something to build a reflection on :-) 

Changing the name is always easier than implementing something new (and it's 
also easier to have the community involved at this level). 

I think that #selectedItem is somehow wrong in the context of a tree. 

I will introduce a specific class to describe a path in the tree 

Ben

----- Reply message -----
De : "Stéphane Ducasse" <stephane.duca...@inria.fr>
Pour : "Any question about pharo is welcome" <pharo-users@lists.pharo.org>
Objet : [Pharo-users] Simple Spec Examples
Date : ven., oct. 11, 2013 21:08

agreed :)


> Would it be possible to change the name of the selector?
> 
> tree selectedItem: (1 -> 11)
> 
> for me that implies that the tree contains an actual item (1 -> 11).
> What you want is maybe, #selectedPath: or #selectedItem:1 withParents:{11}
> 
> My general rule is: Each time you have to use an association or a point you 
> do something wrong..
> It is hard to guess what this association should mean, so either make a 
> domain object to describe
> what you encode in the association or use specific selectors that say what 
> the arguments mean.
> 
> On 2013-10-11, at 19:52, b...@openinworld.com wrote:
> 
>> 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
>> 
>> 
>> 
>> 
>> 
>> <Issue-11849&11850.png>
>

Reply via email to