glimmer-dsl-libui 0.7.8 → 0.9.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 +12 -0
- data/README.md +398 -138
- data/VERSION +1 -1
- data/bin/girb +1 -1
- data/bin/glimmer +30 -0
- data/docs/examples/GLIMMER-DSL-LIBUI-BASIC-EXAMPLES.md +15 -30
- data/examples/basic_composite_shape.rb +145 -0
- data/examples/button_counter.rb +1 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/Rakefile +26 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +1 -2
- data/lib/glimmer/dsl/libui/shape_expression.rb +1 -0
- data/lib/glimmer/launcher.rb +231 -0
- data/lib/glimmer/libui/control_proxy/matrix_proxy.rb +1 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +7 -3
- data/lib/glimmer/libui/control_proxy.rb +5 -5
- data/lib/glimmer/libui/perfect_shaped.rb +9 -1
- data/lib/glimmer/libui/shape/arc.rb +8 -4
- data/lib/glimmer/libui/shape/bezier.rb +8 -4
- data/lib/glimmer/libui/shape/circle.rb +8 -4
- data/lib/glimmer/libui/shape/composite_shape.rb +101 -0
- data/lib/glimmer/libui/shape/figure.rb +8 -4
- data/lib/glimmer/libui/shape/line.rb +8 -4
- data/lib/glimmer/libui/shape/polybezier.rb +9 -5
- data/lib/glimmer/libui/shape/polygon.rb +9 -5
- data/lib/glimmer/libui/shape/polyline.rb +9 -5
- data/lib/glimmer/libui/shape/rectangle.rb +8 -4
- data/lib/glimmer/libui/shape/square.rb +7 -3
- data/lib/glimmer/libui/shape.rb +142 -6
- data/lib/glimmer/libui.rb +15 -0
- data/lib/glimmer/rake_task/list.rb +105 -0
- data/lib/glimmer/rake_task/scaffold.rb +839 -0
- data/lib/glimmer/rake_task.rb +192 -0
- metadata +42 -11
data/README.md
CHANGED
@@ -1,22 +1,24 @@
|
|
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
|
2
|
-
## Prerequisite-Free Ruby Desktop Development GUI Library
|
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 ([Fukuoka Award Winning](http://www.digitalfukuoka.jp/topics/187?locale=ja))
|
2
|
+
## Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library
|
3
3
|
### The Quickest Way From Zero To GUI
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
|
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
|
+
**[If You Liked Shoes, You'll Love Glimmer!](https://github.com/AndyObtiva/glimmer#faq)**
|
8
|
+
|
7
9
|
(**[Fukuoka Ruby Award Competition 2022 Special Award Winner](https://andymaleh.blogspot.com/2022/02/glimmer-dsl-for-libui-wins-fukuoka-ruby.html)** [[Award Announcement]](http://www.digitalfukuoka.jp/topics/187?locale=ja))
|
8
10
|
|
9
11
|
(**[***RubyConf 2022 Talk - Building Native GUI Apps in Ruby***](https://andymaleh.blogspot.com/2023/02/rubyconf-2022-talk-video-for-building.html)**)
|
10
12
|
|
11
13
|
[**(Ruby Rogues Podcast Interview - Desktop Apps in Ruby ft. Andy)**](https://andymaleh.blogspot.com/2022/05/ruby-rogues-podcast-interview-desktop.html)
|
12
14
|
|
13
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [LibUI](https://github.com/libui-ng/libui-ng) is a prerequisite-free [MRI Ruby](https://www.ruby-lang.org) desktop development GUI (Graphical User Interface) library. No need to pre-install any prerequisites. Just install the [gem](https://rubygems.org/gems/glimmer-dsl-libui) and have platform
|
15
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [LibUI](https://github.com/libui-ng/libui-ng) is a [Fukuoka Award Winning](http://www.digitalfukuoka.jp/topics/187?locale=ja) prerequisite-free [MRI Ruby](https://www.ruby-lang.org) desktop development cross-platform native GUI (Graphical User Interface) library. No need to pre-install any prerequisites. Just install the [gem](https://rubygems.org/gems/glimmer-dsl-libui) and have cross-platform native GUI that just works on Mac, Windows, and Linux!
|
14
16
|
|
15
17
|
Mac | Windows | Linux
|
16
18
|
----|---------|------
|
17
19
|
![glimmer-dsl-libui-mac-control-gallery.png](images/glimmer-dsl-libui-mac-control-gallery.png) | ![glimmer-dsl-libui-windows-control-gallery.png](images/glimmer-dsl-libui-windows-control-gallery.png) | ![glimmer-dsl-libui-linux-control-gallery.png](images/glimmer-dsl-libui-linux-control-gallery.png)
|
18
20
|
|
19
|
-
[LibUI](https://github.com/libui-ng/libui-ng) is a relatively new C GUI library that renders native controls 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/)).
|
21
|
+
[LibUI](https://github.com/libui-ng/libui-ng) is a relatively new C GUI library that renders native controls 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/)). Applications built with Glimmer DSL for LibUI will provide the familiar native look, feel, and behavior of GUI on Mac, Windows, and Linux.
|
20
22
|
|
21
23
|
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/libui-ng/libui-ng) 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 Ruby and 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.
|
22
24
|
|
@@ -335,26 +337,18 @@ Mac | Windows | Linux
|
|
335
337
|
|
336
338
|
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is regularly catching up with changes in the C [libui-ng](https://github.com/libui-ng/libui-ng) library API and in beta mode. The C [libui-ng](https://github.com/libui-ng/libui-ng) is still mid-alpha, which is why [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) cannot be declared v1.0.0 yet. 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.
|
337
339
|
|
338
|
-
|
339
|
-
DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
|
340
|
-
----|-----------|---------|------------------|------|------|--------
|
341
|
-
[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
|
342
|
-
[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
|
343
|
-
[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
|
344
|
-
[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
|
345
|
-
[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
|
346
|
-
[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
|
347
|
-
[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
|
348
|
-
[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
|
349
|
-
[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
|
350
|
-
[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
|
340
|
+
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)**.
|
351
341
|
|
352
342
|
## Table of Contents
|
353
343
|
|
354
344
|
- [Glimmer DSL for LibUI](#)
|
355
|
-
- [
|
345
|
+
- [Setup](#setup)
|
356
346
|
- [Usage](#usage)
|
347
|
+
- [Experimentation Usage](#experimentation-usage)
|
348
|
+
- [Prototyping Usage](#prototyping-usage)
|
349
|
+
- [Serious Usage](#serious-usage)
|
357
350
|
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
351
|
+
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
358
352
|
- [API](#api)
|
359
353
|
- [Supported Keywords](#supported-keywords)
|
360
354
|
- [Common Control Properties](#common-control-properties)
|
@@ -373,9 +367,12 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
|
|
373
367
|
- [Area Listeners](#area-listeners)
|
374
368
|
- [Area Methods/Attributes](#area-methods-attributes)
|
375
369
|
- [Area Transform Matrix](#area-transform-matrix)
|
370
|
+
- [Area Composite Shape](#area-composite-shape)
|
376
371
|
- [Area Animation](#area-animation)
|
377
372
|
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
378
|
-
- [Custom
|
373
|
+
- [Custom Controls](#custom-controls)
|
374
|
+
- [Method-Based Custom Controls](#method-based-custom-controls)
|
375
|
+
- [Class-Based Custom Controls](#class-based-custom-controls)
|
379
376
|
- [Observer Pattern](#observer-pattern)
|
380
377
|
- [Data-Binding](#data-binding)
|
381
378
|
- [Bidirectional (Two-Way) Data-Binding](#bidirectional-two-way-data-binding)
|
@@ -409,6 +406,197 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
|
|
409
406
|
- [Contributors](#contributors)
|
410
407
|
- [License](#license)
|
411
408
|
|
409
|
+
## Setup
|
410
|
+
|
411
|
+
Install [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui) gem directly into a [maintained Ruby version](https://www.ruby-lang.org/en/downloads/):
|
412
|
+
|
413
|
+
```
|
414
|
+
gem install glimmer-dsl-libui
|
415
|
+
```
|
416
|
+
|
417
|
+
Or install via Bundler `Gemfile`:
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
gem 'glimmer-dsl-libui', '~> 0.9.0'
|
421
|
+
```
|
422
|
+
|
423
|
+
Test that installation worked by running the [Glimmer Meta-Example](#examples):
|
424
|
+
|
425
|
+
```
|
426
|
+
glimmer examples
|
427
|
+
```
|
428
|
+
|
429
|
+
Or alternatively, run using the explicit Ruby command:
|
430
|
+
|
431
|
+
```
|
432
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/meta_example'"
|
433
|
+
```
|
434
|
+
|
435
|
+
Mac | Windows | Linux
|
436
|
+
----|---------|------
|
437
|
+
![glimmer-dsl-libui-mac-meta-example.png](images/glimmer-dsl-libui-mac-meta-example.png) | ![glimmer-dsl-libui-windows-meta-example.png](images/glimmer-dsl-libui-windows-meta-example.png) | ![glimmer-dsl-libui-linux-meta-example.png](images/glimmer-dsl-libui-linux-meta-example.png)
|
438
|
+
|
439
|
+
## Usage
|
440
|
+
|
441
|
+
Require [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui) (whether through a Ruby `require` statement or `Bundler`) and then include the `Glimmer` or `Glimmer::LibUI::Application` module to enable access to the Glimmer GUI DSL in one of multiple approaches.
|
442
|
+
|
443
|
+
### Experimentation Usage
|
444
|
+
|
445
|
+
For experimenting and learning, add `include Glimmer` into the top-level main object and start using the Glimmer GUI DSL directly.
|
446
|
+
|
447
|
+
Example including `Glimmer` at the top-level scope just for some prototyping/demoing/testing (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
require 'glimmer-dsl-libui'
|
451
|
+
|
452
|
+
include Glimmer
|
453
|
+
|
454
|
+
window('hello world', 300, 200) {
|
455
|
+
button('Button') {
|
456
|
+
on_clicked do
|
457
|
+
puts 'Button Clicked'
|
458
|
+
end
|
459
|
+
}
|
460
|
+
}.show
|
461
|
+
```
|
462
|
+
|
463
|
+
![usage mac](images/glimmer-dsl-libui-mac-usage.png)
|
464
|
+
|
465
|
+
### Prototyping Usage
|
466
|
+
|
467
|
+
For prototyping, add `include Glimmer` into an actual class and start using the Glimmer GUI DSL in instance methods.
|
468
|
+
|
469
|
+
Example including `Glimmer` and manually implementing the `#launch` method (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
470
|
+
|
471
|
+
```ruby
|
472
|
+
require 'glimmer-dsl-libui'
|
473
|
+
|
474
|
+
class SomeGlimmerApp
|
475
|
+
include Glimmer
|
476
|
+
|
477
|
+
def launch
|
478
|
+
window('hello world', 300, 200) {
|
479
|
+
button('Button') {
|
480
|
+
on_clicked do
|
481
|
+
puts 'Button Clicked'
|
482
|
+
end
|
483
|
+
}
|
484
|
+
}.show
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
SomeGlimmerApp.new.launch
|
489
|
+
```
|
490
|
+
|
491
|
+
![usage mac](images/glimmer-dsl-libui-mac-usage.png)
|
492
|
+
|
493
|
+
### Serious Usage
|
494
|
+
|
495
|
+
For more serious usage, add `include Glimmer::LibUI::Application` into an actual class (it automatically includes the `Glimmer` module) to conveniently declare the GUI underneath a `body` block (with the option of implementing `before_body` and `after_body` hooks) and take advantage of the inherited `SomeClass::launch` method implementation that automatically calls `window.show` for you.
|
496
|
+
|
497
|
+
Example including `Glimmer::LibUI::Application` (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
498
|
+
|
499
|
+
```ruby
|
500
|
+
require 'glimmer-dsl-libui'
|
501
|
+
|
502
|
+
class SomeGlimmerApp
|
503
|
+
include Glimmer::LibUI::Application
|
504
|
+
|
505
|
+
body {
|
506
|
+
window('hello world', 300, 200) {
|
507
|
+
button('Button') {
|
508
|
+
on_clicked do
|
509
|
+
puts 'Button Clicked'
|
510
|
+
end
|
511
|
+
}
|
512
|
+
}
|
513
|
+
}
|
514
|
+
end
|
515
|
+
|
516
|
+
SomeGlimmerApp.launch
|
517
|
+
```
|
518
|
+
|
519
|
+
![usage mac](images/glimmer-dsl-libui-mac-usage.png)
|
520
|
+
|
521
|
+
(note: `Glimmer::LibUI::Application` is an alias for `Glimmer::LibUI::CustomWindow` since that is what it represents)
|
522
|
+
|
523
|
+
If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), check out the [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts), [Glimmer Command](#glimmer-command), [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. You may refer to the [API](#api) later on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
|
524
|
+
|
525
|
+
|
526
|
+
## Glimmer Command
|
527
|
+
|
528
|
+
The `glimmer` command allows you to conveniently:
|
529
|
+
- Run Glimmer DSL for LibUI applications (via `glimmer [app_path]`)
|
530
|
+
- Run Glimmer DSL for LibUI included examples (via `glimmer examples`, which brings up the [Glimmer Meta-Example](https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/examples/meta_example.rb))
|
531
|
+
|
532
|
+
You can bring up usage instructions by running the `glimmer` command without arguments:
|
533
|
+
|
534
|
+
```
|
535
|
+
glimmer
|
536
|
+
```
|
537
|
+
|
538
|
+
```
|
539
|
+
% bin/glimmer
|
540
|
+
Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library) - Ruby Gem: glimmer-dsl-libui v0.8.0
|
541
|
+
|
542
|
+
Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-ruby-option]...] (application.rb or task[task_args])
|
543
|
+
|
544
|
+
Runs Glimmer applications and tasks.
|
545
|
+
|
546
|
+
When applications are specified, they are run using Ruby,
|
547
|
+
automatically preloading the glimmer-dsl-libui Ruby gem.
|
548
|
+
|
549
|
+
Optionally, extra Glimmer options, Ruby options, and/or environment variables may be passed in.
|
550
|
+
|
551
|
+
Glimmer options:
|
552
|
+
- "--bundler=GROUP" : Activates gems in Bundler default group in Gemfile
|
553
|
+
- "--pd=BOOLEAN" : Requires puts_debuggerer to enable pd method
|
554
|
+
- "--quiet=BOOLEAN" : Does not announce file path of Glimmer application being launched
|
555
|
+
- "--debug" : Displays extra debugging information and enables debug logging
|
556
|
+
- "--log-level=VALUE" : Sets Glimmer's Ruby logger level ("ERROR" / "WARN" / "INFO" / "DEBUG"; default is none)
|
557
|
+
|
558
|
+
Tasks are run via rake. Some tasks take arguments in square brackets (surround with double-quotes if using Zsh).
|
559
|
+
|
560
|
+
Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
|
561
|
+
|
562
|
+
Select a Glimmer task to run: (Press ↑/↓ arrow to move, Enter to select and letters to filter)
|
563
|
+
‣ glimmer examples # Brings up the Glimmer Meta-Sample app to allow browsing, running, and viewing code of Glimmer samples
|
564
|
+
glimmer list:gems:customcontrol[query] # List Glimmer custom control gems available at rubygems.org (query is optional) [alt: list:gems:cc]
|
565
|
+
glimmer list:gems:customshape[query] # List Glimmer custom shape gems available at rubygems.org (query is optional) [alt: list:gems:cs]
|
566
|
+
glimmer list:gems:customwindow[query] # List Glimmer custom window gems available at rubygems.org (query is optional) [alt: list:gems:cw]
|
567
|
+
glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
568
|
+
glimmer run[app_path] # Runs Glimmer app or custom window gem in the current directory, unless app_path is specified, then runs it instead (app_path is optional)
|
569
|
+
glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
|
570
|
+
glimmer scaffold:customcontrol[name,namespace] # Scaffold Glimmer::UI::CustomControl subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cc]
|
571
|
+
glimmer scaffold:customshape[name,namespace] # Scaffold Glimmer::UI::CustomShape subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cs]
|
572
|
+
glimmer scaffold:customwindow[name,namespace] # Scaffold Glimmer::UI::CustomWindow subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cw]
|
573
|
+
glimmer scaffold:gem:customcontrol[name,namespace] # Scaffold Glimmer::UI::CustomControl subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cc]
|
574
|
+
glimmer scaffold:gem:customshape[name,namespace] # Scaffold Glimmer::UI::CustomShape subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cs]
|
575
|
+
glimmer scaffold:gem:customwindow[name,namespace] # Scaffold Glimmer::UI::CustomWindow subclass (full window view) under its own Ruby gem + app project (namespace is required) [alt: scaffold:gem:cw]
|
576
|
+
```
|
577
|
+
|
578
|
+
On Mac and Linux, it brings up a TUI (Text-based User Interface) for interactive navigation and execution of Glimmer tasks (courtesy of [rake-tui](https://github.com/AndyObtiva/rake-tui)).
|
579
|
+
|
580
|
+
On Windows and ARM64 machines, it simply lists the available Glimmer tasks at the end (courtsey of [rake](https://github.com/ruby/rake)).
|
581
|
+
|
582
|
+
Note: If you encounter an issue running the `glimmer` command, run `bundle exec glimmer` instead.
|
583
|
+
|
584
|
+
## Girb (Glimmer IRB)
|
585
|
+
|
586
|
+
You can run the `girb` command (`bin/girb` if you cloned the project locally) to do some quick and dirty experimentation and learning:
|
587
|
+
|
588
|
+
```
|
589
|
+
girb
|
590
|
+
```
|
591
|
+
|
592
|
+
This gives you `irb` with the `glimmer-dsl-libui` gem loaded and the `Glimmer` module mixed into the main object for easy experimentation with GUI.
|
593
|
+
|
594
|
+
![glimmer-dsl-libui-girb.png](images/glimmer-dsl-libui-girb.png)
|
595
|
+
|
596
|
+
For a more advanced code editing tool, check out the [Meta-Example (The Example of Examples)](#examples).
|
597
|
+
|
598
|
+
Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
|
599
|
+
|
412
600
|
## Glimmer GUI DSL Concepts
|
413
601
|
|
414
602
|
The Glimmer GUI DSL provides object-oriented declarative hierarchical syntax for [LibUI](https://github.com/kojix2/LibUI) that:
|
@@ -532,115 +720,6 @@ window('hello world', 300, 200) {
|
|
532
720
|
end
|
533
721
|
}.show
|
534
722
|
```
|
535
|
-
|
536
|
-
## Usage
|
537
|
-
|
538
|
-
Install [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui) gem directly into a [maintained Ruby version](https://www.ruby-lang.org/en/downloads/):
|
539
|
-
|
540
|
-
```
|
541
|
-
gem install glimmer-dsl-libui
|
542
|
-
```
|
543
|
-
|
544
|
-
Or install via Bundler `Gemfile`:
|
545
|
-
|
546
|
-
```ruby
|
547
|
-
gem 'glimmer-dsl-libui', '~> 0.7.8'
|
548
|
-
```
|
549
|
-
|
550
|
-
Test that installation worked by running the [Meta-Example](#examples):
|
551
|
-
|
552
|
-
```
|
553
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/meta_example'"
|
554
|
-
```
|
555
|
-
|
556
|
-
Mac | Windows | Linux
|
557
|
-
----|---------|------
|
558
|
-
![glimmer-dsl-libui-mac-meta-example.png](images/glimmer-dsl-libui-mac-meta-example.png) | ![glimmer-dsl-libui-windows-meta-example.png](images/glimmer-dsl-libui-windows-meta-example.png) | ![glimmer-dsl-libui-linux-meta-example.png](images/glimmer-dsl-libui-linux-meta-example.png)
|
559
|
-
|
560
|
-
Now to use [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui), add `require 'glimmer-dsl-libui'` at the top.
|
561
|
-
|
562
|
-
Afterwards, `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
|
563
|
-
|
564
|
-
Alternatively, `include Glimmer::LibUI::Application` to conveniently declare the GUI `body` and run via the `::launch` method (`Glimmer::LibUI::Application` is an alias for `Glimmer::LibUI::CustomWindow` since that is what it represents).
|
565
|
-
|
566
|
-
Example including `Glimmer::LibUI::Application` (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
567
|
-
|
568
|
-
```ruby
|
569
|
-
require 'glimmer-dsl-libui'
|
570
|
-
|
571
|
-
class SomeGlimmerApp
|
572
|
-
include Glimmer::LibUI::Application
|
573
|
-
|
574
|
-
body {
|
575
|
-
window('hello world', 300, 200) {
|
576
|
-
button('Button') {
|
577
|
-
on_clicked do
|
578
|
-
puts 'Button Clicked'
|
579
|
-
end
|
580
|
-
}
|
581
|
-
}
|
582
|
-
}
|
583
|
-
end
|
584
|
-
|
585
|
-
SomeGlimmerApp.launch
|
586
|
-
```
|
587
|
-
|
588
|
-
Example including `Glimmer` and manually implementing the `#launch` method (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
589
|
-
|
590
|
-
```ruby
|
591
|
-
require 'glimmer-dsl-libui'
|
592
|
-
|
593
|
-
class SomeGlimmerApp
|
594
|
-
include Glimmer
|
595
|
-
|
596
|
-
def launch
|
597
|
-
window('hello world', 300, 200) {
|
598
|
-
button('Button') {
|
599
|
-
on_clicked do
|
600
|
-
puts 'Button Clicked'
|
601
|
-
end
|
602
|
-
}
|
603
|
-
}.show
|
604
|
-
end
|
605
|
-
end
|
606
|
-
|
607
|
-
SomeGlimmerApp.new.launch
|
608
|
-
```
|
609
|
-
|
610
|
-
Example including `Glimmer` at the top-level scope just for some prototyping/demoing/testing (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
611
|
-
|
612
|
-
```ruby
|
613
|
-
require 'glimmer-dsl-libui'
|
614
|
-
|
615
|
-
include Glimmer
|
616
|
-
|
617
|
-
window('hello world', 300, 200) {
|
618
|
-
button('Button') {
|
619
|
-
on_clicked do
|
620
|
-
puts 'Button Clicked'
|
621
|
-
end
|
622
|
-
}
|
623
|
-
}.show
|
624
|
-
```
|
625
|
-
|
626
|
-
If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), check out [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. You may refer to the [API](#api) later on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
|
627
|
-
|
628
|
-
## Girb (Glimmer IRB)
|
629
|
-
|
630
|
-
You can run the `girb` command (`bin/girb` if you cloned the project locally) to do some quick and dirty experimentation and learning:
|
631
|
-
|
632
|
-
```
|
633
|
-
girb
|
634
|
-
```
|
635
|
-
|
636
|
-
This gives you `irb` with the `glimmer-dsl-libui` gem loaded and the `Glimmer` module mixed into the main object for easy experimentation with GUI.
|
637
|
-
|
638
|
-
![glimmer-dsl-libui-girb.png](images/glimmer-dsl-libui-girb.png)
|
639
|
-
|
640
|
-
For a more advanced code editing tool, check out the [Meta-Example (The Example of Examples)](#examples).
|
641
|
-
|
642
|
-
Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
|
643
|
-
|
644
723
|
## API
|
645
724
|
|
646
725
|
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`).
|
@@ -773,7 +852,7 @@ Keyword(Args) | Properties | Listeners
|
|
773
852
|
|
774
853
|
All operations that could normally be called on `LibUI` can also be called on `Glimmer::LibUI`, but some have enhancements as detailed below.
|
775
854
|
|
776
|
-
- `Glimmer::LibUI::queue_main(&block)`: queues an operation to be run on the main event loop at the earliest opportunity possible
|
855
|
+
- `Glimmer::LibUI::queue_main(&block)`: queues an operation to be run on the main event loop at the earliest opportunity possible. When writing multi-threaded code, it is required to wrap all code interacting with GUI objects (like `window` or `button`) from another `Thread` with `Glimmer::LibUI::queue_main { ... }`. See [Glimmer Meta-Example](https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/examples/meta_example.rb) for an example of using `Glimmer::LibUI::queue_main { ... }` inside another `Thread`.
|
777
856
|
- `Glimmer::LibUI::timer(time_in_seconds=0.1, repeat: true, &block)`: calls block after time_in_seconds has elapsed, repeating indefinitely unless repeat is `false` or an `Integer` for finite number of repeats. Block can return `false` or `true` to override next repetition.
|
778
857
|
|
779
858
|
There are additional useful `Glimmer::LibUI` operations that are not found in `LibUI`, which mostly help if you would like to do advanced lower level [LibUI](https://github.com/kojix2/LibUI) programming:
|
@@ -1563,6 +1642,170 @@ You can set a `matrix`/`transform` on `area` directly to conveniently apply to a
|
|
1563
1642
|
|
1564
1643
|
Note that `area`, `path`, and nested shapes are all truly declarative, meaning they do not care about the ordering of calls to `fill`, `stroke`, and `transform`. Furthermore, any transform that is applied is reversed at the end of the block, so you never have to worry about the ordering of `transform` calls among different paths. You simply set a transform on the `path`s that need it and it is guaranteed to be called before all its content is drawn, and then undone afterwards to avoid affecting later paths. Matrix `transform` can be set on an entire `area` too, applying to all nested `path`s.
|
1565
1644
|
|
1645
|
+
#### Area Composite Shape
|
1646
|
+
|
1647
|
+
If you would like to build a composite shape that contains smaller sub-shapes, which would all get treated as a single unit,
|
1648
|
+
you can use the `shape` (or `composite_shape`) keyword, and wrap all the sub-shapes within the composite `shape`.
|
1649
|
+
|
1650
|
+
If you specify the `fill`, `stroke`, and `transform` at the `shape` level, they will get inherited by all sub-shapes that do not
|
1651
|
+
specify values for `fill`, `stroke`, or `transform` (though if they do, they override their parent's value).
|
1652
|
+
|
1653
|
+
When you use the `include?(x, y)` or `contain?(x, y)` method on a composite `shape`, it automatically includes all its aggregated shapes
|
1654
|
+
in the inclusion or containment check using the corresponding [PerfectShape](https://github.com/AndyObtiva/perfect-shape) object.
|
1655
|
+
|
1656
|
+
Example of a `cube` method-based custom shape built using the composite `shape` keyword:
|
1657
|
+
|
1658
|
+
![glimmer-dsl-libui-mac-basic-composite-shape.gif](/images/glimmer-dsl-libui-mac-basic-composite-shape.gif)
|
1659
|
+
|
1660
|
+
```ruby
|
1661
|
+
require 'glimmer-dsl-libui'
|
1662
|
+
|
1663
|
+
class BasicCompositeShape
|
1664
|
+
include Glimmer::LibUI::Application
|
1665
|
+
|
1666
|
+
body {
|
1667
|
+
window {
|
1668
|
+
title 'Basic Composite Shape'
|
1669
|
+
content_size 200, 225
|
1670
|
+
|
1671
|
+
@area = area {
|
1672
|
+
rectangle(0, 0, 200, 225) {
|
1673
|
+
fill :white
|
1674
|
+
}
|
1675
|
+
|
1676
|
+
7.times do |n|
|
1677
|
+
x_location = (rand*125).to_i%200 + (rand*15).to_i
|
1678
|
+
y_location = (rand*125).to_i%200 + (rand*15).to_i
|
1679
|
+
shape_color = [rand*125 + 130, rand*125 + 130, rand*125 + 130]
|
1680
|
+
shape_size = 20+n
|
1681
|
+
|
1682
|
+
cube(
|
1683
|
+
location_x: x_location,
|
1684
|
+
location_y: y_location,
|
1685
|
+
rectangle_width: shape_size*2,
|
1686
|
+
rectangle_height: shape_size,
|
1687
|
+
cube_height: shape_size*2,
|
1688
|
+
background_color: shape_color,
|
1689
|
+
line_thickness: 2
|
1690
|
+
) { |the_shape|
|
1691
|
+
on_mouse_up do |area_mouse_event|
|
1692
|
+
# Change color on mouse up without dragging
|
1693
|
+
if @drag_shape.nil?
|
1694
|
+
background_color = [rand(255), rand(255), rand(255)]
|
1695
|
+
the_shape.fill = background_color
|
1696
|
+
end
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
on_mouse_drag_start do |area_mouse_event|
|
1700
|
+
@drag_shape = the_shape
|
1701
|
+
@drag_x = area_mouse_event[:x]
|
1702
|
+
@drag_y = area_mouse_event[:y]
|
1703
|
+
end
|
1704
|
+
|
1705
|
+
on_mouse_drag do |area_mouse_event|
|
1706
|
+
if @drag_shape && @drag_x && @drag_y
|
1707
|
+
drag_distance_width = area_mouse_event[:x] - @drag_x
|
1708
|
+
drag_distance_height = area_mouse_event[:y] - @drag_y
|
1709
|
+
@drag_shape.x += drag_distance_width
|
1710
|
+
@drag_shape.y += drag_distance_height
|
1711
|
+
@drag_x = area_mouse_event[:x]
|
1712
|
+
@drag_y = area_mouse_event[:y]
|
1713
|
+
end
|
1714
|
+
end
|
1715
|
+
|
1716
|
+
on_mouse_drop do |area_mouse_event|
|
1717
|
+
@drag_shape = nil
|
1718
|
+
@drag_x = nil
|
1719
|
+
@drag_y = nil
|
1720
|
+
end
|
1721
|
+
}
|
1722
|
+
end
|
1723
|
+
|
1724
|
+
# this general area on_mouse_drag listener is needed to ensure that dragging a shape
|
1725
|
+
# outside of its boundaries would still move the dragged shape
|
1726
|
+
on_mouse_drag do |area_mouse_event|
|
1727
|
+
if @drag_shape && @drag_x && @drag_y
|
1728
|
+
drag_distance_width = area_mouse_event[:x] - @drag_x
|
1729
|
+
drag_distance_height = area_mouse_event[:y] - @drag_y
|
1730
|
+
@drag_shape.x += drag_distance_width
|
1731
|
+
@drag_shape.y += drag_distance_height
|
1732
|
+
@drag_x = area_mouse_event[:x]
|
1733
|
+
@drag_y = area_mouse_event[:y]
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
on_mouse_drop do |area_mouse_event|
|
1738
|
+
@drag_shape = nil
|
1739
|
+
@drag_x = nil
|
1740
|
+
@drag_y = nil
|
1741
|
+
end
|
1742
|
+
}
|
1743
|
+
}
|
1744
|
+
}
|
1745
|
+
|
1746
|
+
# method-based custom shape using `shape` keyword as a composite shape containing nested shapes
|
1747
|
+
# that are declared with relative positioning
|
1748
|
+
def cube(location_x: 0,
|
1749
|
+
location_y: 0,
|
1750
|
+
rectangle_width: nil,
|
1751
|
+
rectangle_height: nil,
|
1752
|
+
cube_height: nil,
|
1753
|
+
background_color: :brown,
|
1754
|
+
line_thickness: 1,
|
1755
|
+
&content_block)
|
1756
|
+
default_size = 28
|
1757
|
+
rectangle_width ||= rectangle_height || cube_height || default_size
|
1758
|
+
rectangle_height ||= rectangle_width || cube_height || default_size
|
1759
|
+
cube_height ||= rectangle_width || rectangle_height || default_size
|
1760
|
+
foreground_color = [0, 0, 0, thickness: line_thickness]
|
1761
|
+
|
1762
|
+
# the shape keyword (alias for composite_shape) enables building a composite shape that is treated as one shape
|
1763
|
+
# like a cube containing polygons, a polyline, a rectangle, and a line
|
1764
|
+
# with the fill and stroke colors getting inherited by all children that do not specify them
|
1765
|
+
shape(location_x, location_y) { |the_shape|
|
1766
|
+
fill background_color
|
1767
|
+
stroke foreground_color
|
1768
|
+
|
1769
|
+
bottom = polygon(0, cube_height + rectangle_height / 2.0,
|
1770
|
+
rectangle_width / 2.0, cube_height,
|
1771
|
+
rectangle_width, cube_height + rectangle_height / 2.0,
|
1772
|
+
rectangle_width / 2.0, cube_height + rectangle_height) {
|
1773
|
+
# inherits fill property from parent shape if not set
|
1774
|
+
# inherits stroke property from parent shape if not set
|
1775
|
+
}
|
1776
|
+
body = rectangle(0, rectangle_height / 2.0, rectangle_width, cube_height) {
|
1777
|
+
# inherits fill property from parent shape if not set
|
1778
|
+
# stroke is overridden to ensure a different value from parent
|
1779
|
+
stroke thickness: 0
|
1780
|
+
}
|
1781
|
+
polyline(0, rectangle_height / 2.0 + cube_height,
|
1782
|
+
0, rectangle_height / 2.0,
|
1783
|
+
rectangle_width, rectangle_height / 2.0,
|
1784
|
+
rectangle_width, rectangle_height / 2.0 + cube_height) {
|
1785
|
+
# inherits stroke property from parent shape if not set
|
1786
|
+
}
|
1787
|
+
top = polygon(0, rectangle_height / 2.0,
|
1788
|
+
rectangle_width / 2.0, 0,
|
1789
|
+
rectangle_width, rectangle_height / 2.0,
|
1790
|
+
rectangle_width / 2.0, rectangle_height) {
|
1791
|
+
# inherits fill property from parent shape if not set
|
1792
|
+
# inherits stroke property from parent shape if not set
|
1793
|
+
}
|
1794
|
+
line(rectangle_width / 2.0, cube_height + rectangle_height,
|
1795
|
+
rectangle_width / 2.0, rectangle_height) {
|
1796
|
+
# inherits stroke property from parent shape if not set
|
1797
|
+
}
|
1798
|
+
|
1799
|
+
content_block&.call(the_shape)
|
1800
|
+
}
|
1801
|
+
end
|
1802
|
+
end
|
1803
|
+
|
1804
|
+
BasicCompositeShape.launch
|
1805
|
+
|
1806
|
+
|
1807
|
+
```
|
1808
|
+
|
1566
1809
|
#### Area Animation
|
1567
1810
|
|
1568
1811
|
If you need to animate `area` vector graphics, you just have to use the [`Glimmer::LibUI::timer`](#libui-operations) method along with making changes to shape attributes.
|
@@ -1696,17 +1939,21 @@ SpinnerExample.new.launch
|
|
1696
1939
|
- Colors may be passed in as a hash of `:r`, `:g`, `:b`, `:a`, or `:red`, `:green`, `:blue`, `:alpha`, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color like `:skyblue`, or 6-char hex or 3-char hex (as `Integer` or `String` with or without `0x` prefix)
|
1697
1940
|
- Color alpha value defaults to `1.0` when not specified.
|
1698
1941
|
|
1699
|
-
### Custom
|
1942
|
+
### Custom Controls
|
1700
1943
|
|
1701
|
-
Custom
|
1944
|
+
Custom controls can be defined to represent custom controls (components) that provide new features or act as composites of [existing controls](#supported-keywords) that need to be reused multiple times in an application or across multiple applications. Custom controls save a lot of development time, improving productivity and maintainability immensely.
|
1702
1945
|
|
1703
1946
|
For example, you can define a custom `address_view` control as an aggregate of multiple `label` controls to reuse multiple times as a standard address View, displaying street, city, state, and zip code.
|
1704
1947
|
|
1705
|
-
There are two ways to define custom
|
1948
|
+
There are two ways to define custom controls:
|
1706
1949
|
- Method-Based: simply define a method representing the custom control you want (e.g. `address_view`) with any arguments needed (e.g. `address(address_model)`).
|
1707
1950
|
- Class-Based: define a class matching the camelcased name of the custom control by convention (e.g. the `address_view` custom control keyword would have a class called `AddressView`) and `include Glimmer::LibUI::CustomControl`. Classes add the benefit of being able to distribute the custom controls into separate files and reuse externally from multiple places or share via Ruby gems.
|
1708
1951
|
|
1709
|
-
It is OK to use the terms "custom
|
1952
|
+
It is OK to use the terms "custom control" and "custom keyword" synonymously though "custom keyword" is a broader term that covers things other than controls too like custom shapes (e.g. `cylinder`), custom attributed strings (e.g. `alternating_color_string`), and custom transforms (`isometric_transform`).
|
1953
|
+
|
1954
|
+
#### Method-Based Custom Controls
|
1955
|
+
|
1956
|
+
Simply define a method representing the custom control you want (e.g. `address_view`) with any arguments needed (e.g. `address(address_model)`).
|
1710
1957
|
|
1711
1958
|
Example that defines `form_field`, `address_form`, `label_pair`, and `address_view` keywords (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
1712
1959
|
|
@@ -1805,7 +2052,9 @@ window('Method-Based Custom Keyword') {
|
|
1805
2052
|
|
1806
2053
|
![glimmer-dsl-libui-mac-method-based-custom-keyword.png](images/glimmer-dsl-libui-mac-method-based-custom-keyword.png)
|
1807
2054
|
|
1808
|
-
|
2055
|
+
#### Class-Based Custom Controls
|
2056
|
+
|
2057
|
+
Define a class matching the camelcased name of the custom control by convention (e.g. the `address_view` custom control keyword would have a class called `AddressView`) and `include Glimmer::LibUI::CustomControl`. Classes add the benefit of being able to distribute the custom controls into separate files and reuse externally from multiple places or share via Ruby gems.
|
1809
2058
|
|
1810
2059
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
1811
2060
|
|
@@ -1935,11 +2184,13 @@ ClassBasedCustomControls.launch
|
|
1935
2184
|
|
1936
2185
|
![glimmer-dsl-libui-mac-method-based-custom-keyword.png](images/glimmer-dsl-libui-mac-method-based-custom-keyword.png)
|
1937
2186
|
|
2187
|
+
You can also define Custom Window keywords, that is custom controls with `window` being the body root. These are also known as Applications. To define a Custom Window, you `include Glimmer::LibUI::CustomWindow` or `include Glimmer:LibUI::Application` and then you can invoke the `::launch` method on the class.
|
2188
|
+
|
1938
2189
|
The [`area`](#area-api) control can be utilized to build non-native custom controls from scratch by leveraging vector graphics, formattable text, keyboard events, and mouse events. This is demonstrated in the [Area-Based Custom Controls](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#area-based-custom-controls) example.
|
1939
2190
|
|
1940
|
-
Defining custom
|
2191
|
+
Defining custom controls enables unlimited extension of the [Glimmer GUI DSL](#glimmer-gui-dsl). The sky is the limit on what can be done with custom controls as a result. You can compose new visual vocabulary to build applications in any domain from higher concepts rather than [mere standard controls](#supported-keywords). For example, in a traffic signaling app, you could define `street`, `light_signal`, `traffic_sign`, and `car` as custom keywords and build your application from these concepts directly, saving enormous time and achieving much higher productivity.
|
1941
2192
|
|
1942
|
-
Learn more from custom
|
2193
|
+
Learn more from custom control usage in [Method-Based Custom Keyword](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#method-based-custom-keyword), [Area-Based Custom Controls](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#area-based-custom-controls), [Basic Scrolling Area](/docs/examples/GLIMMER-DSL-LIBUI-BASIC-EXAMPLES.md#basic-scrolling-area), [Histogram](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#histogram), and [Tetris](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#tetris) examples.
|
1943
2194
|
|
1944
2195
|
### Observer Pattern
|
1945
2196
|
|
@@ -2249,7 +2500,8 @@ Learn more from data-binding usage in [Login](/docs/examples/GLIMMER-DSL-LIBUI-A
|
|
2249
2500
|
- `text` `string` `background` does not work on Windows due to an [issue in libui](https://github.com/andlabs/libui/issues/347).
|
2250
2501
|
- `table` `progress_bar` column on Windows cannot be updated with a positive value if it started initially with `-1` (it ignores update to avoid crashing due to an issue in [libui](https://github.com/andlabs/libui) on Windows.
|
2251
2502
|
- `radio_buttons` on Linux has an issue where it always selects the first item even if you did not set its `selected` value or set it to `-1` (meaning unselected). It works correctly on Mac and Windows.
|
2252
|
-
- It seems that [libui](https://github.com/
|
2503
|
+
- It seems that [libui](https://github.com/libui-ng/libui-ng) does not support nesting multiple `area` controls under a `grid` as only the first one shows up in that scenario. To workaround that limitation, use a `vertical_box` with nested `horizontal_box`s instead to include multiple `area`s in a GUI.
|
2504
|
+
- Both `multiline_entry` and `non_wrapping_multiline_entry` do not seem to play well with being nested in a `grid`. To get around the problem, I would use a combination of `vertical_box` and `horizontal_box`s instead.
|
2253
2505
|
- As per the code of [examples/basic_transform.rb](/docs/examples/GLIMMER-DSL-LIBUI-BASIC-EXAMPLES.md#basic-transform), Windows requires different ordering of transforms than Mac and Linux.
|
2254
2506
|
- `scrolling_area#scroll_to` does not seem to work on Windows and Linux, but works fine on Mac
|
2255
2507
|
|
@@ -2267,7 +2519,7 @@ To learn more about the [LibUI](https://github.com/kojix2/LibUI) API exposed thr
|
|
2267
2519
|
|
2268
2520
|
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.
|
2269
2521
|
|
2270
|
-
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.
|
2522
|
+
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. And, there is a newer fork of the project that supports newer versions of Ruby called [OCRAN](https://github.com/Largo/ocran).
|
2271
2523
|
|
2272
2524
|
For Mac, consider [Platypus](https://github.com/sveinbjornt/Platypus) (builds a native Mac app from a Ruby script)
|
2273
2525
|
|
@@ -2275,6 +2527,8 @@ For Linux, simply package your app as a [Ruby Gem](https://guides.rubygems.org/w
|
|
2275
2527
|
|
2276
2528
|
Also, there is a promising project called [ruby-packer](https://github.com/pmq20/ruby-packer) that supports all platforms.
|
2277
2529
|
|
2530
|
+
Last but not least, Ruby recently supported WASM, including the ability to [package a Ruby application as a WASI application](https://github.com/ruby/ruby.wasm#quick-example-how-to-package-your-ruby-application-as-a-wasi-application).
|
2531
|
+
|
2278
2532
|
## Glimmer Style Guide
|
2279
2533
|
|
2280
2534
|
**1 - Control arguments are always wrapped by parentheses.**
|
@@ -2683,6 +2937,12 @@ https://github.com/kojix2/htsgrid
|
|
2683
2937
|
|
2684
2938
|
![hts grid screenshot](https://raw.githubusercontent.com/AndyObtiva/htsgrid/main/screenshot-00.png)
|
2685
2939
|
|
2940
|
+
### Electric Avenue
|
2941
|
+
|
2942
|
+
This is built as an exploratory software prototype by [Ari Brown](https://github.com/seydar) (closed source software).
|
2943
|
+
|
2944
|
+
![Electric Avenue](https://user-images.githubusercontent.com/16188/260890040-b4b28429-1789-4cdd-a708-45a2bd62b70f.png)
|
2945
|
+
|
2686
2946
|
## Process
|
2687
2947
|
|
2688
2948
|
[Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
|