Class: Glimmer::LibUI::ControlProxy::TableProxy
  
  
  
Overview
  
    
Proxy for LibUI table objects
Follows the Proxy Design Pattern
   
 
  
  
    
      Constant Summary
      collapse
    
    
      
        - CUSTOM_LISTENER_NAMES =
          
        
 
        ['on_changed', 'on_edited']
 
      
        - DEFAULT_COLUMN_SORT_BLOCK =
          
        
 
        lambda do |table_cell_row, column, table_proxy|
  if table_cell_row.is_a?(Array)
    value = table_cell_row[column]
  else
    attribute = table_proxy.column_attributes[column]
    value = table_cell_row.send(attribute)
  end
  if value.is_a?(Array)
        value = value.map do |element|
      case element
      when true
        1
      when false
        0
      else
        element
      end
    end
  end
  value
end 
      
    
  
  
  
  
  BOOLEAN_PROPERTIES, KEYWORD_ALIASES, STRING_PROPERTIES, TransformProxy
  Instance Attribute Summary collapse
  
  
  
  
  #args, #block, #content_added, #custom_control, #keyword, #libui, #options, #parent_custom_control, #parent_proxy, #slot
  
    
      Instance Method Summary
      collapse
    
    
      
        - 
  
    
      #array_deep_dup(array_or_object)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #cell_rows(rows = nil)  ⇒ Object 
    
    
      (also: #cell_rows=, #set_cell_rows)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #column_attributes  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #column_proxies  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #compound_column_index_for(expanded_column_index)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #data_bind_read(property, model_binding)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #data_bind_write(property, model_binding)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #destroy  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #editable(value = nil)  ⇒ Object 
    
    
      (also: #editable=, #set_editable, #editable?)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #expand_cell_row(cell_row)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #expand_cell_row_from_model(cell_row)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #expand_cell_rows(cell_rows = nil)  ⇒ Object 
    
    
      (also: #expanded_cell_rows)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #handle_listener(listener_name, &listener)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #header_visible  ⇒ Object 
    
    
      (also: #header_visible?)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #header_visible=(value)  ⇒ Object 
    
    
      (also: #set_header_visible)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #initialize(keyword, parent, args, &block)  ⇒ TableProxy 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    
A new instance of TableProxy.
 
  
 
      
        - 
  
    
      #post_add_content  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #post_initialize_child(child)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #selection  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #selection=(*value)  ⇒ Object 
    
    
      (also: #set_selection)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #selection_mode(value = nil)  ⇒ Object 
    
    
      (also: #selection_mode=, #set_selection_mode)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #sortable  ⇒ Object 
    
    
      (also: #sortable?)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
        - 
  
    
      #sortable=(value)  ⇒ Object 
    
    
      (also: #set_sortable)
    
  
  
  
  
  
  
  
  
  
    
  
 
      
    
  
  
  
  
  
  
  
  
  
  
  #fiddle_closure_block_caller
  
  
  
  
  
  
  
  
  
  #append_properties, #append_property, #bind_content, #can_handle_listener?, constant_symbol, #content, control_proxies, control_proxy_class, create, #custom_listener_name_aliases, #custom_listener_names, #default_destroy, #deregister_all_custom_listeners, #deregister_custom_listeners, descendant_keyword_constant_map, #destroy_child, #enabled, exists?, #handle_custom_listener, #has_custom_listener?, image_proxies, keyword, #libui_api_keyword, #listeners, #listeners_for, main_window_proxy, map_descendant_keyword_constants_for, menu_proxies, #method_missing, new_control, #notify_custom_listeners, reset_descendant_keyword_constant_map, #respond_to?, #respond_to_libui?, #send_to_libui, #visible, #window_proxy
  
  
  
  
  
  
  
  
  
  #data_bind, #data_binding_model_attribute_observer_registrations
  
  
  
  
  
  
  
  
  Methods included from Parent
  #children
  Constructor Details
  
    
  
  
    #initialize(keyword, parent, args, &block)  ⇒ TableProxy 
  
  
  
  
    
Returns a new instance of TableProxy.
   
 
  
  
    
      
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 65
def initialize(keyword, parent, args, &block)
  @keyword = keyword
  @parent_proxy = parent
  @args = args
  @block = block
  @enabled = true
  @columns = []
  @cell_rows = []
  @last_cell_rows = nil
  register_cell_rows_observer
  window_proxy.on_destroy do
        ::LibUI.free_table_model(@model) unless @destroyed && parent_proxy.is_a?(Box)
  end
end
     | 
  
 
  
 
  
    Instance Attribute Details
    
      
      
      
  
  
    #columns  ⇒ Object  
  
  
  
  
    
Returns the value of attribute columns.
   
 
  
  
    
      
63
64
65 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 63
def columns
  @columns
end 
     | 
  
 
    
      
      
      
  
  
    #model  ⇒ Object  
  
  
  
  
    
Returns the value of attribute model.
   
 
  
  
    
      
63
64
65 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 63
def model
  @model
end 
     | 
  
 
    
      
      
      
  
  
    #model_handler  ⇒ Object  
  
  
  
  
    
Returns the value of attribute model_handler.
   
 
  
  
    
      
63
64
65 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 63
def model_handler
  @model_handler
end 
     | 
  
 
    
      
      
      
  
  
    #table_params  ⇒ Object  
  
  
  
  
    
Returns the value of attribute table_params.
   
 
  
  
    
      
63
64
65 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 63
def table_params
  @table_params
end 
     | 
  
 
    
   
  
    Instance Method Details
    
      
  
  
    #array_deep_dup(array_or_object)  ⇒ Object 
  
  
  
  
    
      
274
275
276
277
278
279
280
281
282 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 274
def array_deep_dup(array_or_object)
  if array_or_object.is_a?(Array)
    array_or_object.map do |element|
      array_deep_dup(element)
    end
  else
    array_or_object.dup
  end
end
     | 
  
 
    
      
  
  
    #cell_rows(rows = nil)  ⇒ Object 
  
  
    Also known as:
    cell_rows=, set_cell_rows
    
  
  
  
    
      
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 115
def cell_rows(rows = nil)
  if rows.nil?
    @cell_rows
  else
    if !rows.equal?(@cell_rows)
      @cell_rows = rows
            clear_cached_cell_rows
      if @cell_rows.is_a?(Enumerator)
        @cell_rows.rewind
        @future_last_cell_rows = array_deep_dup(@cell_rows)       end
    end
    @cell_rows
  end
end
     | 
  
 
    
      
  
  
    #column_attributes  ⇒ Object 
  
  
  
  
    
      
232
233
234 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 232
def column_attributes
  @column_attributes ||= columns.select {|column| column.is_a?(Column)}.map(&:name).map(&:underscore)
end
     | 
  
 
    
      
  
  
    #column_proxies  ⇒ Object 
  
  
  
  
    
      
290
291
292 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 290
def column_proxies
  @columns&.select {|c| c.is_a?(Column)}
end
     | 
  
 
    
      
  
  
    #compound_column_index_for(expanded_column_index)  ⇒ Object 
  
  
  
  
    
      
284
285
286
287
288 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 284
def compound_column_index_for(expanded_column_index)
  compound_column = @columns.find { |compound_column| compound_column.respond_to?(:column_index) && compound_column.column_index == expanded_column_index }
  compound_columns = @columns.select { |compound_column| compound_column.is_a?(Column) }
  compound_columns.index(compound_column)
end
     | 
  
 
    
      
  
  
    #data_bind_read(property, model_binding)  ⇒ Object 
  
  
  
  
    
      
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 236
def data_bind_read(property, model_binding)
  if model_binding.binding_options[:column_attributes].is_a?(Array)
    @column_attributes = model_binding.binding_options[:column_attributes]
  else
    column_attribute_mapping = model_binding.binding_options[:column_attributes].is_a?(Hash) ? model_binding.binding_options[:column_attributes] : {}
    @column_attributes = columns.select {|column| column.is_a?(Column)}.map(&:name).map {|column_name| column_attribute_mapping[column_name] || column_name.underscore}
  end
  model_attribute_observer = model_attribute_observer_registration = nil
  model_attribute_observer = Glimmer::DataBinding::Observer.proc do
    new_value = model_binding.evaluate_property
    if !new_value.is_a?(Enumerator) &&
      (
        model_binding.binding_options[:column_attributes] ||
        (!new_value.nil? && (!new_value.is_a?(String) || !new_value.empty?) && (!new_value.is_a?(Array) || !new_value.first.is_a?(Array)))
      )
      @model_attribute_array_observer_registration&.deregister
      @model_attribute_array_observer_registration = model_attribute_observer.observe(new_value, column_attributes, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
      model_attribute_observer.add_dependent(model_attribute_observer_registration => @model_attribute_array_observer_registration)
    end
        last_cell_rows = @last_cell_rows || []     send("#{property}=", new_value) unless last_cell_rows == new_value
  end
  model_attribute_observer_registration = model_attribute_observer.observe(model_binding, attribute_writer_type: [:attribute=, :set_attribute])
  model_attribute_observer.call   data_binding_model_attribute_observer_registrations << model_attribute_observer_registration
  model_attribute_observer
end
     | 
  
 
    
      
  
  
    #data_bind_write(property, model_binding)  ⇒ Object 
  
  
  
  
    
      
265
266
267
268
269
270
271
272 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 265
def data_bind_write(property, model_binding)
  case property
  when 'cell_rows'
    handle_listener('on_edited') { model_binding.call(cell_rows) }
  when 'selection'
    handle_listener('on_selection_changed') { model_binding.call(selection) }
  end
end
     | 
  
 
    
      
  
  
    #destroy  ⇒ Object 
  
  
  
  
    
      
108
109
110
111
112
113 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 108
def destroy
  super
    @cell_rows_observer&.unobserve(self, :cell_rows, recursive: true, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
  @destroyed = true
end
     | 
  
 
    
      
  
  
    #editable(value = nil)  ⇒ Object 
  
  
    Also known as:
    editable=, set_editable, editable?
    
  
  
  
    
      
151
152
153
154
155
156
157 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 151
def editable(value = nil)
  if value.nil?
    @editable
  else
    @editable = !!value
  end
end
     | 
  
 
    
      
  
  
    #expand_cell_row(cell_row)  ⇒ Object 
  
  
  
  
    
      
141
142
143
144
145 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 141
def expand_cell_row(cell_row)
  return cell_row if cell_row.nil?
  cell_row = expand_cell_row_from_model(cell_row) if !cell_row.is_a?(Array) && column_attributes.any?
  cell_row.flatten(1)
end 
     | 
  
 
    
      
  
  
    #expand_cell_row_from_model(cell_row)  ⇒ Object 
  
  
  
  
    
      
147
148
149 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 147
def expand_cell_row_from_model(cell_row)
  column_attributes.to_a.map {|attribute| cell_row.send(attribute) }
end
     | 
  
 
    
      
  
  
    #expand_cell_rows(cell_rows = nil)  ⇒ Object 
  
  
    Also known as:
    expanded_cell_rows
    
  
  
  
    
      
134
135
136
137
138 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 134
def expand_cell_rows(cell_rows = nil)
  cell_rows ||= self.cell_rows
  cell_rows ||= []
  cell_rows.map { |cell_row| expand_cell_row(cell_row) }
end
     | 
  
 
    
      
  
  
    #handle_listener(listener_name, &listener)  ⇒ Object 
  
  
  
  
    
      
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 294
def handle_listener(listener_name, &listener)
    if CUSTOM_LISTENER_NAMES.include?(listener_name) || @content_added
    actual_listener = listener
    case listener_name
    when 'on_selection_changed'
      actual_listener = Proc.new do |myself, *args|
        added_selection = selection.is_a?(Array) ? (selection - @old_selection.to_a) : selection
        removed_selection = selection.is_a?(Array) ? (@old_selection.to_a - selection) : @old_selection
        listener.call(myself, selection, added_selection, removed_selection)
      end
    end
    super(listener_name, &actual_listener)
  else
        @table_listeners ||= []
    @table_listeners << [listener_name, listener]
  end
end
     | 
  
 
    
      
  
  
    
      
203
204
205
206
207
208 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 203
def 
  return @header_visible if !@content_added
  
  result = ::LibUI.(@libui)
  LibUI.integer_to_boolean(result)
end 
     | 
  
 
    
      
  
  
    
      
211
212
213
214
215
216
217
218 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 211
def (value)
  @header_visible = value
  return @header_visible if !@content_added
  return if value.nil?
  
  value = LibUI.boolean_to_integer(value)
  ::LibUI.(@libui, value)
end 
     | 
  
 
    
      
  
  
    #post_add_content  ⇒ Object 
  
  
  
  
    
      
81
82
83
84
85
86
87
88
89
90
91
92 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 81
def post_add_content
  build_control if !@content_added && @libui.nil?
  super
    register_listeners
  register_column_listeners
  configure_selection_mode
  configure_selection
  
  configure_column_sort_indicators
  configure_sorting
end
     | 
  
 
    
      
  
  
    #post_initialize_child(child)  ⇒ Object 
  
  
  
 
    
      
  
  
    #selection  ⇒ Object 
  
  
  
  
    
      
173
174
175
176
177
178
179
180
181
182
183
184 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 173
def selection
  return @selection if !@content_added
  
  tsp = super
  ts = ::LibUI::FFI::TableSelection.new(tsp)
  if ts.NumRows > 0
    selection_array = ts.Rows[0, Fiddle::SIZEOF_INT * ts.NumRows].unpack("i*")
    selection_mode == ::LibUI::TableSelectionModeZeroOrMany ? selection_array : selection_array.first
  end
ensure
  ::LibUI.free_table_selection(tsp)
end
     | 
  
 
    
      
  
  
    #selection=(*value)  ⇒ Object 
  
  
    Also known as:
    set_selection
    
  
  
  
    
      
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 186
def selection=(*value)
  value = value.first if value.size == 1
  @selection = value
  return @selection if !@content_added
  return if @selection.nil?
  ts = ::LibUI::FFI::TableSelection.malloc
  ts.NumRows = @selection.is_a?(Array) ? @selection.size : 1
  ts.Rows = [@selection].flatten.pack('i*')
  super(ts)
    end
     | 
  
 
    
      
  
  
    #selection_mode(value = nil)  ⇒ Object 
  
  
    Also known as:
    selection_mode=, set_selection_mode
    
  
  
  
    
      
162
163
164
165
166
167
168
169 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 162
def selection_mode(value = nil)
  if value.nil?
    @selection_mode
  else
    value = LibUI.enum_symbol_to_value(:table_selection_mode, value)
    @selection_mode = value
  end
end
     | 
  
 
    
      
  
  
    #sortable  ⇒ Object 
  
  
    Also known as:
    sortable?
    
  
  
  
    
      
221
222
223
224 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 221
def sortable
  @sortable = true if @sortable.nil?
  @sortable
end 
     | 
  
 
    
      
  
  
    #sortable=(value)  ⇒ Object 
  
  
    Also known as:
    set_sortable
    
  
  
  
    
      
227
228
229 
     | 
    
      # File 'lib/glimmer/libui/control_proxy/table_proxy.rb', line 227
def sortable=(value)
  @sortable = value
end 
     |