-
Notifications
You must be signed in to change notification settings - Fork 2
ComboBoxTableCell
Note
|
the problems (and solutions) are similar for all collection views |
- Created
-
2015-10-01 13:48
- Status
-
Resolved
The issue was that navigating the popup by keyboard committed the new selection, making navigation impossible and thus useless for any interaction by keyboard. The technical problem was that the edit was committed on value/selection change of the combo.
The fix is to use the combo’s showing property as commit trigger: commit on hiding. This would be correct only if there ware a strict correlation between the property change and a user’s intention. Use-cases where there’s no correlation:
-
no change: the popup might not be open during the edit - the property is always false, thus a commit is never triggered
-
change without commit-intention: an open popup might be closed (f.i. by alt-arrow on Win) for other reasons, thus triggering an unwanted commit
In fact, it might have introduced several new issues, f.i.:
Just as in ol' Swing, combo’s high-level notification isn’t fit for being used as a trigger in cell editing. At any time the equation holds:
Action == Value == SelectedItem
Navigation inside the popup changes the selectedItem which changes the value which fires the action. So we can’t hook into any of this to trigger a cell commit.
The idea is inspired by ol' Swing: Don’t use high-level notification, instead hook into low-level events such that we effectively ignore the internal coupling.
XComboBoxTableCell is a prototype that implements the basic idea.
It includes:
-
listen to keyStrokes on the combo and the list that indicate the cancel/commit intention of the current value
-
listen to mouse events on the list that indicate a commit intention
-
make sure the selection is adjusted on text changes
A crucial requirement is to reliably react on esc/enter as the usual(?) keys for cancel/commit. Not entirely obvious (to me, at least) that the popup as an internal consumer comes into the way of normal interception (in an eventFilter). Below is a table of which keys are received by which handler on a stand-alone editable combo, depending on whether the popup is visible or not. Having modified the textfield or not doesn’t make a difference, nor does navigation in the open popup.
Key / Showing | Filter:Pressed | Filter:Released | Handler:Pressed | Handler:Released |
---|---|---|---|---|
Enter / false |
yes |
yes |
no |
no |
Esc / false |
yes |
yes |
yes |
yes |
Enter / true |
no |
yes |
no |
no |
Esc / true |
no |
yes |
no |
yes |
Looks like a adding an eventFilter and looking for released meets the requirement always.
Note
|
unrelated aside - Esc has no semantics other than closing the popup, text is committed on focusLost |
When navigating the list, the combo’s value is updated - independent of whether it the text had been modified or not. The other way round: starting with a selection, then modifying the text has no direct effect on the selection (only after the change is committed on the combo level).
A "natural" commit (on cell level) implementation is to commit the combo’s value. As this is not yet updated, the text edit is effectively dismissed and the old selection committed. To overcome this obstacle, the prototye commits-on-textChange (on combo level). Doing so, clears the old selection and allows the "natural" cell commit to work both for hidden and visible popup.
There’s a rudimentary driver application, that has columns with core/x comboTableCell for comparison. No formal testing yet: need to manually walk through the bugs as noted in its api doc.
TBD ;)
All bugs fixed. The fix commits/cancels on Enter/Esc in a filter on the comboBox. For an editable combo, the text is converted into the value immediately before committing. No need to commit-on-typing (on the combo/textfield level) nor for a filter on the list.
What’s missing is the mouse handler on the list: without, the cell edit is not committed on clicking into the popup.