Object » View » ListView » PluggableListView
A pluggable list view gets its content from the model. This allows the same kind of view to be used in different situations, thus avoiding a proliferation of gratuitous view and controller classes.
A pluggable list view is set up with a data provider - its model - and several message selectors that the view can use to communicate with its model.
getListSelector - Symbol
fetch the list of items (strings) to be displayed.
The following assertion holds:
getListSelector isNil or: [getListSelector isSymbol and: [(model respondsTo: getListSelector) and: [(model perform: getListSelector) isKindOf: SequenceableCollection] ] ]
getSelectionSelector - Symbol
get the currently selected item.
The following assertion holds:
getSelectionSelector isNil or: [getSelectionSelector isSymbol and: [(model respondsTo: getSelectionSelector) and: [(model perform: getSelectionSelector ) between: 0 and: items size] ] ]
setSelectionSelector - Symbol
set the currently selected item (takes an argument).
The following assertion holds:
setSelectionSelector isNil or: [setSelectionSelector isSymbol and: [(model respondsTo: setSelectionSelector) and: [setSelectionSelector numArgs = 1] ] ]
getMenuSelelector - Symbol
get the pane-specific, 'yellow-button' menu.
The following assertion holds:
getMenuSelector isSymbol and: [(model respondsTo: getMenuSelector) and: [(getMenuSelector numArgs between: 1 and 2) and: [#(#UndefinedObject #SelectionMenu #CustomMenu) includes: (getMenuSelector numArgs = 2 ifTrue: [model perform: getMenuSelector with: CustomMenu new with: aBoolean] ifFalse: [model perform: getMenuSelector with: CustomMenu] ) class name ] ] ]
getMenuTitleSelector - Symbol
get the title for the pane-specific, 'yellow-button' menu.
The following assertion holds:
getMenuTitleSelector isNil or: [getMenuTitleSelector isSymbol and: [(model respondsTo: getMenuTitleSelector ) and: [#(#UndefinedObject #String) includes: (model perform: getMenuTitleSelector ) class name ] ] ]
keyActionSelector - Symbol
process a keystroke typed in this pane (Message selectors that take either one or two
arguments are allowed here.)
autoDeselect - Boolean
The value true indicates that a mouse click on a selected item causes
deselection. The value false indiates that deselection is not possible.
items - Array
an Aray of Strings, the collection of items to be displayed in the view.
The class protocol of PluggableListView includes method for three frequent use cases. Each of these methods creates a properly initialized instance.
For the creation of initialized instances, the class protocol provides a set of three dedicated class methods. Method on:list:selected:changeSelected:menu:keystroke is the most general of these, two others are shortened variants that provide reasonable default values for some parameters of the general method.
on: anObject
list: getListSel
selected: getSelectionSel
changeSelected: setSelectionSel
menu: getMenuSel
keystroke: keyActionSel
This is the most general use case. It provides an instance that is initialized with all selectors that
the instance needs to communicate with its model. Selector usage is:
getListSel
fetch the list of items (strings) to be displayed
getSelectionSel
get the currently selected item
setSelectionSel
set the currently selected item (takes an argument)
getMenuSel
get the pane-specific, 'yellow-button' menu
keyActionSel
process a keystroke typed in this pane
(A message selector that expects one argument is sent with the typed character.
A message selector that expects two arguments is sent with the typed character
and the view.)
on: anObject
list: getListSel
selected: getSelectionSel
changeSelected: setSelectionSel
menu: getMenuSel
Answers an instance that is initialized with all selectors that
the instance needs to communicate with its model. The selector
arrowKey:from: is assigned as handler for typed input.
A method with this name is part of the instance protocol of
class Model.
on: anObject
list: getListSel
selected: getSelectionSel
changeSelected: setSelectionSel
Answers an instance that is initialized with selectors that
the instance needs to communicate with its model. This method does not
provide a menu accessor; it is designed for view that shall not offer
a menu. The selector
arrowKey:from: is assigned as handler for typed input.
A method with this name is part of the instance protocol of
class Model.
getMenu: aBoolean
The associated controller sends this message to request a menu.
The method is required to answer either the value nil or
a SelectionMenu or a
CustomMenu.
The model should not modify a collection that it shares with the view; it should not even share a collection with the view. The reason is that the view repaints itself only when it received a new content. When it is given a collection that it already uses, possible changes cannot be detected.
A PluggableListView does not repaint itself when its old and its updated contents differ only in text attributes. This may occassionally cause unexpected problems. (The example shows how this problem can be solved.)
Whenever the item collection is updated, the current selection should be updated, too.
Whenever the the model is notified about the index of the currently selected item, it should update the current selection. Otherwise the view will not redisplay itself when its selection was changed with the arrow keys.
Any of the above selectors can be nil, meaning that the model does not supply behavior for the given action, and the default behavior should be used. However, if getListSel is nil, the default behavior just provides an empty list, which makes for a rather dull list view!
The model informs a pluggable view of changes by sending #changed: to itself with getListSel or getSelectionSel as a parameter. The view informs the model of selection changes by sending setSelectionSel to it with the newly selected item as a parameter, and invokes menu and keyboard actions on the model via getMenuSel and keyActionSel.
Pluggability allows a single model object to have pluggable list views on multiple aspects of itself. For example, an object representing one personal music library might be organized as a three-level hierarchy: the types of music, the titles within a given type, and the songs on a given title. Pluggability allows one to easily build a multipane browser for this object with separate list views for the music type, title, and song.
AutoDeselect is a feature, normally set to true, that will tell the model that there is no selection if you click on an item that is currently selected. If autoDeselect is false, then the model will simply be told to select the same item again.
This is a pluggable view. Update methods compare a message argument with stored selectors, and ignore messages with unknown selectors.
textAttributesList " answer a list of four items. The first and second item use text adornments. " ^Array with: 'bold' asText allBold with: ('italic' asText addAttribute: (TextColor color: Color red)) with: 'underlined' asText with: 'struck out' asText "colored items require a ColorSystemView as top view "
Note that you should use a ColorSystemView as top view of your window when you use colored text.