libui_paradise 0.2.49 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +241 -116
  3. data/bin/libui_message +7 -0
  4. data/doc/README.gen +191 -56
  5. data/doc/SNIPPETS.md +1 -30
  6. data/doc/todo/todo.md +13 -8
  7. data/lib/libui_paradise/base/base.rb +64 -25
  8. data/lib/libui_paradise/colours/colours.rb +12 -0
  9. data/lib/libui_paradise/examples/complex/003_open_file_button_example.rb +2 -4
  10. data/lib/libui_paradise/examples/complex/010_table_example.rb +143 -49
  11. data/lib/libui_paradise/examples/simple/003_fancy_text_example.rb +18 -9
  12. data/lib/libui_paradise/examples/simple/005_text_drawing_example.rb +8 -8
  13. data/lib/libui_paradise/examples/simple/007_control_gallery.rb +19 -13
  14. data/lib/libui_paradise/examples/simple/010_font_button.rb +31 -0
  15. data/lib/libui_paradise/examples/simple/011_simple_notepad.rb +24 -0
  16. data/lib/libui_paradise/examples/simple/012_table_example.rb +71 -0
  17. data/lib/libui_paradise/extensions/extensions.rb +961 -11
  18. data/lib/libui_paradise/extensions/toplevel_counters.rb +58 -0
  19. data/lib/libui_paradise/fiddle/{pointer.rb → fiddle.rb} +162 -144
  20. data/lib/libui_paradise/generic_window/generic_window.rb +1 -1
  21. data/lib/libui_paradise/images/README.md +5 -2
  22. data/lib/libui_paradise/libui_classes/box.rb +3 -2
  23. data/lib/libui_paradise/libui_classes/grid.rb +4 -1
  24. data/lib/libui_paradise/libui_classes/libui_classes.rb +113 -78
  25. data/lib/libui_paradise/project/project.rb +5 -1
  26. data/lib/libui_paradise/prototype/prototype.rb +1 -3
  27. data/lib/libui_paradise/requires/require_the_libui_paradise_project.rb +1 -1
  28. data/lib/libui_paradise/version/version.rb +2 -2
  29. data/lib/libui_paradise.rb +0 -0
  30. data/libui_paradise.gemspec +5 -4
  31. metadata +18 -27
  32. data/lib/libui_paradise/extensions/counters.rb +0 -58
  33. data/lib/libui_paradise/extensions/hash_fiddle_pointer_widgets.rb +0 -150
  34. data/lib/libui_paradise/extensions/misc.rb +0 -754
  35. data/lib/libui_paradise/toplevel_methods/misc.rb +0 -13
@@ -5,25 +5,975 @@
5
5
  # === LibuiParadise::Extensions
6
6
  #
7
7
  # This .rb file is primarly used to "extend" libui in a convenient
8
- # way. That way we only have to require this file and the rest will
9
- # be set up correctly for us.
8
+ # way. Upon this file being required, several additional actions
9
+ # are performed, such as "alias e puts". That way we only have
10
+ # to require this file and the rest will be set up correctly for
11
+ # us automatically, for reasons of convenience.
10
12
  # =========================================================================== #
11
- # require 'libui_paradise/extensions/extensions.rb
12
- # include Libuiparadise::Extensions
13
+ # require 'libui_paradise/extensions/extensions.rb'
14
+ # include LibuiParadise::Extensions
13
15
  # =========================================================================== #
14
- require 'libui' # Mandatory require-call.
15
-
16
16
  module LibuiParadise
17
17
 
18
18
  module Extensions # === LibuiParadise::Extensions
19
19
 
20
- require 'libui_paradise/fiddle/pointer.rb'
21
- require 'libui_paradise/extensions/hash_fiddle_pointer_widgets.rb'
22
- require 'libui_paradise/extensions/misc.rb'
20
+ require 'libui' # Mandatory require-call.
21
+ require 'fileutils'
22
+ require 'libui_paradise/colours/colours.rb'
23
+ require 'libui_paradise/fiddle/fiddle.rb'
23
24
  require 'libui_paradise/libui_classes/libui_classes.rb'
24
25
 
25
- end; end
26
+ # ========================================================================= #
27
+ # === return_button_for_opening_a_local_file
28
+ #
29
+ # It is recommended to passs a libui-widget into this method, so that
30
+ # the "open-file" functionality can have a callback. Usually that
31
+ # callback should be a libui-entry, so that we can fill it with
32
+ # the file path that we chose.
33
+ # ========================================================================= #
34
+ def return_button_for_opening_a_local_file(
35
+ connect_this_button_with_that_widget = nil
36
+ )
37
+ button_open_file = ui_button('Open file')
38
+ button_open_file.on_clicked {
39
+ begin
40
+ # filename = ui_open_file(window).to_s
41
+ filename = LibUI.open_file(main_window).to_s
42
+ # e "The filename was: #{filename}" # This line is for debugging.
43
+ if connect_this_button_with_that_widget # This widget is usually an entry.
44
+ filename = File.absolute_path(filename) # We need the full path here.
45
+ connect_this_button_with_that_widget.set_text(filename) if connect_this_button_with_that_widget.respond_to?(:set_text)
46
+ end
47
+ rescue ArgumentError => error # Rescue from "NULL pointer given"
48
+ pp error
49
+ end
50
+ }
51
+ return button_open_file # Always return that button here.
52
+ end; alias return_the_default_open_file_button return_button_for_opening_a_local_file # === return_the_default_open_file_button
53
+
54
+ # ========================================================================= #
55
+ # === sfile
56
+ # ========================================================================= #
57
+ def sfile(i = '')
58
+ ::Colours.sfile(i)
59
+ end
60
+
61
+ # ========================================================================= #
62
+ # === sfancy
63
+ # ========================================================================= #
64
+ def sfancy(i = '')
65
+ ::Colours.sfancy(i)
66
+ end
67
+
68
+ # ========================================================================= #
69
+ # === WIDTH
70
+ # ========================================================================= #
71
+ WIDTH = 1024
72
+
73
+ # ========================================================================= #
74
+ # === @hash_fiddle_pointer_widgets
75
+ #
76
+ # This hash will contain all widgets, via pointer.
77
+ # ========================================================================= #
78
+ @hash_fiddle_pointer_widgets = {}
79
+
80
+ # ========================================================================= #
81
+ # === LibuiParadise::Extensions.hash_fiddle_pointer_widgets?
82
+ # ========================================================================= #
83
+ def self.hash_fiddle_pointer_widgets?
84
+ @hash_fiddle_pointer_widgets
85
+ end
86
+
87
+ # ========================================================================= #
88
+ # === main_hash?
89
+ #
90
+ # Access the main hash defined above.
91
+ # ========================================================================= #
92
+ def main_hash?
93
+ ::LibuiParadise::Extensions.hash_fiddle_pointer_widgets?
94
+ end; alias toplevel_hash? main_hash? # === toplevel_hash?
95
+
96
+ # ========================================================================= #
97
+ # === LibuiParadise::Extensions.notification
98
+ #
99
+ # This method can be used to show a quick message box to the end
100
+ # user.
101
+ # ========================================================================= #
102
+ def self.notification(
103
+ text = 'Backup complete!',
104
+ title_to_use = ''
105
+ )
106
+ ::LibuiParadise::Extensions.message_box(
107
+ text: text,
108
+ title_to_use: title_to_use
109
+ )
110
+ end
111
+
112
+ # ========================================================================= #
113
+ # === ui_sync_connect
114
+ #
115
+ # This method can connect two widgets: the first one should be a
116
+ # combo-box, and the second one a ui-entry.
117
+ # ========================================================================= #
118
+ def ui_sync_connect(
119
+ widget1,
120
+ widget2,
121
+ optional_array = nil
122
+ )
123
+ combobox_selected_callback = proc { |pointer|
124
+ selected_value = selected?(pointer)
125
+ if optional_array and optional_array.is_a?(Array)
126
+ selected_value = optional_array[selected_value.to_i]
127
+ end
128
+ widget2.set_text(
129
+ selected_value
130
+ )
131
+ }
132
+ ::LibUI.combobox_on_selected(
133
+ widget1, combobox_selected_callback, nil
134
+ )
135
+ end; alias sync_connect ui_sync_connect # === sync_connect
136
+
137
+ # ========================================================================= #
138
+ # === LibuiParadise::Extensions.register_this_fiddle_pointer_widget
139
+ #
140
+ # This method registers the particular widget in use.
141
+ #
142
+ # Every new_* method available via LibUI.new* that creates a new widget
143
+ # has to be registered via this method here, by calling it.
144
+ #
145
+ # That way we have a main Hash that contains lots of Fiddle::Pointers
146
+ # and we can, at a later time, modify these Fiddle::Pointer or call
147
+ # toplevel methods with these registered pointers. This will only
148
+ # work if we have registered these pointers, though, which is why
149
+ # each method that creates a new libui-widget has to make use of
150
+ # this method here.
151
+ #
152
+ # Since as of November 2022, the main window is also handled by
153
+ # this.
154
+ #
155
+ # Perhaps it should also use the method here, but I found it simpler
156
+ # to just refer to it via @main_window or main_window?. (Note that
157
+ # in future releases of the libui_paradise gem, @main_window will
158
+ # probably be removed and integrated just like any other
159
+ # libui-widget. But this has not been done yet, so it is retained
160
+ # as-is right now.)
161
+ #
162
+ # The mandatory entries given to this method must be of the
163
+ # following format:
164
+ #
165
+ # object_id -> [:the_fiddle_pointer_widget, :the_type]
166
+ #
167
+ # In other words, a key (as an Integer), and an Array as
168
+ # its primary value.
169
+ #
170
+ # The object_id will be determined automatically, so it can
171
+ # be omitted. It is the value that is simply returned by
172
+ # calling the .object_id method, so we do not have to do
173
+ # anything else here.
174
+ #
175
+ # The very last argument of the two-member Array should be a
176
+ # symbol, such as :grid. This is automatically ensured via a
177
+ # call to __method__ which returns a Symbol. That way we can
178
+ # then call the correct method internally, once we know we
179
+ # have a :grid or any other widget.
180
+ # ========================================================================= #
181
+ def self.register_this_fiddle_pointer_widget(
182
+ the_fiddle_pointer_widget,
183
+ the_type_of_the_widget = nil
184
+ )
185
+ # ======================================================================= #
186
+ # Determine the object-id automatically next:
187
+ # ======================================================================= #
188
+ object_id_to_use = the_fiddle_pointer_widget.object_id
189
+ # ======================================================================= #
190
+ # Then, store it on the main Hash.
191
+ # ======================================================================= #
192
+ @hash_fiddle_pointer_widgets[object_id_to_use] =
193
+ [
194
+ the_fiddle_pointer_widget,
195
+ the_type_of_the_widget
196
+ ]
197
+ end; self.instance_eval { alias add_to_the_registered_widgets register_this_fiddle_pointer_widget } # === LibuiParadise::Extensions.add_to_the_registered_widgets
198
+
199
+ # ========================================================================= #
200
+ # === LibuiParadise::Extensions.current_widget_pointer?
201
+ # ========================================================================= #
202
+ def self.current_widget_pointer?
203
+ LibuiParadise::Extensions.hash_fiddle_pointer_widgets?.values.last.first
204
+ end
205
+
206
+ # ========================================================================= #
207
+ # === last_pointer?
208
+ #
209
+ # This used to return the "current" widget pointer, but past September
210
+ # 2021 this is rarely in use anymore. Use current_widget_pointer?
211
+ # instead, based on the main Hash that keeps all widgets registered.
212
+ # ========================================================================= #
213
+ def last_pointer?
214
+ LibuiParadise::Extensions.current_widget_pointer?
215
+ end; alias current_pointer? last_pointer? # === current_pointer?
216
+ alias current_widget_pointer? last_pointer? # === current_widget_pointer?
217
+
218
+ # ========================================================================= #
219
+ # === current_widget_pointer_type?
220
+ # ========================================================================= #
221
+ def current_widget_pointer_type?
222
+ LibuiParadise::Extensions.hash_fiddle_pointer_widgets?.values.last.last
223
+ end
224
+
225
+ # ========================================================================= #
226
+ # === LibuiParadise::Extensions.hello_world
227
+ #
228
+ # This is merely an ad-hoc test.
229
+ # ========================================================================= #
230
+ def self.hello_world
231
+ e 'Hello world!'
232
+ end
233
+
234
+ # ========================================================================= #
235
+ # === close_properly
236
+ # ========================================================================= #
237
+ def close_properly(
238
+ main_window = LibuiParadise::Extensions.main_window?
239
+ )
240
+ LibUI.window_on_closing(main_window) {
241
+ LibUI.exit_from(main_window)
242
+ }
243
+ end; alias simple_exit close_properly # === simple_exit
244
+
245
+ # ========================================================================= #
246
+ # === LibuiParadise::Extensions.register_sigint
247
+ # ========================================================================= #
248
+ def self.register_sigint
249
+ Signal.trap('SIGINT') { exit }
250
+ end
251
+
252
+ # ========================================================================= #
253
+ # === LibuiParadise::Extensions.initializer
254
+ # ========================================================================= #
255
+ def self.initializer
256
+ LibuiParadise::Extensions.register_sigint
257
+ Object.const_set('UI', LibUI) # This is equal to: UI = LibUI
258
+ ::LibUI.extend(LibuiParadise::Extensions) # This call will also trigger the extended-hook.
259
+ end
260
+
261
+ # ========================================================================= #
262
+ # === LibuiParadise::Extensions.extended
263
+ #
264
+ # This method taps into the extended-hook - see the code in the
265
+ # method shown above this method.
266
+ #
267
+ # The purpose of this hook is to automatically call .init. This saves
268
+ # us one line of code.
269
+ #
270
+ # In regular LibUI code this is equal to:
271
+ #
272
+ # UI.init
273
+ #
274
+ # ========================================================================= #
275
+ def self.extended(i)
276
+ if i.respond_to? :init
277
+ i.init
278
+ else
279
+ ::LibUI.init
280
+ end
281
+ end
282
+
283
+ # ========================================================================= #
284
+ # === register_this_fiddle_pointer_widget
285
+ # ========================================================================= #
286
+ def register_this_fiddle_pointer_widget(
287
+ the_fiddle_pointer_widget,
288
+ the_type_of_the_widget = nil
289
+ )
290
+ ::LibuiParadise::Extensions.register_this_fiddle_pointer_widget(
291
+ the_fiddle_pointer_widget,
292
+ the_type_of_the_widget
293
+ )
294
+ end; alias add_to_the_registered_widgets register_this_fiddle_pointer_widget # === add_to_the_registered_widgets
295
+
296
+ # ========================================================================= #
297
+ # === esystem
298
+ #
299
+ # This method can be used to run system(), with output. Thread.new is
300
+ # used because that seems to work better in a GUI setup.
301
+ # ========================================================================= #
302
+ def esystem(i)
303
+ puts i
304
+ Thread.new { system i }
305
+ end
306
+
307
+ # ========================================================================= #
308
+ # === delete_file
309
+ #
310
+ # This method can be used if you want to quickly delete a (local) file.
311
+ # ========================================================================= #
312
+ def delete_file(i)
313
+ if File.file?(i)
314
+ File.delete(i)
315
+ else
316
+ puts "Not a file: #{i}"
317
+ end
318
+ end
319
+
320
+ # ========================================================================= #
321
+ # === colour_to_rgb
322
+ # ========================================================================= #
323
+ def colour_to_rgb(colour = :steelblue)
324
+ array = Colours.colour_to_rgb(colour)
325
+ return array
326
+ end
327
+
328
+ # ========================================================================= #
329
+ # === assumed_height?
330
+ # ========================================================================= #
331
+ def assumed_height?
332
+ return_the_resolution_using_xrandr.split('x').last.to_i
333
+ end; alias assumed_max_height? assumed_height? # === assumed_max_height?
334
+
335
+ # ========================================================================= #
336
+ # === without_trailing_comment
337
+ # ========================================================================= #
338
+ def without_trailing_comment(i)
339
+ i = i.dup
340
+ if i and i.end_with?('#')
341
+ i = i[0 .. -2]
342
+ end
343
+ return i
344
+ end
345
+
346
+ # ========================================================================= #
347
+ # === assumed_width?
348
+ # ========================================================================= #
349
+ def assumed_width?
350
+ return_the_resolution_using_xrandr.split('x').first.to_i
351
+ end; alias assumed_max_width? assumed_width? # === assumed_max_width?
352
+
353
+ # ========================================================================= #
354
+ # === set_width
355
+ # ========================================================================= #
356
+ def set_width(
357
+ i = 1024
358
+ )
359
+ case i
360
+ # ======================================================================= #
361
+ # === :max_width
362
+ # ======================================================================= #
363
+ when :max_width
364
+ i = assumed_max_width?
365
+ end
366
+ if i.is_a?(String) and i.include?('%')
367
+ # ===================================================================== #
368
+ # In this case we have to modify this a bit.
369
+ # ===================================================================== #
370
+ max_width = assumed_max_width?
371
+ i = (max_width.to_f * i.to_i) / 100.0
372
+ end
373
+ i = i.to_i
374
+ @width = i
375
+ end
376
+
377
+ # ========================================================================= #
378
+ # === is_on_roebe?
379
+ # ========================================================================= #
380
+ def is_on_roebe?
381
+ ENV['IS_ROEBE'].to_s == '1'
382
+ end
383
+
384
+ # ========================================================================= #
385
+ # === set_title
386
+ # ========================================================================= #
387
+ def set_title(i)
388
+ @title = i
389
+ end
390
+
391
+ # ========================================================================= #
392
+ # === LibuiParadise::Extensions.set_title
393
+ #
394
+ # Simpler window-set-title functionality.
395
+ # ========================================================================= #
396
+ def self.set_title(
397
+ this_title,
398
+ main_window = main_window?
399
+ )
400
+ window_set_title(main_window, this_title)
401
+ end
402
+
403
+ # ========================================================================= #
404
+ # === title?
405
+ # ========================================================================= #
406
+ def title?
407
+ @title
408
+ end
409
+
410
+ # ========================================================================= #
411
+ # === width?
412
+ # ========================================================================= #
413
+ def width?
414
+ @width
415
+ end
416
+
417
+ # ========================================================================= #
418
+ # === height?
419
+ # ========================================================================= #
420
+ def height?
421
+ @height
422
+ end
423
+
424
+ # ========================================================================= #
425
+ # === return_the_resolution_using_xrandr
426
+ #
427
+ # This method will only work on e. g. Linux.
428
+ #
429
+ # It will then return a String such as "1920x1080".
430
+ # ========================================================================= #
431
+ def return_the_resolution_using_xrandr
432
+ _ = '800x600' # This is a generic failsafe value.
433
+ begin
434
+ xrandr_result = `xrandr`
435
+ _ = xrandr_result.split("\n").select {|line|
436
+ line.include? '*'
437
+ }.first.strip.squeeze(' ').split(' ').first.to_s
438
+ rescue Errno::ENOENT # Rescue for Windows systems.
439
+ end
440
+ return _ # This will yield e. g. "1920x1080"
441
+ end
442
+
443
+ # ========================================================================= #
444
+ # === ui_table_params_malloc
445
+ #
446
+ # This will basically wrap over LibUI::FFI::TableParams.malloc().
447
+ # ========================================================================= #
448
+ def ui_table_params_malloc(
449
+ optional_model = nil
450
+ )
451
+ _ = ::LibUI::FFI::TableParams.malloc
452
+ if optional_model
453
+ _.to_ptr.free = Fiddle::RUBY_FREE
454
+ _.Model = optional_model
455
+ _.RowBackgroundColorModelColumn = -1
456
+ end
457
+ return _
458
+ end
459
+
460
+ # ========================================================================= #
461
+ # === ui_font_descriptor
462
+ #
463
+ # This method will return a new font-descriptor pointer.
464
+ #
465
+ # Usage example:
466
+ #
467
+ # ui_font_descriptor('Hack')
468
+ #
469
+ # ========================================================================= #
470
+ def ui_font_descriptor(
471
+ use_this_font_family = 'Hack',
472
+ use_this_size = 25,
473
+ use_this_weight = 500,
474
+ is_in_italic_font_variant = :no,
475
+ stretch_factor = 4
476
+ )
477
+ case is_in_italic_font_variant
478
+ when :yes
479
+ is_in_italic_font_variant = 1 # true
480
+ when :no
481
+ is_in_italic_font_variant = 0 # false
482
+ end
483
+ font_descriptor = UI::FFI::FontDescriptor.malloc
484
+ font_descriptor.to_ptr.free = Fiddle::RUBY_FREE
485
+ font_descriptor.Family = use_this_font_family
486
+ font_descriptor.Size = use_this_size
487
+ font_descriptor.Weight = use_this_weight
488
+ font_descriptor.Italic = is_in_italic_font_variant
489
+ font_descriptor.Stretch = stretch_factor
490
+ return font_descriptor
491
+ end; alias font_descriptor ui_font_descriptor # === font_descriptor
492
+
493
+ # ========================================================================= #
494
+ # === ui_text_then_entry
495
+ #
496
+ # This method must return an Array containing three elements.
497
+ #
498
+ # Note that :padding specifies whether we will use padding or not in
499
+ # libui. In ruby-gtk3 we can pass the pixels here; I am not sure
500
+ # whether this is possible via libui as such.
501
+ # ========================================================================= #
502
+ def ui_text_then_entry(
503
+ text = '',
504
+ hash = {
505
+ padding: 0
506
+ }
507
+ )
508
+ text = ui_text(text)
509
+ entry = ui_entry
510
+ hbox = padded_hbox
511
+ hbox.minimal(text, hash[:padding])
512
+ hbox.minimal(entry, hash[:padding])
513
+ return [hbox, text, entry]
514
+ end; alias text_then_entry ui_text_then_entry # === text_then_entry
515
+
516
+ # ========================================================================= #
517
+ # === try_to_parse_this_config_file
518
+ #
519
+ # This method can be used to parse a .config file for data it stores.
520
+ #
521
+ # The .config file must have "width:", "height:" and "title:" settings.
522
+ # ========================================================================= #
523
+ def try_to_parse_this_config_file(i)
524
+ if File.exist? i
525
+ dataset = File.readlines(i)
526
+ # ===================================================================== #
527
+ # Next check for width, height and title:
528
+ # ===================================================================== #
529
+ width = dataset.select {|line| line.include? 'width:' }.first.
530
+ split(':').last.strip.to_i
531
+ height = dataset.select {|line| line.include? 'height:' }.first.
532
+ split(':').last.strip.to_i
533
+ title = dataset.select {|line| line.include? 'title:' }.first.
534
+ split(':').last.strip
535
+ window = LibuiParadise.window(title, width, height)
536
+ return window
537
+ else
538
+ e 'No file exists at `'+i+'`.'
539
+ end
540
+ end; alias parse_this_config_file try_to_parse_this_config_file # === parse_this_config_file
541
+
542
+ # ========================================================================= #
543
+ # === ui_draw_text_layout_params
544
+ # ========================================================================= #
545
+ def ui_draw_text_layout_params
546
+ return ::LibUI::FFI::DrawTextLayoutParams.malloc
547
+ end
548
+
549
+ # ========================================================================= #
550
+ # === left_arrow?
551
+ # ========================================================================= #
552
+ def left_arrow?
553
+ ui_text('→')
554
+ end
555
+
556
+ # ========================================================================= #
557
+ # === append_this_array_to_that_combobox
558
+ # ========================================================================= #
559
+ def append_this_array_to_that_combobox(
560
+ this_array,
561
+ that_combobox
562
+ )
563
+ this_array.each {|this_entry|
564
+ UI.combobox_append(that_combobox, this_entry)
565
+ }
566
+ end
567
+
568
+ # ========================================================================= #
569
+ # === new_brush
570
+ # ========================================================================= #
571
+ def new_brush
572
+ UI::FFI::DrawBrush.malloc
573
+ end
574
+
575
+ # ========================================================================= #
576
+ # === exit_from
577
+ #
578
+ # This method essentially combines UI.control_destroy() and UI.quit(
579
+ # into one method.
580
+ # ========================================================================= #
581
+ def exit_from(
582
+ main_window = ::LibuiParadise::Extensions.main_window?
583
+ )
584
+ LibUI.control_destroy(main_window)
585
+ LibUI.quit
586
+ 0
587
+ end
588
+
589
+ # ========================================================================= #
590
+ # === main_then_quit
591
+ # ========================================================================= #
592
+ def main_then_quit
593
+ ::LibUI.main
594
+ do_quit
595
+ end
596
+
597
+ # ========================================================================= #
598
+ # === do_quit
599
+ # ========================================================================= #
600
+ def do_quit
601
+ ::LibUI.quit
602
+ end
603
+
604
+ # ========================================================================= #
605
+ # === copy
606
+ # ========================================================================= #
607
+ def copy(from, to)
608
+ require 'fileutils'
609
+ FileUtils.cp(from, to)
610
+ end
611
+
612
+ # ========================================================================= #
613
+ # === use_gtk3?
614
+ # ========================================================================= #
615
+ def use_gtk3?
616
+ Object.const_defined?(:Gtk)
617
+ end
618
+
619
+ # ========================================================================= #
620
+ # === use_gtk?
621
+ # ========================================================================= #
622
+ def use_gtk?
623
+ false
624
+ end; alias uses_gtk3? use_gtk? # === uses_gtk3?
625
+ alias uses_gtk4? use_gtk? # === uses_gtk4?
626
+
627
+ # ========================================================================= #
628
+ # === use_libui?
629
+ # ========================================================================= #
630
+ def use_libui?
631
+ true
632
+ end
633
+
634
+ # ========================================================================= #
635
+ # === gtk3?
636
+ # ========================================================================= #
637
+ def gtk3?
638
+ false
639
+ end; alias is_on_gtk? gtk3? # === is_on_gtk?
640
+
641
+ # ========================================================================= #
642
+ # === return_pwd
643
+ # ========================================================================= #
644
+ def return_pwd
645
+ "#{Dir.pwd}/".squeeze('/')
646
+ end
647
+
648
+ # ========================================================================= #
649
+ # === try_to_use_this_font
650
+ #
651
+ # This is currently not in use - once libui supports setting
652
+ # a font then this can be enabled.
653
+ # ========================================================================= #
654
+ def try_to_use_this_font(i = nil); end
655
+ alias use_this_font= try_to_use_this_font # === use_this_font=
656
+ alias set_use_this_font try_to_use_this_font # === set_use_this_font
657
+
658
+ # ========================================================================= #
659
+ # === abort_on_exception
660
+ # ========================================================================= #
661
+ def abort_on_exception
662
+ Thread.abort_on_exception
663
+ end
664
+
665
+ # ========================================================================= #
666
+ # === LibuiParadise::Extensions.draw_rectangle
667
+ #
668
+ # This method can be used to draw a rectangle.
669
+ #
670
+ # The third argument should be a HTML colour.
671
+ # ========================================================================= #
672
+ def self.draw_rectangle(
673
+ width = :default,
674
+ height = :default,
675
+ colour = :orange
676
+ )
677
+ unless ::LibuiParadise.respond_to?(:padded_vbox)
678
+ require 'libui_paradise/libui_classes/vbox.rb'
679
+ end
680
+ unless Object.const_defined? :Colours
681
+ begin
682
+ require 'colours'
683
+ rescue LoadError; end
684
+ end
685
+ case width
686
+ # ======================================================================= #
687
+ # === :default
688
+ # ======================================================================= #
689
+ when :default
690
+ width = 25
691
+ end
692
+ case height
693
+ # ======================================================================= #
694
+ # === :default
695
+ # ======================================================================= #
696
+ when :default
697
+ height = 25
698
+ end
699
+ handler = LibUI::FFI::AreaHandler.malloc
700
+ handler.to_ptr.free = Fiddle::RUBY_FREE
701
+ area = LibUI.new_area(handler)
702
+ brush = LibUI::FFI::DrawBrush.malloc
703
+ brush.to_ptr.free = Fiddle::RUBY_FREE
704
+
705
+ handler_draw_event = Fiddle::Closure::BlockCaller.new(0, [1, 1, 1]) { |_, _, area_draw_params|
706
+ path = LibUI.draw_new_path(0)
707
+ LibUI.draw_path_add_rectangle(path, 0, 0, width, height)
708
+ LibUI.draw_path_end(path)
709
+ brush.Type = 0
710
+ # ===================================================================== #
711
+ # Need to find out the true RGB values. For now we divide by 255.
712
+ #
713
+ # See here:
714
+ #
715
+ # https://stackoverflow.com/questions/10848990/rgb-values-to-0-to-1-scale
716
+ #
717
+ # ===================================================================== #
718
+ array = Colours.colour_to_rgb(colour)
719
+ brush.R = array[0] / 255.0 # 0.4
720
+ brush.G = array[1] / 255.0 # 0.4
721
+ brush.B = array[2] / 255.0 # 0.8
722
+ brush.A = 1.0
723
+ area_draw_params = LibUI::FFI::AreaDrawParams.new(area_draw_params)
724
+ LibUI.draw_fill(area_draw_params.Context, path, brush.to_ptr)
725
+ LibUI.draw_free_path(path)
726
+ }
727
+
728
+ do_nothing = Fiddle::Closure::BlockCaller.new(0, [0]) {}
729
+ key_event = Fiddle::Closure::BlockCaller.new(1, [0]) { 0 }
730
+
731
+ handler.Draw = handler_draw_event
732
+ handler.MouseEvent = do_nothing
733
+ handler.MouseCrossed = do_nothing
734
+ handler.DragBroken = do_nothing
735
+ handler.KeyEvent = key_event
736
+
737
+ box = ::LibuiParadise.padded_vbox
738
+ box.maximal(area)
739
+ return box
740
+ end
741
+
742
+ # ========================================================================= #
743
+ # === chdir (cd tag, chdir tag)
744
+ # ========================================================================= #
745
+ def chdir(i)
746
+ if i and File.directory?(i)
747
+ Dir.chdir(i)
748
+ end
749
+ end; alias cd chdir # === cd
750
+
751
+ # ========================================================================= #
752
+ # === create_skeleton_then_connect_skeleton
753
+ # ========================================================================= #
754
+ def create_skeleton_then_connect_skeleton
755
+ create_skeleton
756
+ connect_skeleton
757
+ end
758
+
759
+ # ========================================================================= #
760
+ # === connect_skeleton
761
+ #
762
+ # This is a stub method, because we want to allow the user to modify it.
763
+ # ========================================================================= #
764
+ def connect_skeleton
765
+ end
766
+
767
+ # ========================================================================= #
768
+ # === title_width_height_font
769
+ #
770
+ # The font-argument is presently not handled. Perhaps one day in the
771
+ # future.
772
+ # ========================================================================= #
773
+ def title_width_height_font(
774
+ title = '',
775
+ width = WIDTH,
776
+ height = 800,
777
+ font = :currently_not_handled
778
+ )
779
+ title_width_height(title, width, height)
780
+ end
781
+
782
+ # ========================================================================= #
783
+ # === set_height
784
+ # ========================================================================= #
785
+ def set_height(
786
+ i = 800
787
+ )
788
+ case i
789
+ # ======================================================================= #
790
+ # === :max_width
791
+ # ======================================================================= #
792
+ when :max_height
793
+ i = assumed_max_height?
794
+ end
795
+ if i.is_a?(String) and i.include?('%')
796
+ # ===================================================================== #
797
+ # In this case we have to modify this a bit.
798
+ # ===================================================================== #
799
+ max_height = assumed_max_height?
800
+ i = (max_height.to_f * i.to_i) / 100.0
801
+ end
802
+ i = i.to_i
803
+ @height = i
804
+ end
805
+
806
+ # ========================================================================= #
807
+ # === copy_file
808
+ # ========================================================================= #
809
+ def copy_file(from, to)
810
+ FileUtils.cp(from, to)
811
+ end; alias cp_file copy_file # === cp_file
812
+
813
+ # ========================================================================= #
814
+ # === create_directory
815
+ # ========================================================================= #
816
+ def create_directory(i)
817
+ FileUtils.mkdir_p(i)
818
+ end; alias mkdir create_directory # === mkdir
819
+
820
+ # ========================================================================= #
821
+ # === run_main
822
+ # ========================================================================= #
823
+ def run_main
824
+ end
825
+
826
+ # ========================================================================= #
827
+ # === set_commandline_arguments
828
+ # ========================================================================= #
829
+ def set_commandline_arguments(i = ARGV)
830
+ @commandline_arguments = [i].flatten.compact
831
+ end
832
+
833
+ # ========================================================================= #
834
+ # === commandline_arguments?
835
+ # ========================================================================= #
836
+ def commandline_arguments?
837
+ @commandline_arguments
838
+ end
839
+
840
+ # ========================================================================= #
841
+ # === title_width_height
842
+ # ========================================================================= #
843
+ def title_width_height(
844
+ title,
845
+ width = WIDTH,
846
+ height = 800
847
+ )
848
+ set_title(title)
849
+ set_width(width)
850
+ set_height(height)
851
+ end; alias set_title_width_height title_width_height # === title_width_height
852
+
853
+ # ========================================================================= #
854
+ # === run
855
+ # ========================================================================= #
856
+ def run
857
+ create_skeleton_then_connect_skeleton
858
+ end
859
+
860
+ end
861
+
862
+ # ========================================================================= #
863
+ # === LibuiParadise.register_this_fiddle_pointer_widget
864
+ # ========================================================================= #
865
+ def self.register_this_fiddle_pointer_widget(
866
+ the_fiddle_pointer_widget,
867
+ the_type_of_the_widget = nil
868
+ )
869
+ ::LibuiParadise::Extensions.register_this_fiddle_pointer_widget(
870
+ the_fiddle_pointer_widget,
871
+ the_type_of_the_widget
872
+ )
873
+ end; self.instance_eval { alias add_to_the_registered_widgets register_this_fiddle_pointer_widget } # === LibuiParadise.add_to_the_registered_widgets
874
+
875
+ # =========================================================================== #
876
+ # === LibuiParadise.run_in_the_background
877
+ # =========================================================================== #
878
+ def self.run_in_the_background
879
+ Process.daemon
880
+ end
881
+
882
+ # =========================================================================== #
883
+ # === LibuiParadise.notification
884
+ # =========================================================================== #
885
+ def self.notification(
886
+ text = 'Backup complete!',
887
+ title_to_use = ''
888
+ )
889
+ ::LibuiParadise::Extensions.message_box(
890
+ :default_window,
891
+ text,
892
+ title_to_use
893
+ )
894
+ end
895
+
896
+ # =========================================================================== #
897
+ # === LibuiParadise.draw_rectangle
898
+ # =========================================================================== #
899
+ def self.draw_rectangle(
900
+ width = :default,
901
+ height = :default,
902
+ colour = :orange
903
+ )
904
+ ::LibuiParadise::Extensions.draw_rectangle(width, height, colour)
905
+ end
906
+
907
+ # =========================================================================== #
908
+ # === LibuiParadise.generic_window
909
+ #
910
+ # Usage example:
911
+ #
912
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2'))
913
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2')) {{ height: 50 }}
914
+ # x = LibuiParadise.generic_window(LibuiParadise.button('1'), LibuiParadise.button('2')) {{ height: 50, width: 120 }}
915
+ #
916
+ # =========================================================================== #
917
+ def self.generic_window(
918
+ *use_these_widgets,
919
+ &block
920
+ )
921
+ unless LibuiParadise.respond_to?(:GenericWindow)
922
+ require 'libui_paradise/generic_window/generic_window.rb'
923
+ end
924
+ generic_window = LibuiParadise::GenericWindow.new { :do_not_run_yet }
925
+ # ========================================================================= #
926
+ # === Handle blocks next
927
+ # ========================================================================= #
928
+ if block_given?
929
+ yielded = yield
930
+ if yielded.is_a? Hash
931
+ # ===================================================================== #
932
+ # === :height
933
+ # ===================================================================== #
934
+ if yielded.has_key?(:height)
935
+ generic_window.set_height(
936
+ yielded[:height]
937
+ )
938
+ generic_window.update_the_main_window
939
+ end
940
+ # ===================================================================== #
941
+ # === :width
942
+ # ===================================================================== #
943
+ if yielded.has_key?(:width)
944
+ generic_window.set_width(
945
+ yielded[:width]
946
+ )
947
+ generic_window.update_the_main_window
948
+ end
949
+ # ===================================================================== #
950
+ # === :title
951
+ # ===================================================================== #
952
+ if yielded.has_key?(:title)
953
+ generic_window.set_title(
954
+ yielded[:title]
955
+ )
956
+ generic_window.update_the_main_window
957
+ end
958
+ end
959
+ end
960
+ # ========================================================================= #
961
+ # Next prepare adding more widgets to this generic window:
962
+ # ========================================================================= #
963
+ use_these_widgets.flatten!
964
+ use_these_widgets.compact!
965
+ if use_these_widgets.is_a?(Array) and !use_these_widgets.empty?
966
+ generic_window.add_these_widgets(use_these_widgets)
967
+ end
968
+ return generic_window
969
+ end
970
+
971
+ end
26
972
 
27
973
  alias e puts
28
974
 
29
- LibuiParadise::Extensions.initializer # Make UI known here.
975
+ LibuiParadise::Extensions.initializer # Make LibUI known here.
976
+
977
+ if __FILE__ == $PROGRAM_NAME
978
+ pp LibuiParadise::Extensions.hash_fiddle_pointer_widgets?
979
+ end