libui_paradise 0.2.49 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
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