Hello JK,
the ComboBox template is in fact still waiting on our to-do list. So let me try to provide you some hints how to implement it. Generally, using modal state for this purpose has an advantage. You don't need to worry about the user interactions on all other widgets. Thus I would use the modal state in this case. Try following:
Step 1: Let assume, the ComboBox will consist internally of two GUI components: the box displaying the actual selected value and a list component which is shown when the user touches the box.
Step 2: The box component should contain a Simple Touch Handler. As soon as the user touches within this handler's area, the associated slot method creates a new instance of the list component and displays it directly in context of the Application component (in context of the root object). This ensure, that the list will overlay all other GUI contents and it will not be clipped by any other view. The implementation should also take care of the proper initialization of the list component with the content to display, etc.. For example:
var Application::ComboBoxList list = new Application::ComboBoxList;
// From the actual touch position get a global (screen) position
// and adjust the combo box list to appear at this position:
list.Bounds.origin = GlobalPosition( SimpleTouchHandler.CurrentPos );
// The list should store a reference to the box component it belongs to.
// Assuming: the class Application::ComboBoxList contains for this purpose
// a variable 'Box':
list.Box = this;
// ... and it also should be loaded with some data.
// Assuming: the class Application::ComboBoxList implements the method
// SetDataProvider() (or something similar) to setup the content of the
// list.
list.SetDataProvider( ... );
// ... and the actual selection should be passed to the list.
// Assuming: the class Application::ComboBoxList implements the method
// SetSelection() (or something similar) to inform the list which item
// is atually selected. The class Application::ComboBox, in turn,
// stores the latest selected value in a variable e.g. ActualSelection.
list.SetSelection( ActualSelection );
// Display the list in context of the 'root' object and make it modal
GetRoot().Add( list, 0 );
GetRoot().BeginModal( list );
Step 3: As soon as the user selects an item within the list, the list informs the associated box component about the selection. For this purpose the list can use the variable Box as the above code initializes such variable with a reference to the box component:
// Assuming: the class Application::ComboBox implements a method SelectOption():
Box.SelectOption( the_value_selected_in_the_list );
Step 4: Thereupon the implementation of the method SelectOption() stores the selected value and dismisses the list component. To dismiss the list following code is needed:
// Obtain the actually modal ComboBox list component
var Core::Group list = GetRoot().GetModalGroup();
// End the modal state and hide the component
GetRoot().EndModal( list );
GetRoot().Remove( list );
Now, let me address your concrete question of how to detect a touch outside a modal list component and dismiss the list. The simplest is you override in your Application class the method DriveMultiTouchHitting. This method is invoked each time the user touches the screen. In your implementation you can thus check whether there is a ComboBox list visible and dismiss it. For this purpose:
Step 5: In your Application class override the method DriveMultiTouchHitting.
Step 6: Open the overridden method and implement following code:
// First perform the regular touch operation by the inherited version of
// the method. If the touch event was handled leave the method.
if ( super( aDown, aFinger, aPos ))
return true;
// The user has not hit any existing touch handler? Then check whether there
// is a modal ComboBox List component.
var Application::ComboBoxList list = (Application::ComboBoxList)GetModalGroup();
// If such list does exist - end its modal state and hide it now
if ( list )
{
EndModal( list );
Remove( list );
}
return false;
So far the basement for such ComboBox List combination. I hope it helps you further.
Best regards
Paul Banach