libui_paradise 0.3.9 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +176 -155
  3. data/bin/libui_message +1 -1
  4. data/doc/README.gen +175 -85
  5. data/doc/todo/todo.md +9 -5
  6. data/lib/libui_paradise/autoinclude.rb +2 -1
  7. data/lib/libui_paradise/base/base.rb +17 -67
  8. data/lib/libui_paradise/base_module/base_module.rb +1514 -0
  9. data/lib/libui_paradise/colours/colours.rb +4 -4
  10. data/lib/libui_paradise/domain_specific_language/README.md +6 -0
  11. data/lib/libui_paradise/examples/complex/002_tabs_example.rb +1 -2
  12. data/lib/libui_paradise/examples/complex/003_open_file_button_example.rb +1 -1
  13. data/lib/libui_paradise/examples/complex/006_coloured_boxes_example.rb +2 -2
  14. data/lib/libui_paradise/examples/complex/007_slider_example.rb +10 -4
  15. data/lib/libui_paradise/examples/complex/008_radio_button_example.rb +2 -2
  16. data/lib/libui_paradise/examples/complex/009_separator_example.rb +2 -2
  17. data/lib/libui_paradise/examples/complex/010_table_example.rb +5 -9
  18. data/lib/libui_paradise/examples/complex/011_two_buttons_showing_how_to_enable_and_disable_them.rb +2 -1
  19. data/lib/libui_paradise/examples/complex/012_password_entry_example.rb +1 -1
  20. data/lib/libui_paradise/examples/complex/013_form_example.rb +1 -1
  21. data/lib/libui_paradise/examples/complex/014_text_example.rb +1 -1
  22. data/lib/libui_paradise/examples/complex/015_text_view_example.rb +4 -4
  23. data/lib/libui_paradise/examples/complex/016_grid_example.rb +20 -11
  24. data/lib/libui_paradise/examples/complex/017_unicode_text_example.rb +2 -2
  25. data/lib/libui_paradise/examples/complex/018_spinbutton_example.rb +1 -1
  26. data/lib/libui_paradise/examples/complex/019_combo_box_example.rb +1 -1
  27. data/lib/libui_paradise/examples/complex/020_checkbox_example.rb +5 -5
  28. data/lib/libui_paradise/examples/complex/021_font_example.rb +4 -3
  29. data/lib/libui_paradise/examples/complex/022_simple_notepad_example.rb +3 -3
  30. data/lib/libui_paradise/examples/complex/023_msg_box_error.rb +5 -5
  31. data/lib/libui_paradise/examples/complex/024_parse_config_file_example.rb +2 -2
  32. data/lib/libui_paradise/examples/complex/025_colour_button.rb +1 -1
  33. data/lib/libui_paradise/examples/complex/026_basic_table_image.rb +5 -8
  34. data/lib/libui_paradise/examples/complex/027_basic_button_example.rb +3 -3
  35. data/lib/libui_paradise/examples/complex/028_try_for_automatic_button_press_event_after_a_delay.rb +4 -5
  36. data/lib/libui_paradise/examples/complex/029_progressbar_example.rb +4 -5
  37. data/lib/libui_paradise/examples/complex/030_entry_responds_to_comment_as_synonymous_to_the_enter_key_pressed_example.rb +5 -6
  38. data/lib/libui_paradise/examples/complex/031_notification_functionality_example.rb +3 -2
  39. data/lib/libui_paradise/examples/complex/032_simple_window_example.rb +2 -1
  40. data/lib/libui_paradise/examples/complex/033_daemonize_and_exit_after_delay_example.rb +3 -2
  41. data/lib/libui_paradise/examples/complex/034_bold_text_example.rb +115 -0
  42. data/lib/libui_paradise/examples/complex/035_parse_into_table_example.rb +109 -0
  43. data/lib/libui_paradise/examples/simple/001_open_file_example.rb +1 -1
  44. data/lib/libui_paradise/examples/simple/002_histogram_example.rb +6 -6
  45. data/lib/libui_paradise/examples/simple/003_fancy_text_example.rb +63 -35
  46. data/lib/libui_paradise/examples/simple/005_text_drawing_example.rb +3 -3
  47. data/lib/libui_paradise/examples/simple/007_control_gallery.rb +2 -1
  48. data/lib/libui_paradise/examples/simple/009_spectrum.rb +7 -1
  49. data/lib/libui_paradise/examples/simple/012_table_example.rb +5 -5
  50. data/lib/libui_paradise/examples/simple/013_scrolling_pane_example.rb +28 -0
  51. data/lib/libui_paradise/examples/simple/014_simple_entry_example.rb +30 -0
  52. data/lib/libui_paradise/examples/simple/015_slider_example.rb +32 -0
  53. data/lib/libui_paradise/fiddle/fiddle.rb +771 -636
  54. data/lib/libui_paradise/libui_classes/button.rb +31 -0
  55. data/lib/libui_paradise/libui_classes/entry.rb +35 -0
  56. data/lib/libui_paradise/libui_classes/grid.rb +14 -26
  57. data/lib/libui_paradise/libui_classes/hbox.rb +39 -0
  58. data/lib/libui_paradise/libui_classes/libui_classes.rb +9 -1630
  59. data/lib/libui_paradise/libui_classes/msg_box.rb +121 -0
  60. data/lib/libui_paradise/libui_classes/msg_box_error.rb +41 -0
  61. data/lib/libui_paradise/libui_classes/slider.rb +28 -0
  62. data/lib/libui_paradise/libui_classes/spinbox.rb +48 -0
  63. data/lib/libui_paradise/libui_classes/vbox.rb +38 -0
  64. data/lib/libui_paradise/project/project.rb +2 -1
  65. data/lib/libui_paradise/prototype/prototype.rb +8 -8
  66. data/lib/libui_paradise/requires/require_the_libui_classes.rb +2 -2
  67. data/lib/libui_paradise/requires/require_the_libui_paradise_project.rb +4 -2
  68. data/lib/libui_paradise/toplevel_methods/add_to_the_registered_widgets.rb +70 -0
  69. data/lib/libui_paradise/toplevel_methods/hash_fiddle_pointer_widgets.rb +37 -0
  70. data/lib/libui_paradise/{extensions → toplevel_methods}/toplevel_counters.rb +26 -1
  71. data/lib/libui_paradise/toplevel_methods/toplevel_methods.rb +792 -0
  72. data/lib/libui_paradise/version/version.rb +2 -2
  73. data/test/testing_generic_window.rb +2 -0
  74. metadata +22 -8
  75. data/doc/SNIPPETS.md +0 -65
  76. data/lib/libui_paradise/extensions/extensions.rb +0 -979
  77. data/lib/libui_paradise/libui_classes/box.rb +0 -157
@@ -0,0 +1,792 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # require 'libui_paradise/toplevel_methods/toplevel_methods.rb'
6
+ # =========================================================================== #
7
+ module LibuiParadise
8
+
9
+ # ========================================================================= #
10
+ # === @main_window
11
+ #
12
+ # This variable can be used to keep track of the main window in use.
13
+ # ========================================================================= #
14
+ @main_window = nil
15
+
16
+ # ========================================================================= #
17
+ # === LibuiParadise.main_window?
18
+ # ========================================================================= #
19
+ def self.main_window?
20
+ @main_window
21
+ end
22
+
23
+ # ========================================================================= #
24
+ # === LibuiParadise.set_main_window
25
+ # ========================================================================= #
26
+ def self.set_main_window(i)
27
+ @main_window = i
28
+ end; self.instance_eval { alias set_window set_main_window } # === LibuiParadise.set_window
29
+
30
+ # ========================================================================= #
31
+ # === LibuiParadise.window (window tag)
32
+ #
33
+ # This method will create a new main-window.
34
+ #
35
+ # It will also call UI.simple_exit(). This is done mostly so that we
36
+ # can omit that line whenever we use e. g. ui_main_window().
37
+ # ========================================================================= #
38
+ def self.window(
39
+ the_title = '', # Pick a title for the window here.
40
+ width = WIDTH, # width in n pixels.
41
+ height = HEIGHT, # height in n pixels.
42
+ has_menubar = 1, # hasMenubar or has not.
43
+ &block
44
+ )
45
+ case width
46
+ # ======================================================================= #
47
+ # === :default
48
+ # ======================================================================= #
49
+ when :default
50
+ width = WIDTH
51
+ end
52
+ case the_title
53
+ # ======================================================================= #
54
+ # === :filename
55
+ # ======================================================================= #
56
+ when :filename,
57
+ :file_name
58
+ # ===================================================================== #
59
+ # __FILE__ contains the desired name. We only need the raw name, though.
60
+ # Well, in 2022 it was realized that the real filename is stored in
61
+ # $PROGRAM_NAME, so here we go.
62
+ # ===================================================================== #
63
+ the_title = File.basename($PROGRAM_NAME)
64
+ end
65
+ raw_has_menubar = 0
66
+ if has_menubar.is_a? Numeric
67
+ raw_has_menubar = has_menubar
68
+ end
69
+ # ======================================================================= #
70
+ # Instantiate a new main-window next:
71
+ # ======================================================================= #
72
+ main_window = ::LibUI.new_window(
73
+ the_title,
74
+ width,
75
+ height,
76
+ raw_has_menubar
77
+ )
78
+ set_main_window(main_window) # Keep a reference stored here.
79
+ # ======================================================================= #
80
+ # Since as of 30.08.2021 we will also register the main-window.
81
+ #
82
+ # In the long run we may obsolete and deprecate @main_window, since
83
+ # it is no longer needed - but for now we will retain that variable.
84
+ # ======================================================================= #
85
+ add_to_the_registered_widgets(main_window, __method__)
86
+ if has_menubar and has_menubar.is_a?(Hash)
87
+ if has_menubar.has_key? :margin
88
+ if has_menubar[:margin] == true
89
+ main_window.has_margin
90
+ end
91
+ end
92
+ end
93
+ ::LibUI.simple_exit(main_window)
94
+ if block_given?
95
+ yield
96
+ end
97
+ return main_window # Always return it here.
98
+ end; self.instance_eval { alias main_window window } # === LibuiParadise.main_window
99
+ self.instance_eval { alias ui_main_window window } # === LibuiParadise.ui_main_window
100
+ self.instance_eval { alias margined_window window } # === LibuiParadise.margined_window
101
+ self.instance_eval { alias ui_window window } # === LibuiParadise.ui_window
102
+ self.instance_eval { alias window_or_vbox window } # === LibuiParadise.window_or_vbox
103
+ self.instance_eval { alias ui_padded_main_window window } # === LibuiParadise.margined_window
104
+ self.instance_eval { alias padded_window window } # === LibuiParadise.padded_window
105
+ self.instance_eval { alias padded_main_window window } # === LibuiParadise.padded_main_window
106
+
107
+ # ========================================================================= #
108
+ # === LibuiParadise.string_length
109
+ #
110
+ # This method is specifically for attributed-Strings.
111
+ # ========================================================================= #
112
+ def self.string_length(i = self)
113
+ return ::LibUI.attributed_string_len(i)
114
+ end
115
+
116
+ # ========================================================================= #
117
+ # === LibuiParadise.init
118
+ # ========================================================================= #
119
+ def self.init
120
+ ::LibUI.init
121
+ end
122
+
123
+ # ========================================================================= #
124
+ # === LibuiParadise.string
125
+ #
126
+ # This is a wrapper over LibUI.new_attributed_string().
127
+ # ========================================================================= #
128
+ def self.string(i = '')
129
+ return ::LibUI.new_attributed_string(i)
130
+ end; self.instance_eval { alias fancy_text string } # === LibuiParadise.fancy_text
131
+
132
+ # ========================================================================= #
133
+ # === LibuiParadise.label (text tag, label tag)
134
+ #
135
+ # Add text to the widget at hand. This is actually called a "label".
136
+ # ========================================================================= #
137
+ def self.label(
138
+ i = ''
139
+ )
140
+ if i.include? '</'
141
+ # ===================================================================== #
142
+ # For now we must remove "HTML tags" from the given input. Perhaps
143
+ # at some later point in time we can retain them.
144
+ # ===================================================================== #
145
+ i = i.dup if i.frozen?
146
+ i.gsub!(%r{<[^>]+>}, '')
147
+ end
148
+ _ = ::LibUI.new_label(i.to_s)
149
+ add_to_the_registered_widgets(_, __method__)
150
+ return _
151
+ end; self.instance_eval { alias text label } # === LibuiParadise.text
152
+ self.instance_eval { alias ui_text label } # === LibuiParadise.ui_text
153
+ self.instance_eval { alias ui_label label } # === LibuiParadise.ui_label
154
+
155
+ # ========================================================================= #
156
+ # === LibuiParadise.radio_buttons
157
+ #
158
+ # This method will create some radio buttons.
159
+ #
160
+ # You can pass an Array into this method, which should be an Array of
161
+ # Strings. This is optional. If such an Array is given, though, then
162
+ # these entries will become radio-buttons, with the associated label
163
+ # (the text they display) becoming the label right next to the radio
164
+ # button element (that round circle that the user can select via
165
+ # the mouse cursor).
166
+ # ========================================================================= #
167
+ def self.radio_buttons(
168
+ optional_array = []
169
+ )
170
+ _ = ::LibUI.new_radio_buttons
171
+ if optional_array and optional_array.is_a?(Array) and !optional_array.empty?
172
+ optional_array.each {|this_element|
173
+ ::LibUI.radio_buttons_append(_, this_element)
174
+ }
175
+ end
176
+ add_to_the_registered_widgets(_, __method__)
177
+ return _
178
+ end; self.instance_eval { alias ui_radio_buttons radio_buttons } # === LibuiParadise.ui_radio_buttons
179
+
180
+ # ========================================================================= #
181
+ # === LibuiParadise.text_layout
182
+ # ========================================================================= #
183
+ def self.text_layout(
184
+ i = ''
185
+ )
186
+ _ = ::LibUI.draw_new_text_layout(i.to_s)
187
+ add_to_the_registered_widgets(_, __method__)
188
+ return _
189
+ end
190
+
191
+ # ========================================================================= #
192
+ # === LibuiParadise.menu (menu tag)
193
+ # ========================================================================= #
194
+ def self.menu(
195
+ title = ''
196
+ )
197
+ _ = ::LibUI.new_menu(title)
198
+ add_to_the_registered_widgets(_, __method__)
199
+ return _
200
+ end; self.instance_eval { alias ui_menu menu } # === ui_menu
201
+
202
+ # ========================================================================= #
203
+ # === LibuiParadise.table
204
+ #
205
+ # The argument to this method should be of type table_params.
206
+ #
207
+ # Example for this:
208
+ #
209
+ # table_params = LibUI::FFI::TableParams.malloc
210
+ # table_params.Model = model
211
+ # table_params.RowBackgroundColorModelColumn = -1
212
+ #
213
+ # ========================================================================= #
214
+ def self.table(i)
215
+ _ = ::LibUI.new_table(i)
216
+ register_this_fiddle_pointer_widget(_, __method__)
217
+ return _
218
+ end; self.instance_eval { alias ui_table table } # === LibuiParadise.ui_table
219
+
220
+ # ========================================================================= #
221
+ # === LibuiParadise.vertical_separator
222
+ #
223
+ # This method will add a new vertical separator.
224
+ # ========================================================================= #
225
+ def self.vertical_separator
226
+ ::LibUI.new_vertical_separator
227
+ end; self.instance_eval { alias ui_vseparator vertical_separator } # === LibuiParadise.ui_verticalseparator
228
+ self.instance_eval { alias ui_vsep vertical_separator } # === LibuiParadise.ui_vsep
229
+ self.instance_eval { alias vspacer vertical_separator } # === LibuiParadise.vspacer
230
+ self.instance_eval { alias vertical_spacer vertical_separator } # === LibuiParadise.vertical_spacer
231
+ self.instance_eval { alias vsep vertical_separator } # === LibuiParadise.vsep
232
+
233
+ # ========================================================================= #
234
+ # === Libuiparadise.image
235
+ #
236
+ # This is currently limited to .png files only, due to ChunkyPng.
237
+ #
238
+ # At some later point in the future this limitation may be lifted. For
239
+ # now it has to remain in place.
240
+ # ========================================================================= #
241
+ def self.image(
242
+ this_file,
243
+ width = :try_to_infer_automatically,
244
+ height = :infer_automatically
245
+ )
246
+ if (width == :infer_automatically) or
247
+ (height == :infer_automatically)
248
+ unless Object.const_defined? :ChunkyPNG
249
+ begin
250
+ require 'chunky_png'
251
+ rescue LoadError; end
252
+ end
253
+ canvas = ChunkyPNG::Canvas.from_file(this_file)
254
+ data = canvas.to_rgba_stream
255
+ width = canvas.width
256
+ height = canvas.height
257
+ _ = ::LibUI.new_image(width, height) # Create the image here.
258
+ add_to_the_registered_widgets(_, __method__)
259
+ ::LibUI.image_append(
260
+ _,
261
+ data,
262
+ width,
263
+ height,
264
+ width
265
+ )
266
+ return _
267
+ end
268
+ nil
269
+ end; self.instance_eval { alias ui_image image } # === LibuiParadise.ui_image
270
+
271
+ # ========================================================================= #
272
+ # === LibuiParadise.font_button
273
+ #
274
+ # Create a new font button via this method.
275
+ # ========================================================================= #
276
+ def self.font_button
277
+ _ = ::LibUI.new_font_button
278
+ add_to_the_registered_widgets(_, __method__)
279
+ return _
280
+ end; self.instance_eval { alias ui_font_button font_button } # === LibuiParadise.ui_font_button
281
+
282
+ # ========================================================================= #
283
+ # === LibuiParadise.multiline_entry (multiline_entry tag)
284
+ #
285
+ # The upstream code for the linux-variant for a multiline-entry can
286
+ # be found here:
287
+ #
288
+ # https://raw.githubusercontent.com/andlabs/libui/master/unix/multilineentry.c
289
+ #
290
+ # A multiline-entry, also known more traditionally as a "textview",
291
+ # is a widget that allows the user to input text and modify that
292
+ # text as well.
293
+ # ========================================================================= #
294
+ def self.multiline_entry(
295
+ optional_content = nil
296
+ )
297
+ _ = ::LibUI.new_multiline_entry
298
+ add_to_the_registered_widgets(_, __method__)
299
+ if optional_content and optional_content.is_a?(String) and !optional_content.empty?
300
+ _.set_text(optional_content) # Set the text here, if the user provided a non-empty String.
301
+ end
302
+ return _
303
+ end; self.instance_eval { alias ui_multiline_entry multiline_entry } # === LibuiParadise.ui_multiline_entry
304
+ self.instance_eval { alias textview multiline_entry } # === LibuiParadise.textview
305
+ self.instance_eval { alias text_view multiline_entry } # === LibuiParadise.text_view
306
+ self.instance_eval { alias ui_text_view multiline_entry } # === LibuiParadise.ui_text_view
307
+ self.instance_eval { alias ui_textview multiline_entry } # === LibuiParadise.ui_textview
308
+ self.instance_eval { alias ui_text_buffer multiline_entry } # === LibuiParadise.ui_text_buffer
309
+ self.instance_eval { alias input_field multiline_entry } # === LibuiParadise.input_field
310
+ self.instance_eval { alias input multiline_entry } # === LibuiParadise.input
311
+ self.instance_eval { alias create_text_view multiline_entry } # === LibuiParadise.create_text_view
312
+
313
+ # ========================================================================= #
314
+ # === LibuiParadise.checkbox (checkbox tag)
315
+ # ========================================================================= #
316
+ def self.checkbox(i = '')
317
+ _ = ::LibUI.new_checkbox(i)
318
+ add_to_the_registered_widgets(_, __method__)
319
+ return _
320
+ end; self.instance_eval { alias create_checkbox checkbox } # === LibuiParadise.create_checkbox
321
+
322
+ # ========================================================================= #
323
+ # === LibuiParadise.password_entry
324
+ #
325
+ # This method will create and returns a new password entry widget. This
326
+ # means that input will be "disguised" via the '*' character.
327
+ #
328
+ # Usage example:
329
+ #
330
+ # entry = LibuiParadise.password_entry
331
+ #
332
+ # ========================================================================= #
333
+ def self.password_entry
334
+ entry = ::LibUI.new_password_entry
335
+ add_to_the_registered_widgets(entry, __method__)
336
+ return entry
337
+ end; self.instance_eval { alias ui_password_entry password_entry } # === LibuiParadise.ui_password_entry
338
+
339
+ # ========================================================================= #
340
+ # === LibuiParadise.wrapper_new_progress_bar
341
+ #
342
+ # The name of this method contains "wrapper_" because there already
343
+ # exists a method called LibUI.new_progress_bar().
344
+ #
345
+ # The upstream C API for the libui-progressbar can be found here:
346
+ #
347
+ # https://github.com/andlabs/libui/blob/master/unix/progressbar.c
348
+ #
349
+ # ========================================================================= #
350
+ def self.wrapper_new_progress_bar
351
+ _ = ::LibUI.new_progress_bar
352
+ add_to_the_registered_widgets(_, :new_progress_bar)
353
+ return _
354
+ end; self.instance_eval { alias new_progress_bar wrapper_new_progress_bar } # === LibuiParadise.new_progress_bar
355
+
356
+ # ========================================================================= #
357
+ # === LibuiParadise.tab
358
+ #
359
+ # This could be also called "notebook_tab" - see the alias on the
360
+ # bottom.
361
+ # ========================================================================= #
362
+ def self.tab
363
+ _ = ::LibUI.new_tab # Create a new notebook-tab here.
364
+ add_to_the_registered_widgets(_, __method__)
365
+ return _
366
+ end; self.instance_eval { alias ui_tab tab } # === LibuiParadise.ui_tab
367
+ self.instance_eval { alias ui_tabs tab } # === LibuiParadise.ui_tabs
368
+ self.instance_eval { alias notebook tab } # === LibuiParadise.notebook
369
+ self.instance_eval { alias ui_notebook tab } # === LibuiParadise.ui_notebook
370
+ self.instance_eval { alias notebook_tab tab } # === LibuiParadise.notebook_tab
371
+ self.instance_eval { alias create_tab tab } # === LibuiParadise.create_tab
372
+
373
+ # ========================================================================= #
374
+ # === LibuiParadise.area
375
+ #
376
+ # AreaHandler defines the functionality needed for handling events from
377
+ # an Area.
378
+ #
379
+ # Upstream documentation, at the least for Go, can be found here:
380
+ #
381
+ # https://github.com/andlabs/ui/blob/master/areahandler.go
382
+ #
383
+ # ========================================================================= #
384
+ def self.area(
385
+ i = :use_new_area_handler
386
+ )
387
+ case i
388
+ # ======================================================================= #
389
+ # === :use_new_area_handler
390
+ # ======================================================================= #
391
+ when :use_new_area_handler,
392
+ :default
393
+ # ===================================================================== #
394
+ # malloc a new area-handled next:
395
+ # ===================================================================== #
396
+ i = ::LibUI::FFI::AreaHandler.malloc
397
+ i.to_ptr.free = Fiddle::RUBY_FREE # This one is done in upstream LibUI as well.
398
+ end
399
+ _ = ::LibUI.new_area(i) # Our new area, with the given handler.
400
+ add_to_the_registered_widgets(_, __method__)
401
+ return _
402
+ end; self.instance_eval { alias area_handler area } # === LibuiParadise.area_handler
403
+
404
+ # ========================================================================= #
405
+ # === LibuiParadise.font (font tag, fonts tag)
406
+ # ========================================================================= #
407
+ def self.font(&block)
408
+ use_this_font = ::LibUI::FFI::FontDescriptor.malloc
409
+ # ======================================================================= #
410
+ # === Handle blocks next
411
+ # ======================================================================= #
412
+ if block_given?
413
+ yielded = yield
414
+ if yielded.is_a? Hash
415
+ # =================================================================== #
416
+ # === :font_size
417
+ # =================================================================== #
418
+ if yielded.has_key? :font_size
419
+ use_this_font.Size = yielded.delete(:font_size)
420
+ end
421
+ # =================================================================== #
422
+ # === :font_family
423
+ # =================================================================== #
424
+ if yielded.has_key? :font_family
425
+ use_this_font.Family = yielded.delete(:font_family)
426
+ end
427
+ # =================================================================== #
428
+ # === :stretch
429
+ # =================================================================== #
430
+ if yielded.has_key? :stretch
431
+ use_this_font.Stretch = yielded.delete(:stretch)
432
+ end
433
+ # =================================================================== #
434
+ # === :weight
435
+ # =================================================================== #
436
+ if yielded.has_key? :weight
437
+ use_this_font.Weight = yielded.delete(:weight)
438
+ end
439
+ # =================================================================== #
440
+ # === :italic
441
+ # =================================================================== #
442
+ if yielded.has_key? :italic
443
+ _ = yielded.delete(:italic_family)
444
+ if _ == true
445
+ _ = 1
446
+ elsif _ == false
447
+ _ = 0
448
+ end
449
+ use_this_font.Italic = _
450
+ end
451
+ end
452
+ end
453
+ return use_this_font
454
+ end; self.instance_eval { alias ui_font font } # === LibuiParadise::Extensions.ui_font
455
+ self.instance_eval { alias font_descriptor font } # === LibuiParadise::Extensions.font_descriptor
456
+
457
+ # ========================================================================= #
458
+ # === LibuiParadise.hello_world
459
+ #
460
+ # This is merely an ad-hoc test.
461
+ # ========================================================================= #
462
+ def self.hello_world
463
+ e 'Hello world!'
464
+ end
465
+
466
+ # ========================================================================= #
467
+ # === LibuiParadise.register_sigint
468
+ # ========================================================================= #
469
+ def self.register_sigint
470
+ Signal.trap('SIGINT') { exit }
471
+ end
472
+
473
+ # ========================================================================= #
474
+ # === LibuiParadise.run_in_the_background
475
+ # ========================================================================= #
476
+ def self.run_in_the_background
477
+ Process.daemon
478
+ end
479
+
480
+ # ========================================================================= #
481
+ # === LibuiParadise.open_file
482
+ #
483
+ # This method can be used to open a local file, via a button, the
484
+ # "open-file" button. Furthermore a begin/rescue clause is used to
485
+ # avoid "NULL pointer given" errors. At a later time we may
486
+ # have to fine-tune this, but for now this shall suffice.
487
+ # ========================================================================= #
488
+ def self.open_file(
489
+ main_window = main_window?
490
+ )
491
+ begin
492
+ _ = ::LibUI.open_file(main_window)
493
+ add_to_the_registered_widgets(_, __method__)
494
+ return _
495
+ rescue ArgumentError => _error # Rescue #<ArgumentError: NULL pointer given> here.
496
+ # pp _error
497
+ return nil
498
+ end
499
+ end; self.instance_eval { alias ui_open_file open_file } # === LibuiParadise.ui_open_file
500
+
501
+ # ========================================================================= #
502
+ # === LibuiParadise.search_entry
503
+ # ========================================================================= #
504
+ def self.search_entry
505
+ _ = ::LibUI.new_search_entry
506
+ add_to_the_registered_widgets(_, __method__)
507
+ return _
508
+ end; self.instance_eval { alias ui_search_entry search_entry } # === LibuiParadise.ui_search_entry
509
+
510
+ # ========================================================================= #
511
+ # === LibuiParadise.non_wrapping_multiline_entry
512
+ #
513
+ # The upstream C API for the non-wrapping multiline edit can be found here:
514
+ #
515
+ # https://raw.githubusercontent.com/andlabs/libui/master/unix/multilineentry.c
516
+ #
517
+ # ========================================================================= #
518
+ def self.non_wrapping_multiline_entry
519
+ _ = ::LibUI.new_non_wrapping_multiline_entry
520
+ add_to_the_registered_widgets(_, __method__)
521
+ return _
522
+ end
523
+
524
+ # ========================================================================= #
525
+ # === LibuiParadise.draw_rectangle
526
+ #
527
+ # This method can be used to draw a rectangle.
528
+ #
529
+ # The third argument to this method should be a HTML colour, as a Symbol.
530
+ # ========================================================================= #
531
+ def self.draw_rectangle(
532
+ width = :default,
533
+ height = :default,
534
+ colour = :orange
535
+ )
536
+ unless ::LibuiParadise.respond_to?(:padded_vbox)
537
+ require 'libui_paradise/libui_classes/vbox.rb'
538
+ end
539
+ unless Object.const_defined? :Colours
540
+ begin
541
+ require 'colours'
542
+ rescue LoadError; end
543
+ end
544
+ case width
545
+ # ======================================================================= #
546
+ # === :default
547
+ # ======================================================================= #
548
+ when :default
549
+ width = 25
550
+ end
551
+ case height
552
+ # ======================================================================= #
553
+ # === :default
554
+ # ======================================================================= #
555
+ when :default
556
+ height = 25
557
+ end
558
+ handler = LibUI::FFI::AreaHandler.malloc
559
+ handler.to_ptr.free = Fiddle::RUBY_FREE
560
+ area = LibUI.new_area(handler)
561
+ brush = LibUI::FFI::DrawBrush.malloc
562
+ brush.to_ptr.free = Fiddle::RUBY_FREE
563
+
564
+ handler_draw_event = Fiddle::Closure::BlockCaller.new(0, [1, 1, 1]) { |_, _, area_draw_params|
565
+ path = LibUI.draw_new_path(0)
566
+ LibUI.draw_path_add_rectangle(path, 0, 0, width, height)
567
+ LibUI.draw_path_end(path)
568
+ brush.Type = 0
569
+ # ===================================================================== #
570
+ # Need to find out the true RGB values. For now we divide by 255.
571
+ #
572
+ # See here:
573
+ #
574
+ # https://stackoverflow.com/questions/10848990/rgb-values-to-0-to-1-scale
575
+ #
576
+ # ===================================================================== #
577
+ array = Colours.colour_to_rgb(colour)
578
+ brush.R = array[0] / 255.0 # 0.4
579
+ brush.G = array[1] / 255.0 # 0.4
580
+ brush.B = array[2] / 255.0 # 0.8
581
+ brush.A = 1.0 # Hardcoded for now.
582
+ area_draw_params = LibUI::FFI::AreaDrawParams.new(area_draw_params)
583
+ LibUI.draw_fill(area_draw_params.Context, path, brush.to_ptr)
584
+ LibUI.draw_free_path(path)
585
+ }
586
+
587
+ do_nothing = Fiddle::Closure::BlockCaller.new(0, [0]) {}
588
+ key_event = Fiddle::Closure::BlockCaller.new(1, [0]) { 0 }
589
+
590
+ handler.Draw = handler_draw_event
591
+ handler.MouseEvent = do_nothing
592
+ handler.MouseCrossed = do_nothing
593
+ handler.DragBroken = do_nothing
594
+ handler.KeyEvent = key_event
595
+
596
+ vbox = ::LibuiParadise.padded_vbox # Create our vbox here.
597
+ vbox.maximal(area)
598
+ return vbox
599
+ end
600
+
601
+ # ========================================================================= #
602
+ # === LibuiParadise.scrolling_area
603
+ #
604
+ # It seems as if scrolling is not yet easily available in libui.
605
+ #
606
+ # The upstream API is like this:
607
+ #
608
+ # uiArea *area = uiNewScrollingArea(&handler, 400, 400);
609
+ #
610
+ # The two numbers are width and height, as integers, respectively.
611
+ # In total three arguments are required. The first argument is
612
+ # a so-called "AreaHandler".
613
+ #
614
+ # The code may be found here:
615
+ #
616
+ # https://github.com/andlabs/libui/blob/master/windows/areascroll.cpp
617
+ #
618
+ # ========================================================================= #
619
+ def self.scrolling_area(
620
+ widget,
621
+ width = :default,
622
+ height = :default
623
+ )
624
+ case width
625
+ # ======================================================================= #
626
+ # === :default
627
+ # ======================================================================= #
628
+ when :default, nil
629
+ width = 400
630
+ end
631
+ case height
632
+ # ======================================================================= #
633
+ # === :default
634
+ # ======================================================================= #
635
+ when :default, nil
636
+ height = 400
637
+ end
638
+ _ = ::LibUI.new_scrolling_area(widget, width, height)
639
+ # ======================================================================= #
640
+ # The next part does not yet work - is it even possible to add widgets
641
+ # to a scrolling area in libui?
642
+ # if optional_widget
643
+ # _.add(optional_widget)
644
+ # end
645
+ # ======================================================================= #
646
+ add_to_the_registered_widgets(_, __method__)
647
+ return _
648
+ end; self.instance_eval { alias ui_scrolling_area scrolling_area } # === LibuiParadise::Extensions.ui_scrolling_area
649
+ self.instance_eval { alias ui_scrolled_window scrolling_area } # === LibuiParadise::Extensions.ui_scrolling_window
650
+
651
+ # ========================================================================= #
652
+ # === LibuiParadise.colour_button
653
+ #
654
+ # The upstream API for a colour-button (in C) can be found here:
655
+ #
656
+ # https://github.com/andlabs/libui/blob/master/unix/colorbutton.c
657
+ #
658
+ # ========================================================================= #
659
+ def self.colour_button
660
+ _ = ::LibUI.new_color_button
661
+ ::LibuiParadise.register_this_fiddle_pointer_widget(_, __method__)
662
+ return _
663
+ end; self.instance_eval { alias color_button colour_button } # === LibuiParadise.color_button
664
+ self.instance_eval { alias new_color_button colour_button } # === LibuiParadise.new_color_button
665
+ self.instance_eval { alias new_colour_button colour_button } # === LibuiParadise.new_colour_button
666
+ self.instance_eval { alias ui_colour_button colour_button } # === LibuiParadise.ui_colour_button
667
+
668
+ # ========================================================================= #
669
+ # === LibuiParadise.generic_window
670
+ #
671
+ # Usage example:
672
+ #
673
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2'))
674
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2')) {{ height: 50 }}
675
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2')) {{ height: 50, width: 120 }}
676
+ #
677
+ # ========================================================================= #
678
+ def self.generic_window(
679
+ *use_these_widgets,
680
+ &block
681
+ )
682
+ unless LibuiParadise.respond_to?(:GenericWindow)
683
+ require 'libui_paradise/generic_window/generic_window.rb'
684
+ end
685
+ generic_window = LibuiParadise::GenericWindow.new { :do_not_run_yet }
686
+ # ======================================================================= #
687
+ # === Handle blocks next
688
+ # ======================================================================= #
689
+ if block_given?
690
+ yielded = yield
691
+ if yielded.is_a? Hash
692
+ # =================================================================== #
693
+ # === :height
694
+ # =================================================================== #
695
+ if yielded.has_key?(:height)
696
+ generic_window.set_height(
697
+ yielded[:height]
698
+ )
699
+ generic_window.update_the_main_window
700
+ end
701
+ # =================================================================== #
702
+ # === :width
703
+ # =================================================================== #
704
+ if yielded.has_key?(:width)
705
+ generic_window.set_width(
706
+ yielded[:width]
707
+ )
708
+ generic_window.update_the_main_window
709
+ end
710
+ # =================================================================== #
711
+ # === :title
712
+ # =================================================================== #
713
+ if yielded.has_key?(:title)
714
+ generic_window.set_title(
715
+ yielded[:title]
716
+ )
717
+ generic_window.update_the_main_window
718
+ end
719
+ end
720
+ end
721
+ # ======================================================================= #
722
+ # Next prepare adding more widgets to this generic window:
723
+ # ======================================================================= #
724
+ use_these_widgets.flatten!
725
+ use_these_widgets.compact!
726
+ if use_these_widgets.is_a?(Array) and !use_these_widgets.empty?
727
+ generic_window.add_these_widgets(use_these_widgets)
728
+ end
729
+ return generic_window
730
+ end
731
+
732
+ # ========================================================================= #
733
+ # === LibuiParadise.combobox
734
+ # ========================================================================= #
735
+ def self.combobox(
736
+ optional_array = nil, &block
737
+ )
738
+ combobox = ::LibUI.new_combobox
739
+ # ======================================================================= #
740
+ # Register it at once:
741
+ # ======================================================================= #
742
+ add_to_the_registered_widgets(combobox, __method__)
743
+ if block_given?
744
+ optional_array = yield
745
+ end
746
+ if optional_array and optional_array.is_a?(Array)
747
+ # append_this_array_to_that_combobox(optional_array, combobox)
748
+ combobox.append_this_array(optional_array)
749
+ end
750
+ return combobox
751
+ end; self.instance_eval { alias combo_box combobox } # === LibuiParadise.combo_box
752
+ self.instance_eval { alias ui_combo_box combobox } # === LibuiParadise.ui_combo_box
753
+ self.instance_eval { alias ui_combobox combobox } # === LibuiParadise.ui_combobox
754
+
755
+ # ========================================================================= #
756
+ # === LibuiParadise.editable_combobox
757
+ #
758
+ # This is a combo-box that the user can modify.
759
+ # ========================================================================= #
760
+ def self.editable_combobox(
761
+ optional_array = nil,
762
+ &block
763
+ )
764
+ _ = ::LibUI.new_editable_combobox
765
+ if block_given?
766
+ optional_array = yield
767
+ end
768
+ if optional_array and optional_array.is_a?(Array)
769
+ append_this_array_to_that_combobox(optional_array, _)
770
+ end
771
+ add_to_the_registered_widgets(_, __method__)
772
+ return _
773
+ end; self.instance_eval { alias editable_combo_box editable_combobox } # === LibuiParadise.editable_combo_box
774
+ self.instance_eval { alias ui_editable_combo_box editable_combobox } # === LibuiParadise.ui_editable_combo_box
775
+
776
+ # ========================================================================= #
777
+ # === LibuiParadise.set_title
778
+ #
779
+ # Simpler window-set-title functionality.
780
+ # ========================================================================= #
781
+ def self.set_title(
782
+ this_title,
783
+ main_window = main_window?
784
+ )
785
+ ::LibUI.window_set_title(main_window, this_title)
786
+ end
787
+
788
+ end
789
+
790
+ if __FILE__ == $PROGRAM_NAME
791
+ LibuiParadise.hello_world
792
+ end