Selecting multiple items in a list, and callbacks

x::w::new_listlayoutmanager new_list;

new_list.selection_type=x::w::multiple_selection_type;

new_list.selection_type=[]
       (ONLY IN_THREAD,
        const x::w::listlayoutmanagerbase & l,
        size_t item_number)
       {
       };

new_list.selection_changed=[]
       (ONLY IN_THREAD,
        const x::w::list_item_status_info_t &info)
       {
       };
	

The default behavior of a selection list is that selecting a different list item automatically unselects the previously-selected list item. Selecting the same list item again unselects it. Setting selection_type to x::w::multiple_selection_type results in each list item getting selected and unselected individually. Clicking on a list item with a pointer, or tabbing to the list, moving the cursor to the item's row, and pressing Enter selects and unselects that item only.

Setting selection_type to a lambda results in custom selection callback lambda. Clicking on an item executes the lambda, and the lambda has full control over which list items get selected or unselected. The selection_type lambda's parameters are: the list layout manager, given as a x::w::listlayoutmanager, the index of which item was clicked on, and the busy mcguffin. The lambda is responsible for selecting or unselecting the list's items, as it sees fit.

Note

selection_type callbacks get executed by the connection thread. They should use IN_THREAD x::w::listlayoutmanager methods to examine and update the list.

selection_changed is an optional callback that gets invoked whenever any item in the list gets selected or unselected, individually. The callback's x::w::list_item_status_info_t reports which item was changed, and its new status is. Each individual list item can also have its own individual callback that gets invoked only when that item's status changes. This is invoked in addition to the list-wide selection_changed callback. This is used in menus, but may also be used in selection lists as well.

Note

The usual rules for captured references apply. Callbacks cannot capture references to their list's container, or any of its parent elements. The callbacks conveniently receive their list layout manager as one of their parameters, which should take care of most of their needs.

Note

The library obtains an internal lock on the underlying list, that's held for the duration of the callback; and the callback must acquire its own lock, if it needs one. In any case, the underlying list is locked for the duration of the callback, and cannot be accessed by other execution threads.

std::optional<size_t> selection=list->selected();
if (selection)
{
     auto v=selection.value();
}

std::vector<size_t> all_selections=list->all_selected();

if (lm->selected(1))
{
   // ...
}

The selected() method makes an ad-hoc query to retrieve the currently-selected item, if there is one. This approach is suitable with single selection lists. With x::w::multiple_selection_type lists all_selected() gives the list of all items that are currently selected; or an overloaded selected() takes a parameter and returns an indication whether the given item is currently selected.

Given LibCXXW's multi-threaded nature, the internal library thread can end up selecting or unselecting a list item at any time in response to pointer or keyboard activity, so what's selected() can change at any time. Use a list lock to freeze the contents of the list, examine what's selected(), at a given time, and perhaps add or remove items from the list while blocking all other threads from accessing the list.

An alternative approach involves attaching callbacks to individual list items. A list item's callback gets invoked whenever the list item gets selected or unselected. Other items may be added or removed from the list, but the callback stays with its paired item, and gets invoked only for its item.