Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editable checkbox columns do not fire SetCellValue on checking/unchecking on the Mac #28

Closed
AndyObtiva opened this issue Sep 26, 2021 · 8 comments

Comments

@AndyObtiva
Copy link
Collaborator

AndyObtiva commented Sep 26, 2021

Please try this example and let me know if you think this is a bug in the C libui or if there is a reason why SetCellValue does not fire:

# frozen_string_literal: true

require 'libui'

UI = LibUI

UI.init

main_window = UI.new_window('Animal sounds', 300, 200, 1)

hbox = UI.new_horizontal_box
UI.window_set_child(main_window, hbox)

data = [
  %w[0 cat 1 meow],
  %w[0 dog 1 woof],
  %w[1 checken 0 cock-a-doodle-doo],
  %w[1 hourse 1 neigh],
  %w[0 cow 0 moo]
]

# Protects BlockCaller objects from garbage collection.
@blockcaller = []
def rbcallback(*args, &block)
  args << [0] if args.size == 1 # Argument types are ommited
  blockcaller = Fiddle::Closure::BlockCaller.new(*args, &block)
  @blockcaller << blockcaller
  blockcaller
end

model_handler = UI::FFI::TableModelHandler.malloc
model_handler.NumColumns   = rbcallback(4) { 2 }
model_handler.ColumnType = rbcallback(4, [1, 1, 4]) do | _mh, _m, column|
  column.odd? ? 0 : 2 # uiTableValueTypeInt : uiTableValueTypeString
end
model_handler.NumRows      = rbcallback(4) { 5 }
model_handler.CellValue    = rbcallback(1, [1, 1, 4, 4]) do |_, _, row, column|
  if column.odd?
    UI.new_table_value_string(data[row][column])
  else
    UI.new_table_value_int(data[row][column].to_i)
  end
end
model_handler.SetCellValue = rbcallback(0, [1, 1, 4, 4, 1]) do |_, _, row, column, val|
  puts [row, column, val].inspect
end

model = UI.new_table_model(model_handler)

table_params = UI::FFI::TableParams.malloc
table_params.Model = model
table_params.RowBackgroundColorModelColumn = -1

table = UI.new_table(table_params)
UI.table_append_checkbox_text_column(table, 'Animal', 0, -2, 1, -2)
UI.table_append_checkbox_text_column(table, 'Description', 2, -2, 3, -2)

UI.box_append(hbox, table, 1)
UI.control_show(main_window)

UI.window_on_closing(main_window) do
  puts 'Bye Bye'
  UI.control_destroy(main_window)
  UI.free_table_model(model)
  UI.quit
  0
end

UI.main
UI.quit

Update: I added the ColumnType code you suggested, which was not needed on the Mac where I first ran the code, but is required on Linux.
Update 2: I had the problem on the Mac (I reported before I got a chance to test on Linux, on which it worked when I later tested)

@kojix2
Copy link
Owner

kojix2 commented Sep 26, 2021

Hmm. I don't know if this is enough, but at least you need to specify the ColumnType.

model_handler.ColumnType = rbcallback(4, [1, 1, 4]) do | _mh, _m, column|
  column.odd? ? 0 : 2 # uiTableValueTypeString : uiTableValueTypeInt
end 

@AndyObtiva
Copy link
Collaborator Author

I added that code and it still does not fire SetCellValue upon editing checkboxes, but it does fire when editing text.

I will look into C libui to see if there is any useful information regarding table checkbox editing.

Thanks

@AndyObtiva
Copy link
Collaborator Author

The documentation of the Golang LibUI library clearly says: "AppendCheckboxColumn appends a column to t that contains a checkbox that the user can interact with (assuming the checkbox is editable). SetCellValue will be called with checkboxModelColumn as the column in this case."

I will keep digging.

@AndyObtiva
Copy link
Collaborator Author

I get the same issue with this example (using checkbox column instead of the dual-checkbox-text column):

# frozen_string_literal: true

require 'libui'

UI = LibUI

UI.init

main_window = UI.new_window('Animal sounds', 300, 200, 1)

hbox = UI.new_horizontal_box
UI.window_set_child(main_window, hbox)

data = [
  [0, 'cat', 'meow'],
  [0, 'dog', 'woof'],
  [1, 'checken', 'cock-a-doodle-doo'],
  [1, 'hourse', 'neigh'],
  [0, 'cow', 'moo']
]

# Protects BlockCaller objects from garbage collection.
@blockcaller = []
def rbcallback(*args, &block)
  args << [0] if args.size == 1 # Argument types are ommited
  blockcaller = Fiddle::Closure::BlockCaller.new(*args, &block)
  @blockcaller << blockcaller
  blockcaller
end

model_handler = UI::FFI::TableModelHandler.malloc
model_handler.NumColumns   = rbcallback(4) { 2 }
model_handler.ColumnType = rbcallback(4, [1, 1, 4]) do | _mh, _m, column|
  case column
  when 0
    2
  else
    0
  end
end
model_handler.NumRows      = rbcallback(4) { 5 }
model_handler.CellValue    = rbcallback(1, [1, 1, 4, 4]) do |_, _, row, column|
  case column
  when 0
    UI.new_table_value_int(data[row][column].to_i)
  else
    UI.new_table_value_string(data[row][column])
  end
end
model_handler.SetCellValue = rbcallback(0, [1, 1, 4, 4, 1]) do |_, _, row, column, val|
  puts [row, column].inspect
  case column
  when 0
    data[row][column] = UI.table_value_int(val).to_i
  else
    data[row][column] = UI.table_value_string(val).to_s
  end
end

model = UI.new_table_model(model_handler)

table_params = UI::FFI::TableParams.malloc
table_params.Model = model
table_params.RowBackgroundColorModelColumn = -1

table = UI.new_table(table_params)
UI.table_append_checkbox_column(table, 'Selected', 0, -2)
UI.table_append_text_column(table, 'Animal', 1, -2)
UI.table_append_text_column(table, 'Description', 2, -2)

UI.box_append(hbox, table, 1)
UI.control_show(main_window)

UI.window_on_closing(main_window) do
  puts 'Bye Bye'
  UI.control_destroy(main_window)
  UI.free_table_model(model)
  UI.quit
  0
end

UI.main
UI.quit

Before reporting to the C libui project, I wondered if you perhaps knew how to replicate the same example in C to fully confirm the bug is not in Ruby and provide an example to report to C libui (I think you would be the better person to report it in that case)

@kojix2
Copy link
Owner

kojix2 commented Sep 27, 2021

I ran your code, and you're right, SetCellValue is not firing.
That is strange. I don't have time today, so I'll look into it after tomorrow.

@kojix2
Copy link
Owner

kojix2 commented Sep 27, 2021

Looking at libui's unix/table.c, you can see signal_connect is here.

	g_signal_connect(r, "toggled", G_CALLBACK(checkboxColumnToggled), p);

So I compiled the tester with printf("FOO"); at the beginning of the checkboxColumnToggled function. checkboxColumnToggled calls SetCellValue via onEdit. So, if FOO is output, SetCellValue should be called.

However, when I click on the checkbox, FOO is not output.
Interestingly, when I edit an Editable cell, the checkboxColumnToggled fires all at once. It seems that all the previous triggers have been flushed out at once.

I found the following problem reported in ui. (Parhaps you may already know this).
andlabs/ui#357

Yes, it might be a bug in C libui. Or. I've only tried it on unix, but if it's the same on macOS, it may be intentional behavior rather than a bug.

@kojix2
Copy link
Owner

kojix2 commented Sep 27, 2021

SetCellValue fires on Windows.

@AndyObtiva AndyObtiva changed the title Editable checkbox columns do not fire SetCellValue on checking/unchecking Editable checkbox columns do not fire SetCellValue on checking/unchecking on the Mac Sep 27, 2021
@AndyObtiva
Copy link
Collaborator Author

Closing this since it has been reported as a C libui issue (not a Ruby one).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants