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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7aaaa95f0efdd3c1dd3dcc5ceb961e6f643d3df62a7145fce68da5dee977bcc6
4
- data.tar.gz: 410b8273b462a9ad76dc7485d4183c0be08be62c60bd64f92a7b7aa974692e5d
3
+ metadata.gz: 5bc0120584b295401bc245af8ff7110fb332dc74a2f2a60d67be31ccace6f615
4
+ data.tar.gz: d456fb5265a0d11c09aede73c9b2930a00710d9696a99f8b91bc180f53b8d153
5
5
  SHA512:
6
- metadata.gz: f04981d43dc57f873da61bd77166d16b519b408a4b11b3695a1f82670e8502eab328d19c4bef60cab5549eae25b6a813ec0ca40342c65b2597c1a9b315ce3014
7
- data.tar.gz: f714acf1968782069530c9ebce6c260080a12bb664d5218e84ec10f86250152e2e0abbc0b48e98c435da46e8915f858ff6e16a241009b0564cb8ebbb8f018c65
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.9
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
- - Scaffolding for new custom controls, apps, and gems
20
- - Native-Executable packaging on Mac, Windows, and Linux.
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
- fill r: 204, g: 102, b: 204
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
- path { # declarative stable path
127
- arc(400, 220, 180, 90, 90, false)
128
-
129
- fill r: 204, g: 102, b: 204, a: 0.5
130
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
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 early alpha mode (only supports included [examples](#examples)). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
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.9](#-glimmer-dsl-for-libui-029)
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.9'
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`), `stroke` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, `:cap` as (`:round`, `:square`, `:flat`), `:join` as (`:miter`, `:round`, `:bevel`), `:thickness` as `Numeric`, `:miter_limit` as `Numeric`, `:dashes` as `Array` of `Numeric` ) | None
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`: it must have a block containing `open_type_tag` occurrances, which take the a, b, c, d arguments plus a number at the end.
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
- check out the [libui C headers](https://github.com/andlabs/libui/blob/master/ui.h)
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
- @rbs = radio_buttons {
1109
+ stretchy false
1110
+
1111
+ @example_radio_buttons = radio_buttons {
969
1112
  stretchy false
970
- items examples
971
- selected 0
1113
+ items examples_with_versions
1114
+ selected @selected_example_index
972
1115
 
973
1116
  on_selected do
974
- @nwme.text = File.read(file_path_for(@examples[@rbs.selected]))
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
- button('Launch') {
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
- on_clicked do
981
- begin
982
- meta_example_file = File.join(Dir.home, '.meta_example.rb')
983
- File.write(meta_example_file, @nwme.text)
984
- result = `ruby -r #{glimmer_dsl_libui_file} #{meta_example_file} 2>&1`
985
- msg_box('Error Running Example', result) if result.include?('error')
986
- rescue => e
987
- puts 'Unable to write code changes! Running original example...'
988
- system "ruby -r #{glimmer_dsl_libui_file} #{file_path_for(@examples[@rbs.selected])}"
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
- end
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
- vertical_box {
994
- @nwme = non_wrapping_multiline_entry {
995
- text File.read(file_path_for(@examples[@rbs.selected]))
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
- fill r: 204, g: 102, b: 204
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
- path { # declarative stable path
3693
- arc(400, 220, 180, 90, 90, false)
3694
-
3695
- fill r: 204, g: 102, b: 204, a: 0.5
3696
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
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
- fill r: 204, g: 102, b: 204
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
- fill r: 204, g: 102, b: 204, a: 0.5
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
- fill r: 204, g: 102, b: 204
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
- path { # a dynamic path is added semi-declaratively inside on_draw block
3977
- arc(400, 220, 180, 90, 90, false)
3978
-
3979
- fill r: 204, g: 102, b: 204, a: 0.5
3980
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
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
- fill r: 204, g: 102, b: 204
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
- fill r: 204, g: 102, b: 204, a: 0.5
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.9
1
+ 0.2.10
@@ -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
- fill r: 204, g: 102, b: 204
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
- path { # declarative stable path
50
- arc(400, 220, 180, 90, 90, false)
51
-
52
- fill r: 204, g: 102, b: 204, a: 0.5
53
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
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|
@@ -32,7 +32,8 @@ window('Area Gallery', 400, 400) {
32
32
  height 100
33
33
  }
34
34
 
35
- fill r: 204, g: 102, b: 204
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
- fill r: 204, g: 102, b: 204, a: 0.5
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
@@ -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
- fill r: 204, g: 102, b: 204
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
- path { # a dynamic path is added semi-declaratively inside on_draw block
51
- arc(400, 220, 180, 90, 90, false)
52
-
53
- fill r: 204, g: 102, b: 204, a: 0.5
54
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
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
 
@@ -33,7 +33,8 @@ window('Area Gallery', 400, 400) {
33
33
  height 100
34
34
  }
35
35
 
36
- fill r: 204, g: 102, b: 204
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
- fill r: 204, g: 102, b: 204, a: 0.5
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|
@@ -6,6 +6,8 @@ include Glimmer
6
6
 
7
7
  window('color button', 230) {
8
8
  color_button { |cb|
9
+ color :blue
10
+
9
11
  on_changed do
10
12
  rgba = cb.color
11
13
  p rgba
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 Name') {
29
+ button('Display Info') {
30
+ stretchy false
31
+
22
32
  on_clicked do
23
- msg_box('Name', "#{@first_name_entry.text} #{@last_name_entry.text}")
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
  }
@@ -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
- @rbs = radio_buttons {
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 = @rbs.selected
69
+ @selected_example_index = @example_radio_buttons.selected
60
70
  example = selected_example
61
- @nwme.text = File.read(file_path_for(example))
62
- @sb.value = 1
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
- @sb = spinbox(1, 100) {
81
+ @version_spinbox = spinbox(1, 100) {
72
82
  value 1
73
83
 
74
84
  on_changed do
75
85
  example = selected_example
76
- if @sb.value > version_count_for(example)
77
- @sb.value -= 1
86
+ if @version_spinbox.value > version_count_for(example)
87
+ @version_spinbox.value -= 1
78
88
  else
79
- version_number = @sb.value == 1 ? '' : @sb.value
89
+ version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
80
90
  example = "#{selected_example}#{version_number}"
81
- @nwme.text = File.read(file_path_for(example))
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, @nwme.text)
95
- result = `ruby -r #{glimmer_dsl_libui_file} #{meta_example_file} 2>&1`
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
- system "ruby -r #{glimmer_dsl_libui_file} #{file_path_for(selected_example)}"
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
- @nwme.text = File.read(file_path_for(selected_example))
115
+ @code_entry.text = File.read(file_path_for(selected_example))
106
116
  end
107
117
  }
108
118
  }
109
119
  }
110
120
 
111
- @nwme = non_wrapping_multiline_entry {
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
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.R = (draw_brush_args[:r] || draw_brush_args[:red]).to_f / 255.0
154
- draw_brush.G = (draw_brush_args[:g] || draw_brush_args[:green]).to_f / 255.0
155
- draw_brush.B = (draw_brush_args[:b] || draw_brush_args[:blue]).to_f / 255.0
156
- draw_brush.A = (draw_brush_args[:a] || draw_brush_args[:alpha])
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.9
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-07 00:00:00.000000000 Z
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