module Canis::NewListSelectable
Public Instance Methods
add the following range to selected items, unless already present should only be used if multiple selection interval
# File lib/canis/core/include/deprecated/listselectable.rb, line 121 def add_selection_interval ix0, ix1 return if @selection_mode != :multiple @widget_scrolled = true # FIXME we need a better name @anchor_selection_index = ix0 @lead_selection_index = ix1 ix0.upto(ix1) {|i| @selected_indices << i unless @selected_indices.include? i } lse = ListSelectionEvent.new(ix0, ix1, self, :INSERT) fire_handler :LIST_SELECTION_EVENT, lse #$log.debug " DLSM firing LIST_SELECTION EVENT #{lse}" end
Only for multiple mode. add an item to selection, if selection mode is multiple if item already selected, it is deselected, else selected typically bound to Ctrl-Space @example
bind_key(0) { add_to_selection }
# File lib/canis/core/include/deprecated/listselectable.rb, line 57 def add_to_selection crow=@current_index-@_header_adjustment @last_clicked ||= crow min = [@last_clicked, crow].min max = [@last_clicked, crow].max case @selection_mode when :multiple @widget_scrolled = true # FIXME we need a better name if @selected_indices.include? crow # delete from last_clicked until this one in any direction min.upto(max){ |i| @selected_indices.delete i } lse = ListSelectionEvent.new(min, max, self, :DELETE) fire_handler :LIST_SELECTION_EVENT, lse else # add to selection from last_clicked until this one in any direction min.upto(max){ |i| @selected_indices << i unless @selected_indices.include?(i) } lse = ListSelectionEvent.new(min, max, self, :INSERT) fire_handler :LIST_SELECTION_EVENT, lse end else end @repaint_required = true self end
please override this, this is just very basic and default Please implement get_matching_indices
(String
).
# File lib/canis/core/include/deprecated/listselectable.rb, line 190 def ask_select prompt="Enter selection pattern: " ret = ask(prompt, String) {|q| yield q if block_given? } return if ret.nil? || ret == "" indices = get_matching_indices ret return if indices.nil? || indices.empty? indices.each { |e| # will not work if single select !! FIXME add_row_selection_interval e,e } @repaint_required = true end
clears selected indices, typically called when multiple select Key binding is application specific
# File lib/canis/core/include/deprecated/listselectable.rb, line 82 def clear_selection return if @selected_indices.nil? || @selected_indices.empty? @selected_indices = [] @selected_index = nil @old_selected_index = nil # Not sure what event type I should give, DELETE or a new one, user should # understand that selection has been cleared, and ignore first two params lse = ListSelectionEvent.new(0, @list.size, self, :CLEAR) fire_handler :LIST_SELECTION_EVENT, lse @repaint_required = true @widget_scrolled = true # FIXME we need a better name end
# File lib/canis/core/include/deprecated/listselectable.rb, line 201 def get_matching_indices pattern alert "please implement this method get_matching_indices(pattern)->[] in your class " return [] end
FIXME add adjustment and test
# File lib/canis/core/include/deprecated/listselectable.rb, line 104 def goto_next_selection return if selected_rows().length == 0 row = selected_rows().sort.find { |i| i > @current_index } row ||= @current_index @current_index = row @repaint_required = true # fire list_select XXX end
FIXME add adjustment and test
# File lib/canis/core/include/deprecated/listselectable.rb, line 112 def goto_prev_selection return if selected_rows().length == 0 row = selected_rows().sort{|a,b| b <=> a}.find { |i| i < @current_index } row ||= @current_index @current_index = row @repaint_required = true # fire list_select XXX end
convenience method to select next len rows
# File lib/canis/core/include/deprecated/listselectable.rb, line 141 def insert_index_interval ix0, len @anchor_selection_index = ix0 @lead_selection_index = ix0+len add_selection_interval @anchor_selection_index, @lead_selection_index end
# File lib/canis/core/include/deprecated/listselectable.rb, line 159 def invert_row_selection row=@current_index-@_header_adjustment @repaint_required = true if is_selected? row remove_row_selection_interval(row, row) else add_row_selection_interval(row, row) end end
# File lib/canis/core/include/deprecated/listselectable.rb, line 155 def invert_selection start_row=0 #+@_header_adjustment start_row.upto(row_count()){|i| invert_row_selection i } end
# File lib/canis/core/include/deprecated/listselectable.rb, line 94 def is_row_selected crow=@current_index-@_header_adjustment case @selection_mode when :multiple @selected_indices.include? crow else crow == @selected_index end end
bindings related to selection
# File lib/canis/core/include/deprecated/listselectable.rb, line 210 def list_bindings # what about users wanting 32 and ENTER to also go to next row automatically # should make that optional, TODO bind_key($row_selector || 32, 'toggle selection') { toggle_row_selection } # 2013-03-24 - 14:46 added condition so single select does not get these if @selection_mode == :multiple bind_key(0, 'range select') { add_to_selection } bind_key(?+, :ask_select) # --> calls select_values bind_key(?-, :ask_unselect) # please implement FIXME TODO bind_key(?a, :select_all) bind_key(?*, :invert_selection) bind_key(?u, :clear_selection) end @_header_adjustment ||= 0 # incase caller does not use @_events << :LIST_SELECTION_EVENT unless @_events.include? :LIST_SELECTION_EVENT end
# File lib/canis/core/include/deprecated/listselectable.rb, line 226 def list_init_vars @selected_indices = [] @selected_index = nil @old_selected_index = nil #@row_selected_symbol = '' if @show_selector @row_selected_symbol ||= '*' @row_unselected_symbol ||= ' ' @left_margin ||= @row_selected_symbol.length end end
paint the selector. Called from repaint, prior to printing data row remember to set left_margin at top of repaint method as:
@left_margin ||= @row_selected_symbol.length
# File lib/canis/core/include/deprecated/listselectable.rb, line 240 def paint_selector crow, r, c, acolor, attrib selected = is_row_selected crow selection_symbol = '' if @show_selector if selected selection_symbol = @row_selected_symbol else selection_symbol = @row_unselected_symbol end @graphic.printstring r, c, selection_symbol, acolor,attrib end end
# File lib/canis/core/include/deprecated/listselectable.rb, line 132 def remove_selection_interval ix0, ix1 @anchor_selection_index = ix0 @lead_selection_index = ix1 @selected_indices.delete_if {|x| x >= ix0 and x <= ix1} lse = ListSelectionEvent.new(ix0, ix1, self, :DELETE) fire_handler :LIST_SELECTION_EVENT, lse end
select all rows, you may specify starting row. if header row, then 1 else should be 0. Actually we should have a way to determine this, and the default should be zero.
# File lib/canis/core/include/deprecated/listselectable.rb, line 149 def select_all start_row=0 #+@_header_adjustment @repaint_required = true # don't select header row - need to make sure this works for all cases. we may # need a variable instead of hardoded value add_row_selection_interval start_row, row_count() end
selects all rows with the values given, leaving existing selections intact. Typically used after accepting search criteria, and getting a list of values to select (such as file names). Will not work with tables (array or array)
# File lib/canis/core/include/deprecated/listselectable.rb, line 170 def select_values values return unless values values.each do |val| row = @list.index val add_row_selection_interval row, row unless row.nil? end end
# File lib/canis/core/include/deprecated/listselectable.rb, line 252 def selected_rows @selected_indices end
change selection of current row on pressing space bar If mode is multiple, then other selections are cleared and this is added @example
bind_key(32) { toggle_row_selection }
current_index is not account for header_adjustment if current row is selected in mulitple we should deselect ?? FIXME
# File lib/canis/core/include/deprecated/listselectable.rb, line 21 def toggle_row_selection crow=@current_index-@_header_adjustment @last_clicked = crow @repaint_required = true case @selection_mode when :multiple @widget_scrolled = true # FIXME we need a better name if @selected_indices.include? crow @selected_indices.delete crow lse = ListSelectionEvent.new(crow, crow, self, :DELETE) fire_handler :LIST_SELECTION_EVENT, lse else @selected_indices << crow lse = ListSelectionEvent.new(crow, crow, self, :INSERT) fire_handler :LIST_SELECTION_EVENT, lse end else if @selected_index == crow @old_selected_index = @selected_index # 2011-10-15 so we can unhighlight @selected_index = nil lse = ListSelectionEvent.new(crow, crow, self, :DELETE) fire_handler :LIST_SELECTION_EVENT, lse else @old_selected_index = @selected_index # 2011-10-15 so we can unhighlight @selected_index = crow lse = ListSelectionEvent.new(crow, crow, self, :INSERT) fire_handler :LIST_SELECTION_EVENT, lse end end end
unselects all rows with the values given, leaving all other rows intact You can map “-” to ask_select
and call this from there.
bind_key(?+, :ask_select) # --> calls select_values bind_key(?-, :ask_unselect)
# File lib/canis/core/include/deprecated/listselectable.rb, line 181 def unselect_values values return unless values values.each do |val| row = @list.index val remove_row_selection_interval row, row unless row.nil? end end