selectionOrNil design change for MultipleSelectionListBox problems

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

selectionOrNil design change for MultipleSelectionListBox problems

Carsten Haerle
There is a pattern which occurs very often with list boxes when dealing with
single and multi selections:

You have an application with a single selection list box. You implement all
the menus and the queryCommand method, so that the menu items are only
enabled when an item is enabled and you use methods like selectionOrNil,
selection and so on.

If you now change the ListBox to a multiple selection list box in the
resource view, your application breaks and you have to change a lot of code,
because selectionOrNil now doesn't answer an object or nil, but always a
collection. So you have to do two things:

1) Change all the code that it now accepts a collection instead of an
object.
2) Usually not all menus can be used with a multi selection but should be
only enabled with exactly one item selected. So you have to check all the
code to see where you change the fragment "listbox selectionOrNil isNil" to
either "listbox selections notEmpty" or "listbox selection size = 1".

SOLUTION:
There is a little change which could solve this problem and the solution is
already partially implemented in Dolphin 5. The change is as follows:

The methods selection, selectionOrNil, selection:ifAbsent:, selection: and
so on should not change their signature in MultipleSelectionListBoxes, this
is e.g. selectionOrNil should still answer an object or nil. They should
answer an object if exactly one item is selected otherwise nil. Dolphin
already introduced additional methods which deal with multiple selections
(the methods starting with "selections"). If you want a collection you have
to use these methods.

Advantages
1) It is vey easy to start converting a single selection application to a
multi selection application. You can just change the view resource and
everything still works! Then you can change only the methods where multi
selection is really supported. All the methods where menus are only for
exactly one selection don't need a change.
2) You could also make the other change, by changing a MultiSelectionListBox
 in the View editor to a Single selection list box, and the application
would still work, because the presenter code deals only in terms of the
methods "selections*" which would answer either an empty or a one element
collection.
3) Even if you don't convert an existing single selection application but
write a new application, it is very handy to be able to make this
distinction between selection ("give me exactly one object") and selections
("give me a collection of objects, which may be empty"), because you still
have the pattern above, that only some methods are situable for multiple
objects.
4) The components and presenters become much more pluggable because they now
always work with single and multiselection listboxes and can be better
reused.

As said it seems to me that exactly this idea lead to the definition of the
two method groups "selection*" and "selections*", but then the idea was not
carried out fully, because the MultiSelectionListBox overrides the methods
in a "wrong" manner and breaks there signatures.

Comments are very welcome.

Regards

Carsten Haerle


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Peter van Rooijen
"Carsten Haerle" <[hidden email]> wrote in message
news:buo3pd$ouo$05

> There is a pattern which occurs very often with list boxes when dealing
with
> single and multi selections:

[snip]

> As said it seems to me that exactly this idea lead to the definition of
the
> two method groups "selection*" and "selections*", but then the idea was
not
> carried out fully, because the MultiSelectionListBox overrides the methods
> in a "wrong" manner and breaks there signatures.
>
> Comments are very welcome.

I think the idea of making single and multi select listboxes interhangeable
is a good one and will work. I use different techniques in my portable GUI
library, but with the same effect; that you can switch between single- and
multi-select, and it just works. It is very convenient.

Regards,

Peter van Rooijen
Amsterdam


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

cstb
In reply to this post by Carsten Haerle
Carsten Haerle wrote:

> SOLUTION:
> There is a little change which could solve this problem and the solution is
> already partially implemented in Dolphin 5. The change is as follows:
>
> The methods selection, selectionOrNil, selection:ifAbsent:, selection: and
> so on should not change their signature in MultipleSelectionListBoxes, this
> is e.g. selectionOrNil should still answer an object or nil. They should
> answer an object if exactly one item is selected otherwise nil.

That's better, but still a bit brittle.
If they would all answer a collection,
they'd be completely interchangeable.

For accessing the result,
you'd also want

        Collection>>firstOrNil
                ^self firstOr: [nil]
                        first

        Collection>>firstOrEmpty
                ^self firstOr: [self]

        Collection>>firstOr: thenWhat
                ^(self orIfEmpty: thenWhat)
                        first

The application logic and presentation/view logic
are then decoupled; either could then change without
affecting the other.

-cstb


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Carsten Haerle
This would be another solution, but with some disadvantages:

* Would need extensions to collection
* Would break a lot of code
* Feels not as intuitive to my as the solution described (I would think that
the intuitive interpretation of a name like #selectionOrNil is that it
answers a single object or nil) .

Also the implementation is Dolphin is already almost done, just a change of
2 or 3 methods which should break almost no existing code.

Regards

Carsten

"cstb" <[hidden email]> schrieb im Newsbeitrag
news:[hidden email]...
>
>
> Carsten Haerle wrote:
>
> > SOLUTION:
> > There is a little change which could solve this problem and the solution
is
> > already partially implemented in Dolphin 5. The change is as follows:
> >
> > The methods selection, selectionOrNil, selection:ifAbsent:, selection:
and
> > so on should not change their signature in MultipleSelectionListBoxes,
this

> > is e.g. selectionOrNil should still answer an object or nil. They should
> > answer an object if exactly one item is selected otherwise nil.
>
> That's better, but still a bit brittle.
> If they would all answer a collection,
> they'd be completely interchangeable.
>
> For accessing the result,
> you'd also want
>
> Collection>>firstOrNil
> ^self firstOr: [nil]
> first
>
> Collection>>firstOrEmpty
> ^self firstOr: [self]
>
> Collection>>firstOr: thenWhat
> ^(self orIfEmpty: thenWhat)
> first
>
> The application logic and presentation/view logic
> are then decoupled; either could then change without
> affecting the other.
>
> -cstb


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Chris Uppal-3
In reply to this post by Carsten Haerle
Carsten Haerle wrote:

> The methods selection, selectionOrNil, selection:ifAbsent:, selection: and
> so on should not change their signature in MultipleSelectionListBoxes,
> this is e.g. selectionOrNil should still answer an object or nil. They
> should answer an object if exactly one item is selected otherwise nil.
> Dolphin already introduced additional methods which deal with multiple
> selections (the methods starting with "selections"). If you want a
> collection you have to use these methods.

I rather like this idea.  In fact most of my code ends up going through local
helper methods coded like:

    selectedWotsits
        | all |
        all := self WostitsPresenter selections.
        ^ all size = 1
            ifTrue: [all first]
            ifFalse: [nil].

so I'm fairly sure that the pattern is a workable one from the point of view of
the application code structure.

My only reservation is that the #selection* methods are used rather a lot, and
it's difficult to know how much code there is that relies on the documented
existing behaviour.  E.g. there are 155 senders of #selectionOrNil in my image
today -- I have little appetite for wading through them checking them all.

Have you tried making this change in your image ?  If so, then what happened ?

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Blair McGlashan
In reply to this post by Carsten Haerle
"Carsten Haerle" <[hidden email]> wrote in message
news:buo3pd$ouo$05$[hidden email]...
> ...
> The methods selection, selectionOrNil, selection:ifAbsent:, selection: and
> so on should not change their signature in MultipleSelectionListBoxes,
this
> is e.g. selectionOrNil should still answer an object or nil. They should
> answer an object if exactly one item is selected otherwise nil. Dolphin
> already introduced additional methods which deal with multiple selections
> (the methods starting with "selections"). If you want a collection you
have
> to use these methods.
>...

I completely agree. This was an early design error that was not spotted
until it was too late. The #selection methods are so widely used that we
came to the conclusion we could not correct it. The problem was (and is,
even more so now) that most applications using multiple selection lists
still go through the #selection* family of methods and expect a to
receive/pass a collection.

As you suspect the selections* family of methods was introduced because of
this issue, since as you have noted this has a consistent and sensible
implementation in all cases. However history prevented the correction of the
single selection case. In D6 we have been moving toward using the multiple
selection protocol more widely. We haven't deprecated the selection*
protocols, but I feel that this combined with the introduction of a new set
of single selection methods might be the only hope for getting this
carbuncle out of the MVP sub-system.

I have to say that I am still not entirely comforable with the idea of
multiple selection lists implementing a single selection protocol at all,
however convenient it might be to the developer. Certainly your proposed
solution of implementing it in the multiple selection case to follow the
pattern of, for example, PackageBrowserShell>>selectedClass,
PackageBrowserShell>>method, PackageSelector>>singlePackage, etc, seems like
the best of the choices. There are three basic cases:
1) Multiple selections
2) Exactly one selection
3) Any one selection

The last case is rarely used, but where appropriate the choice of which
selection to use should not be entirely arbitrary, but something sensible.
This could be the first of the selections, but multiple selection lists
typically have the notion of a "primary" selection. I don't think we
currently provide an easy way to get this that is consistent across the
views and presenters.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Carsten Haerle
One way to solve the problem is to invent a whole new set of apis, but it
will not be easy to find a better name as selectionOrNil for this method.
Another easy solution could work as follows:

The ListView resource gets a new attribut "legacy selection interface" which
will be set to true when an old resource is deserialized, all new resources
will have this attribut set to false. All the selection methods now just
check this attribut and follow the new and better definition, when this
attribut is false and follow the old definition otherwise. This solution
would have the following advantages:

1) No new method names for selectionOrNil and similar, because I think there
is no better name. Also there wouldn't be two set of methods which do almost
the same and would clutter up the ListBox interface.
2) The change would break NO code and could be introduced at any time.
3) It would support the process of migrating old code to new new interface,
so that the backward compatibilty atttribute "legacy selection interface"
could be thrown away one or two versions later.

Comments?

Regards

Carsten

"Blair McGlashan" <[hidden email]> schrieb im Newsbeitrag
news:bur20f$kgl85$[hidden email]...
> "Carsten Haerle" <[hidden email]> wrote in message
> news:buo3pd$ouo$05$[hidden email]...
> > ...
> > The methods selection, selectionOrNil, selection:ifAbsent:, selection:
and
> > so on should not change their signature in MultipleSelectionListBoxes,
> this
> > is e.g. selectionOrNil should still answer an object or nil. They should
> > answer an object if exactly one item is selected otherwise nil. Dolphin
> > already introduced additional methods which deal with multiple
selections

> > (the methods starting with "selections"). If you want a collection you
> have
> > to use these methods.
> >...
>
> I completely agree. This was an early design error that was not spotted
> until it was too late. The #selection methods are so widely used that we
> came to the conclusion we could not correct it. The problem was (and is,
> even more so now) that most applications using multiple selection lists
> still go through the #selection* family of methods and expect a to
> receive/pass a collection.
>
> As you suspect the selections* family of methods was introduced because of
> this issue, since as you have noted this has a consistent and sensible
> implementation in all cases. However history prevented the correction of
the
> single selection case. In D6 we have been moving toward using the multiple
> selection protocol more widely. We haven't deprecated the selection*
> protocols, but I feel that this combined with the introduction of a new
set
> of single selection methods might be the only hope for getting this
> carbuncle out of the MVP sub-system.
>
> I have to say that I am still not entirely comforable with the idea of
> multiple selection lists implementing a single selection protocol at all,
> however convenient it might be to the developer. Certainly your proposed
> solution of implementing it in the multiple selection case to follow the
> pattern of, for example, PackageBrowserShell>>selectedClass,
> PackageBrowserShell>>method, PackageSelector>>singlePackage, etc, seems
like

> the best of the choices. There are three basic cases:
> 1) Multiple selections
> 2) Exactly one selection
> 3) Any one selection
>
> The last case is rarely used, but where appropriate the choice of which
> selection to use should not be entirely arbitrary, but something sensible.
> This could be the first of the selections, but multiple selection lists
> typically have the notion of a "primary" selection. I don't think we
> currently provide an easy way to get this that is consistent across the
> views and presenters.
>
> Regards
>
> Blair
>
>


Reply | Threaded
Open this post in threaded view
|

Re: selectionOrNil design change for MultipleSelectionListBox problems

Blair McGlashan
"Carsten Haerle" <[hidden email]> wrote in message
news:bv5i25$70g$06$[hidden email]...
> One way to solve the problem is to invent a whole new set of apis, but it
> will not be easy to find a better name as selectionOrNil for this method.
> Another easy solution could work as follows:
>
> The ListView resource gets a new attribut "legacy selection interface"
which
> will be set to true when an old resource is deserialized, all new
resources
> will have this attribut set to false. All the selection methods now just
> check this attribut and follow the new and better definition, when this
> attribut is false and follow the old definition otherwise.

That's an interesting idea. We need to think through whether simply changing
the behaviour of the view is sufficient, but certainly a first glance it
would appear to be so.

Thanks for the suggestion,

Regards

Blair