glimmer-dsl-libui 0.2.9 → 0.2.10
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 +11 -0
- data/README.md +419 -80
- data/VERSION +1 -1
- data/examples/area_gallery.rb +18 -8
- data/examples/area_gallery2.rb +26 -12
- data/examples/area_gallery3.rb +16 -6
- data/examples/area_gallery4.rb +26 -12
- data/examples/color_button.rb +2 -0
- data/examples/form.rb +12 -2
- data/examples/meta_example.rb +27 -17
- data/examples/method_based_custom_keyword.rb +87 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +31 -6
- data/lib/glimmer/libui.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bc0120584b295401bc245af8ff7110fb332dc74a2f2a60d67be31ccace6f615
|
4
|
+
data.tar.gz: d456fb5265a0d11c09aede73c9b2930a00710d9696a99f8b91bc180f53b8d153
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b671bfda5925f794d79bbb4b83d849ce772e3f42176d3ed66067567f17584e6fe5296eb0b5d4787b38e1053a822c5bdc50175ff7321e4e67857da39f717b802
|
7
|
+
data.tar.gz: d4c78d48c0118eb9c92345639ef7a24b333a9d818e54529fec599fce852e070d1b8123fc91252e8fc163245f9ca4b2b6ec4384ad9c1ad53e2590ca610ef9f6b4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.2.10
|
4
|
+
|
5
|
+
- New examples/method_based_custom_keyword.rb
|
6
|
+
- Update examples/form.rb to have two more fields
|
7
|
+
- Update color_button example to show how to preset initial color
|
8
|
+
- Support `path` `fill`/`stroke` `:type` of `:linear_gradient`
|
9
|
+
- Support `path` `fill`/`stroke` `:type` of `:radial_gradient`
|
10
|
+
- Add text to Area Gallery examples
|
11
|
+
- Update variable names in examples/meta_example.rb to be more meaningful
|
12
|
+
- Update examples/meta_example.rb to show terminal/command-line output for run examples
|
13
|
+
|
3
14
|
## 0.2.9
|
4
15
|
|
5
16
|
- Upgrade to glimmer 2.3.0
|
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.2.
|
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.10
|
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)
|
@@ -14,10 +14,10 @@ The main trade-off in using [Glimmer DSL for LibUI](https://rubygems.org/gems/gl
|
|
14
14
|
- Declarative DSL syntax that visually maps to the GUI control hierarchy
|
15
15
|
- Convention over configuration via smart defaults and automation of low-level details
|
16
16
|
- Requiring the least amount of syntax possible to build GUI
|
17
|
-
- Bidirectional Data-Binding to declaratively wire and automatically synchronize GUI with Business Models
|
18
17
|
- Custom Control support
|
19
|
-
-
|
20
|
-
-
|
18
|
+
- [Far Future Plan] Bidirectional Data-Binding to declaratively wire and automatically synchronize GUI with Business Models
|
19
|
+
- [Far Future Plan] Scaffolding for new custom controls, apps, and gems
|
20
|
+
- [Far Future Plan] Native-Executable packaging on Mac, Windows, and Linux.
|
21
21
|
|
22
22
|
Hello, World!
|
23
23
|
|
@@ -84,14 +84,15 @@ window('Area Gallery', 400, 400) {
|
|
84
84
|
path { # declarative stable path
|
85
85
|
square(0, 0, 100)
|
86
86
|
square(100, 100, 400)
|
87
|
-
|
87
|
+
|
88
88
|
fill r: 102, g: 102, b: 204
|
89
89
|
}
|
90
90
|
path { # declarative stable path
|
91
91
|
rectangle(0, 100, 100, 400)
|
92
92
|
rectangle(100, 0, 400, 100)
|
93
|
-
|
94
|
-
|
93
|
+
|
94
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
95
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
95
96
|
}
|
96
97
|
path { # declarative stable path
|
97
98
|
figure(100, 100) {
|
@@ -117,17 +118,26 @@ window('Area Gallery', 400, 400) {
|
|
117
118
|
fill r: 202, g: 102, b: 204, a: 0.5
|
118
119
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
119
120
|
}
|
121
|
+
path { # declarative stable path
|
122
|
+
arc(400, 220, 180, 90, 90, false)
|
123
|
+
|
124
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
125
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
126
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
127
|
+
}
|
120
128
|
path { # declarative stable path
|
121
129
|
circle(200, 200, 90)
|
122
130
|
|
123
131
|
fill r: 202, g: 102, b: 204, a: 0.5
|
124
132
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
125
133
|
}
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
134
|
+
text(160, 40, 100) { # x, y, width
|
135
|
+
string {
|
136
|
+
font family: 'Times', size: 14
|
137
|
+
color :black
|
138
|
+
|
139
|
+
'Area Gallery'
|
140
|
+
}
|
131
141
|
}
|
132
142
|
|
133
143
|
on_mouse_event do |area_mouse_event|
|
@@ -186,7 +196,7 @@ window('Area Gallery', 400, 400) {
|
|
186
196
|
|
187
197
|
[Check Out Many More Examples Over Here!](#examples)
|
188
198
|
|
189
|
-
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is in
|
199
|
+
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is feature-complete and in beta mode (though the C [libui](https://github.com/andlabs/libui) is still mid-alpha). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. The more feedback and issues you report the better.
|
190
200
|
|
191
201
|
Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
|
192
202
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
@@ -197,7 +207,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
197
207
|
|
198
208
|
## Table of Contents
|
199
209
|
|
200
|
-
- [Glimmer DSL for LibUI 0.2.
|
210
|
+
- [Glimmer DSL for LibUI 0.2.10](#-glimmer-dsl-for-libui-0210)
|
201
211
|
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
202
212
|
- [Usage](#usage)
|
203
213
|
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
@@ -211,8 +221,10 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
211
221
|
- [Table API](#table-api)
|
212
222
|
- [Area API](#area-api)
|
213
223
|
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
224
|
+
- [Custom Keywords](#custom-keywords)
|
214
225
|
- [API Gotchas](#api-gotchas)
|
215
226
|
- [Original API](#original-api)
|
227
|
+
- [Packaging](#packaging)
|
216
228
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
217
229
|
- [Examples](#examples)
|
218
230
|
- [Basic Window](#basic-window)
|
@@ -247,6 +259,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
247
259
|
- [Color The Circles](#color-the-circles)
|
248
260
|
- [Basic Draw Text](#basic-draw-text)
|
249
261
|
- [Custom Draw Text](#custom-draw-text)
|
262
|
+
- [Method-Based Custom Keyword](#method-based-custom-keyword)
|
250
263
|
- [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
|
251
264
|
- [Help](#help)
|
252
265
|
- [Issues](#issues)
|
@@ -334,7 +347,7 @@ gem install glimmer-dsl-libui
|
|
334
347
|
Or install via Bundler `Gemfile`:
|
335
348
|
|
336
349
|
```ruby
|
337
|
-
gem 'glimmer-dsl-libui', '~> 0.2.
|
350
|
+
gem 'glimmer-dsl-libui', '~> 0.2.10'
|
338
351
|
```
|
339
352
|
|
340
353
|
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.
|
@@ -446,7 +459,7 @@ Control(Args) | Properties | Listeners
|
|
446
459
|
`msg_box_error(window = main_window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
447
460
|
`non_wrapping_multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
448
461
|
`password_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
449
|
-
`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
|
462
|
+
`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`, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color), `stroke` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color), `:cap` as (`:round`, `:square`, `:flat`), `:join` as (`:miter`, `:round`, `:bevel`), `:thickness` as `Numeric`, `:miter_limit` as `Numeric`, `:dashes` as `Array` of `Numeric` ) | None
|
450
463
|
`preferences_menu_item` | None | `on_clicked`
|
451
464
|
`progress_bar` | `value` (`Numeric`) | None
|
452
465
|
`progress_bar_column(name as String)` | None | None
|
@@ -457,7 +470,7 @@ Control(Args) | Properties | Listeners
|
|
457
470
|
`slider(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
458
471
|
`spinbox(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
459
472
|
`square(x as Numeric, y as Numeric, length as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `length` (`Numeric`) | None
|
460
|
-
`string` | `font`, `color`, `background`, `underline`, `underline_color`, `open_type_features` | None
|
473
|
+
`string` | `font`, `color` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color), `background` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color), `underline`, `underline_color` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color), `open_type_features` | None
|
461
474
|
`tab` | `margined` (Boolean), `num_pages` (`Integer`) | None
|
462
475
|
`tab_item(name as String)` | `index` [read-only] (`Integer`), `margined` (Boolean), `name` [read-only] (`String`) | None
|
463
476
|
`table` | `cell_rows` (`Array` (rows) of `Arrays` (row columns) of cell values (e.g. `String` values for `text_column` cells or `Array` of `image`/`String` for `image_text_column`)), `editable` as Boolean | `on_changed {|row, type, row_data| ...}`, `on_edited {|row, row_data| ...}`
|
@@ -813,7 +826,7 @@ To draw `text` in an `area`, you simply nest a `text(x, y, width)` control direc
|
|
813
826
|
- `background`: rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
814
827
|
- `underline`: one of `:none`, `:single`, `:double`, `:suggestion`, `:color_custom`, `:color_spelling`, `:color_grammar`, `:color_auxiliary`
|
815
828
|
- `underline_color`: one of `:spelling`, `:grammar`, `:auxiliary`, rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
816
|
-
- `open_type_features`:
|
829
|
+
- `open_type_features`: Open Type Features (https://www.microsoft.com/typography/otspec/featuretags.htm) consist of `open_type_tag`s nested in content block, which accept (`a`, `b`, `c`, `d`, `Integer`) arguments.
|
817
830
|
|
818
831
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
819
832
|
|
@@ -882,6 +895,104 @@ window('area text drawing') {
|
|
882
895
|
- Colors may be passed in as a hash of `:r`, `:g`, `:b`, `:a`, or `:red`, `:green`, `:blue`, `:alpha`, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color like `:skyblue`, or 6-number hex or 3-number hex (as `Integer` or `String` with or without `0x` prefix)
|
883
896
|
- Color alpha value defaults to `1.0` when not specified.
|
884
897
|
|
898
|
+
### Custom Keywords
|
899
|
+
|
900
|
+
To define custom keywords, simply define a method representing the custom control you want. To make reusable, you can define in modules and simply include the modules in the view classes that need them.
|
901
|
+
|
902
|
+
Example that defines `field`, `address_form`, `label_pair`, and `address` keywords (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
903
|
+
|
904
|
+
```ruby
|
905
|
+
require 'glimmer-dsl-libui'
|
906
|
+
require 'facets'
|
907
|
+
|
908
|
+
include Glimmer
|
909
|
+
|
910
|
+
Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
|
911
|
+
|
912
|
+
def field(model, property)
|
913
|
+
property = property.to_s
|
914
|
+
entry { |e|
|
915
|
+
label property.underscore.split('_').map(&:capitalize).join(' ')
|
916
|
+
text model.send(property).to_s
|
917
|
+
|
918
|
+
on_changed do
|
919
|
+
model.send("#{property}=", e.text)
|
920
|
+
end
|
921
|
+
}
|
922
|
+
end
|
923
|
+
|
924
|
+
def address_form(address)
|
925
|
+
form {
|
926
|
+
field(address, :street)
|
927
|
+
field(address, :p_o_box)
|
928
|
+
field(address, :city)
|
929
|
+
field(address, :state)
|
930
|
+
field(address, :zip_code)
|
931
|
+
}
|
932
|
+
end
|
933
|
+
|
934
|
+
def label_pair(model, attribute, value)
|
935
|
+
name_label = nil
|
936
|
+
value_label = nil
|
937
|
+
horizontal_box {
|
938
|
+
name_label = label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
|
939
|
+
value_label = label(value.to_s)
|
940
|
+
}
|
941
|
+
Glimmer::DataBinding::Observer.proc do
|
942
|
+
value_label.text = model.send(attribute)
|
943
|
+
end.observe(model, attribute)
|
944
|
+
end
|
945
|
+
|
946
|
+
def address(address)
|
947
|
+
vertical_box {
|
948
|
+
address.each_pair do |attribute, value|
|
949
|
+
label_pair(address, attribute, value)
|
950
|
+
end
|
951
|
+
}
|
952
|
+
end
|
953
|
+
|
954
|
+
address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
|
955
|
+
address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
|
956
|
+
|
957
|
+
window('Method-Based Custom Keyword') {
|
958
|
+
margined true
|
959
|
+
|
960
|
+
horizontal_box {
|
961
|
+
vertical_box {
|
962
|
+
label('Address 1') {
|
963
|
+
stretchy false
|
964
|
+
}
|
965
|
+
address_form(address1)
|
966
|
+
horizontal_separator {
|
967
|
+
stretchy false
|
968
|
+
}
|
969
|
+
label('Address 1 (Saved)') {
|
970
|
+
stretchy false
|
971
|
+
}
|
972
|
+
address(address1)
|
973
|
+
}
|
974
|
+
vertical_separator {
|
975
|
+
stretchy false
|
976
|
+
}
|
977
|
+
vertical_box {
|
978
|
+
label('Address 2') {
|
979
|
+
stretchy false
|
980
|
+
}
|
981
|
+
address_form(address2)
|
982
|
+
horizontal_separator {
|
983
|
+
stretchy false
|
984
|
+
}
|
985
|
+
label('Address 2 (Saved)') {
|
986
|
+
stretchy false
|
987
|
+
}
|
988
|
+
address(address2)
|
989
|
+
}
|
990
|
+
}
|
991
|
+
}.show
|
992
|
+
```
|
993
|
+
|
994
|
+

|
995
|
+
|
885
996
|
### API Gotchas
|
886
997
|
|
887
998
|
- There is no proper way to destroy `grid` children due to [libui](https://github.com/andlabs/libui) not offering any API for deleting them from `grid` (no `grid_delete` similar to `box_delete` for `horizontal_box` and `vertical_box`).
|
@@ -890,8 +1001,20 @@ window('area text drawing') {
|
|
890
1001
|
|
891
1002
|
### Original API
|
892
1003
|
|
893
|
-
To learn more about the [LibUI](https://github.com/kojix2/LibUI) API exposed through [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui)
|
894
|
-
|
1004
|
+
To learn more about the [LibUI](https://github.com/kojix2/LibUI) API exposed through [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui):
|
1005
|
+
- Check out [LibUI ffi.rb](https://github.com/kojix2/LibUI/blob/main/lib/libui/ffi.rb)
|
1006
|
+
- Check out the [libui C headers](https://github.com/andlabs/libui/blob/master/ui.h)
|
1007
|
+
- Check out the [Go UI (Golang LibUI) documentation](https://pkg.go.dev/github.com/andlabs/ui) for an alternative well-documented [libui](https://github.com/andlabs/libui) reference.
|
1008
|
+
|
1009
|
+
## Packaging
|
1010
|
+
|
1011
|
+
I am documenting options for packaging, which I have not tried myself, but figured they would still be useful to add to the README.md until I can expand further effort into supporting packaging.
|
1012
|
+
|
1013
|
+
For Windows, the [LibUI](https://github.com/kojix2/LibUI) project recommends [OCRA](https://github.com/larsch/ocra) (One-Click Ruby Application), which builds Windows executables from Ruby source.
|
1014
|
+
|
1015
|
+
For Mac, consider [Platybus](https://github.com/sveinbjornt/Platypus) (builds a native Mac app from a Ruby script)
|
1016
|
+
|
1017
|
+
For Linux, simply package your app as a [Ruby Gem](https://guides.rubygems.org/what-is-a-gem/) and [build rpm package from Ruby Gem](https://www.redpill-linpro.com/sysadvent/2015/12/07/building-rpms-from-gems.html) or [build deb package from Ruby Gem](https://openpreservation.org/blogs/building-debian-package-ruby-program/).
|
895
1018
|
|
896
1019
|
## Glimmer Style Guide
|
897
1020
|
|
@@ -908,8 +1031,6 @@ The following examples include reimplementions of the examples in the [LibUI](ht
|
|
908
1031
|
|
909
1032
|
To browse all examples, simply launch the [Meta-Example](examples/meta_example.rb), which lists all examples and displays each example's code when selected. It also enables code editing to facilitate experimentation and learning.
|
910
1033
|
|
911
|
-
(note that for examples that emit output to terminal/command-line via `p` or `puts`, you must run them directly to see output)
|
912
|
-
|
913
1034
|
[examples/meta_example.rb](examples/meta_example.rb)
|
914
1035
|
|
915
1036
|
Run with this command from the root of the project if you cloned the project:
|
@@ -935,65 +1056,118 @@ Linux
|
|
935
1056
|
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
936
1057
|
|
937
1058
|
```ruby
|
1059
|
+
# frozen_string_literal: true
|
1060
|
+
|
938
1061
|
require 'glimmer-dsl-libui'
|
939
1062
|
require 'facets'
|
940
1063
|
|
941
1064
|
class MetaExample
|
942
1065
|
include Glimmer
|
943
1066
|
|
1067
|
+
def initialize
|
1068
|
+
@selected_example_index = 0
|
1069
|
+
end
|
1070
|
+
|
944
1071
|
def examples
|
945
1072
|
if @examples.nil?
|
946
1073
|
example_files = Dir.glob(File.join(File.expand_path('.', __dir__), '**', '*.rb'))
|
947
1074
|
example_file_names = example_files.map { |f| File.basename(f, '.rb') }
|
948
|
-
example_file_names = example_file_names.reject { |f| f == 'meta_example' }
|
1075
|
+
example_file_names = example_file_names.reject { |f| f == 'meta_example' || f.match(/\d$/) }
|
949
1076
|
@examples = example_file_names.map { |f| f.underscore.titlecase }
|
950
1077
|
end
|
951
1078
|
@examples
|
952
1079
|
end
|
953
1080
|
|
1081
|
+
def examples_with_versions
|
1082
|
+
examples.map do |example|
|
1083
|
+
version_count_for(example) > 1 ? "#{example} (#{version_count_for(example)} versions)" : example
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
|
954
1087
|
def file_path_for(example)
|
955
1088
|
File.join(File.expand_path('.', __dir__), "#{example.underscore}.rb")
|
956
1089
|
end
|
957
1090
|
|
1091
|
+
def version_count_for(example)
|
1092
|
+
Dir.glob(File.join(File.expand_path('.', __dir__), "#{example.underscore}*.rb")).select {|file| file.match(/\d\.rb$/)}.count + 1
|
1093
|
+
end
|
1094
|
+
|
958
1095
|
def glimmer_dsl_libui_file
|
959
1096
|
File.expand_path('../lib/glimmer-dsl-libui', __dir__)
|
960
1097
|
end
|
961
1098
|
|
1099
|
+
def selected_example
|
1100
|
+
examples[@selected_example_index]
|
1101
|
+
end
|
1102
|
+
|
962
1103
|
def launch
|
963
1104
|
window('Meta-Example', 700, 500) {
|
964
1105
|
margined true
|
965
1106
|
|
966
1107
|
horizontal_box {
|
967
1108
|
vertical_box {
|
968
|
-
|
1109
|
+
stretchy false
|
1110
|
+
|
1111
|
+
@example_radio_buttons = radio_buttons {
|
969
1112
|
stretchy false
|
970
|
-
items
|
971
|
-
selected
|
1113
|
+
items examples_with_versions
|
1114
|
+
selected @selected_example_index
|
972
1115
|
|
973
1116
|
on_selected do
|
974
|
-
@
|
1117
|
+
@selected_example_index = @example_radio_buttons.selected
|
1118
|
+
example = selected_example
|
1119
|
+
@code_entry.text = File.read(file_path_for(example))
|
1120
|
+
@version_spinbox.value = 1
|
975
1121
|
end
|
976
1122
|
}
|
977
|
-
|
1123
|
+
|
1124
|
+
horizontal_box {
|
1125
|
+
label('Version') {
|
1126
|
+
stretchy false
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
@version_spinbox = spinbox(1, 100) {
|
1130
|
+
value 1
|
1131
|
+
|
1132
|
+
on_changed do
|
1133
|
+
example = selected_example
|
1134
|
+
if @version_spinbox.value > version_count_for(example)
|
1135
|
+
@version_spinbox.value -= 1
|
1136
|
+
else
|
1137
|
+
version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
|
1138
|
+
example = "#{selected_example}#{version_number}"
|
1139
|
+
@code_entry.text = File.read(file_path_for(example))
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
horizontal_box {
|
978
1146
|
stretchy false
|
979
1147
|
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
1148
|
+
button('Launch') {
|
1149
|
+
on_clicked do
|
1150
|
+
begin
|
1151
|
+
meta_example_file = File.join(Dir.home, '.meta_example.rb')
|
1152
|
+
File.write(meta_example_file, @code_entry.text)
|
1153
|
+
result = `ruby -r #{glimmer_dsl_libui_file} #{meta_example_file} 2>&1`
|
1154
|
+
msg_box('Error Running Example', result) if result.include?('error')
|
1155
|
+
rescue => e
|
1156
|
+
puts 'Unable to write code changes! Running original example...'
|
1157
|
+
system "ruby -r #{glimmer_dsl_libui_file} #{file_path_for(selected_example)}"
|
1158
|
+
end
|
989
1159
|
end
|
990
|
-
|
1160
|
+
}
|
1161
|
+
button('Reset') {
|
1162
|
+
on_clicked do
|
1163
|
+
@code_entry.text = File.read(file_path_for(selected_example))
|
1164
|
+
end
|
1165
|
+
}
|
991
1166
|
}
|
992
1167
|
}
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
}
|
1168
|
+
|
1169
|
+
@code_entry = non_wrapping_multiline_entry {
|
1170
|
+
text File.read(file_path_for(selected_example))
|
997
1171
|
}
|
998
1172
|
}
|
999
1173
|
}.show
|
@@ -2060,6 +2234,8 @@ include Glimmer
|
|
2060
2234
|
|
2061
2235
|
window('color button', 230) {
|
2062
2236
|
color_button { |cb|
|
2237
|
+
color :blue
|
2238
|
+
|
2063
2239
|
on_changed do
|
2064
2240
|
rgba = cb.color
|
2065
2241
|
p rgba
|
@@ -3650,14 +3826,15 @@ window('Area Gallery', 400, 400) {
|
|
3650
3826
|
path { # declarative stable path
|
3651
3827
|
square(0, 0, 100)
|
3652
3828
|
square(100, 100, 400)
|
3653
|
-
|
3829
|
+
|
3654
3830
|
fill r: 102, g: 102, b: 204
|
3655
3831
|
}
|
3656
3832
|
path { # declarative stable path
|
3657
3833
|
rectangle(0, 100, 100, 400)
|
3658
3834
|
rectangle(100, 0, 400, 100)
|
3659
|
-
|
3660
|
-
|
3835
|
+
|
3836
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
3837
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
3661
3838
|
}
|
3662
3839
|
path { # declarative stable path
|
3663
3840
|
figure(100, 100) {
|
@@ -3683,17 +3860,26 @@ window('Area Gallery', 400, 400) {
|
|
3683
3860
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3684
3861
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3685
3862
|
}
|
3863
|
+
path { # declarative stable path
|
3864
|
+
arc(400, 220, 180, 90, 90, false)
|
3865
|
+
|
3866
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
3867
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
3868
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3869
|
+
}
|
3686
3870
|
path { # declarative stable path
|
3687
3871
|
circle(200, 200, 90)
|
3688
3872
|
|
3689
3873
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3690
3874
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3691
3875
|
}
|
3692
|
-
|
3693
|
-
|
3694
|
-
|
3695
|
-
|
3696
|
-
|
3876
|
+
text(160, 40, 100) { # x, y, width
|
3877
|
+
string {
|
3878
|
+
font family: 'Times', size: 14
|
3879
|
+
color :black
|
3880
|
+
|
3881
|
+
'Area Gallery'
|
3882
|
+
}
|
3697
3883
|
}
|
3698
3884
|
|
3699
3885
|
on_mouse_event do |area_mouse_event|
|
@@ -3784,7 +3970,8 @@ window('Area Gallery', 400, 400) {
|
|
3784
3970
|
height 100
|
3785
3971
|
}
|
3786
3972
|
|
3787
|
-
|
3973
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
3974
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
3788
3975
|
}
|
3789
3976
|
path { # declarative stable path
|
3790
3977
|
figure {
|
@@ -3846,16 +4033,6 @@ window('Area Gallery', 400, 400) {
|
|
3846
4033
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3847
4034
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3848
4035
|
}
|
3849
|
-
path { # declarative stable path
|
3850
|
-
circle {
|
3851
|
-
x_center 200
|
3852
|
-
y_center 200
|
3853
|
-
radius 90
|
3854
|
-
}
|
3855
|
-
|
3856
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
3857
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
3858
|
-
}
|
3859
4036
|
path { # declarative stable path
|
3860
4037
|
arc {
|
3861
4038
|
x_center 400
|
@@ -3866,9 +4043,32 @@ window('Area Gallery', 400, 400) {
|
|
3866
4043
|
is_negative false
|
3867
4044
|
}
|
3868
4045
|
|
3869
|
-
|
4046
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
4047
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
3870
4048
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3871
4049
|
}
|
4050
|
+
path { # declarative stable path
|
4051
|
+
circle {
|
4052
|
+
x_center 200
|
4053
|
+
y_center 200
|
4054
|
+
radius 90
|
4055
|
+
}
|
4056
|
+
|
4057
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
4058
|
+
stroke r: 0, g: 0, b: 0, thickness: 2
|
4059
|
+
}
|
4060
|
+
text {
|
4061
|
+
x 160
|
4062
|
+
y 40
|
4063
|
+
width 100
|
4064
|
+
|
4065
|
+
string {
|
4066
|
+
font family: 'Times', size: 14
|
4067
|
+
color :black
|
4068
|
+
|
4069
|
+
'Area Gallery'
|
4070
|
+
}
|
4071
|
+
}
|
3872
4072
|
|
3873
4073
|
on_mouse_event do |area_mouse_event|
|
3874
4074
|
p area_mouse_event
|
@@ -3941,7 +4141,8 @@ window('Area Gallery', 400, 400) {
|
|
3941
4141
|
rectangle(0, 100, 100, 400)
|
3942
4142
|
rectangle(100, 0, 400, 100)
|
3943
4143
|
|
3944
|
-
|
4144
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
4145
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
3945
4146
|
}
|
3946
4147
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3947
4148
|
figure(100, 100) {
|
@@ -3967,17 +4168,26 @@ window('Area Gallery', 400, 400) {
|
|
3967
4168
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3968
4169
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
3969
4170
|
}
|
4171
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4172
|
+
arc(400, 220, 180, 90, 90, false)
|
4173
|
+
|
4174
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
4175
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
4176
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
4177
|
+
}
|
3970
4178
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
3971
4179
|
circle(200, 200, 90)
|
3972
4180
|
|
3973
4181
|
fill r: 202, g: 102, b: 204, a: 0.5
|
3974
4182
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
3975
4183
|
}
|
3976
|
-
|
3977
|
-
|
3978
|
-
|
3979
|
-
|
3980
|
-
|
4184
|
+
text(160, 40, 100) { # x, y, width
|
4185
|
+
string {
|
4186
|
+
font family: 'Times', size: 14
|
4187
|
+
color :black
|
4188
|
+
|
4189
|
+
'Area Gallery'
|
4190
|
+
}
|
3981
4191
|
}
|
3982
4192
|
end
|
3983
4193
|
|
@@ -4070,7 +4280,8 @@ window('Area Gallery', 400, 400) {
|
|
4070
4280
|
height 100
|
4071
4281
|
}
|
4072
4282
|
|
4073
|
-
|
4283
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
4284
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
4074
4285
|
}
|
4075
4286
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4076
4287
|
figure {
|
@@ -4132,16 +4343,6 @@ window('Area Gallery', 400, 400) {
|
|
4132
4343
|
fill r: 202, g: 102, b: 204, a: 0.5
|
4133
4344
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
4134
4345
|
}
|
4135
|
-
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4136
|
-
circle {
|
4137
|
-
x_center 200
|
4138
|
-
y_center 200
|
4139
|
-
radius 90
|
4140
|
-
}
|
4141
|
-
|
4142
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
4143
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
4144
|
-
}
|
4145
4346
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4146
4347
|
arc {
|
4147
4348
|
x_center 400
|
@@ -4152,9 +4353,32 @@ window('Area Gallery', 400, 400) {
|
|
4152
4353
|
is_negative false
|
4153
4354
|
}
|
4154
4355
|
|
4155
|
-
|
4356
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
4357
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
4156
4358
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
4157
4359
|
}
|
4360
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
4361
|
+
circle {
|
4362
|
+
x_center 200
|
4363
|
+
y_center 200
|
4364
|
+
radius 90
|
4365
|
+
}
|
4366
|
+
|
4367
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
4368
|
+
stroke r: 0, g: 0, b: 0, thickness: 2
|
4369
|
+
}
|
4370
|
+
text {
|
4371
|
+
x 160
|
4372
|
+
y 40
|
4373
|
+
width 100
|
4374
|
+
|
4375
|
+
string {
|
4376
|
+
font family: 'Times', size: 14
|
4377
|
+
color :black
|
4378
|
+
|
4379
|
+
'Area Gallery'
|
4380
|
+
}
|
4381
|
+
}
|
4158
4382
|
end
|
4159
4383
|
|
4160
4384
|
on_mouse_event do |area_mouse_event|
|
@@ -5578,7 +5802,122 @@ class CustomDrawText
|
|
5578
5802
|
end
|
5579
5803
|
|
5580
5804
|
CustomDrawText.new.launch
|
5805
|
+
```
|
5806
|
+
|
5807
|
+
### Method-Based Custom Keyword
|
5808
|
+
|
5809
|
+
[examples/method_based_custom_keyword.rb](examples/method_based_custom_keyword.rb)
|
5810
|
+
|
5811
|
+
Run with this command from the root of the project if you cloned the project:
|
5581
5812
|
|
5813
|
+
```
|
5814
|
+
ruby -r './lib/glimmer-dsl-libui' examples/method_based_custom_keyword.rb
|
5815
|
+
```
|
5816
|
+
|
5817
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
5818
|
+
|
5819
|
+
```
|
5820
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/method_based_custom_keyword'"
|
5821
|
+
```
|
5822
|
+
|
5823
|
+
Mac
|
5824
|
+
|
5825
|
+

|
5826
|
+
|
5827
|
+
Linux
|
5828
|
+
|
5829
|
+

|
5830
|
+
|
5831
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
5832
|
+
|
5833
|
+
```ruby
|
5834
|
+
require 'glimmer-dsl-libui'
|
5835
|
+
require 'facets'
|
5836
|
+
|
5837
|
+
include Glimmer
|
5838
|
+
|
5839
|
+
Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
|
5840
|
+
|
5841
|
+
def field(model, property)
|
5842
|
+
property = property.to_s
|
5843
|
+
entry { |e|
|
5844
|
+
label property.underscore.split('_').map(&:capitalize).join(' ')
|
5845
|
+
text model.send(property).to_s
|
5846
|
+
|
5847
|
+
on_changed do
|
5848
|
+
model.send("#{property}=", e.text)
|
5849
|
+
end
|
5850
|
+
}
|
5851
|
+
end
|
5852
|
+
|
5853
|
+
def address_form(address)
|
5854
|
+
form {
|
5855
|
+
field(address, :street)
|
5856
|
+
field(address, :p_o_box)
|
5857
|
+
field(address, :city)
|
5858
|
+
field(address, :state)
|
5859
|
+
field(address, :zip_code)
|
5860
|
+
}
|
5861
|
+
end
|
5862
|
+
|
5863
|
+
def label_pair(model, attribute, value)
|
5864
|
+
name_label = nil
|
5865
|
+
value_label = nil
|
5866
|
+
horizontal_box {
|
5867
|
+
name_label = label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
|
5868
|
+
value_label = label(value.to_s)
|
5869
|
+
}
|
5870
|
+
Glimmer::DataBinding::Observer.proc do
|
5871
|
+
value_label.text = model.send(attribute)
|
5872
|
+
end.observe(model, attribute)
|
5873
|
+
end
|
5874
|
+
|
5875
|
+
def address(address)
|
5876
|
+
vertical_box {
|
5877
|
+
address.each_pair do |attribute, value|
|
5878
|
+
label_pair(address, attribute, value)
|
5879
|
+
end
|
5880
|
+
}
|
5881
|
+
end
|
5882
|
+
|
5883
|
+
address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
|
5884
|
+
address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
|
5885
|
+
|
5886
|
+
window('Method-Based Custom Keyword') {
|
5887
|
+
margined true
|
5888
|
+
|
5889
|
+
horizontal_box {
|
5890
|
+
vertical_box {
|
5891
|
+
label('Address 1') {
|
5892
|
+
stretchy false
|
5893
|
+
}
|
5894
|
+
address_form(address1)
|
5895
|
+
horizontal_separator {
|
5896
|
+
stretchy false
|
5897
|
+
}
|
5898
|
+
label('Address 1 (Saved)') {
|
5899
|
+
stretchy false
|
5900
|
+
}
|
5901
|
+
address(address1)
|
5902
|
+
}
|
5903
|
+
vertical_separator {
|
5904
|
+
stretchy false
|
5905
|
+
}
|
5906
|
+
vertical_box {
|
5907
|
+
label('Address 2') {
|
5908
|
+
stretchy false
|
5909
|
+
}
|
5910
|
+
address_form(address2)
|
5911
|
+
horizontal_separator {
|
5912
|
+
stretchy false
|
5913
|
+
}
|
5914
|
+
label('Address 2 (Saved)') {
|
5915
|
+
stretchy false
|
5916
|
+
}
|
5917
|
+
address(address2)
|
5918
|
+
}
|
5919
|
+
}
|
5920
|
+
}.show
|
5582
5921
|
```
|
5583
5922
|
|
5584
5923
|
## Contributing to glimmer-dsl-libui
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.10
|
data/examples/area_gallery.rb
CHANGED
@@ -7,14 +7,15 @@ window('Area Gallery', 400, 400) {
|
|
7
7
|
path { # declarative stable path
|
8
8
|
square(0, 0, 100)
|
9
9
|
square(100, 100, 400)
|
10
|
-
|
10
|
+
|
11
11
|
fill r: 102, g: 102, b: 204
|
12
12
|
}
|
13
13
|
path { # declarative stable path
|
14
14
|
rectangle(0, 100, 100, 400)
|
15
15
|
rectangle(100, 0, 400, 100)
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
18
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
18
19
|
}
|
19
20
|
path { # declarative stable path
|
20
21
|
figure(100, 100) {
|
@@ -40,17 +41,26 @@ window('Area Gallery', 400, 400) {
|
|
40
41
|
fill r: 202, g: 102, b: 204, a: 0.5
|
41
42
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
42
43
|
}
|
44
|
+
path { # declarative stable path
|
45
|
+
arc(400, 220, 180, 90, 90, false)
|
46
|
+
|
47
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
48
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
49
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
50
|
+
}
|
43
51
|
path { # declarative stable path
|
44
52
|
circle(200, 200, 90)
|
45
53
|
|
46
54
|
fill r: 202, g: 102, b: 204, a: 0.5
|
47
55
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
48
56
|
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
57
|
+
text(160, 40, 100) { # x, y, width
|
58
|
+
string {
|
59
|
+
font family: 'Times', size: 14
|
60
|
+
color :black
|
61
|
+
|
62
|
+
'Area Gallery'
|
63
|
+
}
|
54
64
|
}
|
55
65
|
|
56
66
|
on_mouse_event do |area_mouse_event|
|
data/examples/area_gallery2.rb
CHANGED
@@ -32,7 +32,8 @@ window('Area Gallery', 400, 400) {
|
|
32
32
|
height 100
|
33
33
|
}
|
34
34
|
|
35
|
-
|
35
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
36
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
36
37
|
}
|
37
38
|
path { # declarative stable path
|
38
39
|
figure {
|
@@ -94,16 +95,6 @@ window('Area Gallery', 400, 400) {
|
|
94
95
|
fill r: 202, g: 102, b: 204, a: 0.5
|
95
96
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
96
97
|
}
|
97
|
-
path { # declarative stable path
|
98
|
-
circle {
|
99
|
-
x_center 200
|
100
|
-
y_center 200
|
101
|
-
radius 90
|
102
|
-
}
|
103
|
-
|
104
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
105
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
106
|
-
}
|
107
98
|
path { # declarative stable path
|
108
99
|
arc {
|
109
100
|
x_center 400
|
@@ -114,9 +105,32 @@ window('Area Gallery', 400, 400) {
|
|
114
105
|
is_negative false
|
115
106
|
}
|
116
107
|
|
117
|
-
|
108
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
109
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
118
110
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
119
111
|
}
|
112
|
+
path { # declarative stable path
|
113
|
+
circle {
|
114
|
+
x_center 200
|
115
|
+
y_center 200
|
116
|
+
radius 90
|
117
|
+
}
|
118
|
+
|
119
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
120
|
+
stroke r: 0, g: 0, b: 0, thickness: 2
|
121
|
+
}
|
122
|
+
text {
|
123
|
+
x 160
|
124
|
+
y 40
|
125
|
+
width 100
|
126
|
+
|
127
|
+
string {
|
128
|
+
font family: 'Times', size: 14
|
129
|
+
color :black
|
130
|
+
|
131
|
+
'Area Gallery'
|
132
|
+
}
|
133
|
+
}
|
120
134
|
|
121
135
|
on_mouse_event do |area_mouse_event|
|
122
136
|
p area_mouse_event
|
data/examples/area_gallery3.rb
CHANGED
@@ -15,7 +15,8 @@ window('Area Gallery', 400, 400) {
|
|
15
15
|
rectangle(0, 100, 100, 400)
|
16
16
|
rectangle(100, 0, 400, 100)
|
17
17
|
|
18
|
-
|
18
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
19
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
19
20
|
}
|
20
21
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
21
22
|
figure(100, 100) {
|
@@ -41,17 +42,26 @@ window('Area Gallery', 400, 400) {
|
|
41
42
|
fill r: 202, g: 102, b: 204, a: 0.5
|
42
43
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
43
44
|
}
|
45
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
46
|
+
arc(400, 220, 180, 90, 90, false)
|
47
|
+
|
48
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
49
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
50
|
+
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
51
|
+
}
|
44
52
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
45
53
|
circle(200, 200, 90)
|
46
54
|
|
47
55
|
fill r: 202, g: 102, b: 204, a: 0.5
|
48
56
|
stroke r: 0, g: 0, b: 0, thickness: 2
|
49
57
|
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
58
|
+
text(160, 40, 100) { # x, y, width
|
59
|
+
string {
|
60
|
+
font family: 'Times', size: 14
|
61
|
+
color :black
|
62
|
+
|
63
|
+
'Area Gallery'
|
64
|
+
}
|
55
65
|
}
|
56
66
|
end
|
57
67
|
|
data/examples/area_gallery4.rb
CHANGED
@@ -33,7 +33,8 @@ window('Area Gallery', 400, 400) {
|
|
33
33
|
height 100
|
34
34
|
}
|
35
35
|
|
36
|
-
|
36
|
+
# linear gradient (has x0, y0, x1, y1, and stops)
|
37
|
+
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
37
38
|
}
|
38
39
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
39
40
|
figure {
|
@@ -95,16 +96,6 @@ window('Area Gallery', 400, 400) {
|
|
95
96
|
fill r: 202, g: 102, b: 204, a: 0.5
|
96
97
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
97
98
|
}
|
98
|
-
path { # a dynamic path is added semi-declaratively inside on_draw block
|
99
|
-
circle {
|
100
|
-
x_center 200
|
101
|
-
y_center 200
|
102
|
-
radius 90
|
103
|
-
}
|
104
|
-
|
105
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
106
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
107
|
-
}
|
108
99
|
path { # a dynamic path is added semi-declaratively inside on_draw block
|
109
100
|
arc {
|
110
101
|
x_center 400
|
@@ -115,9 +106,32 @@ window('Area Gallery', 400, 400) {
|
|
115
106
|
is_negative false
|
116
107
|
}
|
117
108
|
|
118
|
-
|
109
|
+
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
110
|
+
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
119
111
|
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
120
112
|
}
|
113
|
+
path { # a dynamic path is added semi-declaratively inside on_draw block
|
114
|
+
circle {
|
115
|
+
x_center 200
|
116
|
+
y_center 200
|
117
|
+
radius 90
|
118
|
+
}
|
119
|
+
|
120
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
121
|
+
stroke r: 0, g: 0, b: 0, thickness: 2
|
122
|
+
}
|
123
|
+
text {
|
124
|
+
x 160
|
125
|
+
y 40
|
126
|
+
width 100
|
127
|
+
|
128
|
+
string {
|
129
|
+
font family: 'Times', size: 14
|
130
|
+
color :black
|
131
|
+
|
132
|
+
'Area Gallery'
|
133
|
+
}
|
134
|
+
}
|
121
135
|
end
|
122
136
|
|
123
137
|
on_mouse_event do |area_mouse_event|
|
data/examples/color_button.rb
CHANGED
data/examples/form.rb
CHANGED
@@ -16,11 +16,21 @@ window('Form') {
|
|
16
16
|
@last_name_entry = entry {
|
17
17
|
label 'Last Name' # label property is available when control is nested under form
|
18
18
|
}
|
19
|
+
|
20
|
+
@phone_entry = entry {
|
21
|
+
label 'Phone' # label property is available when control is nested under form
|
22
|
+
}
|
23
|
+
|
24
|
+
@email_entry = entry {
|
25
|
+
label 'Email' # label property is available when control is nested under form
|
26
|
+
}
|
19
27
|
}
|
20
28
|
|
21
|
-
button('Display
|
29
|
+
button('Display Info') {
|
30
|
+
stretchy false
|
31
|
+
|
22
32
|
on_clicked do
|
23
|
-
msg_box('
|
33
|
+
msg_box('Info', "#{@first_name_entry.text} #{@last_name_entry.text} has phone #{@phone_entry.text} and email #{@email_entry.text}")
|
24
34
|
end
|
25
35
|
}
|
26
36
|
}
|
data/examples/meta_example.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'glimmer-dsl-libui'
|
4
2
|
require 'facets'
|
5
3
|
|
@@ -42,6 +40,18 @@ class MetaExample
|
|
42
40
|
examples[@selected_example_index]
|
43
41
|
end
|
44
42
|
|
43
|
+
def run_example(example)
|
44
|
+
command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
|
45
|
+
result = ''
|
46
|
+
IO.popen(command) do |f|
|
47
|
+
f.each_line do |line|
|
48
|
+
result << line
|
49
|
+
puts line
|
50
|
+
end
|
51
|
+
end
|
52
|
+
msg_box('Error Running Example', result) if result.downcase.include?('error')
|
53
|
+
end
|
54
|
+
|
45
55
|
def launch
|
46
56
|
window('Meta-Example', 700, 500) {
|
47
57
|
margined true
|
@@ -50,16 +60,16 @@ class MetaExample
|
|
50
60
|
vertical_box {
|
51
61
|
stretchy false
|
52
62
|
|
53
|
-
@
|
63
|
+
@example_radio_buttons = radio_buttons {
|
54
64
|
stretchy false
|
55
65
|
items examples_with_versions
|
56
66
|
selected @selected_example_index
|
57
67
|
|
58
68
|
on_selected do
|
59
|
-
@selected_example_index = @
|
69
|
+
@selected_example_index = @example_radio_buttons.selected
|
60
70
|
example = selected_example
|
61
|
-
@
|
62
|
-
@
|
71
|
+
@code_entry.text = File.read(file_path_for(example))
|
72
|
+
@version_spinbox.value = 1
|
63
73
|
end
|
64
74
|
}
|
65
75
|
|
@@ -68,17 +78,17 @@ class MetaExample
|
|
68
78
|
stretchy false
|
69
79
|
}
|
70
80
|
|
71
|
-
@
|
81
|
+
@version_spinbox = spinbox(1, 100) {
|
72
82
|
value 1
|
73
83
|
|
74
84
|
on_changed do
|
75
85
|
example = selected_example
|
76
|
-
if @
|
77
|
-
@
|
86
|
+
if @version_spinbox.value > version_count_for(example)
|
87
|
+
@version_spinbox.value -= 1
|
78
88
|
else
|
79
|
-
version_number = @
|
89
|
+
version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
|
80
90
|
example = "#{selected_example}#{version_number}"
|
81
|
-
@
|
91
|
+
@code_entry.text = File.read(file_path_for(example))
|
82
92
|
end
|
83
93
|
end
|
84
94
|
}
|
@@ -91,24 +101,24 @@ class MetaExample
|
|
91
101
|
on_clicked do
|
92
102
|
begin
|
93
103
|
meta_example_file = File.join(Dir.home, '.meta_example.rb')
|
94
|
-
File.write(meta_example_file, @
|
95
|
-
|
96
|
-
msg_box('Error Running Example', result) if result.include?('error')
|
104
|
+
File.write(meta_example_file, @code_entry.text)
|
105
|
+
run_example(meta_example_file)
|
97
106
|
rescue => e
|
107
|
+
puts e.full_message
|
98
108
|
puts 'Unable to write code changes! Running original example...'
|
99
|
-
|
109
|
+
run_example(file_path_for(selected_example))
|
100
110
|
end
|
101
111
|
end
|
102
112
|
}
|
103
113
|
button('Reset') {
|
104
114
|
on_clicked do
|
105
|
-
@
|
115
|
+
@code_entry.text = File.read(file_path_for(selected_example))
|
106
116
|
end
|
107
117
|
}
|
108
118
|
}
|
109
119
|
}
|
110
120
|
|
111
|
-
@
|
121
|
+
@code_entry = non_wrapping_multiline_entry {
|
112
122
|
text File.read(file_path_for(selected_example))
|
113
123
|
}
|
114
124
|
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
require 'facets'
|
3
|
+
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
|
7
|
+
|
8
|
+
def field(model, property)
|
9
|
+
property = property.to_s
|
10
|
+
entry { |e|
|
11
|
+
label property.underscore.split('_').map(&:capitalize).join(' ')
|
12
|
+
text model.send(property).to_s
|
13
|
+
|
14
|
+
on_changed do
|
15
|
+
model.send("#{property}=", e.text)
|
16
|
+
end
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def address_form(address)
|
21
|
+
form {
|
22
|
+
field(address, :street)
|
23
|
+
field(address, :p_o_box)
|
24
|
+
field(address, :city)
|
25
|
+
field(address, :state)
|
26
|
+
field(address, :zip_code)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def label_pair(model, attribute, value)
|
31
|
+
name_label = nil
|
32
|
+
value_label = nil
|
33
|
+
horizontal_box {
|
34
|
+
name_label = label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
|
35
|
+
value_label = label(value.to_s)
|
36
|
+
}
|
37
|
+
Glimmer::DataBinding::Observer.proc do
|
38
|
+
value_label.text = model.send(attribute)
|
39
|
+
end.observe(model, attribute)
|
40
|
+
end
|
41
|
+
|
42
|
+
def address(address)
|
43
|
+
vertical_box {
|
44
|
+
address.each_pair do |attribute, value|
|
45
|
+
label_pair(address, attribute, value)
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
|
51
|
+
address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
|
52
|
+
|
53
|
+
window('Method-Based Custom Keyword') {
|
54
|
+
margined true
|
55
|
+
|
56
|
+
horizontal_box {
|
57
|
+
vertical_box {
|
58
|
+
label('Address 1') {
|
59
|
+
stretchy false
|
60
|
+
}
|
61
|
+
address_form(address1)
|
62
|
+
horizontal_separator {
|
63
|
+
stretchy false
|
64
|
+
}
|
65
|
+
label('Address 1 (Saved)') {
|
66
|
+
stretchy false
|
67
|
+
}
|
68
|
+
address(address1)
|
69
|
+
}
|
70
|
+
vertical_separator {
|
71
|
+
stretchy false
|
72
|
+
}
|
73
|
+
vertical_box {
|
74
|
+
label('Address 2') {
|
75
|
+
stretchy false
|
76
|
+
}
|
77
|
+
address_form(address2)
|
78
|
+
horizontal_separator {
|
79
|
+
stretchy false
|
80
|
+
}
|
81
|
+
label('Address 2 (Saved)') {
|
82
|
+
stretchy false
|
83
|
+
}
|
84
|
+
address(address2)
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}.show
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -69,7 +69,6 @@ module Glimmer
|
|
69
69
|
@fill ||= {}
|
70
70
|
else
|
71
71
|
@fill = Glimmer::LibUI.interpret_color(args)
|
72
|
-
@fill[:a] = 1.0 if @fill.is_a?(Hash) && @fill[:a].nil?
|
73
72
|
@parent_proxy&.queue_redraw_all
|
74
73
|
end
|
75
74
|
@fill.tap do
|
@@ -94,7 +93,6 @@ module Glimmer
|
|
94
93
|
@stroke ||= {}
|
95
94
|
else
|
96
95
|
@stroke = Glimmer::LibUI.interpret_color(args)
|
97
|
-
@stroke[:a] = 1.0 if @stroke.is_a?(Hash) && @stroke[:a].nil?
|
98
96
|
@parent_proxy&.queue_redraw_all
|
99
97
|
end
|
100
98
|
@stroke.tap do
|
@@ -149,11 +147,38 @@ module Glimmer
|
|
149
147
|
end
|
150
148
|
|
151
149
|
def init_draw_brush(draw_brush, draw_brush_args)
|
150
|
+
if draw_brush_args[:r] || draw_brush_args[:g] || draw_brush_args[:b] || draw_brush_args[:a]
|
151
|
+
draw_brush_args[:type] ||= :solid
|
152
|
+
elsif draw_brush_args[:outer_radius]
|
153
|
+
draw_brush_args[:type] ||= :radial_gradient
|
154
|
+
else
|
155
|
+
draw_brush_args[:type] ||= :linear_gradient
|
156
|
+
end
|
152
157
|
draw_brush.Type = Glimmer::LibUI.enum_symbol_to_value(:draw_brush_type, draw_brush_args[:type])
|
153
|
-
draw_brush.
|
154
|
-
|
155
|
-
|
156
|
-
|
158
|
+
if draw_brush.Type == 0
|
159
|
+
draw_brush.R = (draw_brush_args[:r] || draw_brush_args[:red]).to_f / 255.0
|
160
|
+
draw_brush.G = (draw_brush_args[:g] || draw_brush_args[:green]).to_f / 255.0
|
161
|
+
draw_brush.B = (draw_brush_args[:b] || draw_brush_args[:blue]).to_f / 255.0
|
162
|
+
draw_brush.A = (draw_brush_args[:a] || draw_brush_args[:alpha] || 1.0)
|
163
|
+
else
|
164
|
+
draw_brush.X0 = draw_brush_args[:x0].to_f
|
165
|
+
draw_brush.Y0 = draw_brush_args[:y0].to_f
|
166
|
+
draw_brush.X1 = draw_brush_args[:x1].to_f
|
167
|
+
draw_brush.Y1 = draw_brush_args[:y1].to_f
|
168
|
+
draw_brush.OuterRadius = draw_brush_args[:outer_radius].to_f if draw_brush.Type == 2
|
169
|
+
stop_structs = draw_brush_args[:stops].to_a.map do |stop|
|
170
|
+
::LibUI::FFI::DrawBrushGradientStop.malloc.tap do |stop_struct|
|
171
|
+
stop_struct.Pos = stop[:pos].to_f
|
172
|
+
stop_color = Glimmer::LibUI.interpret_color(stop)
|
173
|
+
stop_struct.R = stop_color[:r].to_f / 255.0
|
174
|
+
stop_struct.G = stop_color[:g].to_f / 255.0
|
175
|
+
stop_struct.B = stop_color[:b].to_f / 255.0
|
176
|
+
stop_struct.A = stop_color[:a] || 1.0
|
177
|
+
end
|
178
|
+
end
|
179
|
+
draw_brush.NumStops = stop_structs.count
|
180
|
+
draw_brush.Stops = stop_structs.map(&:to_ptr).map(&:to_s).reduce(:+)
|
181
|
+
end
|
157
182
|
end
|
158
183
|
end
|
159
184
|
end
|
data/lib/glimmer/libui.rb
CHANGED
@@ -44,8 +44,8 @@ module Glimmer
|
|
44
44
|
value = value[0...-1]
|
45
45
|
end
|
46
46
|
value = value.first if value.is_a?(Array) && value.size == 1
|
47
|
-
value = value.to_s if value.is_a?(Symbol)
|
48
47
|
value = value[:color] if value.is_a?(Hash) && value[:color]
|
48
|
+
value = value.to_s if value.is_a?(Symbol)
|
49
49
|
result = if value.is_a?(Array)
|
50
50
|
old_value = value
|
51
51
|
value = {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -246,6 +246,7 @@ files:
|
|
246
246
|
- examples/histogram.rb
|
247
247
|
- examples/login.rb
|
248
248
|
- examples/meta_example.rb
|
249
|
+
- examples/method_based_custom_keyword.rb
|
249
250
|
- examples/midi_player.rb
|
250
251
|
- examples/simple_notepad.rb
|
251
252
|
- examples/timer.rb
|