624 views
in GUI Development by
Hello, are there any plans to include a combo box widget in the next version of Embedded Wizard?

1 Answer

0 votes
by

Hello,

I am not sure, whether it will be the next version, but yes we have plans to extend the widget set. This would include a template for a combo box. Since every customer has individual and very different requirements regarding the look&feel of the widgets, this is not so trivial. Especially complex widgets like the combo box can appear and behave in many diferent ways.

Anyway, the following is a short common description how to create own combo box widgets. Here you will need to handle with two components:

- One component is intended to display the combo box list items. The simplest is to put inside this component the Vertical List. Eventually you will need to add additional logic to the component to adjust its size depending on the number of items within the list.

- Second component is intended to appear as the combo box standalone without the list. In this component you show the value corresponding to the actual combo box selection.

As soon as the user activates the second component (e.g. touches on it), you create dynamically an instance of the first component, then you add this instance to the application component showing it in this manner top-most on the screen. With BeginModal() you redirect all events to the just added component instance. Now the user can interact with the list. After making a selection, you EndModal() and remove the list component again from the application component.

Of course the real implementation will also need to take care of the communication between the both components, the loading of the Vertical List with combobox items, etc. 

Best reagrds

Paul Banach

by
Sadly there is no ComboBox Template implemented yet.

Therefore i have an additinal question to your answer, Paul.

I do not want to use the modal feature, because in typical UIs when a ComboBox is expanded and the user is pressing out of the ComboBox area it will be closed. For this reason it is necessary to create a TouchHandler to recognize those events. Is there an easier way to implement this behavior?
by

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

by
Thank you Paul for your answer. This is an interesting solution. I will try it.
by

Hello JK,

I have just rethought the application case of how to detect the touch outside of the modal combo box list. In the above approach you need to override in the application class the method DriveMultiTouchHitting. Following different idea is more local without needing to modify the application component. The necessary steps:

First ignore the Step 5 and Step 6 from the above description. Instead:

New Step 5: In the ComboList class override the method CursorHitTest.

New Step 6: Implement the method with following code:

var Core::CursorHit hit = super( aArea, aFinger, aStrikeCount, aDedicatedView, aRetargetReason );

// The user has tapped outside the list component. This can cause the list to disappear
if (( hit == null ) && ( aArea & Bounds ).isempty && ( aDedicatedView == null ))
  postsignal closeList;

return hit;

This implementation detects touches outside of the actually modal list component and sends a signal to a slot method closeList.

New Step 7: Add a new slot method to the List component. Name it closeList.

New Step 8: Implement the slot method:

GetRoot().EndModal( this );
GetRoot().Remove( this );

I hope it helps you further.

Best regards

Paul Banach

by

This is a very smart solution. Thank you so much. yes

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint

...