Spec > TreeModel: Updating the tree selection after a deletion

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

Spec > TreeModel: Updating the tree selection after a deletion

Offray Vladimir Luna Cárdenas-2
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
     | nodeToDelete |
     nodeToDelete := tree selectedItem content.
     nodeToDelete parent removeNode: nodeToDelete.
     tree selectedItem: tree selectedItem parentNode.
     tree needRebuild: true.
     tree roots: tree roots.
     self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but
after the deletion the contents of the old node are showed no matter if
I change the node selection on the tree. I would like to manage
selections in a smart way, so if I add a new node to the notebook, the
new node gets the selection. If I delete a notebook node, the previous
node gets selected or the parent if no more siblings are encountered and
so on. There is some simple example to look for, about managing and
updating selections in a TreeModel interface?

Thanks,

Offray


Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Offray Vladimir Luna Cárdenas-2
Hi,

I have been fighting with this for several hours until now. I can't
understand how to manage change on selections on TreeModels with Spec,
which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
     tree whenSelectedItemChanged:   [ :item |
         self updateBodyFor: item.
         header whenTextChanged: [ :arg |
             (tree selectedItem content header) = arg
                 ifFalse: [
                     (tree highlightedItem) content header: arg.
                     tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
     item
         ifNotNil: [ self changeBody: item ]
         ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to
some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while
changing the selection between nodes, the item variable becomes
temporarily nil and I can't update the contents of the body to
correspond to the current selection. I would like to say explicitly that
a new tree added node gets the selection and that the deletion of nodes
gives selection to its siblings or parent (if there are not siblings)
and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the
computer to dissipate current frustration... Pharo is generally a happy
productive place... but not today :-/... anyway some hits are part of
learning to play with it.

Cheers,

Offray

On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:

> Hi,
>
> I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.
>
> The message that deletes nodes is something like this:
>
> ============
>
> GrafoscopioNotebook>>removeNode
>     | nodeToDelete |
>     nodeToDelete := tree selectedItem content.
>     nodeToDelete parent removeNode: nodeToDelete.
>     tree selectedItem: tree selectedItem parentNode.
>     tree needRebuild: true.
>     tree roots: tree roots.
>     self buildWithSpecLayout: self class defaultSpec.
>
> =============
>
> And its working fine in the sense that it deletes the selected node,
> but after the deletion the contents of the old node are showed no
> matter if I change the node selection on the tree. I would like to
> manage selections in a smart way, so if I add a new node to the
> notebook, the new node gets the selection. If I delete a notebook
> node, the previous node gets selected or the parent if no more
> siblings are encountered and so on. There is some simple example to
> look for, about managing and updating selections in a TreeModel
> interface?
>
> Thanks,
>
> Offray
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Nicolai Hess-3-2


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray






Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Nicolai Hess-3-2


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray







Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Nicolai Hess-3-2


2016-08-10 20:42 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 


And an awfull example on how to modify selection (only the nodes of the root, couldn't find out how to do it for arbitrary subnodes)

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t autoDeselection:true.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t menu:[:menu ||group|
    group := MenuGroupModel new.
    menu addMenuGroup: group.
    group addMenuItem:(MenuItemModel new name:'next';action:[
        |item|
        item := t selectedItem.
        item ifNotNil:[|allItems index|
            allItems := item container roots.
            index := allItems indexOf: item.
            (index < allItems size) ifTrue:[item selected:false. item container selectedItem:((allItems at:(index+1)) selected:true;takeHighlight;yourself)]
            ]
        ])].
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

again, the important part is #selectedItem: and #takeHighlight, otherwise the model doesn't know about the selection change.


 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray








Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Nicolai Hess-3-2


2016-08-10 21:03 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 20:42 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 


And an awfull example on how to modify selection (only the nodes of the root, couldn't find out how to do it for arbitrary subnodes)

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t autoDeselection:true.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t menu:[:menu ||group|
    group := MenuGroupModel new.
    menu addMenuGroup: group.
    group addMenuItem:(MenuItemModel new name:'next';action:[
        |item|
        item := t selectedItem.
        item ifNotNil:[|allItems index|
            allItems := item container roots.
            index := allItems indexOf: item.
            (index < allItems size) ifTrue:[item selected:false. item container selectedItem:((allItems at:(index+1)) selected:true;takeHighlight;yourself)]
            ]
        ])].
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

again, the important part is #selectedItem: and #takeHighlight, otherwise the model doesn't know about the selection change.



Hm, yes, updating the selection after deletion is much more difficult. The problem is that most in spec TreeModel is done for creating the tree widget, not
for managing nodes and changes afterwards.
 
 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray









Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Offray Vladimir Luna Cárdenas-2

Hi all,

Thanks Nicolai. Your examples helped me to advance and now I have the basic possibility to modify the tree. The two methods that did the trick are #addNode and #highlightNextitem, listed below, but I still get a MNU: receiver of "selectedMorphList is nil, anytime I try to highlight the next item and even from time to time with your code example. If you or anyone want to work with the code directly please install run the playgrounds at [1], [2] & [3], select any node after running [3] and press the Plus button. You'll see that nodes are added in the tree after the current selection, but the recently added node doesn't get the selection after being created (instead the MNU mentioned before, appears).

I will try to use the new created grafoscopio node and look for the TreeNodeModel which has this node as a content to get the highlight.

Help as always is greatly appreciated.

Cheers,

Offray

[1] http://ws.stfx.eu/M5A1F2NPD0QU
[2] http://ws.stfx.eu/EVOY0UKH74L0
[3] http://ws.stfx.eu/5EF0OCUIG7CY

================

GrafoscopioNotebook>>addNode   
    tree needRebuild: true.
    tree highlightedItem content addNodeAfterMe.
    self notebookContent: notebook.
    self highlightNextItem.
    self buildWithSpecLayout: self class defaultSpec.


================

GrafoscopioNotebook>>highlightNextItem
    | currentItem |
    currentItem := tree highlightedItem.
    currentItem
        ifNotNil: [ | allItems index childrenSize parentNode |
            currentItem parentNode
                ifNil: [
                    parentNode := currentItem container.
                    allItems := parentNode roots ]
                ifNotNil: [
                    parentNode := currentItem parentNode.
                    allItems := parentNode children value. ].
            childrenSize := currentItem content parent children size.
            index := allItems indexOf: currentItem.
            (index < childrenSize) ifTrue: [
                "{allItems . currentItem . index } inspect."
                currentItem selected: false.
                parentNode
                    highlightedItem: ((allItems at:(index+1)) selected:true;
                    takeHighlight;yourself).
            ]
        ]



On 11/08/16 13:05, Nicolai Hess wrote:


2016-08-10 21:03 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 20:42 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 


And an awfull example on how to modify selection (only the nodes of the root, couldn't find out how to do it for arbitrary subnodes)

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t autoDeselection:true.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t menu:[:menu ||group|
    group := MenuGroupModel new.
    menu addMenuGroup: group.
    group addMenuItem:(MenuItemModel new name:'next';action:[
        |item|
        item := t selectedItem.
        item ifNotNil:[|allItems index|
            allItems := item container roots.
            index := allItems indexOf: item.
            (index < allItems size) ifTrue:[item selected:false. item container selectedItem:((allItems at:(index+1)) selected:true;takeHighlight;yourself)]
            ]
        ])].
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

again, the important part is #selectedItem: and #takeHighlight, otherwise the model doesn't know about the selection change.



Hm, yes, updating the selection after deletion is much more difficult. The problem is that most in spec TreeModel is done for creating the tree widget, not
for managing nodes and changes afterwards.
 
 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray










Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Nicolai Hess-3-2
Hi Offrey,
I think one problem is that the tree is always rebuild (on every selection?)

even with
self needRebuild:false
tree needREbuild: false.

all subwidgets of the notebook (tree and body) are removed and rebuild from changeBodys call to     self buildWithSpecLayout: self class defaultSpec.
I don't know if this is a bug or unavoidable.


2016-08-18 17:31 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:

Hi all,

Thanks Nicolai. Your examples helped me to advance and now I have the basic possibility to modify the tree. The two methods that did the trick are #addNode and #highlightNextitem, listed below, but I still get a MNU: receiver of "selectedMorphList is nil, anytime I try to highlight the next item and even from time to time with your code example. If you or anyone want to work with the code directly please install run the playgrounds at [1], [2] & [3], select any node after running [3] and press the Plus button. You'll see that nodes are added in the tree after the current selection, but the recently added node doesn't get the selection after being created (instead the MNU mentioned before, appears).

I will try to use the new created grafoscopio node and look for the TreeNodeModel which has this node as a content to get the highlight.

Help as always is greatly appreciated.

Cheers,

Offray

[1] http://ws.stfx.eu/M5A1F2NPD0QU
[2] http://ws.stfx.eu/EVOY0UKH74L0
[3] http://ws.stfx.eu/5EF0OCUIG7CY

================

GrafoscopioNotebook>>addNode   
    tree needRebuild: true.
    tree highlightedItem content addNodeAfterMe.
    self notebookContent: notebook.
    self highlightNextItem.
    self buildWithSpecLayout: self class defaultSpec.


================

GrafoscopioNotebook>>highlightNextItem
    | currentItem |
    currentItem := tree highlightedItem.
    currentItem
        ifNotNil: [ | allItems index childrenSize parentNode |
            currentItem parentNode
                ifNil: [
                    parentNode := currentItem container.
                    allItems := parentNode roots ]
                ifNotNil: [
                    parentNode := currentItem parentNode.
                    allItems := parentNode children value. ].
            childrenSize := currentItem content parent children size.
            index := allItems indexOf: currentItem.
            (index < childrenSize) ifTrue: [
                "{allItems . currentItem . index } inspect."
                currentItem selected: false.
                parentNode
                    highlightedItem: ((allItems at:(index+1)) selected:true;
                    takeHighlight;yourself).
            ]
        ]



On 11/08/16 13:05, Nicolai Hess wrote:


2016-08-10 21:03 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 20:42 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 


And an awfull example on how to modify selection (only the nodes of the root, couldn't find out how to do it for arbitrary subnodes)

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t autoDeselection:true.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t menu:[:menu ||group|
    group := MenuGroupModel new.
    menu addMenuGroup: group.
    group addMenuItem:(MenuItemModel new name:'next';action:[
        |item|
        item := t selectedItem.
        item ifNotNil:[|allItems index|
            allItems := item container roots.
            index := allItems indexOf: item.
            (index < allItems size) ifTrue:[item selected:false. item container selectedItem:((allItems at:(index+1)) selected:true;takeHighlight;yourself)]
            ]
        ])].
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

again, the important part is #selectedItem: and #takeHighlight, otherwise the model doesn't know about the selection change.



Hm, yes, updating the selection after deletion is much more difficult. The problem is that most in spec TreeModel is done for creating the tree widget, not
for managing nodes and changes afterwards.
 
 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray











Reply | Threaded
Open this post in threaded view
|

Re: Spec > TreeModel: Updating the tree selection after a deletion

Offray Vladimir Luna Cárdenas-2

Hi Nicolai,

About the rebuilding of the subwidgets, I really don't know. Maybe if I can force the highlighting I can't ignore the rebuilding issue in some way, so that's what I'm trying now and seems I'm closer. Do you know how to make a TreeNodeModel to show itself expanded? I tried with '#isExpanded: true' and still it doesn't show itself expanded.

Any hint? Any Spec expert attendee in ESUG16 that can spare some minuted enlightening a newbie?

Cheers,

Offray


On 21/08/16 18:12, Nicolai Hess wrote:
Hi Offrey,
I think one problem is that the tree is always rebuild (on every selection?)

even with
self needRebuild:false
tree needREbuild: false.

all subwidgets of the notebook (tree and body) are removed and rebuild from changeBodys call to     self buildWithSpecLayout: self class defaultSpec.
I don't know if this is a bug or unavoidable.


2016-08-18 17:31 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:

Hi all,

Thanks Nicolai. Your examples helped me to advance and now I have the basic possibility to modify the tree. The two methods that did the trick are #addNode and #highlightNextitem, listed below, but I still get a MNU: receiver of "selectedMorphList is nil, anytime I try to highlight the next item and even from time to time with your code example. If you or anyone want to work with the code directly please install run the playgrounds at [1], [2] & [3], select any node after running [3] and press the Plus button. You'll see that nodes are added in the tree after the current selection, but the recently added node doesn't get the selection after being created (instead the MNU mentioned before, appears).

I will try to use the new created grafoscopio node and look for the TreeNodeModel which has this node as a content to get the highlight.

Help as always is greatly appreciated.

Cheers,

Offray

[1] http://ws.stfx.eu/M5A1F2NPD0QU
[2] http://ws.stfx.eu/EVOY0UKH74L0
[3] http://ws.stfx.eu/5EF0OCUIG7CY

================

GrafoscopioNotebook>>addNode   
    tree needRebuild: true.
    tree highlightedItem content addNodeAfterMe.
    self notebookContent: notebook.
    self highlightNextItem.
    self buildWithSpecLayout: self class defaultSpec.


================

GrafoscopioNotebook>>highlightNextItem
    | currentItem |
    currentItem := tree highlightedItem.
    currentItem
        ifNotNil: [ | allItems index childrenSize parentNode |
            currentItem parentNode
                ifNil: [
                    parentNode := currentItem container.
                    allItems := parentNode roots ]
                ifNotNil: [
                    parentNode := currentItem parentNode.
                    allItems := parentNode children value. ].
            childrenSize := currentItem content parent children size.
            index := allItems indexOf: currentItem.
            (index < childrenSize) ifTrue: [
                "{allItems . currentItem . index } inspect."
                currentItem selected: false.
                parentNode
                    highlightedItem: ((allItems at:(index+1)) selected:true;
                    takeHighlight;yourself).
            ]
        ]



On 11/08/16 13:05, Nicolai Hess wrote:


2016-08-10 21:03 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 20:42 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:12 GMT+02:00 Nicolai Hess <[hidden email]>:


2016-08-10 19:05 GMT+02:00 Offray Vladimir Luna Cárdenas <[hidden email]>:
Hi,

I have been fighting with this for several hours until now. I can't understand how to manage change on selections on TreeModels with Spec, which is really frustrating....

Here is what I have:

GrafoscopioNotebook>>initializePresenter
    tree whenSelectedItemChanged:   [ :item |
        self updateBodyFor: item.
        header whenTextChanged: [ :arg |
            (tree selectedItem content header) = arg
                ifFalse: [
                    (tree highlightedItem) content header: arg.
                    tree roots: tree roots]]]

GrafoscopioNotebook>>updateBodyFor: item
    item
        ifNotNil: [ self changeBody: item ]
        ifNil: [ self inform: 'Nil node'  ]

and #changeBody: deals with putting a textual or code pane according to some tags on the selected node (and it's working properly).

The problem seems that when I add/delete nodes to my tree, or while changing the selection between nodes, the item variable becomes temporarily nil and I can't update the contents of the body to correspond to the current selection. I would like to say explicitly that a new tree added node gets the selection and that the deletion of nodes gives selection to its siblings or parent (if there are not siblings) and that node body pane should be updated accordingly.

Again, any hint would be really valuable... I'll take a break from the computer to dissipate current frustration... Pharo is generally a happy productive place... but not today :-/... anyway some hits are part of learning to play with it.

Hi Offray,
I do remember that I tried this as well, I will if I can find out how far I got it to work.

a simiple example:

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

the important part is the "takeHighlight" and to call it after the widget is built

 


And an awfull example on how to modify selection (only the nodes of the root, couldn't find out how to do it for arbitrary subnodes)

|t nodeBlock |
nodeBlock:= [:class | |node|
    node := TreeNodeModel new.
    node hasChildren:[ class subclasses isEmpty not].
    node children: [class subclasses collect:[:subclass | nodeBlock value: subclass]].
    node content: class].
t:=TreeModel new.
t autoDeselection:true.
t roots: (Morph subclasses collect:[:class | nodeBlock value:class]).
t menu:[:menu ||group|
    group := MenuGroupModel new.
    menu addMenuGroup: group.
    group addMenuItem:(MenuItemModel new name:'next';action:[
        |item|
        item := t selectedItem.
        item ifNotNil:[|allItems index|
            allItems := item container roots.
            index := allItems indexOf: item.
            (index < allItems size) ifTrue:[item selected:false. item container selectedItem:((allItems at:(index+1)) selected:true;takeHighlight;yourself)]
            ]
        ])].
t whenBuiltDo:[ t selectedItem:( t roots first selected:true;takeHighlight;yourself)].
t openWithSpec

again, the important part is #selectedItem: and #takeHighlight, otherwise the model doesn't know about the selection change.



Hm, yes, updating the selection after deletion is much more difficult. The problem is that most in spec TreeModel is done for creating the tree widget, not
for managing nodes and changes afterwards.
 
 
 

Cheers,

Offray


On 07/08/16 16:11, Offray Vladimir Luna Cárdenas wrote:
Hi,

I have a Spec TreeModel to represent the GUI of a grafoscopio notebook.

The message that deletes nodes is something like this:

============

GrafoscopioNotebook>>removeNode
    | nodeToDelete |
    nodeToDelete := tree selectedItem content.
    nodeToDelete parent removeNode: nodeToDelete.
    tree selectedItem: tree selectedItem parentNode.
    tree needRebuild: true.
    tree roots: tree roots.
    self buildWithSpecLayout: self class defaultSpec.

=============

And its working fine in the sense that it deletes the selected node, but after the deletion the contents of the old node are showed no matter if I change the node selection on the tree. I would like to manage selections in a smart way, so if I add a new node to the notebook, the new node gets the selection. If I delete a notebook node, the previous node gets selected or the parent if no more siblings are encountered and so on. There is some simple example to look for, about managing and updating selections in a TreeModel interface?

Thanks,

Offray