glimmer-dsl-libui 0.4.4 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -1
  3. data/README.md +932 -160
  4. data/VERSION +1 -1
  5. data/examples/button_counter.rb +2 -1
  6. data/examples/color_button.rb +18 -13
  7. data/examples/color_button2.rb +14 -0
  8. data/examples/date_time_picker.rb +19 -14
  9. data/examples/date_time_picker2.rb +20 -0
  10. data/examples/dynamic_area.rb +77 -90
  11. data/examples/dynamic_area2.rb +14 -12
  12. data/examples/dynamic_area3.rb +90 -0
  13. data/examples/dynamic_area4.rb +95 -0
  14. data/examples/font_button.rb +17 -12
  15. data/examples/font_button2.rb +18 -0
  16. data/examples/form_table.rb +0 -2
  17. data/examples/form_table2.rb +0 -2
  18. data/examples/histogram.rb +93 -91
  19. data/examples/histogram2.rb +109 -0
  20. data/examples/meta_example.rb +17 -6
  21. data/examples/midi_player.rb +5 -6
  22. data/examples/midi_player2.rb +83 -0
  23. data/examples/midi_player3.rb +84 -0
  24. data/examples/tetris.rb +15 -18
  25. data/examples/timer.rb +28 -31
  26. data/examples/timer2.rb +129 -0
  27. data/glimmer-dsl-libui.gemspec +0 -0
  28. data/lib/glimmer/libui/control_proxy/checkbox_proxy.rb +5 -0
  29. data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +5 -0
  30. data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +18 -2
  31. data/lib/glimmer/libui/control_proxy/date_time_picker_proxy.rb +5 -0
  32. data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +5 -0
  33. data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +4 -0
  34. data/lib/glimmer/libui/control_proxy/menu_item_proxy/check_menu_item_proxy.rb +5 -0
  35. data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +17 -4
  36. data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +20 -0
  37. data/lib/glimmer/libui/control_proxy/slider_proxy.rb +38 -0
  38. data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +38 -0
  39. data/lib/glimmer/libui/control_proxy.rb +2 -2
  40. metadata +13 -2
data/examples/timer.rb CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'glimmer-dsl-libui'
4
2
 
5
3
  class Timer
@@ -9,9 +7,12 @@ class Timer
9
7
  MINUTE_MAX = 59
10
8
  HOUR_MAX = 23
11
9
 
10
+ attr_accessor :hour, :min, :sec, :started, :played
11
+
12
12
  def initialize
13
13
  @pid = nil
14
14
  @alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
15
+ @hour = @min = @sec = 0
15
16
  at_exit { stop_alarm }
16
17
  setup_timer
17
18
  create_gui
@@ -41,31 +42,29 @@ class Timer
41
42
  unless @setup_timer
42
43
  Glimmer::LibUI.timer(1) do
43
44
  if @started
44
- seconds = @sec_spinbox.value
45
- minutes = @min_spinbox.value
46
- hours = @hour_spinbox.value
45
+ seconds = @sec
46
+ minutes = @min
47
+ hours = @hour
47
48
  if seconds > 0
48
- @sec_spinbox.value = seconds -= 1
49
+ self.sec = seconds -= 1
49
50
  end
50
51
  if seconds == 0
51
52
  if minutes > 0
52
- @min_spinbox.value = minutes -= 1
53
- @sec_spinbox.value = seconds = SECOND_MAX
53
+ self.min = minutes -= 1
54
+ self.sec = seconds = SECOND_MAX
54
55
  end
55
56
  if minutes == 0
56
57
  if hours > 0
57
- @hour_spinbox.value = hours -= 1
58
- @min_spinbox.value = minutes = MINUTE_MAX
59
- @sec_spinbox.value = seconds = SECOND_MAX
58
+ self.hour = hours -= 1
59
+ self.min = minutes = MINUTE_MAX
60
+ self.sec = seconds = SECOND_MAX
60
61
  end
61
62
  if hours == 0 && minutes == 0 && seconds == 0
62
- @start_button.enabled = true
63
- @stop_button.enabled = false
64
- @started = false
63
+ self.started = false
65
64
  unless @played
66
65
  play_alarm
67
66
  msg_box('Alarm', 'Countdown Is Finished!')
68
- @played = true
67
+ self.played = true
69
68
  end
70
69
  end
71
70
  end
@@ -83,42 +82,40 @@ class Timer
83
82
  group('Countdown') {
84
83
  vertical_box {
85
84
  horizontal_box {
86
- @hour_spinbox = spinbox(0, HOUR_MAX) {
85
+ spinbox(0, HOUR_MAX) {
87
86
  stretchy false
88
- value 0
87
+ value <=> [self, :hour]
89
88
  }
90
89
  label(':') {
91
90
  stretchy false
92
91
  }
93
- @min_spinbox = spinbox(0, MINUTE_MAX) {
92
+ spinbox(0, MINUTE_MAX) {
94
93
  stretchy false
95
- value 0
94
+ value <=> [self, :min]
96
95
  }
97
96
  label(':') {
98
97
  stretchy false
99
98
  }
100
- @sec_spinbox = spinbox(0, SECOND_MAX) {
99
+ spinbox(0, SECOND_MAX) {
101
100
  stretchy false
102
- value 0
101
+ value <=> [self, :sec]
103
102
  }
104
103
  }
105
104
  horizontal_box {
106
- @start_button = button('Start') {
105
+ button('Start') {
106
+ enabled <= [self, :started, on_read: :!]
107
+
107
108
  on_clicked do
108
- @start_button.enabled = false
109
- @stop_button.enabled = true
110
- @started = true
111
- @played = false
109
+ self.started = true
110
+ self.played = false
112
111
  end
113
112
  }
114
113
 
115
- @stop_button = button('Stop') {
116
- enabled false
114
+ button('Stop') {
115
+ enabled <= [self, :started]
117
116
 
118
117
  on_clicked do
119
- @start_button.enabled = true
120
- @stop_button.enabled = false
121
- @started = false
118
+ self.started = false
122
119
  end
123
120
  }
124
121
  }
@@ -0,0 +1,129 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class Timer
4
+ include Glimmer
5
+
6
+ SECOND_MAX = 59
7
+ MINUTE_MAX = 59
8
+ HOUR_MAX = 23
9
+
10
+ def initialize
11
+ @pid = nil
12
+ @alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
13
+ at_exit { stop_alarm }
14
+ setup_timer
15
+ create_gui
16
+ end
17
+
18
+ def stop_alarm
19
+ if @pid
20
+ Process.kill(:SIGKILL, @pid) if @th.alive?
21
+ @pid = nil
22
+ end
23
+ end
24
+
25
+ def play_alarm
26
+ stop_alarm
27
+ if @pid.nil?
28
+ begin
29
+ @pid = spawn "timidity -G 0.0-10.0 #{@alarm_file}"
30
+ @th = Process.detach @pid
31
+ rescue Errno::ENOENT
32
+ warn 'Timidty++ not found. Please install Timidity++.'
33
+ warn 'https://sourceforge.net/projects/timidity/'
34
+ end
35
+ end
36
+ end
37
+
38
+ def setup_timer
39
+ unless @setup_timer
40
+ Glimmer::LibUI.timer(1) do
41
+ if @started
42
+ seconds = @sec_spinbox.value
43
+ minutes = @min_spinbox.value
44
+ hours = @hour_spinbox.value
45
+ if seconds > 0
46
+ @sec_spinbox.value = seconds -= 1
47
+ end
48
+ if seconds == 0
49
+ if minutes > 0
50
+ @min_spinbox.value = minutes -= 1
51
+ @sec_spinbox.value = seconds = SECOND_MAX
52
+ end
53
+ if minutes == 0
54
+ if hours > 0
55
+ @hour_spinbox.value = hours -= 1
56
+ @min_spinbox.value = minutes = MINUTE_MAX
57
+ @sec_spinbox.value = seconds = SECOND_MAX
58
+ end
59
+ if hours == 0 && minutes == 0 && seconds == 0
60
+ @start_button.enabled = true
61
+ @stop_button.enabled = false
62
+ @started = false
63
+ unless @played
64
+ play_alarm
65
+ msg_box('Alarm', 'Countdown Is Finished!')
66
+ @played = true
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ @setup_timer = true
74
+ end
75
+ end
76
+
77
+ def create_gui
78
+ window('Timer') {
79
+ margined true
80
+
81
+ group('Countdown') {
82
+ vertical_box {
83
+ horizontal_box {
84
+ @hour_spinbox = spinbox(0, HOUR_MAX) {
85
+ stretchy false
86
+ value 0
87
+ }
88
+ label(':') {
89
+ stretchy false
90
+ }
91
+ @min_spinbox = spinbox(0, MINUTE_MAX) {
92
+ stretchy false
93
+ value 0
94
+ }
95
+ label(':') {
96
+ stretchy false
97
+ }
98
+ @sec_spinbox = spinbox(0, SECOND_MAX) {
99
+ stretchy false
100
+ value 0
101
+ }
102
+ }
103
+ horizontal_box {
104
+ @start_button = button('Start') {
105
+ on_clicked do
106
+ @start_button.enabled = false
107
+ @stop_button.enabled = true
108
+ @started = true
109
+ @played = false
110
+ end
111
+ }
112
+
113
+ @stop_button = button('Stop') {
114
+ enabled false
115
+
116
+ on_clicked do
117
+ @start_button.enabled = true
118
+ @stop_button.enabled = false
119
+ @started = false
120
+ end
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }.show
126
+ end
127
+ end
128
+
129
+ Timer.new
Binary file
@@ -29,6 +29,11 @@ module Glimmer
29
29
  # Follows the Proxy Design Pattern
30
30
  class CheckboxProxy < ControlProxy
31
31
  DEFAULT_TEXT = ''
32
+
33
+ def data_bind(property, model_binding)
34
+ super
35
+ handle_listener('on_toggled') { model_binding.call(checked) } if property == 'checked'
36
+ end
32
37
 
33
38
  private
34
39
 
@@ -113,6 +113,11 @@ module Glimmer
113
113
  Fiddle.free @alpha unless @alpha.nil?
114
114
  super
115
115
  end
116
+
117
+ def data_bind(property, model_binding)
118
+ super
119
+ handle_listener('on_changed') { model_binding.call(color) } if property == 'color'
120
+ end
116
121
  end
117
122
  end
118
123
  end
@@ -54,8 +54,24 @@ module Glimmer
54
54
  alias set_items items
55
55
  alias items= items
56
56
 
57
- def selected_item
58
- items[selected]
57
+ def selected_item(value = nil)
58
+ if value.nil?
59
+ items[selected]
60
+ else
61
+ self.selected = items.index(value)
62
+ end
63
+ end
64
+ alias set_selected_item selected_item
65
+ alias selected_item= selected_item
66
+
67
+ def data_bind(property, model_binding)
68
+ super # model to view data-binding
69
+ case property
70
+ when 'selected'
71
+ handle_listener('on_selected') { model_binding.call(selected) }
72
+ when 'selected_item'
73
+ handle_listener('on_selected') { model_binding.call(selected_item) }
74
+ end
59
75
  end
60
76
  end
61
77
  end
@@ -64,6 +64,11 @@ module Glimmer
64
64
  Fiddle.free @time unless @time.nil?
65
65
  super
66
66
  end
67
+
68
+ def data_bind(property, model_binding)
69
+ super
70
+ handle_listener('on_changed') { model_binding.call(time) } if property == 'time'
71
+ end
67
72
  end
68
73
  end
69
74
  end
@@ -39,6 +39,11 @@ module Glimmer
39
39
  end
40
40
  alias set_items items
41
41
  alias items= items
42
+
43
+ def data_bind(property, model_binding)
44
+ super
45
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
46
+ end
42
47
  end
43
48
  end
44
49
  end
@@ -64,6 +64,10 @@ module Glimmer
64
64
  ::LibUI.free_font_button_font(@font_descriptor) unless @font_descriptor.nil?
65
65
  super
66
66
  end
67
+
68
+ def data_bind(property, model_binding)
69
+ handle_listener('on_changed') { model_binding.call(font) } if property == 'font'
70
+ end
67
71
  end
68
72
  end
69
73
  end
@@ -29,6 +29,11 @@ module Glimmer
29
29
  #
30
30
  # Follows the Proxy Design Pattern
31
31
  class CheckMenuItemProxy < MenuItemProxy
32
+ def data_bind(property, model_binding)
33
+ super
34
+ handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
35
+ end
36
+
32
37
  private
33
38
 
34
39
  def build_control
@@ -29,15 +29,23 @@ module Glimmer
29
29
  #
30
30
  # Follows the Proxy Design Pattern
31
31
  class RadioMenuItemProxy < MenuItemProxy
32
+ def initialize(keyword, parent, args, &block)
33
+ @last_checked = nil
34
+ super
35
+ end
36
+
32
37
  def checked(value = nil)
33
- if !value.nil?
34
- if Glimmer::LibUI.integer_to_boolean(value) != checked?
35
- super
38
+ if value.nil?
39
+ super()
40
+ else
41
+ super
42
+ if Glimmer::LibUI.integer_to_boolean(value, allow_nil: false) != Glimmer::LibUI.integer_to_boolean(@last_checked, allow_nil: false)
36
43
  if Glimmer::LibUI.integer_to_boolean(value)
37
44
  (@parent_proxy.children - [self]).select {|c| c.is_a?(MenuItemProxy)}.each do |menu_item|
38
45
  menu_item.checked = false
39
46
  end
40
47
  end
48
+ @last_checked = checked
41
49
  end
42
50
  end
43
51
  end
@@ -48,7 +56,7 @@ module Glimmer
48
56
  def handle_listener(listener_name, &listener)
49
57
  if listener_name.to_s == 'on_clicked'
50
58
  radio_listener = Proc.new do
51
- self.checked = true if !checked?
59
+ self.checked = true
52
60
  listener.call(self)
53
61
  end
54
62
  super(listener_name, &radio_listener)
@@ -57,6 +65,11 @@ module Glimmer
57
65
  end
58
66
  end
59
67
 
68
+ def data_bind(property, model_binding)
69
+ super
70
+ handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
71
+ end
72
+
60
73
  private
61
74
 
62
75
  def build_control
@@ -39,6 +39,26 @@ module Glimmer
39
39
  end
40
40
  alias set_items items
41
41
  alias items= items
42
+
43
+ def selected_item(value = nil)
44
+ if value.nil?
45
+ items[selected]
46
+ else
47
+ self.selected = items.index(value) || -1
48
+ end
49
+ end
50
+ alias set_selected_item selected_item
51
+ alias selected_item= selected_item
52
+
53
+ def data_bind(property, model_binding)
54
+ super # model to view data-binding
55
+ case property
56
+ when 'selected'
57
+ handle_listener('on_selected') { model_binding.call(selected) }
58
+ when 'selected_item'
59
+ handle_listener('on_selected') { model_binding.call(selected_item) }
60
+ end
61
+ end
42
62
  end
43
63
  end
44
64
  end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/libui/control_proxy'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class ControlProxy
27
+ # Proxy for LibUI slider objects
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SliderProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(value) } if property == 'value'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/libui/control_proxy'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class ControlProxy
27
+ # Proxy for LibUI spinbox objects
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SpinboxProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(value) } if property == 'value'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -245,8 +245,8 @@ module Glimmer
245
245
  args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
246
246
  args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
247
247
  if property.to_s == 'checked'
248
- current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui))
249
- new_value = Glimmer::LibUI.integer_to_boolean(args[0])
248
+ current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui), allow_nil: false)
249
+ new_value = Glimmer::LibUI.integer_to_boolean(args[0], allow_nil: false)
250
250
  ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args) if new_value != current_value
251
251
  else
252
252
  ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-28 00:00:00.000000000 Z
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -247,22 +247,28 @@ files:
247
247
  - examples/basic_window2.rb
248
248
  - examples/button_counter.rb
249
249
  - examples/color_button.rb
250
+ - examples/color_button2.rb
250
251
  - examples/color_the_circles.rb
251
252
  - examples/control_gallery.rb
252
253
  - examples/custom_draw_text.rb
253
254
  - examples/custom_draw_text2.rb
254
255
  - examples/date_time_picker.rb
256
+ - examples/date_time_picker2.rb
255
257
  - examples/dynamic_area.rb
256
258
  - examples/dynamic_area2.rb
259
+ - examples/dynamic_area3.rb
260
+ - examples/dynamic_area4.rb
257
261
  - examples/editable_column_table.rb
258
262
  - examples/editable_table.rb
259
263
  - examples/font_button.rb
264
+ - examples/font_button2.rb
260
265
  - examples/form.rb
261
266
  - examples/form2.rb
262
267
  - examples/form_table.rb
263
268
  - examples/form_table2.rb
264
269
  - examples/grid.rb
265
270
  - examples/histogram.rb
271
+ - examples/histogram2.rb
266
272
  - examples/login.rb
267
273
  - examples/login2.rb
268
274
  - examples/login3.rb
@@ -272,6 +278,8 @@ files:
272
278
  - examples/method_based_custom_keyword.rb
273
279
  - examples/method_based_custom_keyword2.rb
274
280
  - examples/midi_player.rb
281
+ - examples/midi_player2.rb
282
+ - examples/midi_player3.rb
275
283
  - examples/simple_notepad.rb
276
284
  - examples/snake.rb
277
285
  - examples/snake/model/apple.rb
@@ -289,6 +297,7 @@ files:
289
297
  - examples/tic_tac_toe/board.rb
290
298
  - examples/tic_tac_toe/cell.rb
291
299
  - examples/timer.rb
300
+ - examples/timer2.rb
292
301
  - glimmer-dsl-libui.gemspec
293
302
  - icons/glimmer.png
294
303
  - lib/glimmer-dsl-libui.rb
@@ -366,6 +375,8 @@ files:
366
375
  - lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb
367
376
  - lib/glimmer/libui/control_proxy/path_proxy.rb
368
377
  - lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb
378
+ - lib/glimmer/libui/control_proxy/slider_proxy.rb
379
+ - lib/glimmer/libui/control_proxy/spinbox_proxy.rb
369
380
  - lib/glimmer/libui/control_proxy/tab_item_proxy.rb
370
381
  - lib/glimmer/libui/control_proxy/table_proxy.rb
371
382
  - lib/glimmer/libui/control_proxy/text_proxy.rb