indexing description: "[ List with selectable elements Events: - `selection_change_event': Triggered when selection changed. Passes new element as argument. Delegate: EM_LIST_DELEGATE - A list has a special delegate to map mouse coordinates to list elements. Subclasses should call `make_list' at creation. ]" date: "$Date$" revision: "$Revision$" deferred class EM_LIST [G] inherit EM_WIDGET redefine delegate end feature {NONE} -- Initialisation make_list is -- Initialise default values. do create {DS_LINKED_LIST [G]}elements_impl.make elements_impl.set_equality_tester (create {KL_EQUALITY_TESTER[G]}) create selection_changed_event end feature -- Measurement count: INTEGER is -- Number of elements in list do Result := elements_impl.count ensure count_not_negative: count >= 0 consistent: Result = elements.count end feature -- Access delegate: EM_LIST_DELEGATE -- Delegate which draws widget elements: DS_LINEAR [G] is -- Linear representation of elements do Result := elements_impl end selected_element: G -- Currently selected element selected_index: INTEGER -- Index of selected element feature -- Status report has_selected_element: BOOLEAN is -- Is any element selected? do Result := selected_element /= Void ensure consistent: Result implies selected_element /= Void end has_void_element: BOOLEAN -- Is a void element present (at index 0)? has (an_element: G): BOOLEAN is -- Is `an_element' in the list? require an_element_not_void: an_element /= Void do Result := elements_impl.has (an_element) ensure consistent: Result implies elements.has (an_element) end feature -- Element change insert_void_element is -- Insert a void element at the beginning of the list (allows to deselect). -- This element will not count as a normal element do has_void_element := True set_changed ensure has_void_element: has_void_element count_not_changed: count = old count changed: is_changed end unselect is -- Clear selection do selected_element := Void selected_index := 0 Component_event_queue.add_event (selection_changed_event, [selected_element]) set_changed ensure nothing_selected: not has_selected_element changed: is_changed end set_selected_element (an_element: G) is -- Set `selected_element' to `an_element'. require an_element_not_void: an_element /= Void an_element_present: has (an_element) do selected_element := an_element elements_impl.start elements_impl.search_forth (an_element) selected_index := elements_impl.index Component_event_queue.add_event (selection_changed_event, [selected_element]) set_changed ensure selected_element_set: selected_element = an_element changed: is_changed end set_selected_index (an_index: INTEGER) is -- Set `selected_element' to element at `an_index'. require an_index_valid: 1 <= an_index and an_index <= count do selected_element := elements_impl.item (an_index) selected_index := an_index Component_event_queue.add_event (selection_changed_event, [selected_element]) set_changed ensure selected_index_set: selected_index = an_index changed: is_changed end put (an_element: G) is -- Extend `elements' by `an_element'. require an_element_not_void: an_element /= Void do elements_impl.put_last (an_element) set_changed ensure added: has (an_element) changed: is_changed end extend (a_list: DS_LINEAR [G]) is -- Extend `elements' by `a_list'. require a_list_not_void: a_list /= Void do elements_impl.extend_last (a_list) set_changed ensure added: True changed: is_changed end sort (a_sorter: DS_SORTER [G]) is -- Sort `elements' according to `a_sorter'. do a_sorter.sort (elements_impl) set_changed ensure sorted: a_sorter.sorted (elements_impl) changed: is_changed end feature -- Removal remove (an_element: G) is -- Remove `an_element' from the list. require an_element_not_void: an_element /= Void do elements_impl.delete (an_element) set_changed ensure an_element_removed: not has (an_element) changed: is_changed end wipe_out is -- Wipe out 'elements'. do unselect elements_impl.wipe_out set_changed ensure changed: is_changed end feature -- Events selection_changed_event: EM_EVENT_CHANNEL [TUPLE [G]] -- Selection change event feature {EM_LIST, EM_LIST_DELEGATE} -- Implementation elements_impl: DS_LIST [G] -- List of elements invariant element_selected: has_selected_element implies selected_element /= Void index_selected: has_selected_element implies (1 <= selected_index and selected_index <= count) selection_change_event_not_void: selection_changed_event /= Void end