glimmer-dsl-libui 0.0.4 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +540 -41
- data/VERSION +1 -1
- data/examples/basic_button.rb +1 -1
- data/examples/basic_entry.rb +3 -3
- data/examples/basic_window.rb +1 -1
- data/examples/basic_window2.rb +14 -0
- data/examples/control_gallery.rb +168 -0
- data/examples/midi_player.rb +2 -2
- data/examples/simple_notepad.rb +1 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/dsl.rb +1 -1
- data/lib/glimmer/dsl/libui/file_expression.rb +33 -0
- data/lib/glimmer/dsl/libui/open_file_expression.rb +33 -0
- data/lib/glimmer/dsl/libui/save_file_expression.rb +33 -0
- data/lib/glimmer/dsl/libui/tab_item_expression.rb +35 -0
- data/lib/glimmer/libui/about_menu_item_proxy.rb +37 -0
- data/lib/glimmer/libui/box.rb +16 -2
- data/lib/glimmer/libui/check_menu_item_proxy.rb +37 -0
- data/lib/glimmer/libui/combobox_proxy.rb +4 -3
- data/lib/glimmer/libui/control_proxy.rb +135 -29
- data/lib/glimmer/libui/date_picker_proxy.rb +32 -0
- data/lib/glimmer/libui/date_time_picker_proxy.rb +35 -0
- data/lib/glimmer/libui/editable_combobox_proxy.rb +43 -0
- data/lib/glimmer/libui/group_proxy.rb +43 -0
- data/lib/glimmer/libui/menu_item_proxy.rb +4 -1
- data/lib/glimmer/libui/multiline_entry_proxy.rb +35 -0
- data/lib/glimmer/libui/non_wrapping_multiline_entry_proxy.rb +32 -0
- data/lib/glimmer/libui/preferences_menu_item_proxy.rb +37 -0
- data/lib/glimmer/libui/quit_menu_item_proxy.rb +62 -0
- data/lib/glimmer/libui/radio_buttons_proxy.rb +43 -0
- data/lib/glimmer/libui/separator_menu_item_proxy.rb +37 -0
- data/lib/glimmer/libui/tab_item_proxy.rb +67 -0
- data/lib/glimmer/libui/time_picker_proxy.rb +32 -0
- data/lib/glimmer/libui/window_proxy.rb +15 -3
- metadata +25 -5
data/README.md
CHANGED
@@ -1,15 +1,16 @@
|
|
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.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.0.8
|
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)
|
5
5
|
[![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)
|
6
6
|
|
7
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [LibUI](https://github.com/kojix2/LibUI) is a
|
8
|
-
ll any pre-requisites. Just install the gem and have platform-independent GUI that just works!
|
7
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [LibUI](https://github.com/kojix2/LibUI) is a prerequisite-free Ruby desktop development GUI library. No need to pre-install any prerequisites. Just install the gem and have platform-independent native GUI that just works!
|
9
8
|
|
10
|
-
|
9
|
+
[LibUI](https://github.com/kojix2/LibUI) is a thin [Ruby](https://www.ruby-lang.org/en/) wrapper around [libui](https://github.com/andlabs/libui), a relatively new C GUI library that renders native widgets on every platform (similar to [SWT](https://www.eclipse.org/swt/), but without the heavy weight of the [Java Virtual Machine](https://www.java.com/en/)).
|
11
10
|
|
12
|
-
[Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui)
|
11
|
+
The main trade-off in using [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) as opposed to [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) or [Glimmer DSL for Tk](https://github.com/AndyObtiva/glimmer-dsl-tk) is the fact that [SWT](https://www.eclipse.org/swt/) and [Tk](https://www.tcl.tk/) are more mature than mid-alpha [libui](https://github.com/andlabs/libui) as GUI toolkits. Still, if there is only a need to build a small simple application, [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) could be a good convenient choice due to having zero prerequisites beyond the dependencies included in the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui). Also, just like [Glimmer DSL for Tk](https://github.com/AndyObtiva/glimmer-dsl-tk), its apps start instantly and have a small memory footprint. [LibUI](https://github.com/kojix2/LibUI) is a promising new GUI toolkit that might prove quite worthy in the future.
|
12
|
+
|
13
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) 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:
|
13
14
|
- Declarative DSL syntax that visually maps to the GUI widget hierarchy
|
14
15
|
- Convention over configuration via smart defaults and automation of low-level details
|
15
16
|
- Requiring the least amount of syntax possible to build GUI
|
@@ -25,13 +26,13 @@ require 'glimmer-dsl-libui'
|
|
25
26
|
|
26
27
|
include Glimmer
|
27
28
|
|
28
|
-
window('hello world'
|
29
|
+
window('hello world').show
|
29
30
|
```
|
30
31
|
|
31
32
|
![glimmer-dsl-libui-mac-basic-window.png](images/glimmer-dsl-libui-mac-basic-window.png)
|
32
33
|
![glimmer-dsl-libui-linux-basic-window.png](images/glimmer-dsl-libui-linux-basic-window.png)
|
33
34
|
|
34
|
-
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is in early alpha mode (only supports included 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.
|
35
|
+
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.
|
35
36
|
|
36
37
|
Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
|
37
38
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
@@ -40,9 +41,40 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
40
41
|
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
41
42
|
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
|
42
43
|
|
44
|
+
## Table of Contents
|
45
|
+
|
46
|
+
- [Glimmer DSL for LibUI 0.0.8](#-glimmer-dsl-for-libui-008)
|
47
|
+
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
48
|
+
- [Usage](#usage)
|
49
|
+
- [API](#api)
|
50
|
+
- [Supported Controls](#supported-controls)
|
51
|
+
- [Common Control Properties](#common-control-properties)
|
52
|
+
- [Common Control Operations](#common-control-operations)
|
53
|
+
- [Extra Dialogs](#extra-dialogs)
|
54
|
+
- [Extra Operations](#extra-operations)
|
55
|
+
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
56
|
+
- [Original API](#original-api)
|
57
|
+
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
58
|
+
- [Examples](#examples)
|
59
|
+
- [Basic Window](#basic-window)
|
60
|
+
- [Basic Button](#basic-button)
|
61
|
+
- [Basic Entry](#basic-entry)
|
62
|
+
- [Simple Notepad](#simple-notepad)
|
63
|
+
- [Midi Player](#midi-player)
|
64
|
+
- [Control Gallery](#control-gallery)
|
65
|
+
- [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
|
66
|
+
- [Help](#help)
|
67
|
+
- [Issues](#issues)
|
68
|
+
- [Chat](#chat)
|
69
|
+
- [Process](#process)
|
70
|
+
- [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
|
71
|
+
- [Change Log](#change-log)
|
72
|
+
- [Contributors](#contributors)
|
73
|
+
- [License](#license)
|
74
|
+
|
43
75
|
## Glimmer GUI DSL Concepts
|
44
76
|
|
45
|
-
The Glimmer GUI DSL provides
|
77
|
+
The Glimmer GUI DSL provides object-oriented declarative hierarchical syntax for [LibUI](https://github.com/kojix2/LibUI) that:
|
46
78
|
- Supports smart defaults (e.g. automatic `on_closing` listener that quits `window`)
|
47
79
|
- Automates wiring of widgets (e.g. `button` is automatically set as child of `window`)
|
48
80
|
- Hides lower-level details (e.g. `LibUI.main` loop is started automatically when triggering `show` on `window`)
|
@@ -50,8 +82,8 @@ The Glimmer GUI DSL provides a declarative syntax for [LibUI](https://github.com
|
|
50
82
|
- Requires the minimum amount of syntax needed to describe an app's GUI
|
51
83
|
|
52
84
|
The Glimmer GUI DSL follows these simple concepts in mapping from [LibUI](https://github.com/kojix2/LibUI) syntax:
|
53
|
-
- **Control**: [LibUI](https://github.com/kojix2/LibUI) controls may be declared by lower-case underscored name (aka keyword) (e.g. `window` or `button`). Behind the scenes, they are represented by keyword methods that map to corresponding `LibUI.new_keyword` methods receiving args (e.g. `window('hello world', 300, 200,
|
54
|
-
- **Content/Properties/Listeners Block**: Any keyword may be optionally followed by a Ruby curly-brace multi-line-block containing nested controls (content) and/or properties (attributes) (e.g. `window('hello world', 300, 200,
|
85
|
+
- **Control**: [LibUI](https://github.com/kojix2/LibUI) controls may be declared by lower-case underscored name (aka keyword) (e.g. `window` or `button`). Behind the scenes, they are represented by keyword methods that map to corresponding `LibUI.new_keyword` methods receiving args (e.g. `window('hello world', 300, 200, true)`).
|
86
|
+
- **Content/Properties/Listeners Block**: Any keyword may be optionally followed by a Ruby curly-brace multi-line-block containing nested controls (content) and/or properties (attributes) (e.g. `window('hello world', 300, 200, true) {button('greet')}`). It optionally receives one arg representing the control (e.g. `button('greet') {|b| on_clicked { puts b.text}}`)
|
55
87
|
- **Property**: Control properties may be declared inside keyword blocks with lower-case underscored name followed by property value args (e.g. `title "hello world"` inside `group`). Behind the scenes, properties correspond to `control_set_property` methods.
|
56
88
|
- **Listener**: Control listeners may be declared inside keyword blocks with listener lower-case underscored name beginning with `on_` and receiving required block handler (e.g. `on_clicked {puts 'clicked'}` inside `button`). Behind the scenes, listeners correspond to `control_on_event` methods.
|
57
89
|
|
@@ -93,7 +125,7 @@ require 'glimmer-dsl-libui'
|
|
93
125
|
|
94
126
|
include Glimmer
|
95
127
|
|
96
|
-
window('hello world', 300, 200
|
128
|
+
window('hello world', 300, 200) { |w|
|
97
129
|
button('Button') {
|
98
130
|
on_clicked do
|
99
131
|
msg_box(w, 'Information', 'You clicked the button')
|
@@ -117,7 +149,7 @@ gem install glimmer-dsl-libui
|
|
117
149
|
Or install via Bundler `Gemfile`:
|
118
150
|
|
119
151
|
```ruby
|
120
|
-
gem 'glimmer-dsl-libui', '~> 0.0.
|
152
|
+
gem 'glimmer-dsl-libui', '~> 0.0.8'
|
121
153
|
```
|
122
154
|
|
123
155
|
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.
|
@@ -131,7 +163,7 @@ class Application
|
|
131
163
|
include Glimmer
|
132
164
|
|
133
165
|
def launch
|
134
|
-
window('hello world', 300, 200
|
166
|
+
window('hello world', 300, 200) {
|
135
167
|
button('Button') {
|
136
168
|
on_clicked do
|
137
169
|
puts 'Button Clicked'
|
@@ -146,7 +178,7 @@ Application.new.launch
|
|
146
178
|
|
147
179
|
## API
|
148
180
|
|
149
|
-
Any control returned by a Glimmer GUI DSL keyword declaration can be introspected for its properties and updated via object-oriented attributes (standard Ruby `attr`/`attr=` or `set_attr`).
|
181
|
+
Any control returned by a [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) keyword declaration can be introspected for its properties and updated via object-oriented attributes (standard Ruby `attr`/`attr=` or `set_attr`).
|
150
182
|
|
151
183
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
152
184
|
|
@@ -168,28 +200,88 @@ w = window('hello world', 300, 200, 1) # => #<Glimmer::LibUI::WindowProxy:0x0000
|
|
168
200
|
w.libui # => #<Fiddle::Pointer:0x00007fde53997980 ptr=0x00007fde51352a60 size=0 free=0x0000000000000000>
|
169
201
|
```
|
170
202
|
|
171
|
-
Supported Controls
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
203
|
+
### Supported Controls
|
204
|
+
|
205
|
+
Control(Args) | Properties | Listeners
|
206
|
+
------------- | ---------- | ---------
|
207
|
+
`about_menu_item` | None | `on_clicked`
|
208
|
+
`button(text as String)` | `text` (`String`) | `on_clicked`
|
209
|
+
`checkbox(text as String)` | `checked` (Boolean), `text` (`String`) | `on_toggled`
|
210
|
+
`combobox` | `items` (`Array` of `String`), `selected` (`Integer`) | `on_selected`
|
211
|
+
`color_button` | `color` (r `Numeric`, g `Numeric`, b `Numeric`, a `Numeric`) | `on_changed`
|
212
|
+
`date_picker` | `time` (`LibUI::FFI::TM`) | `on_changed`
|
213
|
+
`date_time_picker` | `time` (`LibUI::FFI::TM`) | `on_changed`
|
214
|
+
`editable_combobox` | `items` (`Array` of `String`), `text` (`String`) | `on_changed`
|
215
|
+
`entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
216
|
+
`font_button` | `font` (`LibUI::FFI::FontDescriptor`) | `on_changed`
|
217
|
+
`group(text as String)` | `margined` (Boolean), `title` (`String`) | None
|
218
|
+
`horizontal_box` | `padded` (Boolean) | None
|
219
|
+
`horizontal_separator` | None | None
|
220
|
+
`label(text as String)` | `text` (`String`) | None
|
221
|
+
`menu(text as String)` | None | None
|
222
|
+
`menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
|
223
|
+
`multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
224
|
+
`msg_box(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
225
|
+
`msg_box_error(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
226
|
+
`non_wrapping_multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
227
|
+
`preferences_menu_item` | None | `on_clicked`
|
228
|
+
`progress_bar` | `value` (`Numeric`) | None
|
229
|
+
`quit_menu_item` | None | `on_clicked`
|
230
|
+
`radio_buttons` | `selected` (`Integer`) | `on_selected`
|
231
|
+
`slider(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
232
|
+
`spinbox(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
233
|
+
`tab` | `margined` (Boolean), `num_pages` (`Integer`) | None
|
234
|
+
`tab_item(name as String)` | `index` [read-only] (`Integer`), `margined` (Boolean), `name` [read-only] (`String`) | None
|
235
|
+
`time_picker` | `time` (`LibUI::FFI::TM`) | `on_changed`
|
236
|
+
`vertical_box` | `padded` (Boolean) | None
|
237
|
+
`window(title as String, width as Integer, height as Integer, has_menubar as Boolean)` | `borderless` (Boolean), `content_size` (width `Numeric`, height `Numeric`), `fullscreen` (Boolean), `margined` (Boolean), `title` (`String`) | `on_closing`, `on_content_size_changed`
|
238
|
+
|
239
|
+
### Common Control Properties
|
240
|
+
- `enabled` (Boolean)
|
241
|
+
- `libui` (`Fiddle::Pointer`): returns wrapped [LibUI](https://github.com/kojix2/LibUI) object
|
242
|
+
- `parent_proxy` (`Glimmer::LibUI::ControlProxy` or subclass)
|
243
|
+
- `parent` (`Fiddle::Pointer`)
|
244
|
+
- `toplevel` [read-only] (Boolean)
|
245
|
+
- `visible` (Boolean)
|
246
|
+
- `stretchy` [dsl-only] (Boolean): available in [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) when nested under `horizontal_box` or `vertical_box`
|
247
|
+
|
248
|
+
### Common Control Operations
|
187
249
|
- `destroy`
|
188
250
|
- `disable`
|
189
251
|
- `enable`
|
190
252
|
- `hide`
|
191
253
|
- `show`
|
192
254
|
|
255
|
+
### Extra Dialogs
|
256
|
+
|
257
|
+
- `open_file(window as Glimmer::LibUI::WindowProxy)`: returns selected file (`String`) or `nil` if cancelled
|
258
|
+
- `save_file(window as Glimmer::LibUI::WindowProxy)`: returns selected file (`String`) or `nil` if cancelled
|
259
|
+
|
260
|
+
### Extra Operations
|
261
|
+
|
262
|
+
- `ControlProxy::all_control_proxies`: returns all instantiated control proxies in the application
|
263
|
+
- `ControlProxy::main_window_proxy`: returns the first window proxy instantiated in the application
|
264
|
+
- `ControlProxy#window_proxy`: returns the window proxy parent for a control
|
265
|
+
|
266
|
+
### Smart Defaults and Conventions
|
267
|
+
|
268
|
+
- `horizontal_box` and `vertical_box` controls have `padded` as `1` upon instantiation to ensure more user-friendly GUI by default
|
269
|
+
- `group` controls have `margined` as `1` upon instantiation to ensure more user-friendly GUI by default
|
270
|
+
- All controls nested under a `horizontal_box` or `vertical_box` have `stretchy` property (passed to `box_append` method) as `1` by default (filling maximum space)
|
271
|
+
- `window` constructor args can be left off and have the following defaults when unspecified: `title` as `'Glimmer'`, `width` as `150`, `height` as `150`, and `has_menubar` as `true`)
|
272
|
+
- `window` has an `on_closing` listener by default that quits application upon hitting the close button (can be overridden with a manual `on_closing` implementation that returns integer `0` for success)
|
273
|
+
- `quit_menu_item` has an `on_clicked` listener by default that quits application upon selecting the quit menu item (can be overridden with a manual `on_clicked` implementation that returns integer `0` for success)
|
274
|
+
- If an `on_closing` listener was defined on `window` and it does not return an integer, default exit behavior is assumed (`window.destroy` is called followed by `LibUI.quit`, returning `0`).
|
275
|
+
- If an `on_clicked` listener was defined on `quit_menu_item` and it does not return an integer, default exit behavior is assumed (`main_window.destroy` is called followed by `LibUI.quit`, returning `0`).
|
276
|
+
- All boolean property readers return `true` or `false` in Ruby instead of the [libui](https://github.com/andlabs/libui) original `0` or `1` in C.
|
277
|
+
- All boolean property writers accept `true`/`false` in addition to `1`/`0` in Ruby
|
278
|
+
- All string property readers return a `String` object in Ruby instead of the [libui](https://github.com/andlabs/libui) Fiddle pointer object.
|
279
|
+
|
280
|
+
### Original API
|
281
|
+
|
282
|
+
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),
|
283
|
+
check out the [libui C headers](https://github.com/andlabs/libui/blob/master/ui.h)
|
284
|
+
|
193
285
|
## Girb (Glimmer IRB)
|
194
286
|
|
195
287
|
You can run the `girb` command (`bin/girb` if you cloned the project locally):
|
@@ -204,7 +296,7 @@ Gotcha: On the Mac, when you close a window opened in `girb`, it remains open un
|
|
204
296
|
|
205
297
|
## Examples
|
206
298
|
|
207
|
-
These examples reimplement the ones in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the Glimmer GUI DSL.
|
299
|
+
These examples reimplement the ones in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the [Glimmer GUI DSL](#glimmer-gui-dsl-concepts).
|
208
300
|
|
209
301
|
### Basic Window
|
210
302
|
|
@@ -261,7 +353,7 @@ require 'glimmer-dsl-libui'
|
|
261
353
|
|
262
354
|
include Glimmer
|
263
355
|
|
264
|
-
window('hello world', 300, 200,
|
356
|
+
window('hello world', 300, 200, true) {
|
265
357
|
on_closing do
|
266
358
|
puts 'Bye Bye'
|
267
359
|
end
|
@@ -332,7 +424,7 @@ require 'glimmer-dsl-libui'
|
|
332
424
|
|
333
425
|
include Glimmer
|
334
426
|
|
335
|
-
window('hello world', 300, 200
|
427
|
+
window('hello world', 300, 200) { |w|
|
336
428
|
button('Button') {
|
337
429
|
on_clicked do
|
338
430
|
msg_box(w, 'Information', 'You clicked the button')
|
@@ -345,6 +437,23 @@ window('hello world', 300, 200, 1) { |w|
|
|
345
437
|
}.show
|
346
438
|
```
|
347
439
|
|
440
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
441
|
+
|
442
|
+
```ruby
|
443
|
+
require 'glimmer-dsl-libui'
|
444
|
+
|
445
|
+
include Glimmer
|
446
|
+
|
447
|
+
window { # args can alternatively be set via properties with 4th arg has_menubar=true by default
|
448
|
+
title 'hello world'
|
449
|
+
content_size 300, 200
|
450
|
+
|
451
|
+
on_closing do
|
452
|
+
puts 'Bye Bye'
|
453
|
+
end
|
454
|
+
}.show
|
455
|
+
```
|
456
|
+
|
348
457
|
### Basic Entry
|
349
458
|
|
350
459
|
[examples/basic_entry.rb](examples/basic_entry.rb)
|
@@ -419,10 +528,10 @@ require 'glimmer-dsl-libui'
|
|
419
528
|
|
420
529
|
include Glimmer
|
421
530
|
|
422
|
-
window('Basic Entry', 300, 50
|
531
|
+
window('Basic Entry', 300, 50) { |w|
|
423
532
|
horizontal_box {
|
424
533
|
e = entry {
|
425
|
-
# stretchy
|
534
|
+
# stretchy true # Smart default option for appending to horizontal_box
|
426
535
|
|
427
536
|
on_changed do
|
428
537
|
puts e.text
|
@@ -431,7 +540,7 @@ window('Basic Entry', 300, 50, 1) { |w|
|
|
431
540
|
}
|
432
541
|
|
433
542
|
button('Button') {
|
434
|
-
stretchy
|
543
|
+
stretchy false
|
435
544
|
|
436
545
|
on_clicked do
|
437
546
|
text = e.text
|
@@ -505,7 +614,7 @@ require 'glimmer-dsl-libui'
|
|
505
614
|
|
506
615
|
include Glimmer
|
507
616
|
|
508
|
-
window('Notepad', 500, 300
|
617
|
+
window('Notepad', 500, 300) {
|
509
618
|
on_closing do
|
510
619
|
puts 'Bye Bye'
|
511
620
|
end
|
@@ -518,7 +627,7 @@ window('Notepad', 500, 300, 1) {
|
|
518
627
|
|
519
628
|
### Midi Player
|
520
629
|
|
521
|
-
This example has
|
630
|
+
This example has prerequisites:
|
522
631
|
- Install [TiMidity](http://timidity.sourceforge.net) and ensure `timidity` command is in `PATH` (can be installed via [Homebrew](https://brew.sh) on Mac or [apt-get](https://help.ubuntu.com/community/AptGet/Howto) on Linux).
|
523
632
|
- Add `*.mid` files to `~/Music` directory (you may copy the ones included in [sounds](sounds) directory)
|
524
633
|
|
@@ -706,10 +815,10 @@ class TinyMidiPlayer
|
|
706
815
|
end
|
707
816
|
}
|
708
817
|
}
|
709
|
-
@main_window = window('Tiny Midi Player', 200, 50
|
818
|
+
@main_window = window('Tiny Midi Player', 200, 50) {
|
710
819
|
horizontal_box {
|
711
820
|
vertical_box {
|
712
|
-
stretchy
|
821
|
+
stretchy false
|
713
822
|
|
714
823
|
button('▶') {
|
715
824
|
on_clicked do
|
@@ -740,6 +849,396 @@ end
|
|
740
849
|
TinyMidiPlayer.new
|
741
850
|
```
|
742
851
|
|
852
|
+
### Control Gallery
|
853
|
+
|
854
|
+
[examples/control_gallery.rb](examples/control_gallery.rb)
|
855
|
+
|
856
|
+
Run with this command from the root of the project if you cloned the project:
|
857
|
+
|
858
|
+
```
|
859
|
+
ruby -r './lib/glimmer-dsl-libui' examples/control_gallery.rb
|
860
|
+
```
|
861
|
+
|
862
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
863
|
+
|
864
|
+
```
|
865
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/control_gallery'"
|
866
|
+
```
|
867
|
+
|
868
|
+
Mac
|
869
|
+
|
870
|
+
![glimmer-dsl-libui-mac-control-gallery.png](images/glimmer-dsl-libui-mac-control-gallery.png)
|
871
|
+
|
872
|
+
Linux
|
873
|
+
|
874
|
+
![glimmer-dsl-libui-linux-control-gallery.png](images/glimmer-dsl-libui-linux-control-gallery.png)
|
875
|
+
|
876
|
+
[LibUI](https://github.com/kojix2/LibUI) Original Version:
|
877
|
+
|
878
|
+
```ruby
|
879
|
+
require 'libui'
|
880
|
+
UI = LibUI
|
881
|
+
|
882
|
+
UI.init
|
883
|
+
|
884
|
+
should_quit = proc do
|
885
|
+
puts 'Bye Bye'
|
886
|
+
UI.control_destroy(MAIN_WINDOW)
|
887
|
+
UI.quit
|
888
|
+
0
|
889
|
+
end
|
890
|
+
|
891
|
+
# File menu
|
892
|
+
menu = UI.new_menu('File')
|
893
|
+
open_menu_item = UI.menu_append_item(menu, 'Open')
|
894
|
+
UI.menu_item_on_clicked(open_menu_item) do
|
895
|
+
pt = UI.open_file(MAIN_WINDOW)
|
896
|
+
puts pt unless pt.null?
|
897
|
+
end
|
898
|
+
save_menu_item = UI.menu_append_item(menu, 'Save')
|
899
|
+
UI.menu_item_on_clicked(save_menu_item) do
|
900
|
+
pt = UI.save_file(MAIN_WINDOW)
|
901
|
+
puts pt unless pt.null?
|
902
|
+
end
|
903
|
+
|
904
|
+
UI.menu_append_quit_item(menu)
|
905
|
+
UI.on_should_quit(should_quit)
|
906
|
+
|
907
|
+
# Edit menu
|
908
|
+
edit_menu = UI.new_menu('Edit')
|
909
|
+
UI.menu_append_check_item(edit_menu, 'Checkable Item_')
|
910
|
+
UI.menu_append_separator(edit_menu)
|
911
|
+
disabled_item = UI.menu_append_item(edit_menu, 'Disabled Item_')
|
912
|
+
UI.menu_item_disable(disabled_item)
|
913
|
+
|
914
|
+
preferences = UI.menu_append_preferences_item(menu)
|
915
|
+
|
916
|
+
# Help menu
|
917
|
+
help_menu = UI.new_menu('Help')
|
918
|
+
UI.menu_append_item(help_menu, 'Help')
|
919
|
+
UI.menu_append_about_item(help_menu)
|
920
|
+
|
921
|
+
# Main Window
|
922
|
+
MAIN_WINDOW = UI.new_window('Control Gallery', 600, 500, 1)
|
923
|
+
UI.window_set_margined(MAIN_WINDOW, 1)
|
924
|
+
UI.window_on_closing(MAIN_WINDOW, should_quit)
|
925
|
+
|
926
|
+
vbox = UI.new_vertical_box
|
927
|
+
UI.window_set_child(MAIN_WINDOW, vbox)
|
928
|
+
hbox = UI.new_horizontal_box
|
929
|
+
UI.box_set_padded(vbox, 1)
|
930
|
+
UI.box_set_padded(hbox, 1)
|
931
|
+
|
932
|
+
UI.box_append(vbox, hbox, 1)
|
933
|
+
|
934
|
+
# Group - Basic Controls
|
935
|
+
group = UI.new_group('Basic Controls')
|
936
|
+
UI.group_set_margined(group, 1)
|
937
|
+
UI.box_append(hbox, group, 1) # OSX bug?
|
938
|
+
|
939
|
+
inner = UI.new_vertical_box
|
940
|
+
UI.box_set_padded(inner, 1)
|
941
|
+
UI.group_set_child(group, inner)
|
942
|
+
|
943
|
+
# Button
|
944
|
+
button = UI.new_button('Button')
|
945
|
+
UI.button_on_clicked(button) do
|
946
|
+
UI.msg_box(MAIN_WINDOW, 'Information', 'You clicked the button')
|
947
|
+
end
|
948
|
+
UI.box_append(inner, button, 0)
|
949
|
+
|
950
|
+
# Checkbox
|
951
|
+
checkbox = UI.new_checkbox('Checkbox')
|
952
|
+
UI.checkbox_on_toggled(checkbox) do |ptr|
|
953
|
+
checked = UI.checkbox_checked(ptr) == 1
|
954
|
+
UI.window_set_title(MAIN_WINDOW, "Checkbox is #{checked}")
|
955
|
+
UI.checkbox_set_text(ptr, "I am the checkbox (#{checked})")
|
956
|
+
end
|
957
|
+
UI.box_append(inner, checkbox, 0)
|
958
|
+
|
959
|
+
# Label
|
960
|
+
UI.box_append(inner, UI.new_label('Label'), 0)
|
961
|
+
|
962
|
+
# Separator
|
963
|
+
UI.box_append(inner, UI.new_horizontal_separator, 0)
|
964
|
+
|
965
|
+
# Date Picker
|
966
|
+
UI.box_append(inner, UI.new_date_picker, 0)
|
967
|
+
|
968
|
+
# Time Picker
|
969
|
+
UI.box_append(inner, UI.new_time_picker, 0)
|
970
|
+
|
971
|
+
# Date Time Picker
|
972
|
+
UI.box_append(inner, UI.new_date_time_picker, 0)
|
973
|
+
|
974
|
+
# Font Button
|
975
|
+
UI.box_append(inner, UI.new_font_button, 0)
|
976
|
+
|
977
|
+
# Color Button
|
978
|
+
UI.box_append(inner, UI.new_color_button, 0)
|
979
|
+
|
980
|
+
inner2 = UI.new_vertical_box
|
981
|
+
UI.box_set_padded(inner2, 1)
|
982
|
+
UI.box_append(hbox, inner2, 1)
|
983
|
+
|
984
|
+
# Group - Numbers
|
985
|
+
group = UI.new_group('Numbers')
|
986
|
+
UI.group_set_margined(group, 1)
|
987
|
+
UI.box_append(inner2, group, 0)
|
988
|
+
|
989
|
+
inner = UI.new_vertical_box
|
990
|
+
UI.box_set_padded(inner, 1)
|
991
|
+
UI.group_set_child(group, inner)
|
992
|
+
|
993
|
+
# Spinbox
|
994
|
+
spinbox = UI.new_spinbox(0, 100)
|
995
|
+
UI.spinbox_set_value(spinbox, 42)
|
996
|
+
UI.spinbox_on_changed(spinbox) do |ptr|
|
997
|
+
puts "New Spinbox value: #{UI.spinbox_value(ptr)}"
|
998
|
+
end
|
999
|
+
UI.box_append(inner, spinbox, 0)
|
1000
|
+
|
1001
|
+
# Slider
|
1002
|
+
slider = UI.new_slider(0, 100)
|
1003
|
+
UI.box_append(inner, slider, 0)
|
1004
|
+
|
1005
|
+
# Progressbar
|
1006
|
+
progressbar = UI.new_progress_bar
|
1007
|
+
UI.box_append(inner, progressbar, 0)
|
1008
|
+
|
1009
|
+
UI.slider_on_changed(slider) do |ptr|
|
1010
|
+
v = UI.slider_value(ptr)
|
1011
|
+
puts "New Slider value: #{v}"
|
1012
|
+
UI.progress_bar_set_value(progressbar, v)
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
# Group - Lists
|
1016
|
+
group = UI.new_group('Lists')
|
1017
|
+
UI.group_set_margined(group, 1)
|
1018
|
+
UI.box_append(inner2, group, 0)
|
1019
|
+
|
1020
|
+
inner = UI.new_vertical_box
|
1021
|
+
UI.box_set_padded(inner, 1)
|
1022
|
+
UI.group_set_child(group, inner)
|
1023
|
+
|
1024
|
+
# Combobox
|
1025
|
+
cbox = UI.new_combobox
|
1026
|
+
UI.combobox_append(cbox, 'combobox Item 1')
|
1027
|
+
UI.combobox_append(cbox, 'combobox Item 2')
|
1028
|
+
UI.combobox_append(cbox, 'combobox Item 3')
|
1029
|
+
UI.box_append(inner, cbox, 0)
|
1030
|
+
UI.combobox_on_selected(cbox) do |ptr|
|
1031
|
+
puts "New combobox selection: #{UI.combobox_selected(ptr)}"
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
# Editable Combobox
|
1035
|
+
ebox = UI.new_editable_combobox
|
1036
|
+
UI.editable_combobox_append(ebox, 'Editable Item 1')
|
1037
|
+
UI.editable_combobox_append(ebox, 'Editable Item 2')
|
1038
|
+
UI.editable_combobox_append(ebox, 'Editable Item 3')
|
1039
|
+
UI.box_append(inner, ebox, 0)
|
1040
|
+
|
1041
|
+
# Radio Buttons
|
1042
|
+
rb = UI.new_radio_buttons
|
1043
|
+
UI.radio_buttons_append(rb, 'Radio Button 1')
|
1044
|
+
UI.radio_buttons_append(rb, 'Radio Button 2')
|
1045
|
+
UI.radio_buttons_append(rb, 'Radio Button 3')
|
1046
|
+
UI.box_append(inner, rb, 1)
|
1047
|
+
|
1048
|
+
# Tab
|
1049
|
+
tab = UI.new_tab
|
1050
|
+
hbox1 = UI.new_horizontal_box
|
1051
|
+
hbox2 = UI.new_horizontal_box
|
1052
|
+
UI.tab_append(tab, 'Page 1', hbox1)
|
1053
|
+
UI.tab_append(tab, 'Page 2', hbox2)
|
1054
|
+
UI.tab_append(tab, 'Page 3', UI.new_horizontal_box)
|
1055
|
+
UI.box_append(inner2, tab, 1)
|
1056
|
+
|
1057
|
+
# Text Entry
|
1058
|
+
text_entry = UI.new_entry
|
1059
|
+
UI.entry_set_text text_entry, 'Please enter your feelings'
|
1060
|
+
UI.entry_on_changed(text_entry) do |ptr|
|
1061
|
+
puts "Current textbox data: '#{UI.entry_text(ptr)}'"
|
1062
|
+
end
|
1063
|
+
UI.box_append(hbox1, text_entry, 1)
|
1064
|
+
|
1065
|
+
UI.control_show(MAIN_WINDOW)
|
1066
|
+
|
1067
|
+
UI.main
|
1068
|
+
UI.quit
|
1069
|
+
```
|
1070
|
+
|
1071
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
1072
|
+
|
1073
|
+
```ruby
|
1074
|
+
require 'glimmer-dsl-libui'
|
1075
|
+
|
1076
|
+
include Glimmer
|
1077
|
+
|
1078
|
+
menu('File') {
|
1079
|
+
menu_item('Open') {
|
1080
|
+
on_clicked do
|
1081
|
+
file = open_file(MAIN_WINDOW)
|
1082
|
+
puts file unless file.nil?
|
1083
|
+
end
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
menu_item('Save') {
|
1087
|
+
on_clicked do
|
1088
|
+
file = save_file(MAIN_WINDOW)
|
1089
|
+
puts file unless file.nil?
|
1090
|
+
end
|
1091
|
+
}
|
1092
|
+
|
1093
|
+
quit_menu_item {
|
1094
|
+
on_clicked do
|
1095
|
+
puts 'Bye Bye'
|
1096
|
+
end
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
preferences_menu_item # Can optionally contain an on_clicked listener
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
menu('Edit') {
|
1103
|
+
check_menu_item('Checkable Item_')
|
1104
|
+
separator_menu_item
|
1105
|
+
menu_item('Disabled Item_') {
|
1106
|
+
enabled false
|
1107
|
+
}
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
menu('Help') {
|
1111
|
+
menu_item('Help')
|
1112
|
+
|
1113
|
+
about_menu_item # Can optionally contain an on_clicked listener
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
MAIN_WINDOW = window('Control Gallery', 600, 500) {
|
1117
|
+
margined true
|
1118
|
+
|
1119
|
+
on_closing do
|
1120
|
+
puts 'Bye Bye'
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
vertical_box {
|
1124
|
+
horizontal_box {
|
1125
|
+
group('Basic Controls') {
|
1126
|
+
vertical_box {
|
1127
|
+
button('Button') {
|
1128
|
+
stretchy false
|
1129
|
+
|
1130
|
+
on_clicked do
|
1131
|
+
msg_box(MAIN_WINDOW, 'Information', 'You clicked the button')
|
1132
|
+
end
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
checkbox('Checkbox') {
|
1136
|
+
stretchy false
|
1137
|
+
|
1138
|
+
on_toggled do |c|
|
1139
|
+
checked = c.checked == 1
|
1140
|
+
MAIN_WINDOW.title = "Checkbox is #{checked}"
|
1141
|
+
c.text = "I am the checkbox (#{checked})"
|
1142
|
+
end
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
label('Label') { stretchy false }
|
1146
|
+
|
1147
|
+
horizontal_separator { stretchy false }
|
1148
|
+
|
1149
|
+
date_picker { stretchy false }
|
1150
|
+
|
1151
|
+
time_picker { stretchy false }
|
1152
|
+
|
1153
|
+
date_time_picker { stretchy false }
|
1154
|
+
|
1155
|
+
font_button { stretchy false }
|
1156
|
+
|
1157
|
+
color_button { stretchy false }
|
1158
|
+
}
|
1159
|
+
}
|
1160
|
+
|
1161
|
+
vertical_box {
|
1162
|
+
group('Numbers') {
|
1163
|
+
stretchy false
|
1164
|
+
|
1165
|
+
vertical_box {
|
1166
|
+
spinbox(0, 100) {
|
1167
|
+
stretchy false
|
1168
|
+
value 42
|
1169
|
+
|
1170
|
+
on_changed do |s|
|
1171
|
+
puts "New Spinbox value: #{s.value}"
|
1172
|
+
end
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
slider(0, 100) {
|
1176
|
+
stretchy false
|
1177
|
+
|
1178
|
+
on_changed do |s|
|
1179
|
+
v = s.value
|
1180
|
+
puts "New Slider value: #{v}"
|
1181
|
+
@progress_bar.value = v
|
1182
|
+
end
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
@progress_bar = progress_bar { stretchy false }
|
1186
|
+
}
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
group('Lists') {
|
1190
|
+
stretchy false
|
1191
|
+
|
1192
|
+
vertical_box {
|
1193
|
+
combobox {
|
1194
|
+
stretchy false
|
1195
|
+
items 'combobox Item 1', 'combobox Item 2', 'combobox Item 3' # also accepts a single array argument
|
1196
|
+
|
1197
|
+
on_selected do |c|
|
1198
|
+
puts "New combobox selection: #{c.selected}"
|
1199
|
+
end
|
1200
|
+
}
|
1201
|
+
|
1202
|
+
editable_combobox {
|
1203
|
+
stretchy false
|
1204
|
+
items 'Editable Item 1', 'Editable Item 2', 'Editable Item 3' # also accepts a single array argument
|
1205
|
+
}
|
1206
|
+
|
1207
|
+
radio_buttons {
|
1208
|
+
items 'Radio Button 1', 'Radio Button 2', 'Radio Button 3' # also accepts a single array argument
|
1209
|
+
}
|
1210
|
+
}
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
tab {
|
1214
|
+
tab_item('Page 1') {
|
1215
|
+
horizontal_box {
|
1216
|
+
entry {
|
1217
|
+
text 'Please enter your feelings'
|
1218
|
+
|
1219
|
+
on_changed do |e|
|
1220
|
+
puts "Current textbox data: '#{e.text}'"
|
1221
|
+
end
|
1222
|
+
}
|
1223
|
+
}
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
tab_item('Page 2') {
|
1227
|
+
horizontal_box
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
tab_item('Page 3') {
|
1231
|
+
horizontal_box
|
1232
|
+
}
|
1233
|
+
}
|
1234
|
+
}
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
MAIN_WINDOW.show
|
1240
|
+
```
|
1241
|
+
|
743
1242
|
## Contributing to glimmer-dsl-libui
|
744
1243
|
|
745
1244
|
- Check out the latest master to make sure the feature hasn't been
|