glimmer-dsl-libui 0.2.9 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/ce2853efdbecf6ebdc73/maintainability)](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
|
+
![glimmer-dsl-libui-mac-method-based-custom-keyword.png](images/glimmer-dsl-libui-mac-method-based-custom-keyword.png)
|
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
|
+
![glimmer-dsl-libui-mac-method-based-custom-keyword.png](images/glimmer-dsl-libui-mac-method-based-custom-keyword.png)
|
5826
|
+
|
5827
|
+
Linux
|
5828
|
+
|
5829
|
+
![glimmer-dsl-libui-linux-method-based-custom-keyword.png](images/glimmer-dsl-libui-linux-method-based-custom-keyword.png)
|
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
|