glimmer-dsl-wx 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +482 -101
- data/VERSION +1 -1
- data/bin/girb +1 -1
- data/bin/girb_runner.rb +1 -1
- data/glimmer-dsl-wx.gemspec +0 -0
- data/lib/glimmer/dsl/wx/about_box_expression.rb +1 -1
- data/lib/glimmer/dsl/wx/bind_expression.rb +16 -16
- data/lib/glimmer/dsl/wx/control_expression.rb +1 -1
- data/lib/glimmer/dsl/wx/data_binding_expression.rb +25 -25
- data/lib/glimmer/dsl/wx/dsl.rb +5 -7
- data/lib/glimmer/dsl/wx/listener_expression.rb +1 -1
- data/lib/glimmer/dsl/wx/observe_expression.rb +1 -1
- data/lib/glimmer/dsl/wx/operation_expression.rb +23 -27
- data/lib/glimmer/dsl/wx/property_expression.rb +10 -3
- data/lib/glimmer/dsl/wx/shine_data_binding_expression.rb +23 -22
- data/lib/glimmer/dsl/wx/sizer_addable_expression.rb +42 -0
- data/lib/glimmer/dsl/wx/sizer_args_expression.rb +5 -2
- data/lib/glimmer/dsl/wx/sizer_expression.rb +1 -1
- data/lib/glimmer/wx/control_proxy/frame_proxy.rb +1 -1
- data/lib/glimmer/wx/control_proxy/slider_proxy.rb +55 -0
- data/lib/glimmer/wx/control_proxy/spin_ctrl_double_proxy.rb +41 -0
- data/lib/glimmer/wx/control_proxy/spin_ctrl_proxy.rb +41 -0
- data/lib/glimmer/wx/control_proxy/text_ctrl_proxy.rb +39 -0
- data/lib/glimmer/wx/control_proxy.rb +3 -3
- data/lib/glimmer/wx/data_bindable.rb +1 -1
- data/lib/glimmer/wx/parent.rb +1 -1
- data/lib/glimmer/wx/sizer_proxy.rb +17 -1
- data/lib/glimmer-dsl-wx.rb +1 -1
- data/samples/hello/hello_button.rb +1 -1
- data/samples/hello/hello_button2.rb +1 -1
- data/samples/hello/hello_data_binding.rb +126 -0
- data/samples/hello/hello_sizer.rb +89 -34
- data/samples/hello/hello_world.rb +1 -1
- data/samples/hello/hello_world2.rb +1 -1
- data/samples/minimal/nothing.rb +1 -1
- metadata +20 -10
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
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 WX 0.0
|
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 WX 0.1.0
|
2
2
|
## wxWidgets Ruby Desktop Development GUI Library
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-wx.svg)](
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-wx.svg)](https://badge.fury.io/rb/glimmer-dsl-wx)
|
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)
|
5
5
|
|
6
6
|
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [WX](https://www.wxwidgets.org/) is an [MRI Ruby](https://www.ruby-lang.org) desktop development GUI (Graphical User Interface) library for the cross-platform native widget [wxWidgets](https://www.wxwidgets.org/) GUI toolkit. It provides a Glimmer GUI DSL on top of the [wxruby3](https://github.com/mcorino/wxRuby3) binding.
|
7
7
|
|
8
|
+
![Hello, Data-Binding!](/screenshots/glimmer-dsl-wx-sample-hello-data-binding.gif?raw=true)
|
9
|
+
|
8
10
|
[Glimmer DSL for WX](https://rubygems.org/gems/glimmer-dsl-wx) aims to provide a DSL similar to the [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) to enable more productive desktop development in Ruby with:
|
9
11
|
- [Declarative DSL syntax](#glimmer-gui-dsl-concepts) that visually maps to the GUI control hierarchy
|
10
12
|
- [Convention over configuration](#smart-defaults-and-conventions) via smart defaults and automation of low-level details
|
@@ -16,7 +18,244 @@
|
|
16
18
|
|
17
19
|
**Hello, World!**
|
18
20
|
|
19
|
-
|
21
|
+
```ruby
|
22
|
+
require 'glimmer-dsl-wx'
|
23
|
+
|
24
|
+
include Glimmer
|
25
|
+
|
26
|
+
frame(title: 'Hello, World!')
|
27
|
+
```
|
28
|
+
|
29
|
+
![Hello, World!](/screenshots/glimmer-dsl-wx-sample-hello-world.png?raw=true)
|
30
|
+
|
31
|
+
**Hello Button!**
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'glimmer-dsl-wx'
|
35
|
+
|
36
|
+
include Glimmer
|
37
|
+
|
38
|
+
frame { |main_frame|
|
39
|
+
title 'Hello, Button!'
|
40
|
+
|
41
|
+
h_box_sizer {
|
42
|
+
button {
|
43
|
+
sizer_args 0, Wx::RIGHT, 10
|
44
|
+
label 'Click To Find Who Built This!'
|
45
|
+
|
46
|
+
on_button do
|
47
|
+
about_box(
|
48
|
+
name: main_frame.title,
|
49
|
+
version: Wx::WXRUBY_VERSION,
|
50
|
+
description: "This is the Hello, Button! sample",
|
51
|
+
developers: ['The Glimmer DSL for WX Development Team']
|
52
|
+
)
|
53
|
+
end
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
![Hello, Button!](/screenshots/glimmer-dsl-wx-sample-hello-button.png?raw=true)
|
60
|
+
|
61
|
+
![Hello, Button! Clicked](/screenshots/glimmer-dsl-wx-sample-hello-button-clicked.png?raw=true)
|
62
|
+
|
63
|
+
Learn more about the differences between various [Glimmer](https://github.com/AndyObtiva/glimmer) DSLs by looking at the **[Glimmer DSL Comparison Table](https://github.com/AndyObtiva/glimmer#glimmer-dsl-comparison-table)**.
|
64
|
+
|
65
|
+
## Table of Contents
|
66
|
+
|
67
|
+
- [Glimmer DSL for WX](#)
|
68
|
+
- [Setup](#setup)
|
69
|
+
- [Usage](#usage)
|
70
|
+
- [GIRB (Glimmer IRB)](#girb-glimmer-irb)
|
71
|
+
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
72
|
+
- [Samples](#samples)
|
73
|
+
- [Hello, World!](#hello-world)
|
74
|
+
- [Hello, Button!](#hello-button)
|
75
|
+
- [Hello, Sizer!](#hello-sizer)
|
76
|
+
- [Hello, Data-Binding!](#hello-data-binding)
|
77
|
+
- [Coming From wxruby3](#coming-from-wxruby3)
|
78
|
+
- [Process](#process)
|
79
|
+
- [Resources](#resources)
|
80
|
+
- [Help](#help)
|
81
|
+
- [Issues](#issues)
|
82
|
+
- [Chat](#chat)
|
83
|
+
- [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
|
84
|
+
- [Change Log](#change-log)
|
85
|
+
- [Contributing](#contributing)
|
86
|
+
- [Contributors](#contributors)
|
87
|
+
- [License](#license)
|
88
|
+
|
89
|
+
## Setup
|
90
|
+
|
91
|
+
Follow instructions for installing [wxruby3](https://github.com/mcorino/wxRuby3) on a supported platform (Linux or Windows):
|
92
|
+
https://github.com/mcorino/wxRuby3/blob/master/INSTALL.md
|
93
|
+
|
94
|
+
Install [glimmer-dsl-wx](https://rubygems.org/gems/glimmer-dsl-wx) gem directly into a [maintained Ruby version](https://www.ruby-lang.org/en/downloads/):
|
95
|
+
|
96
|
+
```
|
97
|
+
gem install glimmer-dsl-wx
|
98
|
+
```
|
99
|
+
|
100
|
+
Or install via Bundler `Gemfile`:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
gem 'glimmer-dsl-wx', '~> 0.1.0'
|
104
|
+
```
|
105
|
+
|
106
|
+
Test that installation worked by running a sample:
|
107
|
+
|
108
|
+
```
|
109
|
+
ruby -r glimmer-dsl-wx -e "require 'samples/hello/hello_world'"
|
110
|
+
```
|
111
|
+
|
112
|
+
If you cloned project, test by running a sample locally:
|
113
|
+
|
114
|
+
```
|
115
|
+
ruby -r ./lib/glimmer-dsl-wx.rb samples/hello/hello_world.rb
|
116
|
+
```
|
117
|
+
|
118
|
+
## Usage
|
119
|
+
|
120
|
+
To use [glimmer-dsl-wx](https://rubygems.org/gems/glimmer-dsl-wx):
|
121
|
+
1. Add `require 'glimmer-dsl-wx'` at the top of the Ruby file (this will automatically `require 'wxruby3'` too)
|
122
|
+
2. Add `include Glimmer` into the top-level main object for testing or into an actual class for serious application usage.
|
123
|
+
3. Write GUI DSL code beginning with `frame` to build a window first and then nest other controls/sizers within it.
|
124
|
+
|
125
|
+
Example:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
require 'glimmer-dsl-wx'
|
129
|
+
|
130
|
+
include Glimmer
|
131
|
+
|
132
|
+
frame { |main_frame|
|
133
|
+
title 'Hello, Button!'
|
134
|
+
|
135
|
+
h_box_sizer {
|
136
|
+
button {
|
137
|
+
sizer_args 0, Wx::RIGHT, 10
|
138
|
+
label 'Click To Find Who Built This!'
|
139
|
+
|
140
|
+
on_button do
|
141
|
+
message_dialog(
|
142
|
+
"The Glimmer DSL for WX Team",
|
143
|
+
"Greeting",
|
144
|
+
Wx::OK | Wx::ICON_INFORMATION
|
145
|
+
).show_modal
|
146
|
+
end
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
```
|
151
|
+
|
152
|
+
![Hello, Button!](/screenshots/glimmer-dsl-wx-sample-hello-button.png?raw=true)
|
153
|
+
|
154
|
+
Glimmer DSL for WX follows these simple concepts in mapping from wxruby3 syntax to Glimmer GUI DSL syntax:
|
155
|
+
|
156
|
+
**Keyword(args)**: wxruby3 controls/sizers may be declared by lower-case underscored name. For example, `Frame` becomes `frame`. `HBoxSizer` becomes `h_box_sizer`. And, they receive the same arguments as the wxruby3 class constructor. For example, `Frame.new(title: 'Hello')` becomes `frame(title: 'Hello')`.
|
157
|
+
|
158
|
+
**Content Block** (Properties/Listeners/Controls): Any keyword may be optionally followed by a declarative Ruby curly-brace multi-line content block containing properties (attributes), listeners, and/or nested controls/sizers.
|
159
|
+
|
160
|
+
Example:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
frame(title: 'Hello, Button') {
|
164
|
+
h_box_sizer {
|
165
|
+
button(label: 'Click To Find Who Built This!')
|
166
|
+
}
|
167
|
+
}
|
168
|
+
```
|
169
|
+
|
170
|
+
Content block optionally receives one arg representing the control or sizer it represents.
|
171
|
+
|
172
|
+
Example:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
frame(title: 'Hello, Button!') { |main_frame|
|
176
|
+
h_box_sizer {
|
177
|
+
button {
|
178
|
+
sizer_args 0, Wx::RIGHT, 10
|
179
|
+
label 'Click To Find Who Built This!'
|
180
|
+
|
181
|
+
on_button do
|
182
|
+
about_box(
|
183
|
+
name: main_frame.title,
|
184
|
+
version: Wx::WXRUBY_VERSION,
|
185
|
+
description: "This is the Hello, Button! sample",
|
186
|
+
developers: ['The Glimmer DSL for WX Development Team']
|
187
|
+
)
|
188
|
+
end
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
```
|
193
|
+
|
194
|
+
**Property**: Control properties may be declared inside keyword blocks with lower-case underscored name followed by property value args (e.g. `title "Hello"` inside `frame`). Behind the scenes, properties correspond to `control.property=` methods like `frame.title=`.
|
195
|
+
|
196
|
+
Controls and sizers (objects that organize controls within certain layouts) could accept a special `sizer_args` property, which takes the arguments normally passed to the `sizer.add` method. For example, `sizer_args 0, Wx::RIGHT, 10` translates to `sizer.add(control, 0, Wx::Right, 10)` behind the scenes.
|
197
|
+
|
198
|
+
**Listener**: Control listeners may be declared inside keyword blocks with listener lower-case underscored name beginning with `on_` followed by event name (translates to `frame.evt_#{event_name}` like `frame.evt_button` for the click of a button) and receiving required block handler (always followed by a `do; end` style block to signify imperative Model logic vs declarative View control/sizer nesting).
|
199
|
+
|
200
|
+
Example:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
button('click') {
|
204
|
+
on_clicked do
|
205
|
+
puts 'clicked'
|
206
|
+
end
|
207
|
+
}
|
208
|
+
```
|
209
|
+
|
210
|
+
Optionally, the listener block can receive an arg representing the control.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
...
|
214
|
+
button {
|
215
|
+
sizer_args 0, Wx::RIGHT, 10
|
216
|
+
label 'Click To Find Who Built This!'
|
217
|
+
|
218
|
+
on_button do
|
219
|
+
# Do work!
|
220
|
+
end
|
221
|
+
}
|
222
|
+
...
|
223
|
+
```
|
224
|
+
|
225
|
+
Behind the scenes, listeners correspond to `frame.evt_#{event_name}` methods. So, for `on_button`, the event name is `button`, and that translates to `frame.evt_button(button, &listener)` behind the scenes.
|
226
|
+
|
227
|
+
**Operation**: Controls have methods that invoke certain operations on them. For example, `message_dialog` has a `#show_modal` method that shows the message dialog GUI.
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
...
|
231
|
+
message_dialog(
|
232
|
+
"The Glimmer DSL for WX Team",
|
233
|
+
"Greeting",
|
234
|
+
Wx::OK | Wx::ICON_INFORMATION
|
235
|
+
).show_modal
|
236
|
+
...
|
237
|
+
```
|
238
|
+
|
239
|
+
## GIRB (Glimmer IRB)
|
240
|
+
|
241
|
+
You can run the `girb` command (`bin/girb` if you cloned the project locally) to do some quick and dirty experimentation and learning:
|
242
|
+
|
243
|
+
```
|
244
|
+
girb
|
245
|
+
```
|
246
|
+
|
247
|
+
This gives you `irb` with the `glimmer-dsl-wx` gem loaded and the `Glimmer` module mixed into the main object for easy experimentation with GUI.
|
248
|
+
|
249
|
+
## Smart Defaults and Conventions
|
250
|
+
|
251
|
+
- Instantiate any wxWidgets control or sizer by using its underscored name (e.g. `Button` becomes `button`)
|
252
|
+
- `frame` will automatically execute within a `Wx::App.run` block and `show` the Frame
|
253
|
+
|
254
|
+
## Samples
|
255
|
+
|
256
|
+
### Hello, World!
|
257
|
+
|
258
|
+
![Hello, World!](/screenshots/glimmer-dsl-wx-sample-hello-world.png?raw=true)
|
20
259
|
|
21
260
|
```ruby
|
22
261
|
require 'glimmer-dsl-wx'
|
@@ -38,13 +277,11 @@ frame {
|
|
38
277
|
}
|
39
278
|
```
|
40
279
|
|
41
|
-
|
42
|
-
|
280
|
+
### Hello Button!
|
43
281
|
|
44
|
-
![Hello, Button!](
|
45
|
-
|
46
|
-
![Hello, Button! Clicked](https://github.com/AndyObtiva/glimmer-dsl-wx/blob/master/screenshots/glimmer-dsl-wx-sample-hello-button-clicked.png?raw=true)
|
282
|
+
![Hello, Button!](/screenshots/glimmer-dsl-wx-sample-hello-button.png?raw=true)
|
47
283
|
|
284
|
+
![Hello, Button! Clicked](/screenshots/glimmer-dsl-wx-sample-hello-button-clicked.png?raw=true)
|
48
285
|
|
49
286
|
```ruby
|
50
287
|
require 'glimmer-dsl-wx'
|
@@ -97,7 +334,11 @@ frame { |main_frame|
|
|
97
334
|
}
|
98
335
|
```
|
99
336
|
|
100
|
-
|
337
|
+
### Hello Sizer!
|
338
|
+
|
339
|
+
![Hello, Sizer!](/screenshots/glimmer-dsl-wx-sample-hello-sizer.png?raw=true)
|
340
|
+
|
341
|
+
![Hello, Sizer! Clicked](/screenshots/glimmer-dsl-wx-sample-hello-sizer-clicked.png?raw=true)
|
101
342
|
|
102
343
|
```ruby
|
103
344
|
require 'glimmer-dsl-wx'
|
@@ -107,124 +348,262 @@ include Glimmer
|
|
107
348
|
frame { |main_frame|
|
108
349
|
title 'Hello, Sizer!'
|
109
350
|
|
110
|
-
|
111
|
-
|
112
|
-
sizer_args 0, Wx::
|
113
|
-
label 'Greeting 1'
|
351
|
+
h_box_sizer {
|
352
|
+
v_box_sizer {
|
353
|
+
sizer_args 0, Wx::RIGHT, 10
|
114
354
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
355
|
+
button {
|
356
|
+
sizer_args 0, Wx::DOWN, 10
|
357
|
+
label 'Greeting 1'
|
358
|
+
|
359
|
+
on_button do
|
360
|
+
message_dialog(
|
361
|
+
"Hello",
|
362
|
+
"Greeting 1",
|
363
|
+
Wx::OK | Wx::ICON_INFORMATION
|
364
|
+
).show_modal
|
365
|
+
end
|
366
|
+
}
|
367
|
+
|
368
|
+
spacer(10)
|
127
369
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
370
|
+
button {
|
371
|
+
sizer_args 0, Wx::DOWN, 10
|
372
|
+
label 'Greeting 2'
|
373
|
+
|
374
|
+
on_button do
|
375
|
+
message_dialog(
|
376
|
+
"Howdy",
|
377
|
+
"Greeting 2",
|
378
|
+
Wx::OK | Wx::ICON_INFORMATION
|
379
|
+
).show_modal
|
380
|
+
end
|
381
|
+
}
|
382
|
+
|
383
|
+
spacer(10)
|
384
|
+
|
385
|
+
button {
|
386
|
+
sizer_args 0, Wx::DOWN, 10
|
387
|
+
label 'Greeting 3'
|
388
|
+
|
389
|
+
on_button do
|
390
|
+
message_dialog(
|
391
|
+
"Hi",
|
392
|
+
"Greeting 3",
|
393
|
+
Wx::OK | Wx::ICON_INFORMATION
|
394
|
+
).show_modal
|
395
|
+
end
|
396
|
+
}
|
135
397
|
}
|
136
398
|
|
137
|
-
|
138
|
-
sizer_args 0, Wx::
|
139
|
-
label 'Greeting 3'
|
399
|
+
v_box_sizer {
|
400
|
+
sizer_args 0, Wx::RIGHT, 10
|
140
401
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
402
|
+
button {
|
403
|
+
sizer_args 0, Wx::DOWN, 10
|
404
|
+
label 'Greeting 4'
|
405
|
+
|
406
|
+
on_button do
|
407
|
+
message_dialog(
|
408
|
+
"Ciao",
|
409
|
+
"Greeting 4",
|
410
|
+
Wx::OK | Wx::ICON_INFORMATION
|
411
|
+
).show_modal
|
412
|
+
end
|
413
|
+
}
|
414
|
+
|
415
|
+
spacer(10)
|
416
|
+
|
417
|
+
button {
|
418
|
+
sizer_args 0, Wx::DOWN, 10
|
419
|
+
label 'Greeting 5'
|
420
|
+
|
421
|
+
on_button do
|
422
|
+
message_dialog(
|
423
|
+
"Aloha",
|
424
|
+
"Greeting 5",
|
425
|
+
Wx::OK | Wx::ICON_INFORMATION
|
426
|
+
).show_modal
|
427
|
+
end
|
428
|
+
}
|
429
|
+
|
430
|
+
spacer(10)
|
431
|
+
|
432
|
+
button {
|
433
|
+
sizer_args 0, Wx::DOWN, 10
|
434
|
+
label 'Greeting 6'
|
435
|
+
|
436
|
+
on_button do
|
437
|
+
message_dialog(
|
438
|
+
"Salut",
|
439
|
+
"Greeting 6",
|
440
|
+
Wx::OK | Wx::ICON_INFORMATION
|
441
|
+
).show_modal
|
442
|
+
end
|
443
|
+
}
|
148
444
|
}
|
149
445
|
}
|
150
446
|
}
|
151
447
|
```
|
152
448
|
|
153
|
-
|
154
|
-
DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
|
155
|
-
----|-----------|---------|------------------|------|------|--------
|
156
|
-
[Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](https://github.com/AndyObtiva/glimmer-dsl-swt) | Mac / Windows / Linux | Yes | Yes (Canvas Shape DSL) | Very Mature / Scaffolding / Native Executable Packaging / Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint | Java / JRuby
|
157
|
-
[Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)](https://github.com/AndyObtiva/glimmer-dsl-opal) | All Web Browsers | No | Yes (Canvas Shape DSL) | Simpler than All JavaScript Technologies / Auto-Webify Desktop Apps | Setup Process / Only Rails 5 Support for Now | Rails
|
158
|
-
[Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-libui) | Mac / Windows / Linux | Yes | Yes (Area API) | Fast Startup Time / Light Memory Footprint | LibUI is an Incomplete Mid-Alpha Only | None Other Than MRI Ruby
|
159
|
-
[Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-tk) | Mac / Windows / Linux | Some Native-Themed Widgets (Not Truly Native) | Yes (Canvas) | Fast Startup Time / Light Memory Footprint | Complicated Setup / Widgets Do Not Look Truly Native, Espcially on Linux | ActiveTcl / MRI Ruby
|
160
|
-
[Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-gtk) | Mac / Windows / Linux | Only on Linux | Yes (Cairo) | Complete Access to GNOME Features on Linux (Forte) | Not Native on Mac and Windows | None Other Than MRI Ruby on Linux / Brew Packages on Mac / MSYS & MING Toolchains on Windows / MRI Ruby
|
161
|
-
[Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-fx) | Mac (requires XQuartz) / Windows / Linux | No | Yes (Canvas) | No Prerequisites on Windows (Forte Since Binaries Are Included Out of The Box) | Widgets Do Not Look Native / Mac Usage Obtrusively Starts XQuartz | None Other Than MRI Ruby on Windows / XQuarts on Mac / MRI Ruby
|
162
|
-
[Glimmer DSL for WX (wxWidgets Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-wx) | Mac / Windows / Linux | Yes | Yes | Fast Startup Time / Light Memory Footprint | wxruby3 is still beta and does not support Mac yet | wxWidgets library, Doxygen, and other prereqs
|
163
|
-
[Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-jfx) | Mac / Windows / Linux | No | Yes (javafx.scene.shape and javafx.scene.canvas) | Rich in Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby / JavaFX SDK
|
164
|
-
[Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-swing) | Mac / Windows / Linux | No | Yes (Java2D) | Very Mature | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby
|
165
|
-
[Glimmer DSL for XML (& HTML)](https://github.com/AndyObtiva/glimmer-dsl-xml) | All Web Browsers | No | Yes (SVG) | Programmable / Lighter-weight Than Actual XML | XML Elements Are Sometimes Not Well-Named (Many Types of Input) | None
|
166
|
-
[Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) | All Web Browsers | No | Yes | Programmable | CSS Is Over-Engineered / Too Many Features To Learn | None
|
449
|
+
### Hello Data-Binding!
|
167
450
|
|
168
|
-
|
451
|
+
Glimmer DSL for WX supports data-binding via `<=` for unidirectional data-binding and `<=>` for bidirectional data-binding.
|
169
452
|
|
170
|
-
|
171
|
-
- [Usage](#usage)
|
172
|
-
- [GIRB (Glimmer IRB)](#girb-glimmer-irb)
|
173
|
-
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
174
|
-
- [Process](#process)
|
175
|
-
- [Resources](#resources)
|
176
|
-
- [Help](#help)
|
177
|
-
- [Issues](#issues)
|
178
|
-
- [Chat](#chat)
|
179
|
-
- [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
|
180
|
-
- [Change Log](#change-log)
|
181
|
-
- [Contributing](#contributing)
|
182
|
-
- [Contributors](#contributors)
|
183
|
-
- [License](#license)
|
453
|
+
![Hello, Data-Binding!](/screenshots/glimmer-dsl-wx-sample-hello-data-binding.gif?raw=true)
|
184
454
|
|
185
|
-
|
455
|
+
```ruby
|
456
|
+
require 'glimmer-dsl-wx'
|
186
457
|
|
187
|
-
|
188
|
-
|
458
|
+
class Donor
|
459
|
+
DONATION_AMOUNT_MIN = 0
|
460
|
+
DONATION_AMOUNT_MAX = 100
|
461
|
+
DONATION_AMOUNT_DEFAULT = 50
|
462
|
+
|
463
|
+
attr_accessor :first_name, :last_name, :donation_amount
|
464
|
+
|
465
|
+
def initialize
|
466
|
+
@last_name = @first_name = ''
|
467
|
+
@donation_amount = DONATION_AMOUNT_DEFAULT
|
468
|
+
end
|
469
|
+
|
470
|
+
def full_name
|
471
|
+
full_name_parts = [first_name, last_name]
|
472
|
+
full_name_string = full_name_parts.join(' ').strip
|
473
|
+
if full_name_string.empty?
|
474
|
+
'Anonymous'
|
475
|
+
else
|
476
|
+
full_name_string
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def summary
|
481
|
+
"#{full_name} donated $#{donation_amount}"
|
482
|
+
end
|
483
|
+
end
|
189
484
|
|
190
|
-
|
485
|
+
donor = Donor.new
|
191
486
|
|
192
|
-
|
193
|
-
gem install glimmer-dsl-wx
|
194
|
-
```
|
195
|
-
|
196
|
-
Or install via Bundler `Gemfile`:
|
487
|
+
include Glimmer
|
197
488
|
|
198
|
-
|
199
|
-
|
489
|
+
frame(title: 'Hello, Data-Binding!') { |window|
|
490
|
+
panel {
|
491
|
+
v_box_sizer {
|
492
|
+
h_box_sizer {
|
493
|
+
sizer_args 0, Wx::DOWN, 10
|
494
|
+
|
495
|
+
static_text(label: 'First Name:') {
|
496
|
+
sizer_args 0, Wx::RIGHT, 10
|
497
|
+
}
|
498
|
+
text_ctrl {
|
499
|
+
sizer_args 0, Wx::RIGHT, 10
|
500
|
+
# data-bind donor.first_name to text_ctrl.value bidirectionally,
|
501
|
+
# ensuring changes to either attribute update the other attribute
|
502
|
+
value <=> [donor, :first_name]
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
h_box_sizer {
|
507
|
+
sizer_args 0, Wx::DOWN, 10
|
508
|
+
|
509
|
+
static_text(label: 'Last Name:') {
|
510
|
+
sizer_args 0, Wx::RIGHT, 10
|
511
|
+
}
|
512
|
+
text_ctrl {
|
513
|
+
sizer_args 0, Wx::RIGHT, 10
|
514
|
+
# data-bind donor.last_name to text_ctrl.value bidirectionally,
|
515
|
+
# ensuring changes to either attribute update the other attribute
|
516
|
+
value <=> [donor, :last_name]
|
517
|
+
}
|
518
|
+
}
|
519
|
+
|
520
|
+
h_box_sizer {
|
521
|
+
sizer_args 0, Wx::DOWN, 10
|
522
|
+
|
523
|
+
static_text(label: 'Donation Amount: $') {
|
524
|
+
sizer_args 0, Wx::RIGHT, 1
|
525
|
+
}
|
526
|
+
spin_ctrl {
|
527
|
+
sizer_args 0, Wx::RIGHT, 10
|
528
|
+
range Donor::DONATION_AMOUNT_MIN, Donor::DONATION_AMOUNT_MAX
|
529
|
+
# data-bind donor.donation_amount to spin_ctrl.value bidirectionally,
|
530
|
+
# ensuring changes to either attribute update the other attribute
|
531
|
+
value <=> [donor, :donation_amount]
|
532
|
+
}
|
533
|
+
}
|
534
|
+
|
535
|
+
h_box_sizer {
|
536
|
+
sizer_args 0, Wx::DOWN, 10
|
537
|
+
|
538
|
+
slider {
|
539
|
+
sizer_args 0, Wx::RIGHT, 10
|
540
|
+
range Donor::DONATION_AMOUNT_MIN, Donor::DONATION_AMOUNT_MAX
|
541
|
+
# data-bind donor.first_name to spinner.value bidirectionally,
|
542
|
+
# ensuring changes to either attribute update the other attribute
|
543
|
+
value <=> [donor, :donation_amount]
|
544
|
+
}
|
545
|
+
}
|
546
|
+
|
547
|
+
h_box_sizer {
|
548
|
+
sizer_args 0, Wx::DOWN, 10
|
549
|
+
|
550
|
+
static_text(label: '') {
|
551
|
+
sizer_args 0, Wx::RIGHT, 10
|
552
|
+
# data-bind donor.summary to static_text.label unidirectionally,
|
553
|
+
# with computed data-binding from donor summary dependencies: first_name, last_name, and donation_amount
|
554
|
+
# ensuring changes to donor.summary or any of its dependencies update static_text.label
|
555
|
+
label <= [donor, :summary, computed_by: [:first_name, :last_name, :donation_amount]]
|
556
|
+
}
|
557
|
+
}
|
558
|
+
}
|
559
|
+
}
|
560
|
+
}
|
200
561
|
```
|
201
562
|
|
202
|
-
|
563
|
+
## Coming From wxruby3
|
203
564
|
|
204
|
-
|
205
|
-
ruby -r glimmer-dsl-wx -e "require 'samples/hello/hello_world'"
|
206
|
-
```
|
565
|
+
If you would like to translate wxruby3 code into Glimmer DSL for WX code, read the [Usage](#usage) section to understand how Glimmer GUI DSL syntax works, and then check out the example below, which is written in both wxruby3 and Glimmer DSL for WX.
|
207
566
|
|
208
|
-
|
567
|
+
Example written in wxruby3:
|
209
568
|
|
210
|
-
```
|
211
|
-
|
569
|
+
```ruby
|
570
|
+
require 'wx'
|
571
|
+
|
572
|
+
class TheFrame < Wx::Frame
|
573
|
+
def initialize(title)
|
574
|
+
super(nil, title: title)
|
575
|
+
panel = Wx::Panel.new(self)
|
576
|
+
button = Wx::Button.new(panel, label: 'Click me')
|
577
|
+
button.evt_button(Wx::ID_ANY) { Wx.message_box('Hello. Thanks for clicking me!', 'Hello Button sample') }
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
Wx::App.run { TheFrame.new('Hello world!').show }
|
212
582
|
```
|
213
583
|
|
214
|
-
|
584
|
+
![Hello_Button](https://raw.githubusercontent.com/mcorino/wxRuby3/master/assets/hello_button.png)
|
585
|
+
![Hello_Button_Clicked](https://raw.githubusercontent.com/mcorino/wxRuby3/master/assets/hello_button_clicked.png)
|
215
586
|
|
216
|
-
|
587
|
+
Example re-written in Glimmer DSL for WX:
|
217
588
|
|
218
|
-
```
|
219
|
-
|
220
|
-
```
|
589
|
+
```ruby
|
590
|
+
require 'glimmer-dsl-wx'
|
221
591
|
|
222
|
-
|
592
|
+
include Glimmer
|
223
593
|
|
224
|
-
|
594
|
+
frame(title: 'Hello world!') {
|
595
|
+
panel {
|
596
|
+
button(label: 'Click me') {
|
597
|
+
on_button do
|
598
|
+
Wx.message_box('Hello. Thanks for clicking me!', 'Hello Button sample')
|
599
|
+
end
|
600
|
+
}
|
601
|
+
}
|
602
|
+
}
|
603
|
+
```
|
225
604
|
|
226
|
-
|
227
|
-
|
605
|
+
![Hello_Button](https://raw.githubusercontent.com/mcorino/wxRuby3/master/assets/hello_button.png)
|
606
|
+
![Hello_Button_Clicked](https://raw.githubusercontent.com/mcorino/wxRuby3/master/assets/hello_button_clicked.png)
|
228
607
|
|
229
608
|
## Process
|
230
609
|
|
@@ -233,8 +612,10 @@ This gives you `irb` with the `glimmer-dsl-wx` gem loaded and the `Glimmer` modu
|
|
233
612
|
## Resources
|
234
613
|
|
235
614
|
- [Code Master Blog](https://andymaleh.blogspot.com)
|
236
|
-
- [wxruby3 Bindings](https://github.com/mcorino/wxRuby3)
|
237
|
-
- [wxWidgets GUI Toolkit](https://www.wxwidgets.org/)
|
615
|
+
- [wxruby3 Bindings](https://github.com/mcorino/wxRuby3) (used by Glimmer DSL for WX)
|
616
|
+
- [wxWidgets GUI Toolkit](https://www.wxwidgets.org/) (used by Glimmer DSL for WX)
|
617
|
+
- [wxWidgets Controls](https://docs.wxwidgets.org/3.0/group__group__class__ctrl.html)
|
618
|
+
- [wxWidgets Sizers](https://docs.wxwidgets.org/3.0/overview_sizer.html)
|
238
619
|
|
239
620
|
## Help
|
240
621
|
|
@@ -286,7 +667,7 @@ Note that the latest development sometimes takes place in the [development](http
|
|
286
667
|
|
287
668
|
[MIT](LICENSE.txt)
|
288
669
|
|
289
|
-
Copyright (c) 2023 Andy Maleh
|
670
|
+
Copyright (c) 2023-2024 Andy Maleh
|
290
671
|
|
291
672
|
--
|
292
673
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/girb
CHANGED
data/bin/girb_runner.rb
CHANGED
data/glimmer-dsl-wx.gemspec
CHANGED
Binary file
|