glimmer-dsl-libui 0.2.13 → 0.2.17

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.13
1
+ 0.2.17
data/bin/girb CHANGED
File without changes
@@ -41,21 +41,19 @@ window('Area Gallery', 400, 400) {
41
41
  fill r: 202, g: 102, b: 204, a: 0.5
42
42
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
43
43
  }
44
- unless OS.windows?
45
- path { # declarative stable path
46
- arc(400, 220, 180, 90, 90, false)
47
-
48
- # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
49
- fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
50
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
51
- }
52
- path { # declarative stable path
53
- circle(200, 200, 90)
54
-
55
- fill r: 202, g: 102, b: 204, a: 0.5
56
- stroke r: 0, g: 0, b: 0, thickness: 2
57
- }
58
- end
44
+ path { # declarative stable path
45
+ arc(400, 220, 180, 90, 90, false)
46
+
47
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
48
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
49
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
50
+ }
51
+ path { # declarative stable path
52
+ circle(200, 200, 90)
53
+
54
+ fill r: 202, g: 102, b: 204, a: 0.5
55
+ stroke r: 0, g: 0, b: 0, thickness: 2
56
+ }
59
57
  text(160, 40, 100) { # x, y, width
60
58
  string('Area Gallery') {
61
59
  font family: 'Times', size: 14
@@ -95,32 +95,30 @@ window('Area Gallery', 400, 400) {
95
95
  fill r: 202, g: 102, b: 204, a: 0.5
96
96
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
97
97
  }
98
- unless OS.windows?
99
- path { # declarative stable path
100
- arc {
101
- x_center 400
102
- y_center 220
103
- radius 180
104
- start_angle 90
105
- sweep 90
106
- is_negative false
107
- }
108
-
109
- # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
110
- fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
111
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
98
+ path { # declarative stable path
99
+ arc {
100
+ x_center 400
101
+ y_center 220
102
+ radius 180
103
+ start_angle 90
104
+ sweep 90
105
+ is_negative false
112
106
  }
113
- path { # declarative stable path
114
- circle {
115
- x_center 200
116
- y_center 200
117
- radius 90
118
- }
119
-
120
- fill r: 202, g: 102, b: 204, a: 0.5
121
- stroke r: 0, g: 0, b: 0, thickness: 2
107
+
108
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
109
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
110
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
111
+ }
112
+ path { # declarative stable path
113
+ circle {
114
+ x_center 200
115
+ y_center 200
116
+ radius 90
122
117
  }
123
- end
118
+
119
+ fill r: 202, g: 102, b: 204, a: 0.5
120
+ stroke r: 0, g: 0, b: 0, thickness: 2
121
+ }
124
122
  text {
125
123
  x 160
126
124
  y 40
@@ -42,21 +42,19 @@ window('Area Gallery', 400, 400) {
42
42
  fill r: 202, g: 102, b: 204, a: 0.5
43
43
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
44
44
  }
45
- unless OS.windows?
46
- path { # a dynamic path is added semi-declaratively inside on_draw block
47
- arc(400, 220, 180, 90, 90, false)
48
-
49
- # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
50
- fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
51
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
52
- }
53
- path { # a dynamic path is added semi-declaratively inside on_draw block
54
- circle(200, 200, 90)
55
-
56
- fill r: 202, g: 102, b: 204, a: 0.5
57
- stroke r: 0, g: 0, b: 0, thickness: 2
58
- }
59
- end
45
+ path { # a dynamic path is added semi-declaratively inside on_draw block
46
+ arc(400, 220, 180, 90, 90, false)
47
+
48
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
49
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
50
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
51
+ }
52
+ path { # a dynamic path is added semi-declaratively inside on_draw block
53
+ circle(200, 200, 90)
54
+
55
+ fill r: 202, g: 102, b: 204, a: 0.5
56
+ stroke r: 0, g: 0, b: 0, thickness: 2
57
+ }
60
58
  text(160, 40, 100) { # x, y, width
61
59
  string('Area Gallery') {
62
60
  font family: 'Times', size: 14
@@ -96,32 +96,30 @@ window('Area Gallery', 400, 400) {
96
96
  fill r: 202, g: 102, b: 204, a: 0.5
97
97
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
98
98
  }
99
- unless OS.windows?
100
- path { # a dynamic path is added semi-declaratively inside on_draw block
101
- arc {
102
- x_center 400
103
- y_center 220
104
- radius 180
105
- start_angle 90
106
- sweep 90
107
- is_negative false
108
- }
109
-
110
- # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
111
- fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
112
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
99
+ path { # a dynamic path is added semi-declaratively inside on_draw block
100
+ arc {
101
+ x_center 400
102
+ y_center 220
103
+ radius 180
104
+ start_angle 90
105
+ sweep 90
106
+ is_negative false
113
107
  }
114
- path { # a dynamic path is added semi-declaratively inside on_draw block
115
- circle {
116
- x_center 200
117
- y_center 200
118
- radius 90
119
- }
120
-
121
- fill r: 202, g: 102, b: 204, a: 0.5
122
- stroke r: 0, g: 0, b: 0, thickness: 2
108
+
109
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
110
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
111
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
112
+ }
113
+ path { # a dynamic path is added semi-declaratively inside on_draw block
114
+ circle {
115
+ x_center 200
116
+ y_center 200
117
+ radius 90
123
118
  }
124
- end
119
+
120
+ fill r: 202, g: 102, b: 204, a: 0.5
121
+ stroke r: 0, g: 0, b: 0, thickness: 2
122
+ }
125
123
  text {
126
124
  x 160
127
125
  y 40
@@ -16,10 +16,16 @@ window('Basic Transform', 350, 350) {
16
16
  fill r: [255 - n*5, 0].max, g: [n*5, 255].min, b: 0, a: 0.5
17
17
  stroke :black, thickness: 2
18
18
  transform {
19
- skew 0.15, 0.15
20
- translate 50, 50
19
+ unless OS.windows?
20
+ skew 0.15, 0.15
21
+ translate 50, 50
22
+ end
21
23
  rotate 100, 100, -9 * n
22
24
  scale 1.1, 1.1
25
+ if OS.windows?
26
+ skew 0.15, 0.15
27
+ translate 50, 50
28
+ end
23
29
  }
24
30
  }
25
31
  end
@@ -4,7 +4,7 @@ require 'glimmer-dsl-libui'
4
4
 
5
5
  include Glimmer
6
6
 
7
- window('color button', 230) {
7
+ window('color button', 240) {
8
8
  color_button { |cb|
9
9
  color :blue
10
10
 
@@ -1,55 +1,56 @@
1
1
  require 'glimmer-dsl-libui'
2
2
 
3
- class ColorTheShapes
3
+ class ColorTheCircles
4
4
  include Glimmer
5
5
 
6
6
  WINDOW_WIDTH = 800
7
7
  WINDOW_HEIGHT = 600
8
8
  SHAPE_MIN_SIZE = 15
9
- SHAPE_MAX_SIZE = 100
9
+ SHAPE_MAX_SIZE = 75
10
10
  MARGIN_WIDTH = 55
11
11
  MARGIN_HEIGHT = 155
12
12
  TIME_MAX_EASY = 4
13
13
  TIME_MAX_MEDIUM = 3
14
14
  TIME_MAX_HARD = 2
15
15
  TIME_MAX_INSANE = 1
16
- SHAPES = ['square'] + (OS.windows? ? [] : ['circle'])
17
16
 
18
17
  attr_accessor :score
19
18
 
20
19
  def initialize
21
- @shapes_data = []
20
+ @circles_data = []
22
21
  @score = 0
23
22
  @time_max = TIME_MAX_HARD
24
23
  @game_over = false
25
24
  register_observers
26
- setup_shape_factory
25
+ setup_circle_factory
27
26
  end
28
27
 
29
28
  def register_observers
30
29
  observer = Glimmer::DataBinding::Observer.proc do |new_score|
31
- @score_label.text = new_score.to_s
32
- if new_score == -20
33
- @game_over = true
34
- msg_box('You Lost!', 'Sorry! Your score reached -20')
35
- restart_game
36
- elsif new_score == 0
37
- @game_over = true
38
- msg_box('You Won!', 'Congratulations! Your score reached 0')
39
- restart_game
30
+ Glimmer::LibUI.queue_main do
31
+ @score_label.text = new_score.to_s
32
+ if new_score == -20
33
+ @game_over = true
34
+ msg_box('You Lost!', 'Sorry! Your score reached -20')
35
+ restart_game
36
+ elsif new_score == 0
37
+ @game_over = true
38
+ msg_box('You Won!', 'Congratulations! Your score reached 0')
39
+ restart_game
40
+ end
40
41
  end
41
42
  end
42
43
  observer.observe(self, :score) # automatically enhances self to become Glimmer::DataBinding::ObservableModel and notify observer on score attribute changes
43
44
  end
44
45
 
45
- def setup_shape_factory
46
+ def setup_circle_factory
46
47
  consumer = Proc.new do
47
48
  unless @game_over
48
- if @shapes_data.empty?
49
- # start with 3 shapes to make more challenging
50
- add_shape until @shapes_data.size > 3
49
+ if @circles_data.empty?
50
+ # start with 3 circles to make more challenging
51
+ add_circle until @circles_data.size > 3
51
52
  else
52
- add_shape
53
+ add_circle
53
54
  end
54
55
  end
55
56
  delay = rand * @time_max
@@ -58,13 +59,13 @@ class ColorTheShapes
58
59
  Glimmer::LibUI.queue_main(&consumer)
59
60
  end
60
61
 
61
- def add_shape
62
- shape_x = rand * (WINDOW_WIDTH - MARGIN_WIDTH - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
63
- shape_y = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
64
- shape_size = rand * (SHAPE_MAX_SIZE - SHAPE_MIN_SIZE) + SHAPE_MIN_SIZE
62
+ def add_circle
63
+ circle_x = rand * (WINDOW_WIDTH - MARGIN_WIDTH - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
64
+ circle_y = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
65
+ circle_size = rand * (SHAPE_MAX_SIZE - SHAPE_MIN_SIZE) + SHAPE_MIN_SIZE
65
66
  stroke_color = Glimmer::LibUI.x11_colors.sample
66
- @shapes_data << {
67
- args: [shape_x, shape_y, shape_size],
67
+ @circles_data << {
68
+ args: [circle_x, circle_y, circle_size],
68
69
  fill: nil,
69
70
  stroke: stroke_color
70
71
  }
@@ -74,27 +75,27 @@ class ColorTheShapes
74
75
 
75
76
  def restart_game
76
77
  @score = 0 # update variable directly to avoid notifying observers
77
- @shapes_data.clear
78
+ @circles_data.clear
78
79
  @game_over = false
79
80
  end
80
81
 
81
- def color_shape(x, y)
82
- clicked_shape_data = @shapes_data.find do |shape_data|
83
- shape_data[:fill].nil? && shape_data[:shape]&.include?(x, y)
82
+ def color_circle(x, y)
83
+ clicked_circle_data = @circles_data.find do |circle_data|
84
+ circle_data[:fill].nil? && circle_data[:circle]&.include?(x, y)
84
85
  end
85
- if clicked_shape_data
86
- clicked_shape_data[:fill] = clicked_shape_data[:stroke]
87
- push_colored_shape_behind_uncolored_shapes(clicked_shape_data)
86
+ if clicked_circle_data
87
+ clicked_circle_data[:fill] = clicked_circle_data[:stroke]
88
+ push_colored_circle_behind_uncolored_circles(clicked_circle_data)
88
89
  @area.queue_redraw_all
89
90
  self.score += 1 # notifies score observers automatically of change
90
91
  end
91
92
  end
92
93
 
93
- def push_colored_shape_behind_uncolored_shapes(colored_shape_data)
94
- removed_colored_shape_data = @shapes_data.delete(colored_shape_data)
95
- last_colored_shape_data = @shapes_data.select {|cd| cd[:fill]}.last
96
- last_colored_shape_data_index = @shapes_data.index(last_colored_shape_data) || -1
97
- @shapes_data.insert(last_colored_shape_data_index + 1, removed_colored_shape_data)
94
+ def push_colored_circle_behind_uncolored_circles(colored_circle_data)
95
+ removed_colored_circle_data = @circles_data.delete(colored_circle_data)
96
+ last_colored_circle_data = @circles_data.select {|cd| cd[:fill]}.last
97
+ last_colored_circle_data_index = @circles_data.index(last_colored_circle_data) || -1
98
+ @circles_data.insert(last_colored_circle_data_index + 1, removed_colored_circle_data)
98
99
  end
99
100
 
100
101
  def launch
@@ -139,12 +140,12 @@ class ColorTheShapes
139
140
  menu('Help') {
140
141
  menu_item('Instructions') {
141
142
  on_clicked do
142
- msg_box('Instructions', "Score goes down as shapes are added.\nIf it reaches -20, you lose!\n\nClick shapes to color and score!\nOnce score reaches 0, you win!\n\nBeware of concealed light-colored shapes!\nThey are revealed once darker shapes intersect them.\n\nThere are four levels of difficulty.\nChange via difficulty menu if the game gets too tough.")
143
+ msg_box('Instructions', "Score goes down as circles are added.\nIf it reaches -20, you lose!\n\nClick circles to color and score!\nOnce score reaches 0, you win!\n\nBeware of concealed light-colored circles!\nThey are revealed once darker circles intersect them.\n\nThere are four levels of difficulty.\nChange via difficulty menu if the game gets too tough.")
143
144
  end
144
145
  }
145
146
  }
146
147
 
147
- window('Color The Shapes', WINDOW_WIDTH, WINDOW_HEIGHT) {
148
+ window('Color The Circles', WINDOW_WIDTH, WINDOW_HEIGHT) {
148
149
  margined true
149
150
 
150
151
  grid {
@@ -158,13 +159,13 @@ class ColorTheShapes
158
159
  end
159
160
  }
160
161
 
161
- label('Score goes down as shapes are added. If it reaches -20, you lose!') {
162
+ label('Score goes down as circles are added. If it reaches -20, you lose!') {
162
163
  left 0
163
164
  top 1
164
165
  halign :center
165
166
  }
166
167
 
167
- label('Click shapes to color and score! Once score reaches 0, you win!') {
168
+ label('Click circles to color and score! Once score reaches 0, you win!') {
168
169
  left 0
169
170
  top 2
170
171
  halign :center
@@ -199,18 +200,18 @@ class ColorTheShapes
199
200
  fill :white
200
201
  }
201
202
 
202
- @shapes_data.each do |shape_data|
203
+ @circles_data.each do |circle_data|
203
204
  path {
204
- shape_data[:shape] = send(SHAPES.sample, *shape_data[:args])
205
+ circle_data[:circle] = circle(*circle_data[:args])
205
206
 
206
- fill shape_data[:fill]
207
- stroke shape_data[:stroke]
207
+ fill circle_data[:fill]
208
+ stroke circle_data[:stroke]
208
209
  }
209
210
  end
210
211
  end
211
212
 
212
213
  on_mouse_down do |area_mouse_event|
213
- color_shape(area_mouse_event[:x], area_mouse_event[:y])
214
+ color_circle(area_mouse_event[:x], area_mouse_event[:y])
214
215
  end
215
216
  }
216
217
  }
@@ -218,4 +219,4 @@ class ColorTheShapes
218
219
  end
219
220
  end
220
221
 
221
- ColorTheShapes.new.launch
222
+ ColorTheCircles.new.launch
@@ -11,7 +11,7 @@ class MetaExample
11
11
 
12
12
  def examples
13
13
  if @examples.nil?
14
- example_files = Dir.glob(File.join(File.expand_path('.', __dir__), '**', '*.rb'))
14
+ example_files = Dir.glob(File.join(File.expand_path('.', __dir__), '*.rb'))
15
15
  example_file_names = example_files.map { |f| File.basename(f, '.rb') }
16
16
  example_file_names = example_file_names.reject { |f| f == 'meta_example' || f.match(/\d$/) }
17
17
  @examples = example_file_names.map { |f| f.underscore.titlecase }
@@ -42,16 +42,20 @@ class MetaExample
42
42
  end
43
43
 
44
44
  def run_example(example)
45
- command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
46
- result = ''
47
- IO.popen(command) do |f|
48
- f.each_line do |line|
49
- result << line
50
- puts line
51
- $stdout.flush # for Windows
45
+ Thread.new do
46
+ command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
47
+ result = ''
48
+ IO.popen(command) do |f|
49
+ sleep(0.0001) # yield to main thread
50
+ f.each_line do |line|
51
+ result << line
52
+ puts line
53
+ $stdout.flush # for Windows
54
+ sleep(0.0001) # yield to main thread
55
+ end
52
56
  end
57
+ Glimmer::LibUI.queue_main { msg_box('Error Running Example', result) } if result.downcase.include?('error')
53
58
  end
54
- msg_box('Error Running Example', result) if result.downcase.include?('error')
55
59
  end
56
60
 
57
61
  def launch
@@ -106,6 +110,8 @@ class MetaExample
106
110
  FileUtils.mkdir_p(parent_dir)
107
111
  example_file = File.join(parent_dir, "#{selected_example.underscore}.rb")
108
112
  File.write(example_file, @code_entry.text)
113
+ example_supporting_directory = File.expand_path(selected_example.underscore, __dir__)
114
+ FileUtils.cp_r(example_supporting_directory, parent_dir) if Dir.exist?(example_supporting_directory)
109
115
  FileUtils.cp_r(File.expand_path('../icons', __dir__), File.dirname(parent_dir))
110
116
  FileUtils.cp_r(File.expand_path('../sounds', __dir__), File.dirname(parent_dir))
111
117
  run_example(example_file)
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2007-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
+ class Tetris
23
+ module Model
24
+ class Block
25
+ COLOR_CLEAR = :white
26
+
27
+ attr_accessor :color
28
+
29
+ # Initializes with color. Default color (gray) signifies an empty block
30
+ def initialize(color = COLOR_CLEAR)
31
+ @color = color
32
+ end
33
+
34
+ # Clears block color. `quietly` option indicates if it should not notify observers by setting value quietly via variable not attribute writer.
35
+ def clear
36
+ self.color = COLOR_CLEAR unless self.color == COLOR_CLEAR
37
+ end
38
+
39
+ def clear?
40
+ self.color == COLOR_CLEAR
41
+ end
42
+
43
+ def occupied?
44
+ !clear?
45
+ end
46
+ end
47
+ end
48
+ end