glimmer-dsl-libui 0.2.23 → 0.3.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 +22 -0
- data/README.md +611 -93
- data/VERSION +1 -1
- data/bin/girb +0 -0
- data/examples/basic_image.rb +19 -0
- data/examples/basic_image2.rb +13 -0
- data/examples/basic_image3.rb +23 -0
- data/examples/basic_image4.rb +17 -0
- data/examples/basic_image5.rb +75 -0
- data/examples/basic_table_color.rb +1 -11
- data/examples/basic_table_color2.rb +39 -0
- data/examples/basic_table_image.rb +2 -14
- data/examples/basic_table_image2.rb +44 -0
- data/examples/basic_table_image_text.rb +2 -13
- data/examples/basic_table_image_text2.rb +44 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +1 -1
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +1 -0
- data/lib/glimmer/libui/control_proxy/column.rb +2 -2
- data/lib/glimmer/libui/control_proxy/image_part_proxy.rb +0 -1
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +159 -12
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +15 -2
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +1 -1
- data/lib/glimmer/libui/control_proxy.rb +7 -7
- data/lib/glimmer/libui/image_path_renderer.rb +30 -0
- data/lib/glimmer/libui.rb +1 -0
- metadata +27 -18
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.3.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
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -238,6 +238,14 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
238
238
|
- [Extra Operations](#extra-operations)
|
239
239
|
- [Table API](#table-api)
|
240
240
|
- [Area API](#area-api)
|
241
|
+
- [Area Path Shapes](#area-path-shapes)
|
242
|
+
- [Area Text](#area-text)
|
243
|
+
- [Area Image](#area-image)
|
244
|
+
- [Colors](#colors)
|
245
|
+
- [Area Draw Params](#area-draw-params)
|
246
|
+
- [Area Listeners](#area-listeners)
|
247
|
+
- [Area Methods/Attributes](#area-methods-attributes)
|
248
|
+
- [Area Transform Matrix](#area-transform-matrix)
|
241
249
|
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
242
250
|
- [Custom Keywords](#custom-keywords)
|
243
251
|
- [API Gotchas](#api-gotchas)
|
@@ -270,6 +278,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
270
278
|
- [Basic Area](#basic-area)
|
271
279
|
- [Dynamic Area](#dynamic-area)
|
272
280
|
- [Area Gallery](#area-gallery)
|
281
|
+
- [Basic Image](#basic-image)
|
273
282
|
- [Histogram](#histogram)
|
274
283
|
- [Basic Transform](#basic-transform)
|
275
284
|
- [Login](#login)
|
@@ -373,7 +382,7 @@ gem install glimmer-dsl-libui
|
|
373
382
|
Or install via Bundler `Gemfile`:
|
374
383
|
|
375
384
|
```ruby
|
376
|
-
gem 'glimmer-dsl-libui', '~> 0.2
|
385
|
+
gem 'glimmer-dsl-libui', '~> 0.3.2'
|
377
386
|
```
|
378
387
|
|
379
388
|
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.
|
@@ -444,7 +453,7 @@ w.libui # => #<Fiddle::Pointer:0x00007fde53997980 ptr=0x00007fde51352a60 size=0
|
|
444
453
|
|
445
454
|
### Supported Keywords
|
446
455
|
|
447
|
-
These are all the supported keywords. Note that some keywords do not represent controls, but produce objects that are used as the property values of controls (e.g. `image`
|
456
|
+
These are all the supported keywords. Note that some keywords do not represent controls, but produce objects that are used as the property values of controls (e.g. `image` can be used as a control under `area` or alternatively build objects to use in `cell_rows` for a `table` with an `image_column`)
|
448
457
|
|
449
458
|
Keyword(Args) | Properties | Listeners
|
450
459
|
------------- | ---------- | ---------
|
@@ -473,7 +482,7 @@ Keyword(Args) | Properties | Listeners
|
|
473
482
|
`group(text as String)` | `margined` (Boolean), `title` (`String`) | None
|
474
483
|
`horizontal_box` | `padded` (Boolean) | None
|
475
484
|
`horizontal_separator` | None | None
|
476
|
-
`image(width as Numeric, height as Numeric)` |
|
485
|
+
`image(file as String = nil, width as Numeric = nil, height as Numeric = nil)` | `file` (`String` path or URL), `width`, `height` | None
|
477
486
|
`image_part(pixels as String [encoded image rgba byte array], width as Numeric, height as Numeric, byte_stride as Numeric [usually width*4])` | None | None
|
478
487
|
`image_column(name as String)` | None | None
|
479
488
|
`image_text_column(name as String)` | None | None
|
@@ -552,8 +561,8 @@ There are additional useful `Glimmer::LibUI` operations that are not found in `L
|
|
552
561
|
- `Glimmer::LibUI::integer_to_boolean(int, allow_nil: true)`
|
553
562
|
- `Glimmer::LibUI::boolean_to_integer(int, allow_nil: true)`
|
554
563
|
- `Glimmer::LibUI::degrees_to_radians(degrees)`
|
555
|
-
- `Glimmer::LibUI::interpret_color(value)`: interprets a color in any form like `String`, `Symbol`, or hex into an rgb `Hash`
|
556
|
-
- `Glimmer::LibUI::hex_to_rgb(value)`: converts a hex color to an rgb `Hash`
|
564
|
+
- `Glimmer::LibUI::interpret_color(value)`: interprets a color in any form like `String`, `Symbol`, or hex into an rgb `Hash` (including `0x1f3b5d`, `'0x1f3b5d'`, `'#1f3b5d'`, and 3-char hex-shorthand variations)
|
565
|
+
- `Glimmer::LibUI::hex_to_rgb(value)`: converts a hex color to an rgb `Hash` (including `0x1f3b5d`, `'0x1f3b5d'`, `'#1f3b5d'`, and 3-char hex-shorthand variations)
|
557
566
|
- `Glimmer::LibUI::enum_names`: provides all possible enum names to use with `Glimmer::LibUI::enum_symbols(enum_name)`
|
558
567
|
- `Glimmer::LibUI::enum_symbols(enum_name)`: returns all possible values for an enum. `enum_name` can be:
|
559
568
|
- `:draw_brush_type`: `[:solid, :linear_gradient, :radial_gradient, :image]`
|
@@ -717,6 +726,8 @@ The `area` control is a canvas-like control for drawing paths that can be used i
|
|
717
726
|
- Declaratively via stable paths: useful for stable paths that will not change often later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are preserved across redraws assuming there would be relatively few stable paths (mostly for decorative reasons).
|
718
727
|
- Semi-declaratively via on_draw listener dynamic paths: useful for more dynamic paths that will definitely change very often. Open an `on_draw` listener block that receives a `area_draw_params` argument and nest `path` 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.
|
719
728
|
|
729
|
+
Note that when nesting an `area` directly underneath `window` (without a layout control like `vertical_box`), it is automatically reparented with `vertical_box` in between the `window` and `area` since it would not show up on Linux otherwise.
|
730
|
+
|
720
731
|
Here is an example of a declarative `area` with a stable path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
721
732
|
|
722
733
|
```ruby
|
@@ -739,8 +750,18 @@ window('Basic Area', 400, 400) {
|
|
739
750
|
}.show
|
740
751
|
```
|
741
752
|
|
753
|
+
Mac
|
754
|
+
|
742
755
|
![glimmer-dsl-libui-mac-basic-area.png](images/glimmer-dsl-libui-mac-basic-area.png)
|
743
756
|
|
757
|
+
Windows
|
758
|
+
|
759
|
+
![glimmer-dsl-libui-windows-basic-area.png](images/glimmer-dsl-libui-windows-basic-area.png)
|
760
|
+
|
761
|
+
Linux
|
762
|
+
|
763
|
+
![glimmer-dsl-libui-linux-basic-area.png](images/glimmer-dsl-libui-linux-basic-area.png)
|
764
|
+
|
744
765
|
Here is the same example using a semi-declarative `area` with `on_draw` listener that receives a `area_draw_params` argument and a dynamic path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
745
766
|
|
746
767
|
```ruby
|
@@ -767,6 +788,8 @@ window('Basic Area', 400, 400) {
|
|
767
788
|
|
768
789
|
Check [examples/dynamic_area.rb](#dynamic-area) for a more detailed semi-declarative example.
|
769
790
|
|
791
|
+
#### Area Path Shapes
|
792
|
+
|
770
793
|
`path` can receive a `draw_fill_mode` argument that can accept values `:winding` or `:alternate` and defaults to `:winding`.
|
771
794
|
|
772
795
|
Available nested `path` shapes:
|
@@ -782,6 +805,270 @@ Available nested `path` shapes:
|
|
782
805
|
|
783
806
|
Check [examples/area_gallery.rb](#area-gallery) for an overiew of all `path` shapes.
|
784
807
|
|
808
|
+
Mac
|
809
|
+
|
810
|
+
![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png)
|
811
|
+
|
812
|
+
Windows
|
813
|
+
|
814
|
+
![glimmer-dsl-libui-windows-area-gallery.png](images/glimmer-dsl-libui-windows-area-gallery.png)
|
815
|
+
|
816
|
+
Linux
|
817
|
+
|
818
|
+
![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
|
819
|
+
|
820
|
+
#### Area Text
|
821
|
+
|
822
|
+
To draw `text` in an `area`, you simply nest a `text(x, y, width)` control directly under `area` or inside a `on_draw` listener, and then nest attributed `string {[attributes]; string_value}` controls underneath it returning an actual `String` (think of them as the `<span>` or `<p>` element in html, which contains a string of text). Alternatively, you can nest attributed `string(string_value) {[attributes]}` if `string_value` is a short single-line string. An attributed `string` value can be changed dynamically via its `string` property.
|
823
|
+
|
824
|
+
`text` has the following properties:
|
825
|
+
- `default_font`:
|
826
|
+
- `align`: `:left` (default), `:center`, or `:right` (`align` currently seems not to work on the Mac)
|
827
|
+
- `x`: x coordinate in relation to parent `area` top-left corner
|
828
|
+
- `y`: y coordinate in relation to parent `area` top-left corner
|
829
|
+
- `width` (default: area width - x*2): width of text to display
|
830
|
+
|
831
|
+
`string` has the following properties:
|
832
|
+
- `font`: font descriptor hash consisting of `:family`, `:size`, `:weight` (`[:minimum, :thin, :ultra_light, :light, :book, :normal, :medium, :semi_bold, :bold, :ultra_bold, :heavy, :ultra_heavy, :maximum]`), `:italic` (`[:normal, :oblique, :italic]`), and `:stretch` (`[:ultra_condensed, :extra_condensed, :condensed, :semi_condensed, :normal, :semi_expanded, :expanded, :extra_expanded, :ultra_expanded]`) key values
|
833
|
+
- `color`: rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
834
|
+
- `background`: rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
835
|
+
- `underline`: one of `:none`, `:single`, `:double`, `:suggestion`, `:color_custom`, `:color_spelling`, `:color_grammar`, `:color_auxiliary`
|
836
|
+
- `underline_color`: one of `:spelling`, `:grammar`, `:auxiliary`, rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
837
|
+
- `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.
|
838
|
+
- `string`: string value (`String`)
|
839
|
+
|
840
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
841
|
+
|
842
|
+
```ruby
|
843
|
+
window('area text drawing') {
|
844
|
+
area {
|
845
|
+
text {
|
846
|
+
default_font family: 'Helvetica', size: 12, weight: :normal, italic: :normal, stretch: :normal
|
847
|
+
|
848
|
+
string {
|
849
|
+
font family: 'Georgia', size: 13, weight: :medium, italic: :normal, stretch: :normal
|
850
|
+
color r: 230, g: 100, b: 50, a: 0.5
|
851
|
+
background r: 230, g: 200, b: 250, a: 0.8
|
852
|
+
underline :single
|
853
|
+
underline_color :spelling
|
854
|
+
open_type_features {
|
855
|
+
open_type_tag 'l', 'i', 'g', 'a', 0
|
856
|
+
open_type_tag 'l', 'i', 'g', 'a', 1
|
857
|
+
}
|
858
|
+
|
859
|
+
"This is a demonstration\n" \
|
860
|
+
"of a very long\n" \
|
861
|
+
"attributed string\n" \
|
862
|
+
"spanning multiple lines\n\n"
|
863
|
+
}
|
864
|
+
|
865
|
+
string('This is a short unattributed string')
|
866
|
+
}
|
867
|
+
}
|
868
|
+
}.show
|
869
|
+
```
|
870
|
+
|
871
|
+
You may checkout [examples/basic_draw_text.rb](#basic-draw-text) and [examples/custom_draw_text.rb](#custom-draw-text) for examples of using `text` inside `area`.
|
872
|
+
|
873
|
+
Mac
|
874
|
+
|
875
|
+
![glimmer-dsl-libui-mac-custom-draw-text-changed.png](images/glimmer-dsl-libui-mac-custom-draw-text-changed.png)
|
876
|
+
|
877
|
+
Windows
|
878
|
+
|
879
|
+
![glimmer-dsl-libui-windows-custom-draw-text-changed.png](images/glimmer-dsl-libui-windows-custom-draw-text-changed.png)
|
880
|
+
|
881
|
+
Linux
|
882
|
+
|
883
|
+
![glimmer-dsl-libui-linux-custom-draw-text-changed.png](images/glimmer-dsl-libui-linux-custom-draw-text-changed.png)
|
884
|
+
|
885
|
+
#### Area Image
|
886
|
+
|
887
|
+
**(ALPHA FEATURE)**
|
888
|
+
|
889
|
+
[libui](https://github.com/andlabs/libui) does not support `image` rendering outside of `table` yet.
|
890
|
+
However, [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) adds a special `image(file as String path or web URL, width as Numeric, height as Numeric)` custom control that renders an image unto an `area` pixel by pixel (and when possible to optimize, line by line).
|
891
|
+
|
892
|
+
Given that it is very new and is not a [libui](https://github.com/andlabs/libui)-native control, please keep these notes in mind:
|
893
|
+
- It only supports the `.png` file format.
|
894
|
+
- [libui](https://github.com/andlabs/libui) pixel-by-pixel rendering performance is slow.
|
895
|
+
- Including an `image` inside an `area` `on_draw` listener improves performance due to not retaining pixel/line data in memory.
|
896
|
+
- Supplying `width` and `height` (2nd and 3rd arguments) greatly improves performance when shrinking image.
|
897
|
+
|
898
|
+
Currently, it is recommended to use `image` with very small `width` and `height` values only.
|
899
|
+
|
900
|
+
Setting a `transform` `matrix` is supported under `image` just like it is under `path` and `text` inside `area`.
|
901
|
+
|
902
|
+
Example of using `image` declaratively (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
903
|
+
|
904
|
+
Mac
|
905
|
+
|
906
|
+
![glimmer-dsl-libui-mac-basic-image.png](images/glimmer-dsl-libui-mac-basic-image.png)
|
907
|
+
|
908
|
+
Windows
|
909
|
+
|
910
|
+
![glimmer-dsl-libui-windows-basic-image.png](images/glimmer-dsl-libui-windows-basic-image.png)
|
911
|
+
|
912
|
+
```ruby
|
913
|
+
require 'glimmer-dsl-libui'
|
914
|
+
|
915
|
+
include Glimmer
|
916
|
+
|
917
|
+
window('Basic Image', 96, 96) {
|
918
|
+
area {
|
919
|
+
image(File.expand_path('icons/glimmer.png', __dir__), 96, 96)
|
920
|
+
}
|
921
|
+
}.show
|
922
|
+
```
|
923
|
+
|
924
|
+
Example of better performance via `on_draw` (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
925
|
+
|
926
|
+
```ruby
|
927
|
+
require 'glimmer-dsl-libui'
|
928
|
+
|
929
|
+
include Glimmer
|
930
|
+
|
931
|
+
window('Basic Image', 96, 96) {
|
932
|
+
area {
|
933
|
+
on_draw do |area_draw_params|
|
934
|
+
image(File.expand_path('icons/glimmer.png', __dir__), 96, 96)
|
935
|
+
end
|
936
|
+
}
|
937
|
+
}.show
|
938
|
+
```
|
939
|
+
|
940
|
+
Example of using `image` declaratively with explicit properties (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
941
|
+
|
942
|
+
```ruby
|
943
|
+
require 'glimmer-dsl-libui'
|
944
|
+
|
945
|
+
include Glimmer
|
946
|
+
|
947
|
+
window('Basic Image', 96, 96) {
|
948
|
+
area {
|
949
|
+
image {
|
950
|
+
file File.expand_path('icons/glimmer.png', __dir__)
|
951
|
+
width 96
|
952
|
+
height 96
|
953
|
+
}
|
954
|
+
}
|
955
|
+
}.show
|
956
|
+
```
|
957
|
+
|
958
|
+
Example of better performance via `on_draw` with explicit properties (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
959
|
+
|
960
|
+
```ruby
|
961
|
+
require 'glimmer-dsl-libui'
|
962
|
+
|
963
|
+
include Glimmer
|
964
|
+
|
965
|
+
window('Basic Image', 96, 96) {
|
966
|
+
area {
|
967
|
+
on_draw do |area_draw_params|
|
968
|
+
image {
|
969
|
+
file File.expand_path('icons/glimmer.png', __dir__)
|
970
|
+
width 96
|
971
|
+
height 96
|
972
|
+
}
|
973
|
+
end
|
974
|
+
}
|
975
|
+
}.show
|
976
|
+
```
|
977
|
+
|
978
|
+
If you need to render an image pixel by pixel (e.g. to support a format other than `.png`) for very exceptional scenarios, you may use this example as a guide, including a line-merge optimization for neighboring horizontal pixels with the same color:
|
979
|
+
|
980
|
+
```ruby
|
981
|
+
# This is the manual way of rendering an image unto an area control.
|
982
|
+
# It could come in handy in special situations.
|
983
|
+
# Otherwise, it is recommended to simply utilize the `image` control that
|
984
|
+
# can be nested under area or area on_draw listener to automate all this work.
|
985
|
+
|
986
|
+
require 'glimmer-dsl-libui'
|
987
|
+
require 'chunky_png'
|
988
|
+
|
989
|
+
include Glimmer
|
990
|
+
|
991
|
+
puts 'Parsing image...'; $stdout.flush
|
992
|
+
|
993
|
+
f = File.open(File.expand_path('icons/glimmer.png', __dir__))
|
994
|
+
canvas = ChunkyPNG::Canvas.from_io(f)
|
995
|
+
f.close
|
996
|
+
canvas.resample_nearest_neighbor!(96, 96)
|
997
|
+
data = canvas.to_rgba_stream
|
998
|
+
width = canvas.width
|
999
|
+
height = canvas.height
|
1000
|
+
puts "Image width: #{width}"
|
1001
|
+
puts "Image height: #{height}"
|
1002
|
+
|
1003
|
+
puts 'Parsing colors...'; $stdout.flush
|
1004
|
+
|
1005
|
+
color_maps = height.times.map do |y|
|
1006
|
+
width.times.map do |x|
|
1007
|
+
r = data[(y*width + x)*4].ord
|
1008
|
+
g = data[(y*width + x)*4 + 1].ord
|
1009
|
+
b = data[(y*width + x)*4 + 2].ord
|
1010
|
+
a = data[(y*width + x)*4 + 3].ord
|
1011
|
+
{x: x, y: y, color: {r: r, g: g, b: b, a: a}}
|
1012
|
+
end
|
1013
|
+
end.flatten
|
1014
|
+
puts "#{color_maps.size} pixels to render..."; $stdout.flush
|
1015
|
+
|
1016
|
+
puts 'Parsing shapes...'; $stdout.flush
|
1017
|
+
|
1018
|
+
shape_maps = []
|
1019
|
+
original_color_maps = color_maps.dup
|
1020
|
+
indexed_original_color_maps = Hash[original_color_maps.each_with_index.to_a]
|
1021
|
+
color_maps.each do |color_map|
|
1022
|
+
index = indexed_original_color_maps[color_map]
|
1023
|
+
@rectangle_start_x ||= color_map[:x]
|
1024
|
+
@rectangle_width ||= 1
|
1025
|
+
if color_map[:x] < width - 1 && color_map[:color] == original_color_maps[index + 1][:color]
|
1026
|
+
@rectangle_width += 1
|
1027
|
+
else
|
1028
|
+
if color_map[:x] > 0 && color_map[:color] == original_color_maps[index - 1][:color]
|
1029
|
+
shape_maps << {x: @rectangle_start_x, y: color_map[:y], width: @rectangle_width, height: 1, color: color_map[:color]}
|
1030
|
+
else
|
1031
|
+
shape_maps << {x: color_map[:x], y: color_map[:y], width: 1, height: 1, color: color_map[:color]}
|
1032
|
+
end
|
1033
|
+
@rectangle_width = 1
|
1034
|
+
@rectangle_start_x = color_map[:x] == width - 1 ? 0 : color_map[:x] + 1
|
1035
|
+
end
|
1036
|
+
end
|
1037
|
+
puts "#{shape_maps.size} shapes to render..."; $stdout.flush
|
1038
|
+
|
1039
|
+
puts 'Rendering image...'; $stdout.flush
|
1040
|
+
|
1041
|
+
window('Basic Image', 96, 96) {
|
1042
|
+
area {
|
1043
|
+
on_draw do |area_draw_params|
|
1044
|
+
shape_maps.each do |shape_map|
|
1045
|
+
path {
|
1046
|
+
rectangle(shape_map[:x], shape_map[:y], shape_map[:width], shape_map[:height])
|
1047
|
+
|
1048
|
+
fill shape_map[:color]
|
1049
|
+
}
|
1050
|
+
end
|
1051
|
+
end
|
1052
|
+
}
|
1053
|
+
}.show
|
1054
|
+
```
|
1055
|
+
|
1056
|
+
One final note is that in Linux, table images grow and shrink with the image size unlike on the Mac where table row heights are constant regardless of image sizes. As such, you may be able to repurpose a table with a single image column and a single row as an image control with more native libui rendering if you are only targeting Linux with your app.
|
1057
|
+
|
1058
|
+
Check out [examples/basic_image.rb](#basic-image) (all versions) for examples of using `image` Glimmer custom control.
|
1059
|
+
|
1060
|
+
#### Colors
|
1061
|
+
|
1062
|
+
`fill` and `stroke` accept [X11](https://en.wikipedia.org/wiki/X11_color_names) color `Symbol`s/`String`s like `:skyblue` and `'sandybrown'` or 6-char hex or 3-char hex-shorthand (as `Integer` or `String` with or without `0x` prefix)
|
1063
|
+
|
1064
|
+
Available [X11 colors](https://en.wikipedia.org/wiki/X11_color_names) can be obtained through `Glimmer::LibUI.x11_colors` method.
|
1065
|
+
|
1066
|
+
Check [Basic Transform](#basic-transform) example for use of [X11](https://en.wikipedia.org/wiki/X11_color_names) colors.
|
1067
|
+
|
1068
|
+
Check [Histogram](#histogram) example for use of hex colors.
|
1069
|
+
|
1070
|
+
#### Area Draw Params
|
1071
|
+
|
785
1072
|
The `area_draw_params` argument for `on_draw` block is a hash consisting of the following keys:
|
786
1073
|
- `:context`: the drawing context object
|
787
1074
|
- `:area_width`: area width
|
@@ -793,7 +1080,9 @@ The `area_draw_params` argument for `on_draw` block is a hash consisting of the
|
|
793
1080
|
|
794
1081
|
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 dynamic paths that need maximum performance and low memory footprint.
|
795
1082
|
|
796
|
-
|
1083
|
+
#### Area Listeners
|
1084
|
+
|
1085
|
+
`area` supported listeners are:
|
797
1086
|
- `on_key_event {|area_key_event| ...}`: general catch-all key event (recommend using fine-grained key events below instead)
|
798
1087
|
- `on_key_down {|area_key_event| ...}`
|
799
1088
|
- `on_key_up {|area_key_event| ...}`
|
@@ -821,14 +1110,14 @@ The `area_mouse_event` `Hash` argument for mouse events that receive it (e.g. `o
|
|
821
1110
|
|
822
1111
|
The `area_key_event` `Hash` argument for keyboard events that receive it (e.g. `on_key_up`, `on_key_down`) consist of the following hash keys:
|
823
1112
|
- `:key`: key character (`String`)
|
824
|
-
- `:key_value`: key value (`Integer`). Useful in rare cases for numeric processing of keys instead of dealing with as `:key` character `String`
|
1113
|
+
- `:key_value` (alias: `:key_code`): key code value (`Integer`). Useful in rare cases for numeric processing of keys instead of dealing with as `:key` character `String`
|
825
1114
|
- `:ext_key`: non-character extra key (`Symbol`) from `Glimmer::LibUI.enum_symbols(:ext_key)` such as `:left`, `:right`, `:escape`, `:insert`
|
826
1115
|
- `:ext_key_value`: non-character extra key value (`Integer`). Useful in rare cases for numeric processing of extra keys instead of dealing with as `:ext_key` `Symbol`
|
827
1116
|
- `:modifier`: modifier key pressed alone (e.g. `:shift` or `:control`)
|
828
1117
|
- `:modifiers`: modifier keys pressed simultaneously with `:key`, `:ext_key`, or `:modifier`
|
829
1118
|
- `:up`: indicates if key has been released or not (Boolean)
|
830
1119
|
|
831
|
-
|
1120
|
+
#### Area Methods/Attributes
|
832
1121
|
|
833
1122
|
To redraw an `area`, you may call the `#queue_redraw_all` method, or simply `#redraw`.
|
834
1123
|
|
@@ -838,6 +1127,8 @@ To redraw an `area`, you may call the `#queue_redraw_all` method, or simply `#re
|
|
838
1127
|
- `resume_auto_redraw`: resume auto redraw upon changes to nested stable `path` or shapes
|
839
1128
|
- `auto_redraw_enabled`/`auto_redraw_enabled?`/`auto_redraw_enabled=`: an attribute to disable/enable auto redraw on an `area` upon changes to nested stable `path` or shapes
|
840
1129
|
|
1130
|
+
#### Area Transform Matrix
|
1131
|
+
|
841
1132
|
A transform `matrix` can be set on a path by building a `matrix(m11 = nil, m12 = nil, m21 = nil, m22 = nil, m31 = nil, m32 = nil) {operations}` proxy object and then setting via `transform` property, or alternatively by building and setting the matrix in one call to `transform(m11 = nil, m12 = nil, m21 = nil, m22 = nil, m31 = nil, m32 = nil) {operations}` passing it the matrix arguments and/or content operations.
|
842
1133
|
|
843
1134
|
When instantiating a `matrix` object, it always starts with identity matrix.
|
@@ -901,64 +1192,9 @@ transform m1
|
|
901
1192
|
# and then reuse m1 elsewhere too
|
902
1193
|
```
|
903
1194
|
|
904
|
-
|
905
|
-
|
906
|
-
`fill` and `stroke` accept [X11](https://en.wikipedia.org/wiki/X11_color_names) color `Symbol`s/`String`s like `:skyblue` and `'sandybrown'` or 6-number hex or 3-number hex-shorthand (as `Integer` or `String` with or without `0x` prefix)
|
907
|
-
|
908
|
-
Available [X11 colors](https://en.wikipedia.org/wiki/X11_color_names) can be obtained through `Glimmer::LibUI.x11_colors` method.
|
909
|
-
|
910
|
-
Check [Basic Transform](#basic-transform) example for use of [X11](https://en.wikipedia.org/wiki/X11_color_names) colors.
|
911
|
-
|
912
|
-
Check [Histogram](#histogram) example for use of hex colors.
|
913
|
-
|
914
|
-
To draw `text` in an `area`, you simply nest a `text(x, y, width)` control directly under `area` or inside a `on_draw` listener, and then nest attributed `string {[attributes]; string_value}` controls underneath it returning an actual `String` (think of them as the `<span>` or `<p>` element in html, which contains a string of text). Alternatively, you can nest attributed `string(string_value) {[attributes]}` if `string_value` is a short single-line string. An attributed `string` value can be changed dynamically via its `string` property.
|
1195
|
+
You can set a `matrix`/`transform` on `area` directly to conveniently apply to all nested `path`s too.
|
915
1196
|
|
916
|
-
`
|
917
|
-
- `default_font`:
|
918
|
-
- `align`: `:left` (default), `:center`, or `:right` (`align` currently seems not to work on the Mac)
|
919
|
-
- `x`: x coordinate in relation to parent `area` top-left corner
|
920
|
-
- `y`: y coordinate in relation to parent `area` top-left corner
|
921
|
-
- `width` (default: area width - x*2): width of text to display
|
922
|
-
|
923
|
-
`string` has the following properties:
|
924
|
-
- `font`: font descriptor hash consisting of `:family`, `:size`, `:weight` (`[:minimum, :thin, :ultra_light, :light, :book, :normal, :medium, :semi_bold, :bold, :ultra_bold, :heavy, :ultra_heavy, :maximum]`), `:italic` (`[:normal, :oblique, :italic]`), and `:stretch` (`[:ultra_condensed, :extra_condensed, :condensed, :semi_condensed, :normal, :semi_expanded, :expanded, :extra_expanded, :ultra_expanded]`) key values
|
925
|
-
- `color`: rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
926
|
-
- `background`: rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
927
|
-
- `underline`: one of `:none`, `:single`, `:double`, `:suggestion`, `:color_custom`, `:color_spelling`, `:color_grammar`, `:color_auxiliary`
|
928
|
-
- `underline_color`: one of `:spelling`, `:grammar`, `:auxiliary`, rgba, hex, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color
|
929
|
-
- `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.
|
930
|
-
- `string`: string value (`String`)
|
931
|
-
|
932
|
-
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
933
|
-
|
934
|
-
```ruby
|
935
|
-
window('area text drawing') {
|
936
|
-
area {
|
937
|
-
text {
|
938
|
-
default_font family: 'Helvetica', size: 12, weight: :normal, italic: :normal, stretch: :normal
|
939
|
-
|
940
|
-
string {
|
941
|
-
font family: 'Georgia', size: 13, weight: :medium, italic: :normal, stretch: :normal
|
942
|
-
color r: 230, g: 100, b: 50, a: 0.5
|
943
|
-
background r: 230, g: 200, b: 250, a: 0.8
|
944
|
-
underline :single
|
945
|
-
underline_color :spelling
|
946
|
-
open_type_features {
|
947
|
-
open_type_tag 'l', 'i', 'g', 'a', 0
|
948
|
-
open_type_tag 'l', 'i', 'g', 'a', 1
|
949
|
-
}
|
950
|
-
|
951
|
-
"This is a demonstration\n" \
|
952
|
-
"of a very long\n" \
|
953
|
-
"attributed string\n" \
|
954
|
-
"spanning multiple lines\n\n"
|
955
|
-
}
|
956
|
-
|
957
|
-
string('This is a short unattributed string')
|
958
|
-
}
|
959
|
-
}
|
960
|
-
}.show
|
961
|
-
```
|
1197
|
+
Note that `area`, `path`, and nested shapes are all truly declarative, meaning they do not care about the ordering of calls to `fill`, `stroke`, and `transform`. Furthermore, any transform that is applied is reversed at the end of the block, so you never have to worry about the ordering of `transform` calls among different paths. You simply set a transform on the `path`s that need it and it is guaranteed to be called before all its content is drawn, and then undone afterwards to avoid affecting later paths. Matrix `transform` can be set on an entire `area` too, applying to all nested `path`s.
|
962
1198
|
|
963
1199
|
### Smart Defaults and Conventions
|
964
1200
|
|
@@ -982,7 +1218,7 @@ window('area text drawing') {
|
|
982
1218
|
- When destroying a control nested under a `form`, it is automatically deleted from the form's children
|
983
1219
|
- When destroying a control nested under a `window` or `group`, it is automatically unset as their child to allow successful destruction
|
984
1220
|
- For `date_time_picker`, `date_picker`, and `time_picker`, make sure `time` hash values for `mon`, `wday`, and `yday` are 1-based instead of [libui](https://github.com/andlabs/libui) original 0-based values, and return `dst` as Boolean instead of `isdst` as `1`/`0`
|
985
|
-
- Smart defaults for `grid` child
|
1221
|
+
- Smart defaults for `grid` child properties are `left` (`0`), `top` (`0`), `xspan` (`1`), `yspan` (`1`), `hexpand` (`false`), `halign` (`:fill`), `vexpand` (`false`), and `valign` (`:fill`)
|
986
1222
|
- The `table` control automatically constructs required `TableModelHandler`, `TableModel`, and `TableParams`, calculating all their arguments from `cell_rows` and `editable` properties (e.g. `NumRows`) as well as nested columns (e.g. `text_column`)
|
987
1223
|
- Table model instances are automatically freed from memory after `window` is destroyed.
|
988
1224
|
- Table `cell_rows` data has implicit data-binding to table cell values for deletion, insertion, and change (done by diffing `cell_rows` value before and after change and auto-informing `table` of deletions [`LibUI.table_model_row_deleted`], insertions [`LibUI.table_model_row_deleted`], and changes [`LibUI.table_model_row_changed`]). When deleting data rows from `cell_rows` array, then actual rows from the `table` are automatically deleted. When inserting data rows into `cell_rows` array, then actual `table` rows are automatically inserted. When updating data rows in `cell_rows` array, then actual `table` rows are automatically updated.
|
@@ -996,7 +1232,7 @@ window('area text drawing') {
|
|
996
1232
|
- All controls are protected from garbage collection until no longer needed (explicitly destroyed), so there is no need to worry about surprises.
|
997
1233
|
- All resources are freed automatically once no longer needed or left to garbage collection.
|
998
1234
|
- When nesting an `area` directly underneath `window` (without a layout control like `vertical_box`), it is automatically reparented with `vertical_box` in between the `window` and `area` since it would not show up on Linux otherwise.
|
999
|
-
- 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-
|
1235
|
+
- 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-char hex or 3-char hex (as `Integer` or `String` with or without `0x` prefix)
|
1000
1236
|
- Color alpha value defaults to `1.0` when not specified.
|
1001
1237
|
|
1002
1238
|
### Custom Keywords
|
@@ -1110,7 +1346,8 @@ window('Method-Based Custom Keyword') {
|
|
1110
1346
|
### API Gotchas
|
1111
1347
|
|
1112
1348
|
- 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`).
|
1113
|
-
- `table` `checkbox_column`
|
1349
|
+
- `table` `checkbox_column` checkbox editing only works on Linux and Windows (not Mac) due to a current limitation in [libui](https://github.com/andlabs/ui/issues/357).
|
1350
|
+
- `table` `checkbox_text_column` checkbox editing only works on Linux (not Mac or Windows) due to a current limitation in [libui](https://github.com/andlabs/ui/issues/357).
|
1114
1351
|
- `text` `align` property seems not to work on the Mac ([libui](https://github.com/andlabs/libui) has an [issue](https://github.com/andlabs/libui/pull/407) about it)
|
1115
1352
|
- `text` `string` `background` does not work on Windows due to an [issue in libui](https://github.com/andlabs/libui/issues/347).
|
1116
1353
|
- `table` controls on Windows intentionally get an extra empty row at the end because if any row were to be deleted for the first time, double-deletion happens due to an issue in [libui](https://github.com/andlabs/libui) on Windows.
|
@@ -1760,11 +1997,11 @@ class TinyMidiPlayer
|
|
1760
1997
|
|
1761
1998
|
UI.new_horizontal_box.tap do |hbox|
|
1762
1999
|
UI.new_vertical_box.tap do |vbox|
|
1763
|
-
UI.new_button('âÃÃâ€
|
2000
|
+
UI.new_button('â–¶').tap do |button1|
|
1764
2001
|
UI.button_on_clicked(button1) { play_midi }
|
1765
2002
|
UI.box_append(vbox, button1, 1)
|
1766
2003
|
end
|
1767
|
-
UI.new_button('âÃÃâ€
|
2004
|
+
UI.new_button('â– ').tap do |button2|
|
1768
2005
|
UI.button_on_clicked(button2) { stop_midi }
|
1769
2006
|
UI.box_append(vbox, button2, 1)
|
1770
2007
|
end
|
@@ -1858,12 +2095,12 @@ class TinyMidiPlayer
|
|
1858
2095
|
vertical_box {
|
1859
2096
|
stretchy false
|
1860
2097
|
|
1861
|
-
button('âÃÃâ€
|
2098
|
+
button('â–¶') {
|
1862
2099
|
on_clicked do
|
1863
2100
|
play_midi
|
1864
2101
|
end
|
1865
2102
|
}
|
1866
|
-
button('âÃÃâ€
|
2103
|
+
button('â– ') {
|
1867
2104
|
on_clicked do
|
1868
2105
|
stop_midi
|
1869
2106
|
end
|
@@ -2994,13 +3231,7 @@ window('Editable column animal sounds', 400, 200) {
|
|
2994
3231
|
|
2995
3232
|
### Basic Table Image
|
2996
3233
|
|
2997
|
-
|
2998
|
-
|
2999
|
-
```
|
3000
|
-
gem install chunky_png -v1.4.0
|
3001
|
-
```
|
3002
|
-
|
3003
|
-
Also, note that behavior varies per platform (i.e. how `table` chooses to size images by default).
|
3234
|
+
Note that behavior varies per platform (i.e. how `table` chooses to size images by default).
|
3004
3235
|
|
3005
3236
|
[examples/basic_table_image.rb](examples/basic_table_image.rb)
|
3006
3237
|
|
@@ -3114,6 +3345,41 @@ UI.quit
|
|
3114
3345
|
# NOTE:
|
3115
3346
|
# This example displays images that can be freely downloaded from the Studio Ghibli website.
|
3116
3347
|
|
3348
|
+
require 'glimmer-dsl-libui'
|
3349
|
+
|
3350
|
+
include Glimmer
|
3351
|
+
|
3352
|
+
IMAGE_ROWS = []
|
3353
|
+
|
3354
|
+
50.times do |i|
|
3355
|
+
url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
|
3356
|
+
puts "Processing Image: #{url}"; $stdout.flush # for Windows
|
3357
|
+
IMAGE_ROWS << [image(url)] # array of one column cell
|
3358
|
+
rescue StandardError => e
|
3359
|
+
warn url, e.message
|
3360
|
+
end
|
3361
|
+
|
3362
|
+
window('The Red Turtle', 310, 350, false) {
|
3363
|
+
horizontal_box {
|
3364
|
+
table {
|
3365
|
+
image_column('www.ghibli.jp/works/red-turtle')
|
3366
|
+
|
3367
|
+
cell_rows IMAGE_ROWS
|
3368
|
+
}
|
3369
|
+
}
|
3370
|
+
|
3371
|
+
on_closing do
|
3372
|
+
puts 'Bye Bye'
|
3373
|
+
end
|
3374
|
+
}.show
|
3375
|
+
```
|
3376
|
+
|
3377
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (manual construction of `image` from `image_part`):
|
3378
|
+
|
3379
|
+
```ruby
|
3380
|
+
# NOTE:
|
3381
|
+
# This example displays images that can be freely downloaded from the Studio Ghibli website.
|
3382
|
+
|
3117
3383
|
require 'glimmer-dsl-libui'
|
3118
3384
|
require 'chunky_png'
|
3119
3385
|
require 'open-uri'
|
@@ -3156,13 +3422,7 @@ window('The Red Turtle', 310, 350, false) {
|
|
3156
3422
|
|
3157
3423
|
### Basic Table Image Text
|
3158
3424
|
|
3159
|
-
|
3160
|
-
|
3161
|
-
```
|
3162
|
-
gem install chunky_png -v1.4.0
|
3163
|
-
```
|
3164
|
-
|
3165
|
-
Also, note that behavior varies per platform (i.e. how `table` chooses to size images by default).
|
3425
|
+
Note that behavior varies per platform (i.e. how `table` chooses to size images by default).
|
3166
3426
|
|
3167
3427
|
[examples/basic_table_image_text.rb](examples/basic_table_image_text.rb)
|
3168
3428
|
|
@@ -3196,6 +3456,42 @@ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version
|
|
3196
3456
|
# NOTE:
|
3197
3457
|
# This example displays images that can be freely downloaded from the Studio Ghibli website.
|
3198
3458
|
|
3459
|
+
require 'glimmer-dsl-libui'
|
3460
|
+
|
3461
|
+
include Glimmer
|
3462
|
+
|
3463
|
+
IMAGE_ROWS = []
|
3464
|
+
|
3465
|
+
5.times do |i|
|
3466
|
+
url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
|
3467
|
+
puts "Processing Image: #{url}"; $stdout.flush # for Windows
|
3468
|
+
text = url.sub('https://www.ghibli.jp/gallery/thumb-redturtle', '').sub('.png', '')
|
3469
|
+
img = image(url)
|
3470
|
+
IMAGE_ROWS << [[img, text], [img, text]] # cell values are dual-element arrays
|
3471
|
+
rescue StandardError => e
|
3472
|
+
warn url, e.message
|
3473
|
+
end
|
3474
|
+
|
3475
|
+
window('The Red Turtle', 670, 350) {
|
3476
|
+
horizontal_box {
|
3477
|
+
table {
|
3478
|
+
image_text_column('image/number')
|
3479
|
+
image_text_column('image/number (editable)') {
|
3480
|
+
editable true
|
3481
|
+
}
|
3482
|
+
|
3483
|
+
cell_rows IMAGE_ROWS
|
3484
|
+
}
|
3485
|
+
}
|
3486
|
+
}.show
|
3487
|
+
```
|
3488
|
+
|
3489
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (manual construction of `image` from `image_part`):
|
3490
|
+
|
3491
|
+
```ruby
|
3492
|
+
# NOTE:
|
3493
|
+
# This example displays images that can be freely downloaded from the Studio Ghibli website.
|
3494
|
+
|
3199
3495
|
require 'glimmer-dsl-libui'
|
3200
3496
|
require 'chunky_png'
|
3201
3497
|
require 'open-uri'
|
@@ -3482,12 +3778,6 @@ window('Task Progress', 300, 200) {
|
|
3482
3778
|
|
3483
3779
|
### Basic Table Color
|
3484
3780
|
|
3485
|
-
This example requires pre-installing `chunky_png` Ruby gem:
|
3486
|
-
|
3487
|
-
```
|
3488
|
-
gem install chunky_png -v1.4.0
|
3489
|
-
```
|
3490
|
-
|
3491
3781
|
[examples/basic_table_color.rb](examples/basic_table_color.rb)
|
3492
3782
|
|
3493
3783
|
Run with this command from the root of the project if you cloned the project:
|
@@ -3516,6 +3806,40 @@ Linux
|
|
3516
3806
|
|
3517
3807
|
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
3518
3808
|
|
3809
|
+
```ruby
|
3810
|
+
# frozen_string_literal: true
|
3811
|
+
|
3812
|
+
require 'glimmer-dsl-libui'
|
3813
|
+
|
3814
|
+
include Glimmer
|
3815
|
+
|
3816
|
+
img = image(File.expand_path('../icons/glimmer.png', __dir__), 24, 24)
|
3817
|
+
|
3818
|
+
data = [
|
3819
|
+
[['cat', :red] , ['meow', :blue] , [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], {r: 255, g: 120, b: 0, a: 0.5}],
|
3820
|
+
[['dog', :yellow] , ['woof', {r: 240, g: 32, b: 32}] , [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], :skyblue],
|
3821
|
+
[['chicken', :beige], ['cock-a-doodle-doo', :blue] , [false, 'mammal', :red] , [img, 'Glimmer', :beige], {r: 5, g: 120, b: 110}],
|
3822
|
+
[['horse', :purple] , ['neigh', {r: 240, g: 32, b: 32}], [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], '13a1fb'],
|
3823
|
+
[['cow', :gray] , ['moo', :blue] , [true, 'mammal', :green], [img, 'Glimmer', :brown], 0x12ff02]
|
3824
|
+
]
|
3825
|
+
|
3826
|
+
window('Animals', 500, 200) {
|
3827
|
+
horizontal_box {
|
3828
|
+
table {
|
3829
|
+
text_color_column('Animal')
|
3830
|
+
text_color_column('Sound')
|
3831
|
+
checkbox_text_color_column('Description')
|
3832
|
+
image_text_color_column('GUI')
|
3833
|
+
background_color_column('Mammal')
|
3834
|
+
|
3835
|
+
cell_rows data
|
3836
|
+
}
|
3837
|
+
}
|
3838
|
+
}.show
|
3839
|
+
```
|
3840
|
+
|
3841
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (manual construction of [libui](https://github.com/andlabs/libui) `image` from `image_part`):
|
3842
|
+
|
3519
3843
|
```ruby
|
3520
3844
|
require 'glimmer-dsl-libui'
|
3521
3845
|
require 'chunky_png'
|
@@ -4723,6 +5047,200 @@ window('Area Gallery', 400, 400) {
|
|
4723
5047
|
}.show
|
4724
5048
|
```
|
4725
5049
|
|
5050
|
+
### Basic Image
|
5051
|
+
|
5052
|
+
[examples/basic_image.rb](examples/basic_image.rb)
|
5053
|
+
|
5054
|
+
Run with this command from the root of the project if you cloned the project:
|
5055
|
+
|
5056
|
+
```
|
5057
|
+
ruby -r './lib/glimmer-dsl-libui' examples/basic_image.rb
|
5058
|
+
```
|
5059
|
+
|
5060
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
5061
|
+
|
5062
|
+
```
|
5063
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/basic_image'"
|
5064
|
+
```
|
5065
|
+
|
5066
|
+
Mac
|
5067
|
+
|
5068
|
+
![glimmer-dsl-libui-mac-basic-image.png](images/glimmer-dsl-libui-mac-basic-image.png)
|
5069
|
+
|
5070
|
+
Windows
|
5071
|
+
|
5072
|
+
![glimmer-dsl-libui-windows-basic-image.png](images/glimmer-dsl-libui-windows-basic-image.png)
|
5073
|
+
|
5074
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
5075
|
+
|
5076
|
+
```ruby
|
5077
|
+
require 'glimmer-dsl-libui'
|
5078
|
+
|
5079
|
+
include Glimmer
|
5080
|
+
|
5081
|
+
window('Basic Image', 96, 96) {
|
5082
|
+
area {
|
5083
|
+
# image is not a real LibUI control. It is built in Glimmer as a custom control that renders
|
5084
|
+
# tiny pixels/lines as rectangle paths. As such, it does not have good performance, but can
|
5085
|
+
# be used in exceptional circumstances where an image control is really needed.
|
5086
|
+
#
|
5087
|
+
# Furthermore, adding image directly under area is even slower due to taking up more memory for every
|
5088
|
+
# image pixel rendered. Check basic_image2.rb for a faster alternative using on_draw manually.
|
5089
|
+
#
|
5090
|
+
# It is recommended to pass width/height args to shrink image and achieve faster performance.
|
5091
|
+
image(File.expand_path('../icons/glimmer.png', __dir__), 96, 96)
|
5092
|
+
}
|
5093
|
+
}.show
|
5094
|
+
```
|
5095
|
+
|
5096
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (better performance via `on_draw`):
|
5097
|
+
|
5098
|
+
```ruby
|
5099
|
+
# frozen_string_literal: true
|
5100
|
+
|
5101
|
+
require 'glimmer-dsl-libui'
|
5102
|
+
|
5103
|
+
include Glimmer
|
5104
|
+
|
5105
|
+
window('Basic Image', 96, 96) {
|
5106
|
+
area {
|
5107
|
+
on_draw do |area_draw_params|
|
5108
|
+
image(File.expand_path('../icons/glimmer.png', __dir__), 96, 96)
|
5109
|
+
end
|
5110
|
+
}
|
5111
|
+
}.show
|
5112
|
+
```
|
5113
|
+
|
5114
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3 (explicit properties):
|
5115
|
+
|
5116
|
+
```ruby
|
5117
|
+
# frozen_string_literal: true
|
5118
|
+
|
5119
|
+
require 'glimmer-dsl-libui'
|
5120
|
+
|
5121
|
+
include Glimmer
|
5122
|
+
|
5123
|
+
window('Basic Image', 96, 96) {
|
5124
|
+
area {
|
5125
|
+
# image is not a real LibUI control. It is built in Glimmer as a custom control that renders
|
5126
|
+
# tiny pixels/lines as rectangle paths. As such, it does not have good performance, but can
|
5127
|
+
# be used in exceptional circumstances where an image control is really needed.
|
5128
|
+
#
|
5129
|
+
# Furthermore, adding image directly under area is even slower due to taking up more memory for every
|
5130
|
+
# image pixel rendered. Check basic_image4.rb for a faster alternative using on_draw manually.
|
5131
|
+
#
|
5132
|
+
# It is recommended to pass width/height args to shrink image and achieve faster performance.
|
5133
|
+
image {
|
5134
|
+
file File.expand_path('../icons/glimmer.png', __dir__)
|
5135
|
+
width 96
|
5136
|
+
height 96
|
5137
|
+
}
|
5138
|
+
}
|
5139
|
+
}.show
|
5140
|
+
```
|
5141
|
+
|
5142
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 4 (better performance with `on_draw` when setting explicit properties):
|
5143
|
+
|
5144
|
+
```ruby
|
5145
|
+
# frozen_string_literal: true
|
5146
|
+
|
5147
|
+
require 'glimmer-dsl-libui'
|
5148
|
+
|
5149
|
+
include Glimmer
|
5150
|
+
|
5151
|
+
window('Basic Image', 96, 96) {
|
5152
|
+
area {
|
5153
|
+
on_draw do |area_draw_params|
|
5154
|
+
image {
|
5155
|
+
file File.expand_path('../icons/glimmer.png', __dir__)
|
5156
|
+
width 96
|
5157
|
+
height 96
|
5158
|
+
}
|
5159
|
+
end
|
5160
|
+
}
|
5161
|
+
}.show
|
5162
|
+
```
|
5163
|
+
|
5164
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 5 (fully manual pixel-by-pixel rendering):
|
5165
|
+
|
5166
|
+
```ruby
|
5167
|
+
# frozen_string_literal: true
|
5168
|
+
|
5169
|
+
# This is the manual way of rendering an image unto an area control.
|
5170
|
+
# It could come in handy in special situations.
|
5171
|
+
# Otherwise, it is recommended to simply utilize the `image` control that
|
5172
|
+
# can be nested under area or area on_draw listener to automate all this work.
|
5173
|
+
|
5174
|
+
require 'glimmer-dsl-libui'
|
5175
|
+
require 'chunky_png'
|
5176
|
+
|
5177
|
+
include Glimmer
|
5178
|
+
|
5179
|
+
puts 'Parsing image...'; $stdout.flush
|
5180
|
+
|
5181
|
+
f = File.open(File.expand_path('../icons/glimmer.png', __dir__))
|
5182
|
+
canvas = ChunkyPNG::Canvas.from_io(f)
|
5183
|
+
f.close
|
5184
|
+
canvas.resample_nearest_neighbor!(96, 96)
|
5185
|
+
data = canvas.to_rgba_stream
|
5186
|
+
width = canvas.width
|
5187
|
+
height = canvas.height
|
5188
|
+
puts "Image width: #{width}"
|
5189
|
+
puts "Image height: #{height}"
|
5190
|
+
|
5191
|
+
puts 'Parsing colors...'; $stdout.flush
|
5192
|
+
|
5193
|
+
color_maps = height.times.map do |y|
|
5194
|
+
width.times.map do |x|
|
5195
|
+
r = data[(y*width + x)*4].ord
|
5196
|
+
g = data[(y*width + x)*4 + 1].ord
|
5197
|
+
b = data[(y*width + x)*4 + 2].ord
|
5198
|
+
a = data[(y*width + x)*4 + 3].ord
|
5199
|
+
{x: x, y: y, color: {r: r, g: g, b: b, a: a}}
|
5200
|
+
end
|
5201
|
+
end.flatten
|
5202
|
+
puts "#{color_maps.size} pixels to render..."; $stdout.flush
|
5203
|
+
|
5204
|
+
puts 'Parsing shapes...'; $stdout.flush
|
5205
|
+
|
5206
|
+
shape_maps = []
|
5207
|
+
original_color_maps = color_maps.dup
|
5208
|
+
indexed_original_color_maps = Hash[original_color_maps.each_with_index.to_a]
|
5209
|
+
color_maps.each do |color_map|
|
5210
|
+
index = indexed_original_color_maps[color_map]
|
5211
|
+
@rectangle_start_x ||= color_map[:x]
|
5212
|
+
@rectangle_width ||= 1
|
5213
|
+
if color_map[:x] < width - 1 && color_map[:color] == original_color_maps[index + 1][:color]
|
5214
|
+
@rectangle_width += 1
|
5215
|
+
else
|
5216
|
+
if color_map[:x] > 0 && color_map[:color] == original_color_maps[index - 1][:color]
|
5217
|
+
shape_maps << {x: @rectangle_start_x, y: color_map[:y], width: @rectangle_width, height: 1, color: color_map[:color]}
|
5218
|
+
else
|
5219
|
+
shape_maps << {x: color_map[:x], y: color_map[:y], width: 1, height: 1, color: color_map[:color]}
|
5220
|
+
end
|
5221
|
+
@rectangle_width = 1
|
5222
|
+
@rectangle_start_x = color_map[:x] == width - 1 ? 0 : color_map[:x] + 1
|
5223
|
+
end
|
5224
|
+
end
|
5225
|
+
puts "#{shape_maps.size} shapes to render..."; $stdout.flush
|
5226
|
+
|
5227
|
+
puts 'Rendering image...'; $stdout.flush
|
5228
|
+
|
5229
|
+
window('Basic Image', 96, 96) {
|
5230
|
+
area {
|
5231
|
+
on_draw do |area_draw_params|
|
5232
|
+
shape_maps.each do |shape_map|
|
5233
|
+
path {
|
5234
|
+
rectangle(shape_map[:x], shape_map[:y], shape_map[:width], shape_map[:height])
|
5235
|
+
|
5236
|
+
fill shape_map[:color]
|
5237
|
+
}
|
5238
|
+
end
|
5239
|
+
end
|
5240
|
+
}
|
5241
|
+
}.show
|
5242
|
+
```
|
5243
|
+
|
4726
5244
|
### Histogram
|
4727
5245
|
|
4728
5246
|
[examples/histogram.rb](examples/histogram.rb)
|