glimmer-dsl-libui 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +136 -5
- data/VERSION +1 -1
- data/examples/dynamic_area2.rb +97 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy.rb +4 -0
- data/lib/glimmer/libui/path_proxy.rb +20 -2
- data/lib/glimmer/libui/rectangle_proxy.rb +46 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 588ece65aa562fd337018de00f5e60156926cb6d9ee6144f5f89e2e8dfaa2d74
|
4
|
+
data.tar.gz: f50f57a58f6b7915f5e9fc123eecf9e982be5f18ff93833a8d0603ce3955063d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b0d02fde1567c4be008e81b91fc67df319fd2c46bf44466da6e4ff2e8a49f31bd239a78ed69be43f1338fa51dd4fcd648d6c5ecbe2aafe41fb345911df327bf
|
7
|
+
data.tar.gz: cfe32a98fddb52c1cf320e4e8d7651d0b083172ada4dd4b43441f0fdb839cde207841c96e39d9e47c7cffeb536a7d6620aed3abe869c790ce595c4361ac2988c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.1.2
|
4
|
+
|
5
|
+
- Support re-opening a control by using `#content {...}`
|
6
|
+
- Ensure destroying `path`/`rectangle` after drawing if it is declared inside `on_draw`
|
7
|
+
- Observe `path` `fill` and `stroke` hashes for changes and automatically redraw area accordingly
|
8
|
+
- New examples/dynamic_area2.rb (using stable paths)
|
9
|
+
|
3
10
|
## 0.1.1
|
4
11
|
|
5
12
|
- Support `area` listener: `on_draw`
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.1.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.1.2
|
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)
|
@@ -43,7 +43,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
43
43
|
|
44
44
|
## Table of Contents
|
45
45
|
|
46
|
-
- [Glimmer DSL for LibUI 0.1.
|
46
|
+
- [Glimmer DSL for LibUI 0.1.2](#-glimmer-dsl-for-libui-012)
|
47
47
|
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
48
48
|
- [Usage](#usage)
|
49
49
|
- [API](#api)
|
@@ -170,7 +170,7 @@ gem install glimmer-dsl-libui
|
|
170
170
|
Or install via Bundler `Gemfile`:
|
171
171
|
|
172
172
|
```ruby
|
173
|
-
gem 'glimmer-dsl-libui', '~> 0.1.
|
173
|
+
gem 'glimmer-dsl-libui', '~> 0.1.2'
|
174
174
|
```
|
175
175
|
|
176
176
|
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.
|
@@ -308,6 +308,7 @@ Control(Args) | Properties | Listeners
|
|
308
308
|
- `ControlProxy::image_proxies`: returns all instantiated `image` proxies in the application
|
309
309
|
- `ControlProxy::main_window_proxy`: returns the first window proxy instantiated in the application
|
310
310
|
- `ControlProxy#window_proxy`: returns the window proxy parent for a control
|
311
|
+
- `ControlProxy#content {...}`: re-opens control's content to add more nested controls or properties
|
311
312
|
|
312
313
|
### Table API
|
313
314
|
|
@@ -330,8 +331,8 @@ Note that the `cell_rows` property declaration results in "implicit data-binding
|
|
330
331
|
### Area API
|
331
332
|
|
332
333
|
The `area` control can be used in one of two ways:
|
333
|
-
- Declaratively via stable paths: useful for stable paths that will not change later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically.
|
334
|
-
- Semi-declaratively via on_draw listener dynamic paths: useful for more dynamic paths that will definitely change. Open an `on_draw` listener block and nest `path(area_draw_params)` and figures like `rectangle` and all drawing logic is generated automatically.
|
334
|
+
- Declaratively via stable paths: useful for stable paths that will not change later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Paths proxy objects are preserved across redraws assuming there would be few stable paths (mostly for decorative reasons).
|
335
|
+
- Semi-declaratively via on_draw listener dynamic paths: useful for more dynamic paths that will definitely change. Open an `on_draw` listener block and nest `path(area_draw_params)` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are destroyed (thrown-away) at the end of drawing, thus having less memory overhead for drawing thousands of dynamic paths.
|
335
336
|
|
336
337
|
Here is an example of a declarative `area` with a stable path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
337
338
|
|
@@ -383,6 +384,8 @@ window('Basic Area', 400, 400) {
|
|
383
384
|
|
384
385
|
Check [examples/dynamic_area.rb](#dynamic-area) for a more detailed semi-declarative example.
|
385
386
|
|
387
|
+
In general, it is recommended to use declarative stable paths whenever feasible since they require less code and simpler maintenance. But, in more advanced cases, semi-declarative dynamic paths could be used instead, especially if there are thousands of paths.
|
388
|
+
|
386
389
|
To redraw an `area`, you may call `#queue_redraw_all` method.
|
387
390
|
|
388
391
|
### Smart Defaults and Conventions
|
@@ -414,6 +417,8 @@ To redraw an `area`, you may call `#queue_redraw_all` method.
|
|
414
417
|
- `image` instances are automatically freed from memory after `window` is destroyed.
|
415
418
|
- `image` `width` and `height` can be left off if it has one `image_part` only as they default to the same `width` and `height` of the `image_part`
|
416
419
|
- `area` paths are specified declaratively with figures underneath (e.g. `rectangle`) and `area` draw listener is automatically generated
|
420
|
+
- Observe figure properties (e.g. `rectangle` `width`) for changes and automatically redraw containing area accordingly
|
421
|
+
- Observe `path` `fill` and `stroke` hashes for changes and automatically redraw containing area accordingly
|
417
422
|
|
418
423
|
### API Gotchas
|
419
424
|
|
@@ -2744,6 +2749,30 @@ window('Basic Area', 400, 400) {
|
|
2744
2749
|
}.show
|
2745
2750
|
```
|
2746
2751
|
|
2752
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
2753
|
+
|
2754
|
+
```ruby
|
2755
|
+
require 'glimmer-dsl-libui'
|
2756
|
+
|
2757
|
+
include Glimmer
|
2758
|
+
|
2759
|
+
window('Basic Area', 400, 400) {
|
2760
|
+
margined true
|
2761
|
+
|
2762
|
+
vertical_box {
|
2763
|
+
area {
|
2764
|
+
on_draw do |area_draw_params|
|
2765
|
+
path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
|
2766
|
+
rectangle(0, 0, 400, 400)
|
2767
|
+
|
2768
|
+
fill r: 102, g: 102, b: 204, a: 1.0
|
2769
|
+
}
|
2770
|
+
end
|
2771
|
+
}
|
2772
|
+
}
|
2773
|
+
}.show
|
2774
|
+
```
|
2775
|
+
|
2747
2776
|
### Dynamic Area
|
2748
2777
|
|
2749
2778
|
[examples/dynamic_area.rb](examples/dynamic_area.rb)
|
@@ -2874,6 +2903,108 @@ window('Dynamic Area', 240, 500) {
|
|
2874
2903
|
}.show
|
2875
2904
|
```
|
2876
2905
|
|
2906
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
2907
|
+
|
2908
|
+
```ruby
|
2909
|
+
require 'glimmer-dsl-libui'
|
2910
|
+
|
2911
|
+
include Glimmer
|
2912
|
+
|
2913
|
+
window('Dynamic Area', 240, 600) {
|
2914
|
+
margined true
|
2915
|
+
|
2916
|
+
vertical_box {
|
2917
|
+
label('Rectangle Properties') {
|
2918
|
+
stretchy false
|
2919
|
+
}
|
2920
|
+
|
2921
|
+
form {
|
2922
|
+
stretchy false
|
2923
|
+
|
2924
|
+
@x_spinbox = spinbox(0, 1000) {
|
2925
|
+
label 'x'
|
2926
|
+
value 25
|
2927
|
+
|
2928
|
+
on_changed do
|
2929
|
+
@rectangle.x = @x_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2930
|
+
end
|
2931
|
+
}
|
2932
|
+
|
2933
|
+
@y_spinbox = spinbox(0, 1000) {
|
2934
|
+
label 'y'
|
2935
|
+
value 25
|
2936
|
+
|
2937
|
+
on_changed do
|
2938
|
+
@rectangle.y = @y_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2939
|
+
end
|
2940
|
+
}
|
2941
|
+
|
2942
|
+
@width_spinbox = spinbox(0, 1000) {
|
2943
|
+
label 'width'
|
2944
|
+
value 150
|
2945
|
+
|
2946
|
+
on_changed do
|
2947
|
+
@rectangle.width = @width_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2948
|
+
end
|
2949
|
+
}
|
2950
|
+
|
2951
|
+
@height_spinbox = spinbox(0, 1000) {
|
2952
|
+
label 'height'
|
2953
|
+
value 150
|
2954
|
+
|
2955
|
+
on_changed do
|
2956
|
+
@rectangle.height = @height_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2957
|
+
end
|
2958
|
+
}
|
2959
|
+
|
2960
|
+
@red_spinbox = spinbox(0, 255) {
|
2961
|
+
label 'red'
|
2962
|
+
value 102
|
2963
|
+
|
2964
|
+
on_changed do
|
2965
|
+
@path.fill[:r] = @red_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2966
|
+
end
|
2967
|
+
}
|
2968
|
+
|
2969
|
+
@green_spinbox = spinbox(0, 255) {
|
2970
|
+
label 'green'
|
2971
|
+
value 102
|
2972
|
+
|
2973
|
+
on_changed do
|
2974
|
+
@path.fill[:g] = @green_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2975
|
+
end
|
2976
|
+
}
|
2977
|
+
|
2978
|
+
@blue_spinbox = spinbox(0, 255) {
|
2979
|
+
label 'blue'
|
2980
|
+
value 204
|
2981
|
+
|
2982
|
+
on_changed do
|
2983
|
+
@path.fill[:b] = @blue_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2984
|
+
end
|
2985
|
+
}
|
2986
|
+
|
2987
|
+
@alpha_spinbox = spinbox(0, 100) {
|
2988
|
+
label 'alpha'
|
2989
|
+
value 100
|
2990
|
+
|
2991
|
+
on_changed do
|
2992
|
+
@path.fill[:a] = @alpha_spinbox.value / 100.0 # updating hash properties automatically triggers area.queue_redraw_all
|
2993
|
+
end
|
2994
|
+
}
|
2995
|
+
}
|
2996
|
+
|
2997
|
+
area {
|
2998
|
+
@path = path { # stable path
|
2999
|
+
@rectangle = rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
|
3000
|
+
|
3001
|
+
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
3002
|
+
}
|
3003
|
+
}
|
3004
|
+
}
|
3005
|
+
}.show
|
3006
|
+
```
|
3007
|
+
|
2877
3008
|
## Contributing to glimmer-dsl-libui
|
2878
3009
|
|
2879
3010
|
- Check out the latest master to make sure the feature hasn't been
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
include Glimmer
|
4
|
+
|
5
|
+
window('Dynamic Area', 240, 600) {
|
6
|
+
margined true
|
7
|
+
|
8
|
+
vertical_box {
|
9
|
+
label('Rectangle Properties') {
|
10
|
+
stretchy false
|
11
|
+
}
|
12
|
+
|
13
|
+
form {
|
14
|
+
stretchy false
|
15
|
+
|
16
|
+
@x_spinbox = spinbox(0, 1000) {
|
17
|
+
label 'x'
|
18
|
+
value 25
|
19
|
+
|
20
|
+
on_changed do
|
21
|
+
@rectangle.x = @x_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
@y_spinbox = spinbox(0, 1000) {
|
26
|
+
label 'y'
|
27
|
+
value 25
|
28
|
+
|
29
|
+
on_changed do
|
30
|
+
@rectangle.y = @y_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
@width_spinbox = spinbox(0, 1000) {
|
35
|
+
label 'width'
|
36
|
+
value 150
|
37
|
+
|
38
|
+
on_changed do
|
39
|
+
@rectangle.width = @width_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
@height_spinbox = spinbox(0, 1000) {
|
44
|
+
label 'height'
|
45
|
+
value 150
|
46
|
+
|
47
|
+
on_changed do
|
48
|
+
@rectangle.height = @height_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
49
|
+
end
|
50
|
+
}
|
51
|
+
|
52
|
+
@red_spinbox = spinbox(0, 255) {
|
53
|
+
label 'red'
|
54
|
+
value 102
|
55
|
+
|
56
|
+
on_changed do
|
57
|
+
@path.fill[:r] = @red_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
58
|
+
end
|
59
|
+
}
|
60
|
+
|
61
|
+
@green_spinbox = spinbox(0, 255) {
|
62
|
+
label 'green'
|
63
|
+
value 102
|
64
|
+
|
65
|
+
on_changed do
|
66
|
+
@path.fill[:g] = @green_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
67
|
+
end
|
68
|
+
}
|
69
|
+
|
70
|
+
@blue_spinbox = spinbox(0, 255) {
|
71
|
+
label 'blue'
|
72
|
+
value 204
|
73
|
+
|
74
|
+
on_changed do
|
75
|
+
@path.fill[:b] = @blue_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
@alpha_spinbox = spinbox(0, 100) {
|
80
|
+
label 'alpha'
|
81
|
+
value 100
|
82
|
+
|
83
|
+
on_changed do
|
84
|
+
@path.fill[:a] = @alpha_spinbox.value / 100.0 # updating hash properties automatically triggers area.queue_redraw_all
|
85
|
+
end
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
area {
|
90
|
+
@path = path { # stable path
|
91
|
+
@rectangle = rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
|
92
|
+
|
93
|
+
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}.show
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -258,6 +258,10 @@ module Glimmer
|
|
258
258
|
alias set_visible visible
|
259
259
|
alias visible= visible
|
260
260
|
|
261
|
+
def content(&block)
|
262
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ControlExpression.new, @keyword, &block)
|
263
|
+
end
|
264
|
+
|
261
265
|
private
|
262
266
|
|
263
267
|
def build_control
|
@@ -44,7 +44,10 @@ module Glimmer
|
|
44
44
|
|
45
45
|
def post_add_content
|
46
46
|
super
|
47
|
-
|
47
|
+
if @parent_proxy.nil? && area_draw_params
|
48
|
+
draw(area_draw_params)
|
49
|
+
destroy
|
50
|
+
end
|
48
51
|
end
|
49
52
|
|
50
53
|
def children
|
@@ -69,6 +72,13 @@ module Glimmer
|
|
69
72
|
@fill ||= {}
|
70
73
|
else
|
71
74
|
@fill = args
|
75
|
+
@parent_proxy&.queue_redraw_all
|
76
|
+
end
|
77
|
+
@fill.tap do
|
78
|
+
@fill_observer ||= Glimmer::DataBinding::Observer.proc do
|
79
|
+
@parent_proxy&.queue_redraw_all
|
80
|
+
end
|
81
|
+
@fill_observer.observe(@fill)
|
72
82
|
end
|
73
83
|
end
|
74
84
|
alias fill= fill
|
@@ -85,6 +95,13 @@ module Glimmer
|
|
85
95
|
@stroke ||= {}
|
86
96
|
else
|
87
97
|
@stroke = args
|
98
|
+
@parent_proxy&.queue_redraw_all
|
99
|
+
end
|
100
|
+
@stroke.tap do
|
101
|
+
@stroke_observer ||= Glimmer::DataBinding::Observer.proc do
|
102
|
+
@parent_proxy&.queue_redraw_all
|
103
|
+
end
|
104
|
+
@stroke_observer.observe(@stroke)
|
88
105
|
end
|
89
106
|
end
|
90
107
|
alias stroke= stroke
|
@@ -116,8 +133,9 @@ module Glimmer
|
|
116
133
|
|
117
134
|
def destroy
|
118
135
|
@parent_proxy.children.delete(self) unless @parent_proxy.nil?
|
136
|
+
ControlProxy.control_proxies.delete(self)
|
119
137
|
end
|
120
|
-
|
138
|
+
|
121
139
|
private
|
122
140
|
|
123
141
|
def build_control
|
@@ -38,13 +38,57 @@ module Glimmer
|
|
38
38
|
|
39
39
|
def draw(area_draw_params)
|
40
40
|
::LibUI.draw_path_add_rectangle(@parent_proxy.libui, *@args)
|
41
|
+
destroy if @parent_proxy.parent_proxy.nil?
|
41
42
|
end
|
42
43
|
|
43
44
|
def destroy
|
44
|
-
|
45
|
-
|
45
|
+
@parent_proxy.children.delete(self) unless @parent_proxy.nil?
|
46
|
+
ControlProxy.control_proxies.delete(self)
|
47
|
+
end
|
48
|
+
|
49
|
+
def x(value = nil)
|
50
|
+
if value.nil?
|
51
|
+
@args[0]
|
52
|
+
else
|
53
|
+
@args[0] = value
|
54
|
+
@parent_proxy.parent_proxy&.queue_redraw_all
|
55
|
+
end
|
56
|
+
end
|
57
|
+
alias x= x
|
58
|
+
alias set_x x
|
59
|
+
|
60
|
+
def y(value = nil)
|
61
|
+
if value.nil?
|
62
|
+
@args[1]
|
63
|
+
else
|
64
|
+
@args[1] = value
|
65
|
+
@parent_proxy.parent_proxy&.queue_redraw_all
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias y= y
|
69
|
+
alias set_y y
|
70
|
+
|
71
|
+
def width(value = nil)
|
72
|
+
if value.nil?
|
73
|
+
@args[2]
|
74
|
+
else
|
75
|
+
@args[2] = value
|
76
|
+
@parent_proxy.parent_proxy&.queue_redraw_all
|
77
|
+
end
|
78
|
+
end
|
79
|
+
alias width= width
|
80
|
+
alias set_width width
|
81
|
+
|
82
|
+
def height(value = nil)
|
83
|
+
if value.nil?
|
84
|
+
@args[3]
|
85
|
+
else
|
86
|
+
@args[3] = value
|
87
|
+
@parent_proxy.parent_proxy&.queue_redraw_all
|
46
88
|
end
|
47
89
|
end
|
90
|
+
alias height= height
|
91
|
+
alias set_height height
|
48
92
|
|
49
93
|
private
|
50
94
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: 2.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: os
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,6 +211,7 @@ files:
|
|
211
211
|
- examples/control_gallery.rb
|
212
212
|
- examples/date_time_picker.rb
|
213
213
|
- examples/dynamic_area.rb
|
214
|
+
- examples/dynamic_area2.rb
|
214
215
|
- examples/editable_column_table.rb
|
215
216
|
- examples/editable_table.rb
|
216
217
|
- examples/font_button.rb
|