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.
- checksums.yaml +4 -4
- data/README.md +241 -116
- data/bin/libui_message +7 -0
- data/doc/README.gen +191 -56
- data/doc/SNIPPETS.md +1 -30
- data/doc/todo/todo.md +13 -8
- data/lib/libui_paradise/base/base.rb +64 -25
- data/lib/libui_paradise/colours/colours.rb +12 -0
- data/lib/libui_paradise/examples/complex/003_open_file_button_example.rb +2 -4
- data/lib/libui_paradise/examples/complex/010_table_example.rb +143 -49
- data/lib/libui_paradise/examples/simple/003_fancy_text_example.rb +18 -9
- data/lib/libui_paradise/examples/simple/005_text_drawing_example.rb +8 -8
- data/lib/libui_paradise/examples/simple/007_control_gallery.rb +19 -13
- data/lib/libui_paradise/examples/simple/010_font_button.rb +31 -0
- data/lib/libui_paradise/examples/simple/011_simple_notepad.rb +24 -0
- data/lib/libui_paradise/examples/simple/012_table_example.rb +71 -0
- data/lib/libui_paradise/extensions/extensions.rb +961 -11
- data/lib/libui_paradise/extensions/toplevel_counters.rb +58 -0
- data/lib/libui_paradise/fiddle/{pointer.rb → fiddle.rb} +162 -144
- data/lib/libui_paradise/generic_window/generic_window.rb +1 -1
- data/lib/libui_paradise/images/README.md +5 -2
- data/lib/libui_paradise/libui_classes/box.rb +3 -2
- data/lib/libui_paradise/libui_classes/grid.rb +4 -1
- data/lib/libui_paradise/libui_classes/libui_classes.rb +113 -78
- data/lib/libui_paradise/project/project.rb +5 -1
- data/lib/libui_paradise/prototype/prototype.rb +1 -3
- data/lib/libui_paradise/requires/require_the_libui_paradise_project.rb +1 -1
- data/lib/libui_paradise/version/version.rb +2 -2
- data/lib/libui_paradise.rb +0 -0
- data/libui_paradise.gemspec +5 -4
- metadata +18 -27
- data/lib/libui_paradise/extensions/counters.rb +0 -58
- data/lib/libui_paradise/extensions/hash_fiddle_pointer_widgets.rb +0 -150
- data/lib/libui_paradise/extensions/misc.rb +0 -754
- 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.
|
9
|
-
#
|
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
|
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 '
|
21
|
-
require '
|
22
|
-
require 'libui_paradise/
|
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
|
-
|
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
|
975
|
+
LibuiParadise::Extensions.initializer # Make LibUI known here.
|
976
|
+
|
977
|
+
if __FILE__ == $PROGRAM_NAME
|
978
|
+
pp LibuiParadise::Extensions.hash_fiddle_pointer_widgets?
|
979
|
+
end
|