glimmer-dsl-libui 0.1.10 → 0.2.2
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 +30 -0
- data/README.md +574 -19
- 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/color_the_circles.rb +220 -0
- data/examples/control_gallery.rb +1 -1
- data/examples/form_table.rb +20 -0
- data/examples/login.rb +45 -0
- data/examples/midi_player.rb +1 -1
- data/examples/timer.rb +135 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/area_proxy/scrolling_area_proxy.rb +40 -0
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +19 -2
- data/lib/glimmer/libui/control_proxy/entry_proxy/password_entry_proxy.rb +36 -0
- data/lib/glimmer/libui/control_proxy/entry_proxy/search_entry_proxy.rb +36 -0
- data/lib/glimmer/libui/control_proxy/entry_proxy.rb +39 -0
- 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/window_proxy.rb +0 -6
- data/lib/glimmer/libui/control_proxy.rb +8 -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 +59 -2
- 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 +19 -4
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.2
|
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.2](#-glimmer-dsl-for-libui-022)
|
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)
|
@@ -234,6 +241,9 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
234
241
|
- [Area Gallery](#area-gallery)
|
235
242
|
- [Histogram](#histogram)
|
236
243
|
- [Basic Transform](#basic-transform)
|
244
|
+
- [Login](#login)
|
245
|
+
- [Timer](#timer)
|
246
|
+
- [Color The Circles](#color-the-circles)
|
237
247
|
- [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
|
238
248
|
- [Help](#help)
|
239
249
|
- [Issues](#issues)
|
@@ -321,7 +331,7 @@ gem install glimmer-dsl-libui
|
|
321
331
|
Or install via Bundler `Gemfile`:
|
322
332
|
|
323
333
|
```ruby
|
324
|
-
gem 'glimmer-dsl-libui', '~> 0.
|
334
|
+
gem 'glimmer-dsl-libui', '~> 0.2.2'
|
325
335
|
```
|
326
336
|
|
327
337
|
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.
|
@@ -429,6 +439,7 @@ Control(Args) | Properties | Listeners
|
|
429
439
|
`msg_box(window = main_window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
430
440
|
`msg_box_error(window = main_window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
431
441
|
`non_wrapping_multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
442
|
+
`password_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
432
443
|
`path(draw_fill_mode = :winding)` | `fill` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`), `stroke` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, `:cap` as (`:round`, `:square`, `:flat`), `:join` as (`:miter`, `:round`, `:bevel`), `:thickness` as `Numeric`, `:miter_limit` as `Numeric`, `:dashes` as `Array` of `Numeric` ) | None
|
433
444
|
`preferences_menu_item` | None | `on_clicked`
|
434
445
|
`progress_bar` | `value` (`Numeric`) | None
|
@@ -436,6 +447,7 @@ Control(Args) | Properties | Listeners
|
|
436
447
|
`quit_menu_item` | None | `on_clicked`
|
437
448
|
`radio_buttons` | `selected` (`Integer`) | `on_selected`
|
438
449
|
`rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `width` (`Numeric`), `height` (`Numeric`) | None
|
450
|
+
`search_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
439
451
|
`slider(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
440
452
|
`spinbox(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
441
453
|
`square(x as Numeric, y as Numeric, length as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `length` (`Numeric`) | None
|
@@ -445,6 +457,7 @@ Control(Args) | Properties | Listeners
|
|
445
457
|
`text_column(name as String)` | `editable` (Boolean) | None
|
446
458
|
`time_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`) | `on_changed`
|
447
459
|
`vertical_box` | `padded` (Boolean) | None
|
460
|
+
`vertical_separator` | None | None
|
448
461
|
`window(title as String, width as Integer, height as Integer, has_menubar as Boolean)` | `borderless` (Boolean), `content_size` (width `Numeric`, height `Numeric`), `fullscreen` (Boolean), `margined` (Boolean), `title` (`String`) | `on_closing`, `on_content_size_changed`, `on_destroy`
|
449
462
|
|
450
463
|
### Common Control Properties
|
@@ -471,6 +484,13 @@ Control(Args) | Properties | Listeners
|
|
471
484
|
- `hide`
|
472
485
|
- `show`
|
473
486
|
|
487
|
+
### LibUI Operations
|
488
|
+
|
489
|
+
All operations that could normally be called on `LibUI` can also be called on `Glimmer::LibUI`, but some have enhancements as detailed below.
|
490
|
+
|
491
|
+
- `Glimmer::LibUI::queue_main(&block)`: queues an operation to be run on the main event loop at the earliest opportunity possible
|
492
|
+
- `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.
|
493
|
+
|
474
494
|
### Extra Dialogs
|
475
495
|
|
476
496
|
- `open_file(window as Glimmer::LibUI::WindowProxy)`: returns selected file (`String`) or `nil` if cancelled
|
@@ -762,6 +782,8 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
|
|
762
782
|
|
763
783
|
`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)
|
764
784
|
|
785
|
+
Available [X11](https://en.wikipedia.org/wiki/X11_color_names) colors can be obtained through `Glimmer::LibUI.x11_colors` method.
|
786
|
+
|
765
787
|
Check [Basic Transform](#basic-transform) example for use of [X11](https://en.wikipedia.org/wiki/X11_color_names) colors.
|
766
788
|
|
767
789
|
Check [Histogram](#histogram) example for use of hex colors.
|
@@ -1434,7 +1456,7 @@ class TinyMidiPlayer
|
|
1434
1456
|
end
|
1435
1457
|
|
1436
1458
|
def create_gui
|
1437
|
-
menu('Help') {
|
1459
|
+
menu('Help') {
|
1438
1460
|
menu_item('Version') {
|
1439
1461
|
on_clicked do
|
1440
1462
|
show_version
|
@@ -2995,15 +3017,19 @@ Mac
|
|
2995
3017
|
|
2996
3018
|

|
2997
3019
|

|
3020
|
+

|
2998
3021
|
|
2999
3022
|
Linux
|
3000
3023
|
|
3001
3024
|

|
3002
3025
|

|
3026
|
+

|
3003
3027
|
|
3004
3028
|
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
3005
3029
|
|
3006
3030
|
```ruby
|
3031
|
+
# frozen_string_literal: true
|
3032
|
+
|
3007
3033
|
require 'glimmer-dsl-libui'
|
3008
3034
|
|
3009
3035
|
include Glimmer
|
@@ -3049,6 +3075,7 @@ window('Contacts', 600, 600) { |w|
|
|
3049
3075
|
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
3050
3076
|
else
|
3051
3077
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
3078
|
+
@unfiltered_data = data.dup
|
3052
3079
|
@name_entry.text = ''
|
3053
3080
|
@email_entry.text = ''
|
3054
3081
|
@phone_entry.text = ''
|
@@ -3058,6 +3085,25 @@ window('Contacts', 600, 600) { |w|
|
|
3058
3085
|
end
|
3059
3086
|
}
|
3060
3087
|
|
3088
|
+
search_entry { |se|
|
3089
|
+
stretchy false
|
3090
|
+
|
3091
|
+
on_changed do
|
3092
|
+
filter_value = se.text
|
3093
|
+
@unfiltered_data ||= data.dup
|
3094
|
+
# Unfilter first to remove any previous filters
|
3095
|
+
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
3096
|
+
# Now, apply filter if entered
|
3097
|
+
unless filter_value.empty?
|
3098
|
+
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
3099
|
+
row_data.any? do |cell|
|
3100
|
+
cell.to_s.downcase.include?(filter_value.downcase)
|
3101
|
+
end
|
3102
|
+
end
|
3103
|
+
end
|
3104
|
+
end
|
3105
|
+
}
|
3106
|
+
|
3061
3107
|
table {
|
3062
3108
|
text_column('Name')
|
3063
3109
|
text_column('Email')
|
@@ -3495,11 +3541,17 @@ window('Area Gallery', 400, 400) {
|
|
3495
3541
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3496
3542
|
}
|
3497
3543
|
path { # declarative stable path
|
3498
|
-
|
3544
|
+
circle(200, 200, 90)
|
3499
3545
|
|
3500
3546
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3501
3547
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3502
3548
|
}
|
3549
|
+
path { # declarative stable path
|
3550
|
+
arc(400, 220, 180, 90, 90, false)
|
3551
|
+
|
3552
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3553
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3554
|
+
}
|
3503
3555
|
|
3504
3556
|
on_mouse_event do |area_mouse_event|
|
3505
3557
|
p area_mouse_event
|
@@ -3652,18 +3704,28 @@ window('Area Gallery', 400, 400) {
|
|
3652
3704
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3653
3705
|
}
|
3654
3706
|
path { # declarative stable path
|
3655
|
-
|
3707
|
+
circle {
|
3656
3708
|
x_center 200
|
3657
3709
|
y_center 200
|
3658
3710
|
radius 90
|
3659
|
-
start_angle 0
|
3660
|
-
sweep 360
|
3661
|
-
is_negative false
|
3662
3711
|
}
|
3663
3712
|
|
3664
3713
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3665
3714
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3666
3715
|
}
|
3716
|
+
path { # declarative stable path
|
3717
|
+
arc {
|
3718
|
+
x_center 400
|
3719
|
+
y_center 220
|
3720
|
+
radius 180
|
3721
|
+
start_angle 90
|
3722
|
+
sweep 90
|
3723
|
+
is_negative false
|
3724
|
+
}
|
3725
|
+
|
3726
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3727
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3728
|
+
}
|
3667
3729
|
|
3668
3730
|
on_mouse_event do |area_mouse_event|
|
3669
3731
|
p area_mouse_event
|
@@ -3763,13 +3825,19 @@ window('Area Gallery', 400, 400) {
|
|
3763
3825
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3764
3826
|
}
|
3765
3827
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3766
|
-
|
3767
|
-
|
3828
|
+
circle(200, 200, 90)
|
3829
|
+
|
3768
3830
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3769
3831
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3770
3832
|
}
|
3833
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3834
|
+
arc(400, 220, 180, 90, 90, false)
|
3835
|
+
|
3836
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
3837
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3838
|
+
}
|
3771
3839
|
end
|
3772
|
-
|
3840
|
+
|
3773
3841
|
on_mouse_event do |area_mouse_event|
|
3774
3842
|
p area_mouse_event
|
3775
3843
|
end
|
@@ -3922,20 +3990,30 @@ window('Area Gallery', 400, 400) {
|
|
3922
3990
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3923
3991
|
}
|
3924
3992
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3925
|
-
|
3993
|
+
circle {
|
3926
3994
|
x_center 200
|
3927
3995
|
y_center 200
|
3928
3996
|
radius 90
|
3929
|
-
start_angle 0
|
3930
|
-
sweep 360
|
3931
|
-
is_negative false
|
3932
3997
|
}
|
3933
|
-
|
3998
|
+
|
3934
3999
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3935
4000
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3936
4001
|
}
|
4002
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4003
|
+
arc {
|
4004
|
+
x_center 400
|
4005
|
+
y_center 220
|
4006
|
+
radius 180
|
4007
|
+
start_angle 90
|
4008
|
+
sweep 90
|
4009
|
+
is_negative false
|
4010
|
+
}
|
4011
|
+
|
4012
|
+
fill r: 204, g: 102, b: 204, a: 0.5
|
4013
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
4014
|
+
}
|
3937
4015
|
end
|
3938
|
-
|
4016
|
+
|
3939
4017
|
on_mouse_event do |area_mouse_event|
|
3940
4018
|
p area_mouse_event
|
3941
4019
|
end
|
@@ -4384,6 +4462,483 @@ window('Basic Transform', 350, 350) {
|
|
4384
4462
|
}.show
|
4385
4463
|
```
|
4386
4464
|
|
4465
|
+
### Login
|
4466
|
+
|
4467
|
+
[examples/login.rb](examples/login.rb)
|
4468
|
+
|
4469
|
+
Run with this command from the root of the project if you cloned the project:
|
4470
|
+
|
4471
|
+
```
|
4472
|
+
ruby -r './lib/glimmer-dsl-libui' examples/login.rb
|
4473
|
+
```
|
4474
|
+
|
4475
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
4476
|
+
|
4477
|
+
```
|
4478
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/login'"
|
4479
|
+
```
|
4480
|
+
|
4481
|
+
Mac
|
4482
|
+
|
4483
|
+

|
4484
|
+

|
4485
|
+
|
4486
|
+
Linux
|
4487
|
+
|
4488
|
+

|
4489
|
+

|
4490
|
+
|
4491
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
4492
|
+
|
4493
|
+
```ruby
|
4494
|
+
require 'glimmer-dsl-libui'
|
4495
|
+
|
4496
|
+
include Glimmer
|
4497
|
+
|
4498
|
+
window('Login') {
|
4499
|
+
margined true
|
4500
|
+
|
4501
|
+
vertical_box {
|
4502
|
+
form {
|
4503
|
+
@username_entry = entry {
|
4504
|
+
label 'Username:'
|
4505
|
+
}
|
4506
|
+
|
4507
|
+
@password_entry = password_entry {
|
4508
|
+
label 'Password:'
|
4509
|
+
}
|
4510
|
+
}
|
4511
|
+
|
4512
|
+
horizontal_box {
|
4513
|
+
@login_button = button('Login') {
|
4514
|
+
on_clicked do
|
4515
|
+
@username_entry.enabled = false
|
4516
|
+
@password_entry.enabled = false
|
4517
|
+
@login_button.enabled = false
|
4518
|
+
@logout_button.enabled = true
|
4519
|
+
end
|
4520
|
+
}
|
4521
|
+
|
4522
|
+
@logout_button = button('Logout') {
|
4523
|
+
enabled false
|
4524
|
+
|
4525
|
+
on_clicked do
|
4526
|
+
@username_entry.text = ''
|
4527
|
+
@password_entry.text = ''
|
4528
|
+
@username_entry.enabled = true
|
4529
|
+
@password_entry.enabled = true
|
4530
|
+
@login_button.enabled = true
|
4531
|
+
@logout_button.enabled = false
|
4532
|
+
end
|
4533
|
+
}
|
4534
|
+
}
|
4535
|
+
}
|
4536
|
+
}.show
|
4537
|
+
```
|
4538
|
+
|
4539
|
+
### Timer
|
4540
|
+
|
4541
|
+
[examples/timer.rb](examples/timer.rb)
|
4542
|
+
|
4543
|
+
Run with this command from the root of the project if you cloned the project:
|
4544
|
+
|
4545
|
+
```
|
4546
|
+
ruby -r './lib/glimmer-dsl-libui' examples/timer.rb
|
4547
|
+
```
|
4548
|
+
|
4549
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
4550
|
+
|
4551
|
+
```
|
4552
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/timer'"
|
4553
|
+
```
|
4554
|
+
|
4555
|
+
Mac
|
4556
|
+
|
4557
|
+

|
4558
|
+

|
4559
|
+
|
4560
|
+
Linux
|
4561
|
+
|
4562
|
+

|
4563
|
+

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

|
4723
|
+

|
4724
|
+

|
4725
|
+
|
4726
|
+
Linux
|
4727
|
+
|
4728
|
+

|
4729
|
+

|
4730
|
+

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