Class: Umbra::Table

Inherits:
Multiline show all
Extended by:
Forwardable
Defined in:
lib/umbra/table.rb

Overview

A table of columnar data. This uses Tabular as a table model and extends Multiline.

Instance Attribute Summary collapse

Attributes inherited from Multiline

#current_index, #list, #panned_cols, #search_offset

Attributes inherited from Widget

#col, #col_offset, #curpos, #focusable, #graphic, #handler, #key_label, #modified, #name, #repaint_required, #row, #row_offset, #state

Instance Method Summary collapse

Methods inherited from Multiline

#_truncate_to_width, #ask_search, #color_of_row, #command, #current_row, #cursor_backward, #cursor_down, #cursor_end, #cursor_forward, #cursor_home, #cursor_up, #delete_at, #ensure_visible, #find_more, #getvalue, #goto_end, #goto_line, #goto_start, #handle_key, #insert, #is_visible?, #map_keys, #next_match, #on_enter, #on_enter_row, #on_leave, #on_leave_row, #page_backward, #page_forward, #paint_row, #scroll_down, #scroll_left, #scroll_right, #scroll_up, #state_of_row, #to_searchable, #value_of_row

Methods inherited from Widget

#_form=, #color_pair, #command, #getvalue, #getvalue_for_paint, #handle_key, #height, #highlight_attr, #init_vars, #modified?, #on_enter, #on_leave, #repaint_all, #rowcol, #set_form_col, #set_form_row, #text, #touch, #variable_set, #visible, #width

Methods included from KeyMappingHandler

#_process_key, #bind_key, #bind_keys, #process_key, #unbind_key

Methods included from EventHandler

#bind_event, #event?, #fire_handler, #fire_property_change, #register_events

Constructor Details

#initialize(config = {}, &block) ⇒ Table

Create a Table object passing either a Tabular object or columns and list e.g. Table.new tabular: tabular

Table.new columns: cols, list: mylist


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/umbra/table.rb', line 58

def initialize config={}, &block
  if config.key? :tabular
    @tabular = config.delete(:tabular)
  else
    cols = config.delete(:columns)
    data = config.delete(:list)
    @tabular = Tabular.new cols
    if data
      @tabular.data = data
    end
  end
  @rendered = nil
  super

  bind_key(?w, "next column") { self.next_column }
  bind_key(?b, "prev column") { self.prev_column }
  bind_key(KEY_RETURN, :fire_action_event)
  ## NOTE: a tabular object should be existing at this point.
end

Instance Attribute Details

#header_attrObject

color pair and attribute for header row



49
50
51
# File 'lib/umbra/table.rb', line 49

def header_attr
  @header_attr
end

#header_color_pairObject

color pair and attribute for header row



49
50
51
# File 'lib/umbra/table.rb', line 49

def header_color_pair
  @header_color_pair
end

#renderedObject

boolean, if data has changed, we need to re-render



51
52
53
# File 'lib/umbra/table.rb', line 51

def rendered
  @rendered
end

#tabularObject

tabular is the data model for Table. It may be passed in in the constructor, or else is created when columns and data are passed in.



46
47
48
# File 'lib/umbra/table.rb', line 46

def tabular
  @tabular
end

Instance Method Details

#_print_data(win, row, col, str, index, state, data_index) ⇒ Object

Print the data. index is index into visual row, starting 0 for headings, and 1 for separator data_index is index into actual data object. Use this if checking actual data array



151
152
153
154
155
156
# File 'lib/umbra/table.rb', line 151

def _print_data(win, row, col, str, index, state, data_index)
  data_index = index - @data_offset  ## index into actual data object
  arr = color_of_data_row(index, state, data_index)

  win.printstring(row, col, str, arr[0], arr[1])
end

#_print_headings(win, row, col, str, index, state) ⇒ Object

Print the header row index [Integer] - should be 0 or 1 (1 for optional separator)



141
142
143
144
# File 'lib/umbra/table.rb', line 141

def _print_headings(win, row, col, str, index, state)
  arr = color_of_header_row(index, state)
  win.printstring(row, col, str, arr[0], arr[1])
end

#color_of_column(ix, value, defaultcolor) ⇒ Object



157
158
159
# File 'lib/umbra/table.rb', line 157

def color_of_column ix, value, defaultcolor
  raise "unused yet"
end

#color_of_data_row(index, state, data_index) ⇒ Object

Specify how the data rows are to be coloured. Override this to have customised row coloring.

Returns:

  • array of color_pair and attrib.



124
125
126
# File 'lib/umbra/table.rb', line 124

def color_of_data_row index, state, data_index
  color_of_row(index, state)         ## calling superclass here
end

#color_of_header_row(index, state) ⇒ Object

Specify how to print the header and separator. index can be 0 or 1 returns an array of color_pair and attribute



115
116
117
118
119
# File 'lib/umbra/table.rb', line 115

def color_of_header_row index, state
    arr =  [ @header_color_pair || CP_MAGENTA, @header_attr || REVERSE ] 
    return arr if index == 0
    [ arr[0], NORMAL ]
end

#current_column_offsetInteger

Convert current cursor position to a table column calculate column based on curpos since user may not have used w and b keys (:next_column)

Returns:

  • (Integer)

    column index base 0



226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/umbra/table.rb', line 226

def current_column_offset
  _calculate_column_offsets unless @coffsets
  x = 0
  @coffsets.each_with_index { |i, ix| 
    if @curpos < i 
      break
    else 
      x += 1
    end
  }
  x -= 1 # since we start offsets with 0, so first auto becoming 1
  return x
end

#current_idObject

return rowid (assumed to be first column)



169
170
171
172
173
# File 'lib/umbra/table.rb', line 169

def current_id
  data = current_row_as_array()
  return nil unless data
  data.first
end

#current_row_as_arrayObject

How do I deal with separators and headers here - return nil This returns all columns including hidden so rowid can be accessed



176
177
178
179
180
# File 'lib/umbra/table.rb', line 176

def current_row_as_array
  data_index = @current_index - @data_offset  ## index into actual data object
  return nil if data_index < 0                ## separator and heading
  data()[data_index]
end

#current_row_as_hashObject

returns the current row as a hash with column name as key.



183
184
185
186
187
188
# File 'lib/umbra/table.rb', line 183

def current_row_as_hash
  data = current_row_as_array
  return nil unless data
  columns = @tabular.columns
  hash = columns.zip(data).to_h
end

#dataObject

returns the raw data as array of arrays in tabular



79
80
81
# File 'lib/umbra/table.rb', line 79

def data
  @tabular.list
end

#data=(list) ⇒ Object



84
85
86
87
88
89
90
91
92
93
# File 'lib/umbra/table.rb', line 84

def data=(list)
  @rendered = false
  @tabular.data = list
  @repaint_required = true
  self.focusable = true
  @pstart = @current_index = 0
  @pcol               = 0
  #$log.debug "  before table data= CHANGED "
  #fire_handler(:CHANGED, self)    ## added 2018-05-08 - 
end

#fire_action_eventObject

Handle case where ENTER/RETURN pressed on header row (so sorting can be done).



245
246
247
248
249
250
251
# File 'lib/umbra/table.rb', line 245

def fire_action_event
  if header_row?
    # TODO sorting here
    $log.debug "  PRESSED ENTER on header row, TODO sorting here"
  end
  super
end

#header_row?Boolean

Returns:

  • (Boolean)


240
241
242
# File 'lib/umbra/table.rb', line 240

def header_row?
  @current_index == 0 and @data_offset > 0
end

#next_columnObject

Move cursor to next column



191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/umbra/table.rb', line 191

def next_column
  @coffsets = @tabular._calculate_column_offsets unless @coffsets
  #c = @column_pointer.next
  current_column = current_column_offset() +1
  if current_column > @tabular.column_count-1
    current_column = 0
  end
  cp = @coffsets[current_column] 
  @curpos = cp if cp
  $log.debug " next_column #{@coffsets} :::: #{cp}, curpos=#{@curpos} "
  set_col_offset @curpos
  #down() if c < @column_pointer.last_index
  #fire_column_event :ENTER_COLUMN
end

#prev_columnObject

Move cursor to previous column



207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/umbra/table.rb', line 207

def prev_column
  @coffsets = @tabular._calculate_column_offsets unless @coffsets
  #c = @column_pointer.next
  current_column = current_column_offset() -1
  if current_column < 0 # 
    current_column = @tabular.column_count-1
  end
  cp = @coffsets[current_column] 
  @curpos = cp if cp
  $log.debug " next_column #{@coffsets} :::: #{cp}, curpos=#{@curpos} "
  set_col_offset @curpos
  #down() if c < @column_pointer.last_index
  #fire_column_event :ENTER_COLUMN
end

Print the row which could be header or data

Parameters:

  • index (Integer)
    • index of list, starting with header and separator



130
131
132
133
134
135
136
137
# File 'lib/umbra/table.rb', line 130

def print_row(win, row, col, str, index, state)
  if index <= @data_offset - 1
    _print_headings(win, row, col, str, index, state)
  else
    data_index = index - @data_offset  ## index into actual data object
    _print_data(win, row, col, str, index, state, data_index)
  end
end

#renderObject

render the two-dimensional array of data as an array of Strings. Calculates data_offset which is the row offset from which data starts.



97
98
99
100
101
102
# File 'lib/umbra/table.rb', line 97

def render
  @data_offset = 0
  @data_offset +=1 if @tabular.use_separator
  @data_offset +=1 if @tabular.columns
  self.list = @tabular.render
end

#repaintObject

paint the table



105
106
107
108
109
110
# File 'lib/umbra/table.rb', line 105

def repaint
  render if !@rendered
  super

  @rendered = true
end

#row_countObject



163
164
165
# File 'lib/umbra/table.rb', line 163

def row_count
  @tabular.list.size
end