glimmer-dsl-libui 0.2.13 → 0.2.17

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