Spec Lists - setting the selection

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

Spec Lists - setting the selection

Ben Coman

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


Reply | Threaded
Open this post in threaded view
|

Re: Spec Lists - setting the selection

Stéphane Ducasse
Yes we need to stabilize it and get a real document.


On Oct 11, 2013, at 8:23 AM, [hidden email] 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
>
>


Reply | Threaded
Open this post in threaded view
|

Simple Spec Examples (was: Spec Lists - setting the selection)

Ben Coman
In reply to this post by Ben Coman
[hidden email] 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




Spec-TreeModel-simple-example.png (11K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Spec Lists - setting the selection

Benjamin Van Ryseghem (Pharo)
In reply to this post by Ben Coman
Thanks for the example :)

Indeed, the documentation is a bit outdated since Spec is still improving a lot,
a changing a bit in its API.

One of my goal now is to write proper doc for Spec :)

Ben

On Oct 11, 2013, at 8:23 AM, [hidden email] 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 ).

this could be changed in:

list := self newList. 


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



Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples (was: Spec Lists - setting the selection)

Benjamin Van Ryseghem (Pharo)
In reply to this post by Ben Coman


Ben

On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:

[hidden email] 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 :)

Then your example make me think that using association 
to describe the path may lead to an ambiguous situation

Ben





<Spec-TreeModel-simple-example.png>

Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Ben Coman
Benjamin wrote:
Ben

On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:

  
[hidden email] 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>
    


  

Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Ben Coman
In reply to this post by Benjamin Van Ryseghem (Pharo)
Benjamin wrote:
Ben

On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:

  
[hidden email] 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 :)

Then your example make me think that using association 
to describe the path may lead to an ambiguous situation
  

btw, random (likely improbable) idea - could Path from FileSystem could be reused, or part of it made more generic ? 
cheers -ben

Ben

[1] https://pharo.fogbugz.com/default.asp?11849
[2] https://pharo.fogbugz.com/default.asp?11850

  

<Spec-TreeModel-simple-example.png>
    


  

Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Ben Coman
In reply to this post by Ben Coman
[hidden email] wrote:

> Benjamin wrote:
> > Ben
> >
> > On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:
> >
> >  
> >> [hidden email] 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 (20K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Camillo Bruni-3
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, [hidden email] wrote:

> [hidden email] wrote:
>> Benjamin wrote:
>> > Ben
>> >
>> > On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:
>> >
>> >   >> [hidden email] 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>


signature.asc (457 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

jfabry

I agree with Camillo in that I think it would be better to use specific selectors, e.g. selectedItem:withParents: as it better reveals the intention.

Just my 2 cents ...

On Oct 11, 2013, at 3:23 PM, Camillo Bruni <[hidden email]> wrote:

> 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, [hidden email] wrote:
>
>> [hidden email] wrote:
>>> Benjamin wrote:
>>>> Ben
>>>>
>>>> On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:
>>>>
>>>>>> [hidden email] 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>
>



---> Save our in-boxes! http://emailcharter.org <---

Johan Fabry   -   http://pleiad.cl/~jfabry
PLEIAD lab  -  Computer Science Department (DCC)  -  University of Chile


Reply | Threaded
Open this post in threaded view
|

Re: Spec Lists - setting the selection

Stéphane Ducasse
In reply to this post by Benjamin Van Ryseghem (Pharo)

On Oct 11, 2013, at 2:47 PM, Benjamin <[hidden email]> wrote:

Thanks for the example :)

Indeed, the documentation is a bit outdated since Spec is still improving a lot,
a changing a bit in its API.

One of my goal now is to write proper doc for Spec :)

youpi!


Ben

On Oct 11, 2013, at 8:23 AM, [hidden email] 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 ).

this could be changed in:

list := self newList. 


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




Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Stéphane Ducasse
In reply to this post by Camillo Bruni-3
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, [hidden email] wrote:
>
>> [hidden email] wrote:
>>> Benjamin wrote:
>>>> Ben
>>>>
>>>> On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:
>>>>
>>>>>> [hidden email] 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 | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Benjamin Van Ryseghem (Pharo)
In reply to this post by Ben Coman
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" <[hidden email]>
Pour : "Any question about pharo is welcome" <[hidden email]>
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, [hidden email] wrote:
> 
>> [hidden email] wrote:
>>> Benjamin wrote:
>>>> Ben
>>>> 
>>>> On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:
>>>> 
>>>>>> [hidden email] 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 | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Ben Coman
In reply to this post by Camillo Bruni-3
Camillo Bruni wrote:
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}
  
I'd vote for reciprocal methods #selectedPath and #selectedPath:
so the output of the first can be fed unmodified into the second.

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, [hidden email] wrote:

  
[hidden email] wrote:
    
Benjamin wrote:
      
Ben

On Oct 11, 2013, at 9:24 AM, [hidden email] wrote:

  >> [hidden email] 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 | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Sean P. DeNigris
Administrator
In reply to this post by Camillo Bruni-3
Camillo Bruni-3 wrote
for me that implies that the tree contains an actual item (1 -> 11).
Yes, not only is it a C-style obfuscation (remember how much confusing the event buffers are!!), but what do you do when the tree is more than two levels? Definitely an object is calling to be born here...
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Benjamin Van Ryseghem (Pharo)
Actually, you can do (1->2 -> 3) if you have multiple levels :)

But clearly I will introduce a real data structure here.
I just wanted to quickly hack it and have something where 
I can do  #head and #tail easily, and keep a simple way to write it :)

Ben

On Oct 12, 2013, at 3:04 PM, Sean P. DeNigris <[hidden email]> wrote:

Camillo Bruni-3 wrote
for me that implies that the tree contains an actual item (1 -> 11).

Yes, not only is it a C-style obfuscation (remember how much confusing the
event buffers are!!), but what do you do when the tree is more than two
levels? Definitely an object is calling to be born here...



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Spec-Lists-setting-the-selection-tp4713776p4714058.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Sean P. DeNigris
Administrator
Benjamin Van Ryseghem-2 wrote
Actually, you can do (1->2 -> 3) if you have multiple levels :)
Oh, a *nested* association! Yes, that's much better ;p
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Simple Spec Examples

Camillo Bruni-3
In reply to this post by Benjamin Van Ryseghem (Pharo)

On 2013-10-12, at 15:37, Benjamin <[hidden email]> wrote:

> Actually, you can do (1->2 -> 3) if you have multiple levels :)
>
> But clearly I will introduce a real data structure here.
> I just wanted to quickly hack it and have something where
> I can do  #head and #tail easily, and keep a simple way to write it :)

sounds familiar ;)

http://en.wikipedia.org/wiki/Cons
http://en.wikipedia.org/wiki/Car_and_cdr

signature.asc (457 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Spec Lists - setting the selection

Ben Coman
In reply to this post by Benjamin Van Ryseghem (Pharo)
Benjamin wrote:
Thanks for the example :)

Indeed, the documentation is a bit outdated since Spec is still improving a lot,
a changing a bit in its API.

One of my goal now is to write proper doc for Spec :)

Ben

On Oct 11, 2013, at 8:23 AM, [hidden email] 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 ).
    

this could be changed in:

list := self newList. 
  

Benjamin,
What are the advantages of doing it one way or the other?
So do you mean that #instantiateModels: will be deprecated?
cheers -ben

  
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