How childrenBlock: in TreeModel works

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

How childrenBlock: in TreeModel works

chrismihaylyk
Hi!

Could anyone explain me how works childrenBlock: method from TreeModel? step-by-step.
What data it operates? How makes a result?

Thanks a lot? Khrystyna.

Reply | Threaded
Open this post in threaded view
|

Re: How childrenBlock: in TreeModel works

Peter Uhnak
Hi,

I wanted to point you to the new Spec book ( http://files.pharo.org/books-pdfs/spec/2017-01-23-SpecBooklet.pdf ), but apprently it's not there.

Many Spec widgets have examples accompanying them, so always check class side (not for all though). For TreeModel you can see couple there - good for playing around; e.g.

exampleWithNoSpecifiedNodes
        "self exampleWithNoSpecifiedNodes"
        TreeModel new
                roots: (1 to: 5);
                childrenBlock: [ :item | 1+item to: 5+item ];
                openWithSpec

You specify the initial data (root nodes) via the `roots:` message.
The `childrenBlock:` then specifies how one would retrieve data given a particular node; note that this  applies to _any node_, not just the root ones; so you can have potentially infinitely deep trees.

A more complex example could be this (this is awful code for demonstration only ;):

TreeModel new
        roots: {#parent. #childless. 20. #root -> #(a b c)};
        childrenBlock: [ :item |
                item isSymbol ifTrue: [
                        item = #parent
                                ifTrue: [ #(child1 child2) ]
                                ifFalse: [ #() ]
                ] ifFalse: [
                        item isNumber
                                ifTrue: [ {item + 2. item ** 2} ]
                                ifFalse: [ "association" item value ]
                ]
        ];
        openWithSpec


Peter

On Sat, Apr 01, 2017 at 06:49:41AM -0700, chrismihaylyk wrote:

> Hi!
>
> Could anyone explain me how works childrenBlock: method from TreeModel?
> step-by-step.
> What data it operates? How makes a result?
>
> Thanks a lot? Khrystyna.
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-childrenBlock-in-TreeModel-works-tp4940884.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|

Re: How childrenBlock: in TreeModel works

chrismihaylyk
Now I understand. Thank you very much! =)

2017-04-01 17:48 GMT+03:00 Peter Uhnak <[hidden email]>:
Hi,

I wanted to point you to the new Spec book ( http://files.pharo.org/books-pdfs/spec/2017-01-23-SpecBooklet.pdf ), but apprently it's not there.

Many Spec widgets have examples accompanying them, so always check class side (not for all though). For TreeModel you can see couple there - good for playing around; e.g.

exampleWithNoSpecifiedNodes
        "self exampleWithNoSpecifiedNodes"
        TreeModel new
                roots: (1 to: 5);
                childrenBlock: [ :item | 1+item to: 5+item ];
                openWithSpec

You specify the initial data (root nodes) via the `roots:` message.
The `childrenBlock:` then specifies how one would retrieve data given a particular node; note that this  applies to _any node_, not just the root ones; so you can have potentially infinitely deep trees.

A more complex example could be this (this is awful code for demonstration only ;):

TreeModel new
        roots: {#parent. #childless. 20. #root -> #(a b c)};
        childrenBlock: [ :item |
                item isSymbol ifTrue: [
                        item = #parent
                                ifTrue: [ #(child1 child2) ]
                                ifFalse: [ #() ]
                ] ifFalse: [
                        item isNumber
                                ifTrue: [ {item + 2. item ** 2} ]
                                ifFalse: [ "association" item value ]
                ]
        ];
        openWithSpec


Peter

On Sat, Apr 01, 2017 at 06:49:41AM -0700, chrismihaylyk wrote:
> Hi!
>
> Could anyone explain me how works childrenBlock: method from TreeModel?
> step-by-step.
> What data it operates? How makes a result?
>
> Thanks a lot? Khrystyna.
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-childrenBlock-in-TreeModel-works-tp4940884.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: How childrenBlock: in TreeModel works

chrismihaylyk
Hello!

Could anyone help me, please?

I have faced with a problem of TreeModel childrenBlock: for more complex build in structure.

For example, I have anOrderedCollection of Dictionary, and in each dictionary, there are exist associations, which values are      anArray(aDictionary, aDictionary ...).

I need to make drop downs for all of these entire levels of arrays and dictionaries.
For first level I made it:

collectionsList
                ifNil: [ ^ nil ]
                ifNotNil: [ collectionsList hasChildrenBlock: [ :item | item isMyDictionary. ].
                        collectionsList
                                childrenBlock: [ :item | item associations
                                                                collect: [ :assoc |
                                                                        assoc key asString , '  ->  ' , assoc value asString. ] ] ]

MyDictionaly is the class, inherited from Dictionary, just to override method printOn:

At the first picture, it's how it looks like, how I made it.
At the second - how I expect it to be (taken from Inspector window).

Thanks a lot!


Reply | Threaded
Open this post in threaded view
|

Re: How childrenBlock: in TreeModel works

Peter Uhnak
I guess something like this could work...

```
d := {
        Dictionary
                with: #n -> 'whatever'
                with: #d -> {
                        Dictionary with: #a -> #AA with: #b -> #BB.
                        Dictionary with: #c -> #CC with: #d -> #DD
                }.

        Dictionary
                with: #n -> 'wherever'
                with: #d -> {
                        Dictionary
                                with: #a -> #AA
                                with: #b -> #BB.
                        Dictionary with: #c -> #CC with: #d -> #DD
                }.
}.

TreeModel new
        roots: d;
        childrenBlock: [ :item |
                item isDictionary
                        ifTrue: [
                                item associations flatCollect: [ :pair |
                                        pair value isArray
                                                ifTrue: [ pair value ]
                                                ifFalse: [ {pair} ].
                                ]
                        ]
                        ifFalse: [ #() ]
        ];
        openWithSpec
```

but forcing this much behavior is a bad practice... because it's hard to read, hard to understand, and hard to test.

So I suggest using custom classes as nodes (so each node can simply tell what its children are), and then delegate the retrieval... you could also add extension methods to the respective classes' protocols to acheive the same...

TreeModel new
        childrenBlock: [ :item |
                item children
        ];
        displayBlock: [ :item |
                item name
        ]

Peter


On Mon, Apr 17, 2017 at 09:12:47AM -0700, chrismihaylyk wrote:

> Hello!
>
> Could anyone help me, please?
>
> I have faced with a problem of TreeModel childrenBlock: for more complex
> build in structure.
>
> For example, I have anOrderedCollection of Dictionary, and in each
> dictionary, there are exist associations, which values are    
> anArray(aDictionary, aDictionary ...).
>
> I need to make drop downs for all of these entire levels of arrays and
> dictionaries.
> For first level I made it:
>
> collectionsList
> ifNil: [ ^ nil ]
> ifNotNil: [ collectionsList hasChildrenBlock: [ :item | item
> isMyDictionary. ].
> collectionsList
> childrenBlock: [ :item | item associations
> collect: [ :assoc |
> assoc key asString , '  ->  ' , assoc value asString. ] ] ]
>
> MyDictionaly is the class, inherited from Dictionary, just to override
> method printOn:
>
> At the first picture, it's how it looks like, how I made it.
> At the second - how I expect it to be (taken from Inspector window).
>
> Thanks a lot!
> <http://forum.world.st/file/n4942409/before.jpg>
> <http://forum.world.st/file/n4942409/after.jpg>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-childrenBlock-in-TreeModel-works-tp4940884p4942409.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>