glimmer-dsl-libui 0.1.11 → 0.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +573 -23
- data/VERSION +1 -1
- data/examples/area_gallery.rb +7 -1
- data/examples/area_gallery2.rb +14 -4
- data/examples/area_gallery3.rb +8 -2
- data/examples/area_gallery4.rb +15 -5
- data/examples/basic_draw_text.rb +67 -0
- data/examples/color_the_circles.rb +220 -0
- data/examples/midi_player.rb +2 -2
- data/examples/timer.rb +135 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +0 -1
- data/lib/glimmer/dsl/libui/property_expression.rb +3 -1
- data/lib/glimmer/dsl/libui/string_expression.rb +48 -0
- data/lib/glimmer/libui/attributed_string.rb +90 -0
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +14 -3
- data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +3 -3
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +69 -0
- data/lib/glimmer/libui/control_proxy/menu_proxy.rb +3 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +0 -2
- data/lib/glimmer/libui/control_proxy/text_proxy.rb +158 -0
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +0 -6
- data/lib/glimmer/libui/control_proxy.rb +7 -1
- data/lib/glimmer/libui/shape/arc.rb +6 -3
- data/lib/glimmer/libui/shape/circle.rb +50 -0
- data/lib/glimmer/libui/shape/rectangle.rb +4 -0
- data/lib/glimmer/libui/shape/square.rb +4 -0
- data/lib/glimmer/libui.rb +73 -6
- data/sounds/AlanWalker-Faded.mid +0 -0
- data/sounds/AlanWalker-SingMeToSleep.mid +0 -0
- data/sounds/CalvinHarris-Blame.mid +0 -0
- data/sounds/CalvinHarris-MyWay.mid +0 -0
- data/sounds/deadmau5-2448.mid +0 -0
- data/sounds/deadmau5-SoThereIWas.mid +0 -0
- metadata +16 -2
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
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 LibUI 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 LibUI 0.2.3
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
[](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[](https://codeclimate.com/github/AndyObtiva/glimmer-dsl-libui/maintainability)
|
@@ -118,11 +118,17 @@ window('Area Gallery', 400, 400) {
|
|
118
118
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
119
119
|
}
|
120
120
|
path { # declarative stable path
|
121
|
-
|
121
|
+
circle(200, 200, 90)
|
122
122
|
|
123
123
|
fill r: 202, g: 102, b: 204, a: 0.5
|
124
124
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
125
125
|
}
|
126
|
+
path { # declarative stable path
|
127
|
+
arc(400, 220, 180, 90, 90, false)
|
128
|
+
|
129
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
130
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
131
|
+
}
|
126
132
|
|
127
133
|
on_mouse_event do |area_mouse_event|
|
128
134
|
p area_mouse_event
|
@@ -191,7 +197,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
191
197
|
|
192
198
|
## Table of Contents
|
193
199
|
|
194
|
-
- [Glimmer DSL for LibUI 0.
|
200
|
+
- [Glimmer DSL for LibUI 0.2.3](#-glimmer-dsl-for-libui-023)
|
195
201
|
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
196
202
|
- [Usage](#usage)
|
197
203
|
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
@@ -199,6 +205,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
199
205
|
- [Supported Controls](#supported-controls)
|
200
206
|
- [Common Control Properties](#common-control-properties)
|
201
207
|
- [Common Control Operations](#common-control-operations)
|
208
|
+
- [LibUI Operations](#libui-operations)
|
202
209
|
- [Extra Dialogs](#extra-dialogs)
|
203
210
|
- [Extra Operations](#extra-operations)
|
204
211
|
- [Table API](#table-api)
|
@@ -235,6 +242,9 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
235
242
|
- [Histogram](#histogram)
|
236
243
|
- [Basic Transform](#basic-transform)
|
237
244
|
- [Login](#login)
|
245
|
+
- [Timer](#timer)
|
246
|
+
- [Color The Circles](#color-the-circles)
|
247
|
+
- [Basic Draw Text](#basic-draw-text)
|
238
248
|
- [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
|
239
249
|
- [Help](#help)
|
240
250
|
- [Issues](#issues)
|
@@ -322,7 +332,7 @@ gem install glimmer-dsl-libui
|
|
322
332
|
Or install via Bundler `Gemfile`:
|
323
333
|
|
324
334
|
```ruby
|
325
|
-
gem 'glimmer-dsl-libui', '~> 0.
|
335
|
+
gem 'glimmer-dsl-libui', '~> 0.2.3'
|
326
336
|
```
|
327
337
|
|
328
338
|
Add `require 'glimmer-dsl-libui'` at the top, and then `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
|
@@ -475,6 +485,13 @@ Control(Args) | Properties | Listeners
|
|
475
485
|
- `hide`
|
476
486
|
- `show`
|
477
487
|
|
488
|
+
### LibUI Operations
|
489
|
+
|
490
|
+
All operations that could normally be called on `LibUI` can also be called on `Glimmer::LibUI`, but some have enhancements as detailed below.
|
491
|
+
|
492
|
+
- `Glimmer::LibUI::queue_main(&block)`: queues an operation to be run on the main event loop at the earliest opportunity possible
|
493
|
+
- `Glimmer::LibUI::timer(time_in_seconds=0.1, repeat: true, &block)`: calls block after time_in_seconds has elapsed, repeating indefinitely unless repeat is `false` or an `Integer` for finite number of repeats. Block can return `false` or `true` to override next repetition.
|
494
|
+
|
478
495
|
### Extra Dialogs
|
479
496
|
|
480
497
|
- `open_file(window as Glimmer::LibUI::WindowProxy)`: returns selected file (`String`) or `nil` if cancelled
|
@@ -766,6 +783,8 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
|
|
766
783
|
|
767
784
|
`fill` and `stroke` accept [X11](https://en.wikipedia.org/wiki/X11_color_names) color `Symbol`s/`String`s like `:skyblue` and `'sandybrown'` or 6-number hex or 3-number hex-shorthand (as `Integer` or `String` with or without `0x` prefix)
|
768
785
|
|
786
|
+
Available [X11](https://en.wikipedia.org/wiki/X11_color_names) colors can be obtained through `Glimmer::LibUI.x11_colors` method.
|
787
|
+
|
769
788
|
Check [Basic Transform](#basic-transform) example for use of [X11](https://en.wikipedia.org/wiki/X11_color_names) colors.
|
770
789
|
|
771
790
|
Check [Histogram](#histogram) example for use of hex colors.
|
@@ -1258,9 +1277,7 @@ window('Notepad', 500, 300) {
|
|
1258
1277
|
|
1259
1278
|
### Midi Player
|
1260
1279
|
|
1261
|
-
|
1262
|
-
- Install [TiMidity](http://timidity.sourceforge.net) and ensure `timidity` command is in `PATH` (can be installed via [Homebrew](https://brew.sh) on Mac or [apt-get](https://help.ubuntu.com/community/AptGet/Howto) on Linux).
|
1263
|
-
- Add `*.mid` files to `~/Music` directory (you may copy the ones included in [sounds](sounds) directory)
|
1280
|
+
To run this example, install [TiMidity](http://timidity.sourceforge.net) and ensure `timidity` command is in `PATH` (can be installed via [Homebrew](https://brew.sh) on Mac or [apt-get](https://help.ubuntu.com/community/AptGet/Howto) on Linux).
|
1264
1281
|
|
1265
1282
|
[examples/midi_player.rb](examples/midi_player.rb)
|
1266
1283
|
|
@@ -1399,7 +1416,7 @@ class TinyMidiPlayer
|
|
1399
1416
|
|
1400
1417
|
def initialize
|
1401
1418
|
@pid = nil
|
1402
|
-
@music_directory = File.expand_path(
|
1419
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
1403
1420
|
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
1404
1421
|
.sort_by { |path| File.basename(path) }
|
1405
1422
|
at_exit { stop_midi }
|
@@ -1438,7 +1455,7 @@ class TinyMidiPlayer
|
|
1438
1455
|
end
|
1439
1456
|
|
1440
1457
|
def create_gui
|
1441
|
-
menu('Help') {
|
1458
|
+
menu('Help') {
|
1442
1459
|
menu_item('Version') {
|
1443
1460
|
on_clicked do
|
1444
1461
|
show_version
|
@@ -3523,11 +3540,17 @@ window('Area Gallery', 400, 400) {
|
|
3523
3540
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3524
3541
|
}
|
3525
3542
|
path { # declarative stable path
|
3526
|
-
|
3543
|
+
circle(200, 200, 90)
|
3527
3544
|
|
3528
3545
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3529
3546
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3530
3547
|
}
|
3548
|
+
path { # declarative stable path
|
3549
|
+
arc(400, 220, 180, 90, 90, false)
|
3550
|
+
|
3551
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3552
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3553
|
+
}
|
3531
3554
|
|
3532
3555
|
on_mouse_event do |area_mouse_event|
|
3533
3556
|
p area_mouse_event
|
@@ -3680,18 +3703,28 @@ window('Area Gallery', 400, 400) {
|
|
3680
3703
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3681
3704
|
}
|
3682
3705
|
path { # declarative stable path
|
3683
|
-
|
3706
|
+
circle {
|
3684
3707
|
x_center 200
|
3685
3708
|
y_center 200
|
3686
3709
|
radius 90
|
3687
|
-
start_angle 0
|
3688
|
-
sweep 360
|
3689
|
-
is_negative false
|
3690
3710
|
}
|
3691
3711
|
|
3692
3712
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3693
3713
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3694
3714
|
}
|
3715
|
+
path { # declarative stable path
|
3716
|
+
arc {
|
3717
|
+
x_center 400
|
3718
|
+
y_center 220
|
3719
|
+
radius 180
|
3720
|
+
start_angle 90
|
3721
|
+
sweep 90
|
3722
|
+
is_negative false
|
3723
|
+
}
|
3724
|
+
|
3725
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3726
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3727
|
+
}
|
3695
3728
|
|
3696
3729
|
on_mouse_event do |area_mouse_event|
|
3697
3730
|
p area_mouse_event
|
@@ -3791,13 +3824,19 @@ window('Area Gallery', 400, 400) {
|
|
3791
3824
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3792
3825
|
}
|
3793
3826
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3794
|
-
|
3795
|
-
|
3827
|
+
circle(200, 200, 90)
|
3828
|
+
|
3796
3829
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3797
3830
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3798
3831
|
}
|
3832
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3833
|
+
arc(400, 220, 180, 90, 90, false)
|
3834
|
+
|
3835
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3836
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3837
|
+
}
|
3799
3838
|
end
|
3800
|
-
|
3839
|
+
|
3801
3840
|
on_mouse_event do |area_mouse_event|
|
3802
3841
|
p area_mouse_event
|
3803
3842
|
end
|
@@ -3950,20 +3989,30 @@ window('Area Gallery', 400, 400) {
|
|
3950
3989
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3951
3990
|
}
|
3952
3991
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3953
|
-
|
3992
|
+
circle {
|
3954
3993
|
x_center 200
|
3955
3994
|
y_center 200
|
3956
3995
|
radius 90
|
3957
|
-
start_angle 0
|
3958
|
-
sweep 360
|
3959
|
-
is_negative false
|
3960
3996
|
}
|
3961
|
-
|
3997
|
+
|
3962
3998
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3963
3999
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3964
4000
|
}
|
4001
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4002
|
+
arc {
|
4003
|
+
x_center 400
|
4004
|
+
y_center 220
|
4005
|
+
radius 180
|
4006
|
+
start_angle 90
|
4007
|
+
sweep 90
|
4008
|
+
is_negative false
|
4009
|
+
}
|
4010
|
+
|
4011
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
4012
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
4013
|
+
}
|
3965
4014
|
end
|
3966
|
-
|
4015
|
+
|
3967
4016
|
on_mouse_event do |area_mouse_event|
|
3968
4017
|
p area_mouse_event
|
3969
4018
|
end
|
@@ -4486,6 +4535,507 @@ window('Login') {
|
|
4486
4535
|
}.show
|
4487
4536
|
```
|
4488
4537
|
|
4538
|
+
### Timer
|
4539
|
+
|
4540
|
+
To run this example, install [TiMidity](http://timidity.sourceforge.net) and ensure `timidity` command is in `PATH` (can be installed via [Homebrew](https://brew.sh) on Mac or [apt-get](https://help.ubuntu.com/community/AptGet/Howto) on Linux).
|
4541
|
+
|
4542
|
+
[examples/timer.rb](examples/timer.rb)
|
4543
|
+
|
4544
|
+
Run with this command from the root of the project if you cloned the project:
|
4545
|
+
|
4546
|
+
```
|
4547
|
+
ruby -r './lib/glimmer-dsl-libui' examples/timer.rb
|
4548
|
+
```
|
4549
|
+
|
4550
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
4551
|
+
|
4552
|
+
```
|
4553
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/timer'"
|
4554
|
+
```
|
4555
|
+
|
4556
|
+
Mac
|
4557
|
+
|
4558
|
+

|
4559
|
+

|
4560
|
+
|
4561
|
+
Linux
|
4562
|
+
|
4563
|
+

|
4564
|
+

|
4565
|
+
|
4566
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
4567
|
+
|
4568
|
+
```ruby
|
4569
|
+
# frozen_string_literal: true
|
4570
|
+
|
4571
|
+
require 'glimmer-dsl-libui'
|
4572
|
+
|
4573
|
+
class Timer
|
4574
|
+
include Glimmer
|
4575
|
+
|
4576
|
+
SECOND_MAX = 59
|
4577
|
+
MINUTE_MAX = 59
|
4578
|
+
HOUR_MAX = 23
|
4579
|
+
|
4580
|
+
def initialize
|
4581
|
+
@pid = nil
|
4582
|
+
@midi_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
|
4583
|
+
at_exit { stop_midi }
|
4584
|
+
setup_timer
|
4585
|
+
create_gui
|
4586
|
+
end
|
4587
|
+
|
4588
|
+
def stop_midi
|
4589
|
+
if @pid
|
4590
|
+
if @th.alive?
|
4591
|
+
Process.kill(:SIGKILL, @pid)
|
4592
|
+
@pid = nil
|
4593
|
+
else
|
4594
|
+
@pid = nil
|
4595
|
+
end
|
4596
|
+
end
|
4597
|
+
end
|
4598
|
+
|
4599
|
+
def play_midi
|
4600
|
+
stop_midi
|
4601
|
+
if @pid.nil?
|
4602
|
+
begin
|
4603
|
+
@pid = spawn "timidity -G 0.0-10.0 #{@midi_file}"
|
4604
|
+
@th = Process.detach @pid
|
4605
|
+
rescue Errno::ENOENT
|
4606
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
4607
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
4608
|
+
end
|
4609
|
+
end
|
4610
|
+
end
|
4611
|
+
|
4612
|
+
def setup_timer
|
4613
|
+
unless @setup_timer
|
4614
|
+
Glimmer::LibUI.timer(1) do
|
4615
|
+
if @started
|
4616
|
+
seconds = @sec_spinbox.value
|
4617
|
+
minutes = @min_spinbox.value
|
4618
|
+
hours = @hour_spinbox.value
|
4619
|
+
if seconds > 0
|
4620
|
+
@sec_spinbox.value = seconds -= 1
|
4621
|
+
end
|
4622
|
+
if seconds == 0
|
4623
|
+
if minutes > 0
|
4624
|
+
@min_spinbox.value = minutes -= 1
|
4625
|
+
@sec_spinbox.value = seconds = SECOND_MAX
|
4626
|
+
end
|
4627
|
+
if minutes == 0
|
4628
|
+
if hours > 0
|
4629
|
+
@hour_spinbox.value = hours -= 1
|
4630
|
+
@min_spinbox.value = minutes = MINUTE_MAX
|
4631
|
+
@sec_spinbox.value = seconds = SECOND_MAX
|
4632
|
+
end
|
4633
|
+
if hours == 0 && minutes == 0 && seconds == 0
|
4634
|
+
@start_button.enabled = true
|
4635
|
+
@stop_button.enabled = false
|
4636
|
+
@started = false
|
4637
|
+
unless @played
|
4638
|
+
play_midi
|
4639
|
+
@played = true
|
4640
|
+
end
|
4641
|
+
end
|
4642
|
+
end
|
4643
|
+
end
|
4644
|
+
end
|
4645
|
+
end
|
4646
|
+
@setup_timer = true
|
4647
|
+
end
|
4648
|
+
end
|
4649
|
+
|
4650
|
+
def create_gui
|
4651
|
+
window('Timer') {
|
4652
|
+
margined true
|
4653
|
+
|
4654
|
+
group('Countdown') {
|
4655
|
+
vertical_box {
|
4656
|
+
horizontal_box {
|
4657
|
+
@hour_spinbox = spinbox(0, HOUR_MAX) {
|
4658
|
+
stretchy false
|
4659
|
+
value 0
|
4660
|
+
}
|
4661
|
+
label(':') {
|
4662
|
+
stretchy false
|
4663
|
+
}
|
4664
|
+
@min_spinbox = spinbox(0, MINUTE_MAX) {
|
4665
|
+
stretchy false
|
4666
|
+
value 0
|
4667
|
+
}
|
4668
|
+
label(':') {
|
4669
|
+
stretchy false
|
4670
|
+
}
|
4671
|
+
@sec_spinbox = spinbox(0, SECOND_MAX) {
|
4672
|
+
stretchy false
|
4673
|
+
value 0
|
4674
|
+
}
|
4675
|
+
}
|
4676
|
+
horizontal_box {
|
4677
|
+
@start_button = button('Start') {
|
4678
|
+
on_clicked do
|
4679
|
+
@start_button.enabled = false
|
4680
|
+
@stop_button.enabled = true
|
4681
|
+
@started = true
|
4682
|
+
@played = false
|
4683
|
+
end
|
4684
|
+
}
|
4685
|
+
|
4686
|
+
@stop_button = button('Stop') {
|
4687
|
+
enabled false
|
4688
|
+
|
4689
|
+
on_clicked do
|
4690
|
+
@start_button.enabled = true
|
4691
|
+
@stop_button.enabled = false
|
4692
|
+
@started = false
|
4693
|
+
end
|
4694
|
+
}
|
4695
|
+
}
|
4696
|
+
}
|
4697
|
+
}
|
4698
|
+
}.show
|
4699
|
+
end
|
4700
|
+
end
|
4701
|
+
|
4702
|
+
Timer.new
|
4703
|
+
```
|
4704
|
+
|
4705
|
+
### Color The Circles
|
4706
|
+
|
4707
|
+
[examples/color_the_circles.rb](examples/color_the_circles.rb)
|
4708
|
+
|
4709
|
+
Run with this command from the root of the project if you cloned the project:
|
4710
|
+
|
4711
|
+
```
|
4712
|
+
ruby -r './lib/glimmer-dsl-libui' examples/color_the_circles.rb
|
4713
|
+
```
|
4714
|
+
|
4715
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
4716
|
+
|
4717
|
+
```
|
4718
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/color_the_circles'"
|
4719
|
+
```
|
4720
|
+
|
4721
|
+
Mac
|
4722
|
+
|
4723
|
+

|
4724
|
+

|
4725
|
+

|
4726
|
+
|
4727
|
+
Linux
|
4728
|
+
|
4729
|
+

|
4730
|
+

|
4731
|
+

|
4732
|
+
|
4733
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
4734
|
+
|
4735
|
+
```ruby
|
4736
|
+
require 'glimmer-dsl-libui'
|
4737
|
+
|
4738
|
+
class ColorTheCircles
|
4739
|
+
include Glimmer
|
4740
|
+
|
4741
|
+
WINDOW_WIDTH = 800
|
4742
|
+
WINDOW_HEIGHT = 600
|
4743
|
+
CIRCLE_MIN_RADIUS = 15
|
4744
|
+
CIRCLE_MAX_RADIUS = 50
|
4745
|
+
MARGIN_WIDTH = 55
|
4746
|
+
MARGIN_HEIGHT = 155
|
4747
|
+
TIME_MAX_EASY = 4
|
4748
|
+
TIME_MAX_MEDIUM = 3
|
4749
|
+
TIME_MAX_HARD = 2
|
4750
|
+
TIME_MAX_INSANE = 1
|
4751
|
+
|
4752
|
+
attr_accessor :score
|
4753
|
+
|
4754
|
+
def initialize
|
4755
|
+
@circles_data = []
|
4756
|
+
@score = 0
|
4757
|
+
@time_max = TIME_MAX_HARD
|
4758
|
+
register_observers
|
4759
|
+
setup_circle_factory
|
4760
|
+
end
|
4761
|
+
|
4762
|
+
def register_observers
|
4763
|
+
observer = Glimmer::DataBinding::Observer.proc do |new_score|
|
4764
|
+
@score_label.text = new_score.to_s
|
4765
|
+
if new_score == -20
|
4766
|
+
msg_box('You Lost!', 'Sorry! Your score reached -20')
|
4767
|
+
restart_game
|
4768
|
+
elsif new_score == 0
|
4769
|
+
msg_box('You Won!', 'Congratulations! Your score reached 0')
|
4770
|
+
restart_game
|
4771
|
+
end
|
4772
|
+
end
|
4773
|
+
observer.observe(self, :score) # automatically enhances self to become Glimmer::DataBinding::ObservableModel and notify observer on score attribute changes
|
4774
|
+
end
|
4775
|
+
|
4776
|
+
def setup_circle_factory
|
4777
|
+
consumer = Proc.new do
|
4778
|
+
if @circles_data.empty?
|
4779
|
+
# start with 3 circles to make more challenging
|
4780
|
+
add_circle until @circles_data.size > 3
|
4781
|
+
else
|
4782
|
+
add_circle
|
4783
|
+
end
|
4784
|
+
delay = rand * @time_max
|
4785
|
+
Glimmer::LibUI.timer(delay, repeat: false, &consumer)
|
4786
|
+
end
|
4787
|
+
Glimmer::LibUI.queue_main(&consumer)
|
4788
|
+
end
|
4789
|
+
|
4790
|
+
def add_circle
|
4791
|
+
circle_x_center = rand * (WINDOW_WIDTH - MARGIN_WIDTH - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
|
4792
|
+
circle_y_center = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
|
4793
|
+
circle_radius = rand * (CIRCLE_MAX_RADIUS - CIRCLE_MIN_RADIUS) + CIRCLE_MIN_RADIUS
|
4794
|
+
stroke_color = Glimmer::LibUI.x11_colors.sample
|
4795
|
+
@circles_data << {
|
4796
|
+
args: [circle_x_center, circle_y_center, circle_radius],
|
4797
|
+
fill: nil,
|
4798
|
+
stroke: stroke_color
|
4799
|
+
}
|
4800
|
+
@area.queue_redraw_all
|
4801
|
+
self.score -= 1 # notifies score observers automatically of change
|
4802
|
+
end
|
4803
|
+
|
4804
|
+
def restart_game
|
4805
|
+
@score = 0 # update variable directly to avoid notifying observers
|
4806
|
+
@circles_data.clear
|
4807
|
+
end
|
4808
|
+
|
4809
|
+
def launch
|
4810
|
+
menu('Actions') {
|
4811
|
+
menu_item('Restart') {
|
4812
|
+
on_clicked do
|
4813
|
+
restart_game
|
4814
|
+
end
|
4815
|
+
}
|
4816
|
+
|
4817
|
+
quit_menu_item
|
4818
|
+
}
|
4819
|
+
|
4820
|
+
menu('Difficulty') {
|
4821
|
+
radio_menu_item('Easy') {
|
4822
|
+
on_clicked do
|
4823
|
+
@time_max = TIME_MAX_EASY
|
4824
|
+
end
|
4825
|
+
}
|
4826
|
+
|
4827
|
+
radio_menu_item('Medium') {
|
4828
|
+
on_clicked do
|
4829
|
+
@time_max = TIME_MAX_MEDIUM
|
4830
|
+
end
|
4831
|
+
}
|
4832
|
+
|
4833
|
+
radio_menu_item('Hard') {
|
4834
|
+
checked true
|
4835
|
+
|
4836
|
+
on_clicked do
|
4837
|
+
@time_max = TIME_MAX_HARD
|
4838
|
+
end
|
4839
|
+
}
|
4840
|
+
|
4841
|
+
radio_menu_item('Insane') {
|
4842
|
+
on_clicked do
|
4843
|
+
@time_max = TIME_MAX_INSANE
|
4844
|
+
end
|
4845
|
+
}
|
4846
|
+
}
|
4847
|
+
|
4848
|
+
menu('Help') {
|
4849
|
+
menu_item('Instructions') {
|
4850
|
+
on_clicked do
|
4851
|
+
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.")
|
4852
|
+
end
|
4853
|
+
}
|
4854
|
+
}
|
4855
|
+
|
4856
|
+
window('Color The Circles', WINDOW_WIDTH, WINDOW_HEIGHT) {
|
4857
|
+
margined true
|
4858
|
+
|
4859
|
+
grid {
|
4860
|
+
button('Restart') {
|
4861
|
+
left 0
|
4862
|
+
top 0
|
4863
|
+
halign :center
|
4864
|
+
|
4865
|
+
on_clicked do
|
4866
|
+
restart_game
|
4867
|
+
end
|
4868
|
+
}
|
4869
|
+
|
4870
|
+
label('Score goes down as circles are added. If it reaches -20, you lose!') {
|
4871
|
+
left 0
|
4872
|
+
top 1
|
4873
|
+
halign :center
|
4874
|
+
}
|
4875
|
+
|
4876
|
+
label('Click circles to color and score! Once score reaches 0, you win!') {
|
4877
|
+
left 0
|
4878
|
+
top 2
|
4879
|
+
halign :center
|
4880
|
+
}
|
4881
|
+
|
4882
|
+
horizontal_box {
|
4883
|
+
left 0
|
4884
|
+
top 3
|
4885
|
+
halign :center
|
4886
|
+
|
4887
|
+
label('Score:') {
|
4888
|
+
stretchy false
|
4889
|
+
}
|
4890
|
+
|
4891
|
+
@score_label = label(@score.to_s) {
|
4892
|
+
stretchy false
|
4893
|
+
}
|
4894
|
+
}
|
4895
|
+
|
4896
|
+
vertical_box {
|
4897
|
+
left 0
|
4898
|
+
top 4
|
4899
|
+
hexpand true
|
4900
|
+
vexpand true
|
4901
|
+
halign :fill
|
4902
|
+
valign :fill
|
4903
|
+
|
4904
|
+
@area = area {
|
4905
|
+
on_draw do |area_draw_params|
|
4906
|
+
path {
|
4907
|
+
rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
|
4908
|
+
|
4909
|
+
fill :white
|
4910
|
+
}
|
4911
|
+
|
4912
|
+
@circles_data.each do |circle_data|
|
4913
|
+
path {
|
4914
|
+
circle_data[:circle] = circle(*circle_data[:args])
|
4915
|
+
|
4916
|
+
fill circle_data[:fill]
|
4917
|
+
stroke circle_data[:stroke]
|
4918
|
+
}
|
4919
|
+
end
|
4920
|
+
end
|
4921
|
+
|
4922
|
+
on_mouse_down do |area_mouse_event|
|
4923
|
+
clicked_circle_data = @circles_data.find do |circle_data|
|
4924
|
+
circle_data[:fill].nil? && circle_data[:circle].include?(area_mouse_event[:x], area_mouse_event[:y])
|
4925
|
+
end
|
4926
|
+
if clicked_circle_data
|
4927
|
+
clicked_circle_data[:fill] = clicked_circle_data[:stroke]
|
4928
|
+
@area.queue_redraw_all
|
4929
|
+
self.score += 1 # notifies score observers automatically of change
|
4930
|
+
end
|
4931
|
+
end
|
4932
|
+
}
|
4933
|
+
}
|
4934
|
+
|
4935
|
+
}
|
4936
|
+
}.show
|
4937
|
+
end
|
4938
|
+
end
|
4939
|
+
|
4940
|
+
ColorTheCircles.new.launch
|
4941
|
+
```
|
4942
|
+
|
4943
|
+
### Basic Draw Text
|
4944
|
+
|
4945
|
+
[examples/basic_draw_text.rb](examples/basic_draw_text.rb)
|
4946
|
+
|
4947
|
+
Run with this command from the root of the project if you cloned the project:
|
4948
|
+
|
4949
|
+
```
|
4950
|
+
ruby -r './lib/glimmer-dsl-libui' examples/basic_draw_text.rb
|
4951
|
+
```
|
4952
|
+
|
4953
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
4954
|
+
|
4955
|
+
```
|
4956
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/basic_draw_text'"
|
4957
|
+
```
|
4958
|
+
|
4959
|
+
Mac
|
4960
|
+
|
4961
|
+

|
4962
|
+
|
4963
|
+
Linux
|
4964
|
+
|
4965
|
+

|
4966
|
+
|
4967
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
4968
|
+
|
4969
|
+
```ruby
|
4970
|
+
require 'glimmer-dsl-libui'
|
4971
|
+
|
4972
|
+
# Michael Ende (1929-1995)
|
4973
|
+
# The Neverending Story is a fantasy novel by German writer Michael Ende,
|
4974
|
+
# The English version, translated by Ralph Manheim, was published in 1983.
|
4975
|
+
class BasicDrawText
|
4976
|
+
include Glimmer
|
4977
|
+
|
4978
|
+
def alternating_color_string(&block)
|
4979
|
+
@index ||= 0
|
4980
|
+
@index += 1
|
4981
|
+
string {
|
4982
|
+
if @index.odd?
|
4983
|
+
color r: 0.5, g: 0, b: 0.25, a: 0.7
|
4984
|
+
else
|
4985
|
+
color r: 0, g: 0.5, b: 0, a: 0.7
|
4986
|
+
end
|
4987
|
+
|
4988
|
+
block.call + "\n\n"
|
4989
|
+
}
|
4990
|
+
end
|
4991
|
+
|
4992
|
+
def launch
|
4993
|
+
window('Michael Ende (1929-1995) The Neverending Story', 600, 400) {
|
4994
|
+
margined true
|
4995
|
+
|
4996
|
+
area {
|
4997
|
+
on_draw do |area_draw_params|
|
4998
|
+
text(0, 0, area_draw_params[:area_width]) {
|
4999
|
+
align 0
|
5000
|
+
default_font family: 'Georgia', size: 13, weight: 500, italic: 0, stretch: 4
|
5001
|
+
|
5002
|
+
alternating_color_string {
|
5003
|
+
' At last Ygramul sensed that something was coming toward ' \
|
5004
|
+
'her. With the speed of lightning, she turned about, confronting ' \
|
5005
|
+
'Atreyu with an enormous steel-blue face. Her single eye had a ' \
|
5006
|
+
'vertical pupil, which stared at Atreyu with inconceivable malignancy. '
|
5007
|
+
}
|
5008
|
+
alternating_color_string {
|
5009
|
+
' A cry of fear escaped Bastian. '
|
5010
|
+
}
|
5011
|
+
alternating_color_string {
|
5012
|
+
' A cry of terror passed through the ravine and echoed from ' \
|
5013
|
+
'side to side. Ygramul turned her eye to left and right, to see if ' \
|
5014
|
+
'someone else had arrived, for that sound could not have been ' \
|
5015
|
+
'made by the boy who stood there as though paralyzed with ' \
|
5016
|
+
'horror. '
|
5017
|
+
}
|
5018
|
+
alternating_color_string {
|
5019
|
+
' Could she have heard my cry? Bastion wondered in alarm. ' \
|
5020
|
+
"But that's not possible. "
|
5021
|
+
}
|
5022
|
+
alternating_color_string {
|
5023
|
+
' And then Atreyu heard Ygramuls voice. It was very high ' \
|
5024
|
+
'and slightly hoarse, not at all the right kind of voice for that ' \
|
5025
|
+
'enormous face. Her lips did not move as she spoke. It was the ' \
|
5026
|
+
'buzzing of a great swarm of hornets that shaped itself into ' \
|
5027
|
+
'words. '
|
5028
|
+
}
|
5029
|
+
}
|
5030
|
+
end
|
5031
|
+
}
|
5032
|
+
}.show
|
5033
|
+
end
|
5034
|
+
end
|
5035
|
+
|
5036
|
+
BasicDrawText.new.launch
|
5037
|
+
```
|
5038
|
+
|
4489
5039
|
## Contributing to glimmer-dsl-libui
|
4490
5040
|
|
4491
5041
|
- Check out the latest master to make sure the feature hasn't been
|