glimmer-dsl-libui 0.2.0 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/README.md +975 -23
  4. data/VERSION +1 -1
  5. data/examples/area_gallery.rb +7 -1
  6. data/examples/area_gallery2.rb +14 -4
  7. data/examples/area_gallery3.rb +8 -2
  8. data/examples/area_gallery4.rb +15 -5
  9. data/examples/basic_draw_text.rb +65 -0
  10. data/examples/basic_draw_text2.rb +68 -0
  11. data/examples/color_the_circles.rb +220 -0
  12. data/examples/custom_draw_text.rb +84 -0
  13. data/examples/custom_draw_text2.rb +95 -0
  14. data/examples/midi_player.rb +2 -2
  15. data/examples/timer.rb +135 -0
  16. data/glimmer-dsl-libui.gemspec +0 -0
  17. data/lib/glimmer/dsl/libui/control_expression.rb +0 -1
  18. data/lib/glimmer/dsl/libui/property_expression.rb +3 -1
  19. data/lib/glimmer/dsl/libui/string_expression.rb +48 -0
  20. data/lib/glimmer/libui/attributed_string.rb +135 -0
  21. data/lib/glimmer/libui/control_proxy/area_proxy.rb +14 -3
  22. data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +0 -1
  23. data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +18 -0
  24. data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +3 -3
  25. data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +69 -0
  26. data/lib/glimmer/libui/control_proxy/menu_proxy.rb +3 -0
  27. data/lib/glimmer/libui/control_proxy/path_proxy.rb +0 -2
  28. data/lib/glimmer/libui/control_proxy/text_proxy.rb +172 -0
  29. data/lib/glimmer/libui/control_proxy/window_proxy.rb +0 -6
  30. data/lib/glimmer/libui/control_proxy.rb +7 -1
  31. data/lib/glimmer/libui/shape/arc.rb +6 -3
  32. data/lib/glimmer/libui/shape/circle.rb +50 -0
  33. data/lib/glimmer/libui/shape/rectangle.rb +4 -0
  34. data/lib/glimmer/libui/shape/square.rb +4 -0
  35. data/lib/glimmer/libui.rb +73 -6
  36. metadata +13 -2
data/examples/timer.rb ADDED
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ class Timer
6
+ include Glimmer
7
+
8
+ SECOND_MAX = 59
9
+ MINUTE_MAX = 59
10
+ HOUR_MAX = 23
11
+
12
+ def initialize
13
+ @pid = nil
14
+ @alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
15
+ at_exit { stop_alarm }
16
+ setup_timer
17
+ create_gui
18
+ end
19
+
20
+ def stop_alarm
21
+ if @pid
22
+ if @th.alive?
23
+ Process.kill(:SIGKILL, @pid)
24
+ @pid = nil
25
+ else
26
+ @pid = nil
27
+ end
28
+ end
29
+ end
30
+
31
+ def play_alarm
32
+ stop_alarm
33
+ if @pid.nil?
34
+ begin
35
+ @pid = spawn "timidity -G 0.0-10.0 #{@alarm_file}"
36
+ @th = Process.detach @pid
37
+ rescue Errno::ENOENT
38
+ warn 'Timidty++ not found. Please install Timidity++.'
39
+ warn 'https://sourceforge.net/projects/timidity/'
40
+ end
41
+ end
42
+ end
43
+
44
+ def setup_timer
45
+ unless @setup_timer
46
+ Glimmer::LibUI.timer(1) do
47
+ if @started
48
+ seconds = @sec_spinbox.value
49
+ minutes = @min_spinbox.value
50
+ hours = @hour_spinbox.value
51
+ if seconds > 0
52
+ @sec_spinbox.value = seconds -= 1
53
+ end
54
+ if seconds == 0
55
+ if minutes > 0
56
+ @min_spinbox.value = minutes -= 1
57
+ @sec_spinbox.value = seconds = SECOND_MAX
58
+ end
59
+ if minutes == 0
60
+ if hours > 0
61
+ @hour_spinbox.value = hours -= 1
62
+ @min_spinbox.value = minutes = MINUTE_MAX
63
+ @sec_spinbox.value = seconds = SECOND_MAX
64
+ end
65
+ if hours == 0 && minutes == 0 && seconds == 0
66
+ @start_button.enabled = true
67
+ @stop_button.enabled = false
68
+ @started = false
69
+ unless @played
70
+ play_alarm
71
+ msg_box('Alarm', 'Countdown Is Finished!')
72
+ @played = true
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ @setup_timer = true
80
+ end
81
+ end
82
+
83
+ def create_gui
84
+ window('Timer') {
85
+ margined true
86
+
87
+ group('Countdown') {
88
+ vertical_box {
89
+ horizontal_box {
90
+ @hour_spinbox = spinbox(0, HOUR_MAX) {
91
+ stretchy false
92
+ value 0
93
+ }
94
+ label(':') {
95
+ stretchy false
96
+ }
97
+ @min_spinbox = spinbox(0, MINUTE_MAX) {
98
+ stretchy false
99
+ value 0
100
+ }
101
+ label(':') {
102
+ stretchy false
103
+ }
104
+ @sec_spinbox = spinbox(0, SECOND_MAX) {
105
+ stretchy false
106
+ value 0
107
+ }
108
+ }
109
+ horizontal_box {
110
+ @start_button = button('Start') {
111
+ on_clicked do
112
+ @start_button.enabled = false
113
+ @stop_button.enabled = true
114
+ @started = true
115
+ @played = false
116
+ end
117
+ }
118
+
119
+ @stop_button = button('Stop') {
120
+ enabled false
121
+
122
+ on_clicked do
123
+ @start_button.enabled = true
124
+ @stop_button.enabled = false
125
+ @started = false
126
+ end
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }.show
132
+ end
133
+ end
134
+
135
+ Timer.new
Binary file
@@ -40,7 +40,6 @@ module Glimmer
40
40
  super
41
41
  parent.post_add_content
42
42
  end
43
-
44
43
  end
45
44
  end
46
45
  end
@@ -22,6 +22,7 @@
22
22
  require 'glimmer/dsl/expression'
23
23
  require 'glimmer/libui/control_proxy'
24
24
  require 'glimmer/libui/shape'
25
+ require 'glimmer/libui/attributed_string'
25
26
 
26
27
  module Glimmer
27
28
  module DSL
@@ -30,7 +31,8 @@ module Glimmer
30
31
  def can_interpret?(parent, keyword, *args, &block)
31
32
  (
32
33
  parent.is_a?(Glimmer::LibUI::ControlProxy) or
33
- parent.is_a?(Glimmer::LibUI::Shape)
34
+ parent.is_a?(Glimmer::LibUI::Shape) or
35
+ parent.is_a?(Glimmer::LibUI::AttributedString)
34
36
  ) and
35
37
  block.nil? and
36
38
  parent.respond_to?(keyword, *args)
@@ -0,0 +1,48 @@
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/dsl/static_expression'
23
+ require 'glimmer/dsl/parent_expression'
24
+ require 'glimmer/libui/control_proxy/text_proxy'
25
+ require 'glimmer/libui/attributed_string'
26
+
27
+ module Glimmer
28
+ module DSL
29
+ module Libui
30
+ class StringExpression < StaticExpression
31
+ include ParentExpression
32
+
33
+ def can_interpret?(parent, keyword, *args, &block)
34
+ super and
35
+ parent.is_a?(Glimmer::LibUI::ControlProxy::TextProxy)
36
+ end
37
+
38
+ def interpret(parent, keyword, *args, &block)
39
+ Glimmer::LibUI::AttributedString.new(keyword, parent, args, &block)
40
+ end
41
+
42
+ def add_content(parent, keyword, *args, &block)
43
+ parent.post_add_content
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,135 @@
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
+ require 'glimmer/libui/control_proxy/area_proxy'
24
+ require 'glimmer/libui/parent'
25
+ require 'glimmer/libui/control_proxy/transformable'
26
+
27
+ module Glimmer
28
+ module LibUI
29
+ class AttributedString
30
+ attr_accessor :string
31
+ attr_reader :block, :keyword, :parent_proxy, :args
32
+
33
+ def initialize(keyword, parent_proxy, args, &block)
34
+ @keyword = keyword
35
+ @parent_proxy = parent_proxy
36
+ @args = args
37
+ @string = @args.first || ''
38
+ @block = block
39
+ post_add_content if @block.nil?
40
+ end
41
+
42
+ def font(value = nil)
43
+ if value.nil?
44
+ @font
45
+ else
46
+ @font = value
47
+ redraw
48
+ end
49
+ end
50
+ alias font= font
51
+ alias set_font font
52
+
53
+ def color(value = nil)
54
+ if value.nil?
55
+ @color
56
+ else
57
+ @color = Glimmer::LibUI.interpret_color(value)
58
+ redraw
59
+ end
60
+ end
61
+ alias color= color
62
+ alias set_color color
63
+
64
+ def background(value = nil)
65
+ if value.nil?
66
+ @background
67
+ else
68
+ @background = Glimmer::LibUI.interpret_color(value)
69
+ redraw
70
+ end
71
+ end
72
+ alias background= background
73
+ alias background background
74
+
75
+ def underline(value = nil)
76
+ if value.nil?
77
+ @underline
78
+ else
79
+ @underline = value
80
+ redraw
81
+ end
82
+ end
83
+ alias underline= underline
84
+ alias underline underline
85
+
86
+ def post_add_content
87
+ block_result = block&.call
88
+ @string = block_result if block_result.is_a?(String)
89
+ @parent_proxy&.post_initialize_child(self)
90
+ end
91
+
92
+ def draw(area_draw_params)
93
+ @start = ::LibUI.attributed_string_len(@parent_proxy.attributed_string)
94
+ ::LibUI.attributed_string_append_unattributed(@parent_proxy.attributed_string, @string)
95
+ unless color.nil?
96
+ color_attribute = ::LibUI.new_color_attribute(@color[:r].to_f / 255.0, @color[:g].to_f / 255.0, @color[:b].to_f / 255.0, @color[:a] || 1.0)
97
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, color_attribute, @start, @start + @string.size)
98
+ end
99
+ unless background.nil?
100
+ background_attribute = ::LibUI.new_background_attribute(@background[:r].to_f / 255.0, @background[:g].to_f / 255.0, @background[:b].to_f / 255.0, @background[:a] || 1.0)
101
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, background_attribute, @start, @start + @string.size)
102
+ end
103
+ unless underline.nil?
104
+ underline_attribute = ::LibUI.new_underline_attribute(Glimmer::LibUI.enum_symbol_to_value(:underline, @underline))
105
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, underline_attribute, @start, @start + @string.size)
106
+ end
107
+ unless font.nil?
108
+ family_attribute = ::LibUI.new_family_attribute(font[:family])
109
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, family_attribute, @start, @start + @string.size)
110
+ size_attribute = ::LibUI.new_size_attribute(font[:size])
111
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, size_attribute, @start, @start + @string.size)
112
+ weight_attribute = ::LibUI.new_weight_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_weight, font[:weight]))
113
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, weight_attribute, @start, @start + @string.size)
114
+ italic_attribute = ::LibUI.new_italic_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_italic, font[:italic]))
115
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, italic_attribute, @start, @start + @string.size)
116
+ stretch_attribute = ::LibUI.new_stretch_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_stretch, font[:stretch]))
117
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, stretch_attribute, @start, @start + @string.size)
118
+ end
119
+ destroy if area_proxy.nil?
120
+ end
121
+
122
+ def destroy
123
+ @parent_proxy&.children&.delete(self)
124
+ end
125
+
126
+ def redraw
127
+ area_proxy&.queue_redraw_all
128
+ end
129
+
130
+ def area_proxy
131
+ @parent_proxy.parent_proxy
132
+ end
133
+ end
134
+ end
135
+ end
@@ -60,7 +60,18 @@ module Glimmer
60
60
  end
61
61
 
62
62
  def post_add_content
63
- super
63
+ unless parent_proxy.is_a?(Box)
64
+ original_parent_proxy = @parent_proxy
65
+ @vertical_box_parent_proxy = ControlProxy.create('vertical_box', parent_proxy, []) {} # block prevents calling post add content
66
+ append_properties.each do |property|
67
+ @vertical_box_parent_proxy.append_property(property, append_property(property))
68
+ end
69
+ @vertical_box_parent_proxy.post_add_content
70
+ @parent_proxy = @vertical_box_parent_proxy
71
+ @vertical_box_parent_proxy.post_initialize_child(self)
72
+ else
73
+ super
74
+ end
64
75
  install_listeners
65
76
  end
66
77
 
@@ -72,7 +83,7 @@ module Glimmer
72
83
  def redraw
73
84
  queue_redraw_all
74
85
  end
75
-
86
+
76
87
  private
77
88
 
78
89
  def build_control
@@ -169,7 +180,7 @@ module Glimmer
169
180
  end
170
181
 
171
182
  def ext_key_to_symbol(ext_key_value)
172
- Glimmer::LibUI.enum_symbols(:ext_key)[ext_key_value - 1].to_s.to_sym if ext_key_value > 0
183
+ Glimmer::LibUI.enum_value_to_symbol(:ext_key, ext_key_value)
173
184
  end
174
185
 
175
186
  def modifiers_to_symbols(modifiers_value)
@@ -29,7 +29,6 @@ module Glimmer
29
29
  # Follows the Proxy Design Pattern
30
30
  class ColorButtonProxy < ControlProxy
31
31
  def color(value = nil)
32
- # TODO support hex color value
33
32
  if value.nil?
34
33
  @red ||= Fiddle::Pointer.malloc(8) # double
35
34
  @green ||= Fiddle::Pointer.malloc(8) # double
@@ -28,6 +28,20 @@ module Glimmer
28
28
  #
29
29
  # Follows the Proxy Design Pattern
30
30
  class ComboboxProxy < ControlProxy
31
+ def selected(value = nil)
32
+ if value.nil?
33
+ super()
34
+ else
35
+ if value.is_a?(String)
36
+ super(items.index(value).to_i)
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
42
+ alias selected= selected
43
+ alias set_selected selected
44
+
31
45
  def items(*values)
32
46
  values = values.first if values.first.is_a?(Array)
33
47
  if values.empty?
@@ -39,6 +53,10 @@ module Glimmer
39
53
  end
40
54
  alias set_items items
41
55
  alias items= items
56
+
57
+ def selected_item
58
+ items[selected]
59
+ end
42
60
  end
43
61
  end
44
62
  end
@@ -34,9 +34,9 @@ module Glimmer
34
34
  {
35
35
  family: @font_descriptor.Family.to_s,
36
36
  size: @font_descriptor.Size,
37
- weight: @font_descriptor.Weight,
38
- italic: @font_descriptor.Italic,
39
- stretch: @font_descriptor.Stretch
37
+ weight: Glimmer::LibUI.enum_value_to_symbol(:text_weight, @font_descriptor.Weight),
38
+ italic: Glimmer::LibUI.enum_value_to_symbol(:text_italic, @font_descriptor.Italic),
39
+ stretch: Glimmer::LibUI.enum_value_to_symbol(:text_stretch, @font_descriptor.Stretch),
40
40
  }
41
41
  end
42
42
 
@@ -0,0 +1,69 @@
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/menu_item_proxy'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class ControlProxy
27
+ class MenuItemProxy < ControlProxy
28
+ # Proxy for LibUI radio menu item object
29
+ #
30
+ # Follows the Proxy Design Pattern
31
+ class RadioMenuItemProxy < MenuItemProxy
32
+ def checked(value = nil)
33
+ if !value.nil?
34
+ if Glimmer::LibUI.integer_to_boolean(value) != checked?
35
+ super
36
+ if Glimmer::LibUI.integer_to_boolean(value)
37
+ (@parent_proxy.children - [self]).select {|c| c.is_a?(MenuItemProxy)}.each do |menu_item|
38
+ menu_item.checked = false
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ alias checked? checked
45
+ alias set_checked checked
46
+ alias checked= checked
47
+
48
+ def handle_listener(listener_name, &listener)
49
+ if listener_name.to_s == 'on_clicked'
50
+ radio_listener = Proc.new do
51
+ self.checked = true if !checked?
52
+ listener.call(self)
53
+ end
54
+ super(listener_name, &radio_listener)
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def build_control
63
+ @libui = @parent_proxy.append_check_item(*@args)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -20,6 +20,7 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  require 'glimmer/libui/control_proxy'
23
+ require 'glimmer/libui/parent'
23
24
 
24
25
  module Glimmer
25
26
  module LibUI
@@ -28,6 +29,8 @@ module Glimmer
28
29
  #
29
30
  # Follows the Proxy Design Pattern
30
31
  class MenuProxy < ControlProxy
32
+ include Parent
33
+
31
34
  DEFAULT_TEXT = ''
32
35
 
33
36
  private
@@ -34,13 +34,11 @@ module Glimmer
34
34
  include Parent
35
35
  prepend Transformable
36
36
 
37
- # TODO support mode without parent proxy
38
37
  def initialize(keyword, parent, args, &block)
39
38
  @keyword = keyword
40
39
  @parent_proxy = parent
41
40
  @args = args
42
41
  @block = block
43
- @enabled = true
44
42
  post_add_content if @block.nil?
45
43
  end
46
44