Open AndyObtiva opened 1 year ago
Hello I have added recent libui functions and structures. I have not checked that it works. However, very few people seem to be using the pre-release version, so I have released it. Before I forget this issue exists. Please let me know if you have any problems. Thank you very much.
https://github.com/kojix2/LibUI/commit/921157e4b4dd6c8bc193e6e32dc48dd442372be3
Thank you! I missed those new table methods the last time I supported a pre version of your bindings.
But, my code crashes whenever I try to use any of the new table listeners:
table_on_row_clicked
table_on_row_double_clicked
table_on_selection_changed
Perhaps their new API differs from the older common API for listeners?
Could you please share code using the listeners above that works using LibUI
alone so that I could translate it to Glimmer DSL for LibUI code (please include table_header_on_clicked
too in your example)?
Sure. If you use a block to receive arguments, it works like this.
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[cat meow],
%w[dog woof],
%w[chicken cock-a-doodle-doo],
%w[horse neigh],
%w[cow moo]
]
# Protects BlockCaller objects from garbage collection.
@block_callers = []
def rbcallback(*args, &block)
args << [0] if args.size == 1 # Argument types are ommited
block_caller = Fiddle::Closure::BlockCaller.new(*args, &block)
@block_callers << block_caller
block_caller
end
model_handler = UI::FFI::TableModelHandler.malloc
model_handler.to_ptr.free = Fiddle::RUBY_FREE
model_handler.NumColumns = rbcallback(4) { 2 }
model_handler.ColumnType = rbcallback(4) { 0 }
model_handler.NumRows = rbcallback(4) { 5 }
model_handler.CellValue = rbcallback(1, [1, 1, 4, 4]) do |_, _, row, column|
UI.new_table_value_string(data[row][column])
end
model_handler.SetCellValue = rbcallback(0, [0]) {}
model = UI.new_table_model(model_handler)
table_params = UI::FFI::TableParams.malloc
table_params.to_ptr.free = Fiddle::RUBY_FREE
table_params.Model = model
table_params.RowBackgroundColorModelColumn = -1
table = UI.new_table(table_params)
UI.table_append_text_column(table, 'Animal', 0, -1)
UI.table_append_text_column(table, 'Description', 1, -1)
UI.table_set_selection_mode(table, UI::TableSelectionModeZeroOrMany)
UI.table_on_row_clicked(table) do |_, row_idx|
puts "#{data[row_idx][0]} \"#{data[row_idx][1]}\""
end
UI.table_on_row_double_clicked(table) do |_, row_idx|
puts "#{data[row_idx][0]} \"#{data[row_idx][1]}!!\"".upcase
end
UI.table_on_selection_changed(table) do |ptr|
tsp = UI.table_get_selection(ptr)
ts = UI::FFI::TableSelection.new(tsp)
if ts.NumRows > 0 #
p selected: ts.Rows[0, Fiddle::SIZEOF_INT * ts.NumRows].unpack("i*")
end
UI.free_table_selection(tsp)
end
UI.table_header_on_clicked(table) do |_, col_idx|
puts col_idx
end
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
It's not like Ruby, it's terrible code...
very few people seem to be using the pre-release version
This may be because it can be a hassle to test things that are unstable or semi-stable.
Personally I actually never (or rather almost never) use pre-release versions. I much prefer using "stable" releases but keep on updating within that tag, if possible. So for instance:
Version: 10.1 Version: 10.2 Version: 10.3
and so forth.
t's not like Ruby, it's terrible code...
Yeah. C. :)
Ruby is like a prettier syntactic sugar over C at the end of the day.
I should have learned C first - after having learned Ruby, C seems so messy in comparison ...
Thank you very much for the quick response @kojix2 . I will try to run the code on my machine to support it in Glimmer DSL for LibUI.
It's not like Ruby, it's terrible code...
It is great code for the middle architectural layer (binding) between high-level Ruby code and low-level C code. Thanks again. I will test the code when I get a chance and close this issue again if it ends up working for me.
OK, the code works, and I got it working in Glimmer DSL for LibUI locally too.
Thanks again.
I am closing this.
One more thing. @kojix2 could you please provide code examples of setting selection on a table (LibUI.table_set_selection
), including both:
And, if you could cover the following with an example (just in case), it would be helpful too:
LibUI.table_header_set_sort_indicator
LibUI.table_header_set_visible
LibUI.table_header_sort_indicator
LibUI.table_header_visible
OK, I figured out how to set selection by first building a selection struct:
ts = ::LibUI::FFI::TableSelection.malloc
ts.NumRows = value.is_a?(Array) ? value.size : 1
ts.Rows = [value].flatten.pack('i*')
So, I'm good for now as far as selection.
I already made a release for Glimmer DSL for LibUI that supports Table Selection API in version 0.0.7: https://rubygems.org/gems/glimmer-dsl-libui/versions/0.7.0
There is a new example too: https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/examples/basic_table_selection.rb
I need to add support for the table column listener next: LibUI.table_header_on_clicked
I tried a new example. It's amazing!
ChatGPT's solution appears to be incorrect and has been removed!
I think the following is one solution. It is not that good, though.
https://github.com/kojix2/LibUI/commit/59f757cd0f0d8e393463d5ec0eba1d3ac8af126e
In the new version of Fiddle
font_descriptor = UI::FFI::FontDescriptor.malloc(Fiddle::RUBY_FREE)
is supported. However, this may not work with the old Fiddle that is included with older Ruby.
I see. uiTableSelection
typedef struct uiTableSelection uiTableSelection;
struct uiTableSelection
{
int NumRows; //! < Number of selected rows.
int *Rows; //! < Array containing selected row indices, NULL on empty selection.
};
is only a part of the allocated memory.
Metadata is allocated before Rows. uiFreeTableSelection
frees this metadata.
If you try to free a FFI::TableSelection
allocated by Ruby using uiFreeTableSelection
, you will get an error, which seems to be caused by the metadata not existing.
I definitely got an error every time I tried to free the table selection struct memory. If you could figure that out too, that would be great.
Could it be that the LibUI table automatically frees the memory of the table selection struct as soon as we set the selection on the table? If that is true, then perhaps that is the reason why we can’t free the memory afterwards.
libui-ng recently merged a table selection API: https://github.com/libui-ng/libui-ng/pull/73
Could you please provide FFI bindings for that API in Ruby so that I could expose in Glimmer DSL for LibUI's GUI DSL?
I got a request about it from a user over here: https://github.com/AndyObtiva/glimmer-dsl-libui/issues/41
You could make a small release with a newer version of libui-ng and the table selection API only. Afterwards, you could continue to make small releases that add more and more FFI bindings in Ruby for other APIs that got added to libui-ng recently. But, to start, the table selection API should be enough for me to be able to expose it and make a release in Glimmer DSL for LibUI