glimmer-dsl-gtk 0.0.3 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/README.md +925 -29
- data/VERSION +1 -1
- data/glimmer-dsl-gtk.gemspec +0 -0
- data/images/breaking-blue-wave.png +0 -0
- data/lib/glimmer/gtk/shape/arc_negative.rb +70 -0
- data/lib/glimmer/gtk/shape/path.rb +55 -0
- data/lib/glimmer/gtk/shape.rb +71 -21
- data/lib/glimmer/gtk/transformable.rb +93 -0
- data/lib/glimmer/gtk/widget_proxy/drawing_area_proxy.rb +16 -0
- data/lib/glimmer/gtk/widget_proxy.rb +2 -2
- data/samples/cairo/arc.rb +44 -0
- data/samples/cairo/arc_negative.rb +44 -0
- data/samples/cairo/clip.rb +34 -0
- data/samples/cairo/clip_image.rb +28 -0
- data/samples/cairo/curve_to.rb +39 -0
- data/samples/cairo/dashes.rb +30 -0
- data/samples/cairo/fill_and_stroke2.rb +36 -0
- data/samples/cairo/fill_style.rb +43 -0
- data/samples/cairo/gradient.rb +31 -0
- data/samples/cairo/image.rb +23 -0
- data/samples/cairo/image_gradient.rb +32 -0
- data/samples/cairo/multi_segment_caps.rb +27 -0
- data/samples/cairo/rounded_rectangle.rb +20 -0
- data/samples/cairo/set_line_cap.rb +53 -0
- data/samples/cairo/set_line_join.rb +43 -0
- data/samples/cairo/text.rb +46 -0
- data/samples/elaborate/tetris/model/game.rb +12 -0
- data/samples/elaborate/tetris.rb +172 -1
- data/samples/hello/hello_drawing_area.rb +1 -3
- data/samples/hello/hello_drawing_area_manual.rb +20 -21
- metadata +23 -3
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for GTK 0.0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for GTK 0.0.7
|
2
2
|
## Ruby-GNOME Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-gtk.svg)](http://badge.fury.io/rb/glimmer-dsl-gtk)
|
4
4
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
5
|
|
6
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [GTK](https://www.gtk.org/) enables building desktop applications with [Ruby-GNOME](https://github.com/ruby-gnome/ruby-gnome).
|
6
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [GTK](https://www.gtk.org/) enables building desktop applications with [Ruby-GNOME](https://github.com/ruby-gnome/ruby-gnome) (including [Cairo graphics](#declarative-cairo-graphics)).
|
7
7
|
|
8
8
|
[GTK](https://www.gtk.org/) (aka GIMP-Toolkit or [incorrectly] GNOME-Toolkit) is the premiere desktop GUI toolkit on [Linux](https://www.gtk.org/docs/installations/linux/), which also runs on [Mac](https://www.gtk.org/docs/installations/macos/) ([Quartz GTK+](https://wiki.gnome.org/Projects/GTK/OSX)) and [Windows](https://www.gtk.org/docs/installations/windows).
|
9
9
|
|
@@ -61,6 +61,7 @@ sudo apt install -y -V libgirepository1.0-dev
|
|
61
61
|
On the Mac, make sure to:
|
62
62
|
- Have [Homebrew](https://brew.sh/) installed
|
63
63
|
- Run this [Homebrew](https://brew.sh/) command to have GTK display GUI icons: `brew install adwaita-icon-theme`
|
64
|
+
- (Optional) You can upgrade your GTK3/GTK4/GTK+ by running: `brew install gtk+3` / `brew install gtk+4` / `brew install gtk+`
|
64
65
|
|
65
66
|
### Windows
|
66
67
|
|
@@ -79,7 +80,7 @@ gem install glimmer-dsl-gtk
|
|
79
80
|
|
80
81
|
Add the following to `Gemfile`:
|
81
82
|
```
|
82
|
-
gem 'glimmer-dsl-gtk', '~> 0.0.
|
83
|
+
gem 'glimmer-dsl-gtk', '~> 0.0.7'
|
83
84
|
```
|
84
85
|
|
85
86
|
And, then run:
|
@@ -135,7 +136,7 @@ SomeGlimmerApplication.new.launch
|
|
135
136
|
- Properties: All GTK widget properties can be set via lowercase underscored names (without the 'set_' prefix) nested under widget keywords (e.g. `window {title 'Hello, World'}` sets `title` property of `window`)
|
136
137
|
- Signals: All GTK signals can be wired with `on(signal) { ... }` syntax (e.g. `on(:activate) { do_something }`)
|
137
138
|
|
138
|
-
|
139
|
+
### MVC Observer Pattern
|
139
140
|
|
140
141
|
In Smalltalk-MVC ([Model View Controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) Architectural Pattern), the View is an active View that observes the Model for changes and updates itself.
|
141
142
|
|
@@ -147,6 +148,733 @@ The model is automatically enhanced as an `Glimmer::DataBinding::ObservableModel
|
|
147
148
|
|
148
149
|
Note that it is usually recommended to observe external model objects (not `self`), but `self` is OK in very simple cases or presentation-related attributes only.
|
149
150
|
|
151
|
+
### Declarative Cairo Graphics
|
152
|
+
|
153
|
+
[Cairo](https://www.cairographics.org/) is the engine behind drawing arbitrary 2D geometric shapes in [GTK](https://www.gtk.org/).
|
154
|
+
|
155
|
+
In [Glimmer DSL for GTK](https://rubygems.org/gems/glimmer-dsl-gtk), you can draw Cairo shapes declaratively in a way similar to how SVG works, but using one language; Ruby, thus being able to utilize Ruby logic (e.g. if statement or each loop) with it effortlessly when needed. Declarative syntax also yields less code that is simpler, not dependent on ordering of nested properties, and more understandable/maintainable.
|
156
|
+
|
157
|
+
Below is a quick tutorial consisting of samples inspired and ported from [Mohit Sindhwani's blog post "Cairo with Ruby - Samples using RCairo"](https://notepad.onghu.com/2021/cairo-samples-in-ruby/).
|
158
|
+
|
159
|
+
### Arc
|
160
|
+
|
161
|
+
[samples/cairo/arc.rb](/samples/cairo/arc.rb)
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
require 'glimmer-dsl-gtk'
|
165
|
+
|
166
|
+
include Glimmer
|
167
|
+
|
168
|
+
window {
|
169
|
+
title 'Hello, Drawing Area!'
|
170
|
+
default_size 256, 256
|
171
|
+
|
172
|
+
drawing_area {
|
173
|
+
# Surface Paint
|
174
|
+
paint 242.25, 242.25, 242.25
|
175
|
+
|
176
|
+
# Set up the parameters
|
177
|
+
xc = 128.0
|
178
|
+
yc = 128.0
|
179
|
+
radius = 100.0
|
180
|
+
angle1 = 45.0 * (Math::PI/180.0) # angles are specified
|
181
|
+
angle2 = 180.0 * (Math::PI/180.0) # in radians
|
182
|
+
|
183
|
+
# The main arc
|
184
|
+
arc(xc, yc, radius, angle1, angle2) {
|
185
|
+
stroke 0, 0, 0
|
186
|
+
line_width 10
|
187
|
+
}
|
188
|
+
|
189
|
+
# Draw helping lines
|
190
|
+
|
191
|
+
# First, the circle at the centre
|
192
|
+
arc(xc, yc, 10.0, 0, 2*Math::PI) {
|
193
|
+
fill 255, 51, 51, 0.6
|
194
|
+
}
|
195
|
+
|
196
|
+
# Then, the lines reaching out
|
197
|
+
path {
|
198
|
+
arc xc, yc, radius, angle1, angle1
|
199
|
+
line_to xc, yc
|
200
|
+
arc xc, yc, radius, angle2, angle2
|
201
|
+
line_to xc, yc
|
202
|
+
|
203
|
+
stroke 255, 51, 51, 0.6
|
204
|
+
line_width 6
|
205
|
+
}
|
206
|
+
}
|
207
|
+
}.show
|
208
|
+
```
|
209
|
+
|
210
|
+
![Arc](/screenshots/glimmer-dsl-gtk-mac-cairo-arc.png)
|
211
|
+
|
212
|
+
### Arc Negative
|
213
|
+
|
214
|
+
[samples/cairo/arc_negative.rb](/samples/cairo/arc_negative.rb)
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
require 'glimmer-dsl-gtk'
|
218
|
+
|
219
|
+
include Glimmer
|
220
|
+
|
221
|
+
window {
|
222
|
+
title 'Arc Negative'
|
223
|
+
default_size 256, 256
|
224
|
+
|
225
|
+
drawing_area {
|
226
|
+
# Surface Paint
|
227
|
+
paint 255, 255, 255
|
228
|
+
|
229
|
+
# Set up the parameters
|
230
|
+
xc = 128.0
|
231
|
+
yc = 128.0
|
232
|
+
radius = 100.0
|
233
|
+
angle1 = 45.0 * (Math::PI/180.0) # angles are specified
|
234
|
+
angle2 = 180.0 * (Math::PI/180.0) # in radians
|
235
|
+
|
236
|
+
# The main negative arc
|
237
|
+
arc_negative(xc, yc, radius, angle1, angle2) {
|
238
|
+
stroke 0, 0, 0
|
239
|
+
line_width 10
|
240
|
+
}
|
241
|
+
|
242
|
+
# Draw helping lines
|
243
|
+
|
244
|
+
# First, the circle at the centre
|
245
|
+
arc(xc, yc, 10.0, 0, 2*Math::PI) {
|
246
|
+
fill 255, 51, 51, 0.6
|
247
|
+
}
|
248
|
+
|
249
|
+
# Then, the lines reaching out
|
250
|
+
path {
|
251
|
+
arc(xc, yc, radius, angle1, angle1)
|
252
|
+
line_to(xc, yc)
|
253
|
+
arc(xc, yc, radius, angle2, angle2)
|
254
|
+
line_to(xc, yc)
|
255
|
+
|
256
|
+
stroke 255, 51, 51, 0.6
|
257
|
+
line_width 6
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}.show
|
261
|
+
```
|
262
|
+
|
263
|
+
![Arc Negative](/screenshots/glimmer-dsl-gtk-mac-cairo-arc-negative.png)
|
264
|
+
|
265
|
+
### Clip
|
266
|
+
|
267
|
+
[samples/cairo/clip.rb](/samples/cairo/clip.rb)
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
require 'glimmer-dsl-gtk'
|
271
|
+
|
272
|
+
include Glimmer
|
273
|
+
|
274
|
+
window {
|
275
|
+
title 'Clip'
|
276
|
+
default_size 256, 256
|
277
|
+
|
278
|
+
drawing_area {
|
279
|
+
# Surface Paint
|
280
|
+
paint 255, 255, 255
|
281
|
+
|
282
|
+
# Designate arc as the clipping area
|
283
|
+
arc(128.0, 128.0, 76.8, 0, 2 * Math::PI) {
|
284
|
+
clip true
|
285
|
+
}
|
286
|
+
|
287
|
+
# Rectangle will get clipped by arc
|
288
|
+
rectangle(0, 0, 256, 256) {
|
289
|
+
fill 0, 0, 0
|
290
|
+
}
|
291
|
+
|
292
|
+
# Path will get clipped by arc
|
293
|
+
path {
|
294
|
+
move_to 0, 0
|
295
|
+
line_to 256, 256
|
296
|
+
move_to 256, 0
|
297
|
+
line_to 0, 256
|
298
|
+
|
299
|
+
stroke 0, 255, 0
|
300
|
+
line_width 10
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}.show
|
304
|
+
```
|
305
|
+
|
306
|
+
![Clip](/screenshots/glimmer-dsl-gtk-mac-cairo-clip.png)
|
307
|
+
|
308
|
+
### Clip Image
|
309
|
+
|
310
|
+
[samples/cairo/clip_image.rb](/samples/cairo/clip_image.rb)
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
require 'glimmer-dsl-gtk'
|
314
|
+
|
315
|
+
include Glimmer
|
316
|
+
|
317
|
+
window {
|
318
|
+
title 'Clip Image'
|
319
|
+
default_size 256, 256
|
320
|
+
|
321
|
+
drawing_area {
|
322
|
+
paint 242.25, 242.25, 242.25
|
323
|
+
|
324
|
+
arc(128.0, 128.0, 76.8, 0, 2 * Math::PI) {
|
325
|
+
clip true # designate arc as the clipping area
|
326
|
+
}
|
327
|
+
|
328
|
+
rectangle(0, 0, 256, 256) {
|
329
|
+
# Source image is from:
|
330
|
+
# - https://www.publicdomainpictures.net/en/view-image.php?image=7683&picture=breaking-blue-wave
|
331
|
+
# Converted to PNG before using it
|
332
|
+
image = Cairo::ImageSurface.from_png(File.expand_path(File.join('..', '..', 'images', 'breaking-blue-wave.png'), __dir__))
|
333
|
+
w = image.width
|
334
|
+
h = image.height
|
335
|
+
|
336
|
+
scale 256.0/w, 256.0/h, exclude: :shape # applies scale to fill source image only
|
337
|
+
fill image, 0, 0
|
338
|
+
}
|
339
|
+
}
|
340
|
+
}.show
|
341
|
+
```
|
342
|
+
|
343
|
+
![Clip Image](/screenshots/glimmer-dsl-gtk-mac-cairo-clip-image.png)
|
344
|
+
|
345
|
+
### Curve to
|
346
|
+
|
347
|
+
[samples/cairo/curve_to.rb](/samples/cairo/curve_to.rb)
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
require 'glimmer-dsl-gtk'
|
351
|
+
|
352
|
+
include Glimmer
|
353
|
+
|
354
|
+
window {
|
355
|
+
title 'Curve to'
|
356
|
+
default_size 256, 256
|
357
|
+
|
358
|
+
drawing_area {
|
359
|
+
paint 242.25, 242.25, 242.25
|
360
|
+
|
361
|
+
x=25.6
|
362
|
+
y=128.0
|
363
|
+
x1=102.4
|
364
|
+
y1=230.4
|
365
|
+
x2=153.6
|
366
|
+
y2=25.6
|
367
|
+
x3=230.4
|
368
|
+
y3=128.0
|
369
|
+
|
370
|
+
path {
|
371
|
+
move_to x, y
|
372
|
+
curve_to x1, y1, x2, y2, x3, y3
|
373
|
+
|
374
|
+
line_width 10
|
375
|
+
stroke 0, 0, 0
|
376
|
+
}
|
377
|
+
|
378
|
+
path {
|
379
|
+
move_to x,y
|
380
|
+
line_to x1,y1
|
381
|
+
move_to x2,y2
|
382
|
+
line_to x3,y3
|
383
|
+
|
384
|
+
line_width 6
|
385
|
+
stroke 255, 51, 51, 0.6
|
386
|
+
}
|
387
|
+
}
|
388
|
+
}.show
|
389
|
+
```
|
390
|
+
|
391
|
+
![Curve to](/screenshots/glimmer-dsl-gtk-mac-cairo-curve-to.png)
|
392
|
+
|
393
|
+
### Dashes
|
394
|
+
|
395
|
+
[samples/cairo/dashes.rb](/samples/cairo/dashes.rb)
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
require 'glimmer-dsl-gtk'
|
399
|
+
|
400
|
+
include Glimmer
|
401
|
+
|
402
|
+
window {
|
403
|
+
title 'Dashes'
|
404
|
+
default_size 256, 256
|
405
|
+
|
406
|
+
drawing_area {
|
407
|
+
paint 242.25, 242.25, 242.25
|
408
|
+
|
409
|
+
dashes = [ 50.0, # ink
|
410
|
+
10.0, # skip
|
411
|
+
10.0, # ink
|
412
|
+
10.0 # skip
|
413
|
+
]
|
414
|
+
offset = -50.0
|
415
|
+
|
416
|
+
path {
|
417
|
+
move_to 128.0, 25.6
|
418
|
+
line_to 230.4, 230.4
|
419
|
+
rel_line_to -102.4, 0.0
|
420
|
+
curve_to 51.2, 230.4, 51.2, 128.0, 128.0, 128.0
|
421
|
+
|
422
|
+
line_width 10
|
423
|
+
dash dashes, offset
|
424
|
+
stroke 0, 0, 0
|
425
|
+
}
|
426
|
+
}
|
427
|
+
}.show
|
428
|
+
```
|
429
|
+
|
430
|
+
![Dashes](/screenshots/glimmer-dsl-gtk-mac-cairo-dashes.png)
|
431
|
+
|
432
|
+
### Fill and Stroke 2
|
433
|
+
|
434
|
+
(note: there is no Fill and Stroke 1; this was adopted from [Mohit's blog post](https://notepad.onghu.com/2021/cairo-samples-in-ruby/), which only mentioned Fill and Stroke 2)
|
435
|
+
|
436
|
+
[samples/cairo/fill_and_stroke2.rb](/samples/cairo/fill_and_stroke2.rb)
|
437
|
+
|
438
|
+
```ruby
|
439
|
+
require 'glimmer-dsl-gtk'
|
440
|
+
|
441
|
+
include Glimmer
|
442
|
+
|
443
|
+
window {
|
444
|
+
title 'Fill and Stroke 2'
|
445
|
+
default_size 256, 256
|
446
|
+
|
447
|
+
drawing_area {
|
448
|
+
paint 242.25, 242.25, 242.25
|
449
|
+
|
450
|
+
path {
|
451
|
+
move_to 128.0, 25.6
|
452
|
+
line_to 230.4, 230.4
|
453
|
+
rel_line_to -102.4, 0.0
|
454
|
+
curve_to 51.2, 230.4, 51.2, 128.0, 128.0, 128.0
|
455
|
+
close_path
|
456
|
+
|
457
|
+
fill 0, 0, 255
|
458
|
+
stroke 0, 0, 0
|
459
|
+
line_width 10
|
460
|
+
}
|
461
|
+
|
462
|
+
path {
|
463
|
+
move_to 64.0, 25.6
|
464
|
+
rel_line_to 51.2, 51.2
|
465
|
+
rel_line_to -51.2, 51.2
|
466
|
+
rel_line_to -51.2, -51.2
|
467
|
+
close_path
|
468
|
+
|
469
|
+
fill 0, 0, 255
|
470
|
+
stroke 0, 0, 0
|
471
|
+
line_width 10
|
472
|
+
}
|
473
|
+
}
|
474
|
+
}.show
|
475
|
+
```
|
476
|
+
|
477
|
+
![Fill and Stroke 2](/screenshots/glimmer-dsl-gtk-mac-cairo-fill-and-stroke2.png)
|
478
|
+
|
479
|
+
### Fill Style
|
480
|
+
|
481
|
+
[samples/cairo/fill_style.rb](/samples/cairo/fill_style.rb)
|
482
|
+
|
483
|
+
```ruby
|
484
|
+
require 'glimmer-dsl-gtk'
|
485
|
+
|
486
|
+
include Glimmer
|
487
|
+
|
488
|
+
window {
|
489
|
+
title 'Fill Style'
|
490
|
+
default_size 256, 256
|
491
|
+
|
492
|
+
drawing_area {
|
493
|
+
paint 242.25, 242.25, 242.25
|
494
|
+
|
495
|
+
path {
|
496
|
+
rectangle 12, 12, 232, 70
|
497
|
+
path { # sub-path
|
498
|
+
arc 64, 64, 40, 0, 2*Math::PI
|
499
|
+
}
|
500
|
+
path { # sub-path
|
501
|
+
arc_negative 192, 64, 40, 0, -2*Math::PI
|
502
|
+
}
|
503
|
+
|
504
|
+
fill_rule Cairo::FILL_RULE_EVEN_ODD
|
505
|
+
line_width 6
|
506
|
+
fill 0, 178.5, 0
|
507
|
+
stroke 0, 0, 0
|
508
|
+
}
|
509
|
+
|
510
|
+
path {
|
511
|
+
rectangle 12, 12, 232, 70
|
512
|
+
path { # sub-path
|
513
|
+
arc 64, 64, 40, 0, 2*Math::PI
|
514
|
+
}
|
515
|
+
path { # sub-path
|
516
|
+
arc_negative 192, 64, 40, 0, -2*Math::PI
|
517
|
+
}
|
518
|
+
|
519
|
+
translate 0, 128
|
520
|
+
fill_rule Cairo::FILL_RULE_WINDING
|
521
|
+
line_width 6
|
522
|
+
fill 0, 0, 229.5
|
523
|
+
stroke 0, 0, 0
|
524
|
+
}
|
525
|
+
}
|
526
|
+
}.show
|
527
|
+
```
|
528
|
+
|
529
|
+
![Fill Style](/screenshots/glimmer-dsl-gtk-mac-cairo-fill-style.png)
|
530
|
+
|
531
|
+
### Gradient
|
532
|
+
|
533
|
+
[samples/cairo/gradient.rb](/samples/cairo/gradient.rb)
|
534
|
+
|
535
|
+
```ruby
|
536
|
+
require 'glimmer-dsl-gtk'
|
537
|
+
|
538
|
+
include Glimmer
|
539
|
+
|
540
|
+
window {
|
541
|
+
title 'Gradient'
|
542
|
+
default_size 256, 256
|
543
|
+
|
544
|
+
drawing_area {
|
545
|
+
paint 242.25, 242.25, 242.25
|
546
|
+
|
547
|
+
# Create the Linear Pattern
|
548
|
+
rectangle(0, 0, 256, 256) {
|
549
|
+
pat = Cairo::LinearPattern.new(0.0, 0.0, 0.0, 256.0)
|
550
|
+
pat.add_color_stop_rgba(1, 0, 0, 0, 1)
|
551
|
+
pat.add_color_stop_rgba(0, 1, 1, 1, 1)
|
552
|
+
|
553
|
+
fill pat
|
554
|
+
}
|
555
|
+
|
556
|
+
# Create the radial pattern
|
557
|
+
arc(128.0, 128.0, 76.8, 0, 2 * Math::PI) {
|
558
|
+
pat = Cairo::RadialPattern.new(115.2, 102.4, 25.6,
|
559
|
+
102.4, 102.4, 128.0)
|
560
|
+
pat.add_color_stop_rgba(0, 1, 1, 1, 1)
|
561
|
+
pat.add_color_stop_rgba(1, 0, 0, 0, 1)
|
562
|
+
|
563
|
+
fill pat
|
564
|
+
}
|
565
|
+
}
|
566
|
+
}.show
|
567
|
+
```
|
568
|
+
|
569
|
+
![Gradient](/screenshots/glimmer-dsl-gtk-mac-cairo-gradient.png)
|
570
|
+
|
571
|
+
### Image
|
572
|
+
|
573
|
+
[samples/cairo/image.rb](/samples/cairo/image.rb)
|
574
|
+
|
575
|
+
```ruby
|
576
|
+
require 'glimmer-dsl-gtk'
|
577
|
+
|
578
|
+
include Glimmer
|
579
|
+
|
580
|
+
window {
|
581
|
+
title 'Image'
|
582
|
+
default_size 256, 256
|
583
|
+
|
584
|
+
drawing_area {
|
585
|
+
paint 242.25, 242.25, 242.25
|
586
|
+
|
587
|
+
image = Cairo::ImageSurface.from_png(File.expand_path(File.join('..', '..', 'images', 'breaking-blue-wave.png'), __dir__))
|
588
|
+
w = image.width
|
589
|
+
h = image.height
|
590
|
+
|
591
|
+
translate 128.0, 128.0
|
592
|
+
rotate 45*Math::PI/180
|
593
|
+
scale 256.0/w, 256.0/h
|
594
|
+
translate -0.5*w, -0.5*h
|
595
|
+
|
596
|
+
paint image, 0, 0
|
597
|
+
}
|
598
|
+
}.show
|
599
|
+
```
|
600
|
+
|
601
|
+
![Image](/screenshots/glimmer-dsl-gtk-mac-cairo-image.png)
|
602
|
+
|
603
|
+
### Image Gradient
|
604
|
+
|
605
|
+
[samples/cairo/image_gradient.rb](/samples/cairo/image_gradient.rb)
|
606
|
+
|
607
|
+
```ruby
|
608
|
+
require 'glimmer-dsl-gtk'
|
609
|
+
|
610
|
+
include Glimmer
|
611
|
+
|
612
|
+
window {
|
613
|
+
title 'Image Gradient'
|
614
|
+
default_size 256, 256
|
615
|
+
|
616
|
+
drawing_area {
|
617
|
+
paint 242.25, 242.25, 242.25
|
618
|
+
|
619
|
+
image = Cairo::ImageSurface.from_png(File.expand_path(File.join('..', '..', 'images', 'breaking-blue-wave.png'), __dir__))
|
620
|
+
w = image.width
|
621
|
+
h = image.height
|
622
|
+
|
623
|
+
# Load the image as a surface pattern
|
624
|
+
pattern = Cairo::SurfacePattern.new(image)
|
625
|
+
pattern.extend = Cairo::EXTEND_REPEAT
|
626
|
+
|
627
|
+
# Set up the scale matrix
|
628
|
+
pattern.matrix = Cairo::Matrix.scale(w/256.0 * 5.0, h/256.0 * 5.0)
|
629
|
+
|
630
|
+
rectangle(0, 0, 256, 256) {
|
631
|
+
translate 128.0, 128.0
|
632
|
+
rotate Math::PI / 4
|
633
|
+
scale 1/Math.sqrt(2), 1/Math.sqrt(2)
|
634
|
+
translate -128.0, -128.0
|
635
|
+
|
636
|
+
fill pattern
|
637
|
+
}
|
638
|
+
}
|
639
|
+
}.show
|
640
|
+
```
|
641
|
+
|
642
|
+
![Image Gradient](/screenshots/glimmer-dsl-gtk-mac-cairo-image-gradient.png)
|
643
|
+
|
644
|
+
### Multi Segment Caps
|
645
|
+
|
646
|
+
[samples/cairo/multi_segment_caps.rb](/samples/cairo/multi_segment_caps.rb)
|
647
|
+
|
648
|
+
```ruby
|
649
|
+
require 'glimmer-dsl-gtk'
|
650
|
+
|
651
|
+
include Glimmer
|
652
|
+
|
653
|
+
window {
|
654
|
+
title 'Multi Segment Caps'
|
655
|
+
default_size 256, 256
|
656
|
+
|
657
|
+
drawing_area {
|
658
|
+
paint 242.25, 242.25, 242.25
|
659
|
+
|
660
|
+
path {
|
661
|
+
move_to 50.0, 75.0
|
662
|
+
line_to 200.0, 75.0
|
663
|
+
|
664
|
+
move_to 50.0, 125.0
|
665
|
+
line_to 200.0, 125.0
|
666
|
+
|
667
|
+
move_to 50.0, 175.0
|
668
|
+
line_to 200.0, 175.0
|
669
|
+
|
670
|
+
line_width 30
|
671
|
+
line_cap Cairo::LINE_CAP_ROUND
|
672
|
+
stroke 0, 0, 0
|
673
|
+
}
|
674
|
+
}
|
675
|
+
}.show
|
676
|
+
```
|
677
|
+
|
678
|
+
![Multi Segment Caps](/screenshots/glimmer-dsl-gtk-mac-cairo-multi-segment-caps.png)
|
679
|
+
|
680
|
+
### Rounded Rectangle
|
681
|
+
|
682
|
+
[samples/cairo/rounded_rectangle.rb](/samples/cairo/rounded_rectangle.rb)
|
683
|
+
|
684
|
+
```ruby
|
685
|
+
require 'glimmer-dsl-gtk'
|
686
|
+
|
687
|
+
include Glimmer
|
688
|
+
|
689
|
+
window {
|
690
|
+
title 'Rounded Rectangle'
|
691
|
+
default_size 256, 256
|
692
|
+
|
693
|
+
drawing_area {
|
694
|
+
paint 242.25, 242.25, 242.25
|
695
|
+
|
696
|
+
path {
|
697
|
+
rounded_rectangle(25.6, 25.6, 204.8, 204.8, 20)
|
698
|
+
|
699
|
+
fill 127.5, 127.5, 255
|
700
|
+
line_width 10.0
|
701
|
+
stroke 127.5, 0, 0, 0.5
|
702
|
+
}
|
703
|
+
}
|
704
|
+
}.show
|
705
|
+
```
|
706
|
+
|
707
|
+
![Rounded Rectangle](/screenshots/glimmer-dsl-gtk-mac-cairo-rounded-rectangle.png)
|
708
|
+
|
709
|
+
### Set line cap
|
710
|
+
|
711
|
+
[samples/cairo/set_line_cap.rb](/samples/cairo/set_line_cap.rb)
|
712
|
+
|
713
|
+
```ruby
|
714
|
+
require 'glimmer-dsl-gtk'
|
715
|
+
|
716
|
+
include Glimmer
|
717
|
+
|
718
|
+
window {
|
719
|
+
title 'Set line cap'
|
720
|
+
default_size 256, 256
|
721
|
+
|
722
|
+
drawing_area {
|
723
|
+
paint 242.25, 242.25, 242.25
|
724
|
+
|
725
|
+
# The main code
|
726
|
+
path {
|
727
|
+
move_to 64.0, 50.0
|
728
|
+
line_to 64.0, 200.0
|
729
|
+
|
730
|
+
line_cap Cairo::LINE_CAP_BUTT # default
|
731
|
+
line_width 30
|
732
|
+
stroke 0, 0, 0
|
733
|
+
}
|
734
|
+
|
735
|
+
path {
|
736
|
+
move_to 128.0, 50.0
|
737
|
+
line_to 128.0, 200.0
|
738
|
+
|
739
|
+
line_cap Cairo::LINE_CAP_ROUND
|
740
|
+
line_width 30
|
741
|
+
stroke 0, 0, 0
|
742
|
+
}
|
743
|
+
|
744
|
+
path {
|
745
|
+
move_to 192.0, 50.0
|
746
|
+
line_to 192.0, 200.0
|
747
|
+
|
748
|
+
line_cap Cairo::LINE_CAP_SQUARE
|
749
|
+
line_width 30
|
750
|
+
stroke 0, 0, 0
|
751
|
+
}
|
752
|
+
|
753
|
+
# draw helping lines */
|
754
|
+
path {
|
755
|
+
move_to 64.0, 50.0
|
756
|
+
line_to 64.0, 200.0
|
757
|
+
move_to 128.0, 50.0
|
758
|
+
line_to 128.0, 200.0
|
759
|
+
move_to 192.0, 50.0
|
760
|
+
line_to 192.0, 200.0
|
761
|
+
|
762
|
+
line_width 2.56
|
763
|
+
stroke 255, 51, 51
|
764
|
+
}
|
765
|
+
}
|
766
|
+
}.show
|
767
|
+
```
|
768
|
+
|
769
|
+
![Set line cap](/screenshots/glimmer-dsl-gtk-mac-cairo-set-line-cap.png)
|
770
|
+
|
771
|
+
### Set line join
|
772
|
+
|
773
|
+
[samples/cairo/set_line_join.rb](/samples/cairo/set_line_join.rb)
|
774
|
+
|
775
|
+
```ruby
|
776
|
+
require 'glimmer-dsl-gtk'
|
777
|
+
|
778
|
+
include Glimmer
|
779
|
+
|
780
|
+
window {
|
781
|
+
title 'Set line join'
|
782
|
+
default_size 256, 256
|
783
|
+
|
784
|
+
drawing_area {
|
785
|
+
paint 242.25, 242.25, 242.25
|
786
|
+
|
787
|
+
# The main code
|
788
|
+
path {
|
789
|
+
move_to 76.8, 84.48
|
790
|
+
rel_line_to 51.2, -51.2
|
791
|
+
rel_line_to 51.2, 51.2
|
792
|
+
|
793
|
+
line_join Cairo::LINE_JOIN_MITER # default
|
794
|
+
line_width 40.96
|
795
|
+
stroke 0, 0, 0
|
796
|
+
}
|
797
|
+
|
798
|
+
path {
|
799
|
+
move_to 76.8, 161.28
|
800
|
+
rel_line_to 51.2, -51.2
|
801
|
+
rel_line_to 51.2, 51.2
|
802
|
+
|
803
|
+
line_join Cairo::LINE_JOIN_BEVEL
|
804
|
+
line_width 40.96
|
805
|
+
stroke 0, 0, 0
|
806
|
+
}
|
807
|
+
|
808
|
+
path {
|
809
|
+
move_to 76.8, 238.08
|
810
|
+
rel_line_to 51.2, -51.2
|
811
|
+
rel_line_to 51.2, 51.2
|
812
|
+
|
813
|
+
line_join Cairo::LINE_JOIN_ROUND
|
814
|
+
line_width 40.96
|
815
|
+
stroke 0, 0, 0
|
816
|
+
}
|
817
|
+
}
|
818
|
+
}.show
|
819
|
+
```
|
820
|
+
|
821
|
+
![Set line join](/screenshots/glimmer-dsl-gtk-mac-cairo-set-line-join.png)
|
822
|
+
|
823
|
+
### Text
|
824
|
+
|
825
|
+
[samples/cairo/text.rb](/samples/cairo/text.rb)
|
826
|
+
|
827
|
+
```ruby
|
828
|
+
require 'glimmer-dsl-gtk'
|
829
|
+
|
830
|
+
include Glimmer
|
831
|
+
|
832
|
+
window {
|
833
|
+
title 'Text'
|
834
|
+
default_size 256, 256
|
835
|
+
|
836
|
+
drawing_area {
|
837
|
+
paint 242.25, 242.25, 242.25
|
838
|
+
|
839
|
+
font_family = OS.linux? ? 'Sans' : (OS.mac? ? 'Helvetica' : 'Arial')
|
840
|
+
|
841
|
+
# The main code
|
842
|
+
path {
|
843
|
+
move_to 10.0, 135.0
|
844
|
+
show_text 'Hello'
|
845
|
+
|
846
|
+
font_face font_family, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD
|
847
|
+
font_size 90.0
|
848
|
+
line_width 2.56
|
849
|
+
fill 0, 0, 0
|
850
|
+
stroke 0, 0, 0
|
851
|
+
}
|
852
|
+
|
853
|
+
path {
|
854
|
+
move_to 70.0, 165.0
|
855
|
+
text_path 'void'
|
856
|
+
|
857
|
+
font_face font_family, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD
|
858
|
+
font_size 90.0
|
859
|
+
line_width 2.56
|
860
|
+
fill 127.5, 127.5, 255
|
861
|
+
stroke 0, 0, 0
|
862
|
+
}
|
863
|
+
|
864
|
+
# draw helping lines
|
865
|
+
path {
|
866
|
+
arc 10.0, 135.0, 5.12, 0, 2*Math::PI
|
867
|
+
close_path
|
868
|
+
arc 70.0, 165.0, 5.12, 0, 2*Math::PI
|
869
|
+
|
870
|
+
fill 255, 51, 51, 0.6
|
871
|
+
}
|
872
|
+
}
|
873
|
+
}.show
|
874
|
+
```
|
875
|
+
|
876
|
+
![Text](/screenshots/glimmer-dsl-gtk-mac-cairo-text.png)
|
877
|
+
|
150
878
|
## Girb (Glimmer IRB)
|
151
879
|
|
152
880
|
You can run the `girb` command (`bin/girb` if you cloned the project locally):
|
@@ -377,9 +1105,7 @@ window {
|
|
377
1105
|
default_size 400, 400
|
378
1106
|
|
379
1107
|
drawing_area {
|
380
|
-
|
381
|
-
fill 255, 255, 255
|
382
|
-
}
|
1108
|
+
paint 255, 255, 255
|
383
1109
|
|
384
1110
|
arc(85, 85, 45, (Math::PI/180)*90, -(Math::PI/180)*90) {
|
385
1111
|
fill 255, 0, 0
|
@@ -491,61 +1217,60 @@ window {
|
|
491
1217
|
|
492
1218
|
drawing_area {
|
493
1219
|
on(:draw) do |drawing_area_widget, cairo_context|
|
494
|
-
cairo_context.
|
495
|
-
cairo_context.
|
496
|
-
cairo_context.fill
|
1220
|
+
cairo_context.set_source_rgb(255/255.0, 255/255.0, 255/255.0)
|
1221
|
+
cairo_context.paint
|
497
1222
|
|
498
1223
|
cairo_context.arc(85, 85, 45, (Math::PI/180)*90, -(Math::PI/180)*90)
|
499
1224
|
cairo_context.set_source_rgb(255, 0, 0)
|
500
1225
|
cairo_context.fill
|
501
1226
|
|
502
1227
|
cairo_context.arc(85, 85, 45, (Math::PI/180)*90, -(Math::PI/180)*90)
|
503
|
-
cairo_context.set_source_rgb(0, 128, 255)
|
1228
|
+
cairo_context.set_source_rgb(0, 128/255.0, 255/255.0)
|
504
1229
|
cairo_context.set_line_width(3)
|
505
1230
|
cairo_context.stroke
|
506
1231
|
|
507
1232
|
cairo_context.arc(85, 185, 45, (Math::PI/180)*100, -(Math::PI/180)*30)
|
508
|
-
cairo_context.set_source_rgb(255, 0, 0)
|
1233
|
+
cairo_context.set_source_rgb(255/255.0, 0, 0)
|
509
1234
|
cairo_context.fill
|
510
1235
|
|
511
1236
|
cairo_context.arc(85, 185, 45, (Math::PI/180)*100, -(Math::PI/180)*30)
|
512
|
-
cairo_context.set_source_rgb(0, 128, 255)
|
1237
|
+
cairo_context.set_source_rgb(0, 128/255.0, 255/255.0)
|
513
1238
|
cairo_context.set_line_width(3)
|
514
1239
|
cairo_context.stroke
|
515
1240
|
|
516
1241
|
cairo_context.circle(85, 285, 45)
|
517
|
-
cairo_context.set_source_rgb(255, 0, 0)
|
1242
|
+
cairo_context.set_source_rgb(255/255.0, 0, 0)
|
518
1243
|
cairo_context.fill
|
519
1244
|
|
520
1245
|
cairo_context.circle(85, 285, 45)
|
521
|
-
cairo_context.set_source_rgb(0, 128, 255)
|
1246
|
+
cairo_context.set_source_rgb(0, 128/255.0, 255/255.0)
|
522
1247
|
cairo_context.set_line_width(3)
|
523
1248
|
cairo_context.stroke
|
524
1249
|
|
525
1250
|
cairo_context.rectangle(140, 40, 180, 90)
|
526
|
-
cairo_context.set_source_rgb(255, 255, 0)
|
1251
|
+
cairo_context.set_source_rgb(255/255.0, 255/255.0, 0)
|
527
1252
|
cairo_context.fill
|
528
1253
|
|
529
1254
|
cairo_context.rectangle(140, 40, 180, 90)
|
530
|
-
cairo_context.set_source_rgb(255, 0, 0)
|
1255
|
+
cairo_context.set_source_rgb(255/255.0, 0, 0)
|
531
1256
|
cairo_context.set_line_width(3)
|
532
1257
|
cairo_context.stroke
|
533
1258
|
|
534
1259
|
cairo_context.rounded_rectangle(140, 140, 180, 90, 30, 20)
|
535
|
-
cairo_context.set_source_rgb(255, 255, 0)
|
1260
|
+
cairo_context.set_source_rgb(255/255.0, 255/255.0, 0)
|
536
1261
|
cairo_context.fill
|
537
1262
|
|
538
1263
|
cairo_context.rounded_rectangle(140, 140, 180, 90, 30, 20)
|
539
|
-
cairo_context.set_source_rgb(255, 0, 0)
|
1264
|
+
cairo_context.set_source_rgb(255/255.0, 0, 0)
|
540
1265
|
cairo_context.set_line_width(3)
|
541
1266
|
cairo_context.stroke
|
542
1267
|
|
543
1268
|
cairo_context.triangle(140, 240, 320, 240, 230, 330)
|
544
|
-
cairo_context.set_source_rgb(255, 255, 0)
|
1269
|
+
cairo_context.set_source_rgb(255/255.0, 255/255.0, 0)
|
545
1270
|
cairo_context.fill
|
546
1271
|
|
547
1272
|
cairo_context.triangle(140, 240, 320, 240, 230, 330)
|
548
|
-
cairo_context.set_source_rgb(255, 0, 0)
|
1273
|
+
cairo_context.set_source_rgb(255/255.0, 0, 0)
|
549
1274
|
cairo_context.set_line_width(3)
|
550
1275
|
cairo_context.stroke
|
551
1276
|
|
@@ -554,7 +1279,7 @@ window {
|
|
554
1279
|
cairo_context.curve_to 190, 60, 200, 80, 210, 70
|
555
1280
|
cairo_context.curve_to 240, 80, 250, 100, 260, 90
|
556
1281
|
cairo_context.curve_to 290, 90, 300, 110, 310, 100
|
557
|
-
cairo_context.set_source_rgb(0, 255, 0)
|
1282
|
+
cairo_context.set_source_rgb(0, 255/255.0, 0)
|
558
1283
|
cairo_context.fill
|
559
1284
|
|
560
1285
|
cairo_context.new_path
|
@@ -562,7 +1287,7 @@ window {
|
|
562
1287
|
cairo_context.curve_to 190, 60, 200, 80, 210, 70
|
563
1288
|
cairo_context.curve_to 240, 80, 250, 100, 260, 90
|
564
1289
|
cairo_context.curve_to 290, 90, 300, 110, 310, 100
|
565
|
-
cairo_context.set_source_rgb(0, 0, 255)
|
1290
|
+
cairo_context.set_source_rgb(0, 0, 255/255.0)
|
566
1291
|
cairo_context.stroke
|
567
1292
|
|
568
1293
|
cairo_context.new_path
|
@@ -573,7 +1298,7 @@ window {
|
|
573
1298
|
cairo_context.line_to 200, 200
|
574
1299
|
cairo_context.line_to 180, 170
|
575
1300
|
cairo_context.close_path
|
576
|
-
cairo_context.set_source_rgb(0, 255, 0)
|
1301
|
+
cairo_context.set_source_rgb(0, 255/255.0, 0)
|
577
1302
|
cairo_context.fill
|
578
1303
|
|
579
1304
|
cairo_context.new_path
|
@@ -584,7 +1309,7 @@ window {
|
|
584
1309
|
cairo_context.line_to 200, 200
|
585
1310
|
cairo_context.line_to 180, 170
|
586
1311
|
cairo_context.close_path
|
587
|
-
cairo_context.set_source_rgb(0, 0, 255)
|
1312
|
+
cairo_context.set_source_rgb(0, 0, 255/255.0)
|
588
1313
|
cairo_context.stroke
|
589
1314
|
|
590
1315
|
cairo_context.new_path
|
@@ -595,7 +1320,7 @@ window {
|
|
595
1320
|
cairo_context.line_to 200, 280
|
596
1321
|
cairo_context.line_to 180, 270
|
597
1322
|
cairo_context.close_path
|
598
|
-
cairo_context.set_source_rgb(0, 255, 0)
|
1323
|
+
cairo_context.set_source_rgb(0, 255/255.0, 0)
|
599
1324
|
cairo_context.fill
|
600
1325
|
|
601
1326
|
cairo_context.new_path
|
@@ -606,7 +1331,7 @@ window {
|
|
606
1331
|
cairo_context.line_to 200, 280
|
607
1332
|
cairo_context.line_to 180, 270
|
608
1333
|
cairo_context.close_path
|
609
|
-
cairo_context.set_source_rgb(0, 0, 255)
|
1334
|
+
cairo_context.set_source_rgb(0, 0, 255/255.0)
|
610
1335
|
cairo_context.stroke
|
611
1336
|
|
612
1337
|
cairo_context.new_path
|
@@ -616,7 +1341,7 @@ window {
|
|
616
1341
|
cairo_context.line_to 220, 340
|
617
1342
|
cairo_context.line_to 200, 330
|
618
1343
|
cairo_context.line_to 180, 320
|
619
|
-
cairo_context.set_source_rgb(0, 0, 255)
|
1344
|
+
cairo_context.set_source_rgb(0, 0, 255/255.0)
|
620
1345
|
cairo_context.stroke
|
621
1346
|
end
|
622
1347
|
}
|
@@ -842,7 +1567,14 @@ class Tetris
|
|
842
1567
|
default_size Model::Game::PLAYFIELD_WIDTH * BLOCK_SIZE, Model::Game::PLAYFIELD_HEIGHT * BLOCK_SIZE # + 98
|
843
1568
|
|
844
1569
|
box(:vertical) {
|
845
|
-
|
1570
|
+
tetris_menu_bar
|
1571
|
+
|
1572
|
+
box(:horizontal) {
|
1573
|
+
@playfield_blocks = playfield(playfield_width: @game.playfield_width, playfield_height: @game.playfield_height, block_size: BLOCK_SIZE)
|
1574
|
+
|
1575
|
+
score_board
|
1576
|
+
}
|
1577
|
+
|
846
1578
|
}
|
847
1579
|
|
848
1580
|
on(:key_press_event) do |widget, key_event|
|
@@ -900,6 +1632,135 @@ class Tetris
|
|
900
1632
|
end
|
901
1633
|
end
|
902
1634
|
end
|
1635
|
+
|
1636
|
+
Model::Game::PREVIEW_PLAYFIELD_HEIGHT.times do |row|
|
1637
|
+
Model::Game::PREVIEW_PLAYFIELD_WIDTH.times do |column|
|
1638
|
+
observe(@game.preview_playfield[row][column], :color) do |new_color|
|
1639
|
+
color = new_color
|
1640
|
+
block = @preview_playfield_blocks[row][column]
|
1641
|
+
block[:background_square].fill = color
|
1642
|
+
block[:top_bevel_edge].fill = [color[0] + 4*BEVEL_CONSTANT, color[1] + 4*BEVEL_CONSTANT, color[2] + 4*BEVEL_CONSTANT]
|
1643
|
+
block[:right_bevel_edge].fill = [color[0] - BEVEL_CONSTANT, color[1] - BEVEL_CONSTANT, color[2] - BEVEL_CONSTANT]
|
1644
|
+
block[:bottom_bevel_edge].fill = [color[0] - BEVEL_CONSTANT, color[1] - BEVEL_CONSTANT, color[2] - BEVEL_CONSTANT]
|
1645
|
+
block[:left_bevel_edge].fill = [color[0] - BEVEL_CONSTANT, color[1] - BEVEL_CONSTANT, color[2] - BEVEL_CONSTANT]
|
1646
|
+
block[:border_square].stroke = new_color == Model::Block::COLOR_CLEAR ? COLOR_GRAY : color
|
1647
|
+
block[:drawing_area].queue_draw
|
1648
|
+
end
|
1649
|
+
end
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
observe(@game, :score) do |new_score|
|
1653
|
+
@score_label.text = new_score.to_s
|
1654
|
+
end
|
1655
|
+
|
1656
|
+
observe(@game, :lines) do |new_lines|
|
1657
|
+
@lines_label.text = new_lines.to_s
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
observe(@game, :level) do |new_level|
|
1661
|
+
@level_label.text = new_level.to_s
|
1662
|
+
end
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
def tetris_menu_bar
|
1666
|
+
menu_bar {
|
1667
|
+
menu_item(label: 'Game') { |mi|
|
1668
|
+
m = menu {
|
1669
|
+
check_menu_item(label: 'Pause') {
|
1670
|
+
on(:activate) do
|
1671
|
+
@game.paused = !@game.paused?
|
1672
|
+
end
|
1673
|
+
}
|
1674
|
+
|
1675
|
+
menu_item(label: 'Restart') {
|
1676
|
+
on(:activate) do
|
1677
|
+
@game.restart!
|
1678
|
+
end
|
1679
|
+
}
|
1680
|
+
|
1681
|
+
separator_menu_item
|
1682
|
+
|
1683
|
+
menu_item(label: 'Exit') {
|
1684
|
+
on(:activate) do
|
1685
|
+
@main_window.close
|
1686
|
+
end
|
1687
|
+
}
|
1688
|
+
}
|
1689
|
+
mi.submenu = m.gtk
|
1690
|
+
}
|
1691
|
+
|
1692
|
+
menu_item(label: 'View') { |mi|
|
1693
|
+
m = menu {
|
1694
|
+
menu_item(label: 'Show High Scores') {
|
1695
|
+
on(:activate) do
|
1696
|
+
show_high_score_dialog
|
1697
|
+
end
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
menu_item(label: 'Clear High Scores') {
|
1701
|
+
on(:activate) do
|
1702
|
+
@game.clear_high_scores!
|
1703
|
+
end
|
1704
|
+
}
|
1705
|
+
}
|
1706
|
+
mi.submenu = m.gtk
|
1707
|
+
}
|
1708
|
+
|
1709
|
+
menu_item(label: 'Options') { |mi|
|
1710
|
+
m = menu {
|
1711
|
+
rmi = radio_menu_item(nil, 'Instant Down on Up') {
|
1712
|
+
on(:activate) do
|
1713
|
+
@game.instant_down_on_up!
|
1714
|
+
end
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
default_rmi = radio_menu_item(rmi.group, 'Rotate Right on Up') {
|
1718
|
+
on(:activate) do
|
1719
|
+
@game.rotate_right_on_up!
|
1720
|
+
end
|
1721
|
+
}
|
1722
|
+
default_rmi.activate
|
1723
|
+
|
1724
|
+
radio_menu_item(rmi.group, 'Rotate Left on Up') {
|
1725
|
+
on(:activate) do
|
1726
|
+
@game.rotate_left_on_up!
|
1727
|
+
end
|
1728
|
+
}
|
1729
|
+
}
|
1730
|
+
mi.submenu = m.gtk
|
1731
|
+
}
|
1732
|
+
|
1733
|
+
menu_item(label: 'Options') { |mi|
|
1734
|
+
m = menu {
|
1735
|
+
menu_item(label: 'About') {
|
1736
|
+
on(:activate) do
|
1737
|
+
show_about_dialog
|
1738
|
+
end
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
mi.submenu = m.gtk
|
1742
|
+
}
|
1743
|
+
}
|
1744
|
+
end
|
1745
|
+
|
1746
|
+
def score_board
|
1747
|
+
box(:vertical) {
|
1748
|
+
label
|
1749
|
+
@preview_playfield_blocks = playfield(playfield_width: Model::Game::PREVIEW_PLAYFIELD_WIDTH, playfield_height: Model::Game::PREVIEW_PLAYFIELD_HEIGHT, block_size: BLOCK_SIZE)
|
1750
|
+
|
1751
|
+
label
|
1752
|
+
label('Score')
|
1753
|
+
@score_label = label
|
1754
|
+
|
1755
|
+
label
|
1756
|
+
label('Lines')
|
1757
|
+
@lines_label = label
|
1758
|
+
|
1759
|
+
label
|
1760
|
+
label('Level')
|
1761
|
+
@level_label = label
|
1762
|
+
label
|
1763
|
+
}
|
903
1764
|
end
|
904
1765
|
|
905
1766
|
def playfield(playfield_width: , playfield_height: , block_size: , &extra_content)
|
@@ -978,6 +1839,41 @@ class Tetris
|
|
978
1839
|
@game.restart!
|
979
1840
|
false
|
980
1841
|
end
|
1842
|
+
|
1843
|
+
def show_high_score_dialog
|
1844
|
+
game_paused = !!@game.paused
|
1845
|
+
@game.paused = true
|
1846
|
+
|
1847
|
+
if @game.high_scores.empty?
|
1848
|
+
high_scores_string = "No games have been scored yet."
|
1849
|
+
else
|
1850
|
+
high_scores_string = @game.high_scores.map do |high_score|
|
1851
|
+
"#{high_score.name} | Score: #{high_score.score} | Lines: #{high_score.lines} | Level: #{high_score.level}"
|
1852
|
+
end.join("\n")
|
1853
|
+
end
|
1854
|
+
|
1855
|
+
message_dialog(@main_window) { |md|
|
1856
|
+
title 'High Scores'
|
1857
|
+
text high_scores_string
|
1858
|
+
|
1859
|
+
on(:response) do
|
1860
|
+
md.destroy
|
1861
|
+
end
|
1862
|
+
}.show
|
1863
|
+
|
1864
|
+
@game.paused = game_paused
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
def show_about_dialog
|
1868
|
+
message_dialog(@main_window) { |md|
|
1869
|
+
title 'About'
|
1870
|
+
text "Glimmer Tetris\n\nGlimmer DSL for GTK\n\nElaborate Sample\n\nCopyright (c) 2021-2022 Andy Maleh"
|
1871
|
+
|
1872
|
+
on(:response) do
|
1873
|
+
md.destroy
|
1874
|
+
end
|
1875
|
+
}.show
|
1876
|
+
end
|
981
1877
|
end
|
982
1878
|
|
983
1879
|
Tetris.new.launch
|