Today we'll play with the DropDownList and some colors
Design
The DropDownList is really a simple widget. We'll have one DropDownList, and a bunch of CheckBoxes to play with some of the attributes, such as the input background and foreground colors, the list background and foreground colors and the display string for items in the list itself.
As always we start off with a subclass of UserInterface:
Smalltalk defineClass: #DropDownListWork
superclass: #{Widgetry.UserInterface}
indexedType: #none
private: false
instanceVariableNames: 'dropDownList inputForeground inputBackground listForeground listBackground displaySelector '
classInstanceVariableNames: ''
imports: 'private Widgetry.*'
category: '(none)'
Now we'll create our widgets in the #createInterface method:
createInterface
dropDownList := DropDownList new.
dropDownList frame
inset: 10 @ 10;
extent: 150 @ 25.
self addComponent: dropDownList.
inputForeground := CheckBox withLabelString: 'Input Foreground Blue'.
inputForeground frame
inset: 10 @ 40;
extent: 150 @ 25.
self addComponent: inputForeground.
inputBackground := CheckBox withLabelString: 'Input Background Yellow'.
inputBackground frame
inset: 10 @ 70;
extent: 150 @ 25.
self addComponent: inputBackground.
listForeground := CheckBox withLabelString: 'List Foreground Red'.
listForeground frame
inset: 10 @ 100;
extent: 150 @ 25.
self addComponent: listForeground.
listBackground := CheckBox withLabelString: 'List Background Pink'.
listBackground frame
inset: 10 @ 130;
extent: 150 @ 25.
self addComponent: listBackground.
displaySelector := CheckBox withLabelString: 'Reverse List Text'.
displaySelector frame
inset: 10 @ 160;
extent: 150 @ 25.
self addComponent: displaySelector.
We've seen all this before, and here is what it looks like if we now execute DropDownListWork open:
Gimme A Double
If we play with our DropDownList, we see if we press the button. or press the down arrow when in the input field part of the DropDownList, an empty list will show:
So, let's fill that list with some items, which we'll do in our #hookupInterface method:
hookupInterface
dropDownList list:
#('January' 'February' 'March' 'April' 'May' 'June'
'July' 'August' 'September' 'October' 'November' 'December').
Now if we open the drop down, here is what it looks like:
If when the drop down is open, we start typing, the selection target in the list changes to match what we've typed in. I call this tippy-typing, but I suppose that is just my silly naming. That said, it works not only in a DropDownList but also in a regular ListBox. If we hit enter when one of the items is target selected, the drop down will close, and the value will be put into the input field portion of the DropDownList.
Also, if we type in a value that is in the list into the input field (such as September), and then open the drop down, that item will be pre-selected in the list.
Finger Painting
Let's hookup our check boxes for the color changes:
hookupInterface
dropDownList list:
#('January' 'February' 'March' 'April' 'May' 'June'
'July' 'August' 'September' 'October' 'November' 'December').
inputForeground when: ValueChanged send: #updateInputForeground to: self.
inputBackground when: ValueChanged send: #updateInputBackground to: self.
listForeground when: ValueChanged send: #updateListForeground to: self.
listBackground when: ValueChanged send: #updateListBackground to: self.
updateInputBackground
dropDownList inputBackground: (inputBackground model value
ifTrue: [ColorValue yellow]
ifFalse: [nil]).
updateInputForeground
dropDownList inputForeground: (inputForeground model value
ifTrue: [ColorValue blue]
ifFalse: [nil]).
updateListBackground
dropDownList dropDownBackground: (listBackground model value
ifTrue: [ColorValue pink]
ifFalse: [nil]).
updateListForeground
dropDownList dropDownForeground: (listBackground model value
ifTrue: [ColorValue red]
ifFalse: [nil]).
And this is the what it looks like with all the colors turned on:
Extra Credit
By default, the list will display the objects that it holds by sending #displayString to each object. We can change that to be any other method on that object that answers a string. This is something that works on a ListBox also, except for a ListBox, the method is just #displaySelector:. Here we use the DropDownList's #listDisplaySelector: method.
For giggles and today's Extra Credit, we'll just make it be #reverse:
hookupInterface
dropDownList list:
#('January' 'February' 'March' 'April' 'May' 'June'
'July' 'August' 'September' 'October' 'November' 'December').
inputForeground when: ValueChanged send: #updateInputForeground to: self.
inputBackground when: ValueChanged send: #updateInputBackground to: self.
listForeground when: ValueChanged send: #updateListForeground to: self.
listBackground when: ValueChanged send: #updateListBackground to: self.
displaySelector when: ValueChanged send: #udpateDisplaySelector to: self
udpateDisplaySelector
dropDownList listDisplaySelector: (displaySelector model value
ifTrue: [#reverse]
ifFalse: [nil]).
And if we check that last check box, here's the result:
Isn't that pretty?
And So It GoesSames