glimmer-dsl-libui 0.4.19 → 0.4.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +323 -12
- data/VERSION +1 -1
- data/examples/area_based_custom_controls.rb +278 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/box.rb +1 -0
- data/lib/glimmer/libui/control_proxy/form_proxy.rb +1 -0
- data/lib/glimmer/libui/control_proxy.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 594b6127dd134d82d6f91dd4856aadb841ecceb04a8e9b34741d940212956997
|
4
|
+
data.tar.gz: efe2aa6e53ea80b58c1a1a12351c67e476e5ec3170aba680573d2f963680ccba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d21fba0daf5a73da1b7d31aac00d492508d92ceda522751a3908b7b3c794368286e7d971aa525322a08d91f48e11b71ad9c838393de65e12c4fc5f8133b5e6f
|
7
|
+
data.tar.gz: 2e448728ad41a976a169e5913e941cad523c5f897849ccacc82eb9d1ae2c75e002b8c9c5a933b9642d2845d263ed252a2e4826e29a0d18467b5e6bae63b51f8e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.4.20
|
4
|
+
|
5
|
+
- New examples/area_based_custom_controls.rb
|
6
|
+
- Fix issue with calling `destroy` multiple times on children of `vertical_box`/`horizontal_box`/`form` (worked only the first time before this fix)
|
7
|
+
|
3
8
|
## 0.4.19
|
4
9
|
|
5
10
|
- Have `line` optionally support 4 arguments instead of 2 to use outside of a `figure`
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.4.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.4.20
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -324,7 +324,7 @@ Mac | Windows | Linux
|
|
324
324
|
----|---------|------
|
325
325
|
![glimmer-dsl-libui-mac-tetris.png](images/glimmer-dsl-libui-mac-tetris.png) | ![glimmer-dsl-libui-windows-tetris.png](images/glimmer-dsl-libui-windows-tetris.png) | ![glimmer-dsl-libui-linux-tetris.png](images/glimmer-dsl-libui-linux-tetris.png)
|
326
326
|
|
327
|
-
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is feature-complete and in beta mode (though the C [libui](https://github.com/andlabs/libui) is still mid-alpha). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. The more feedback and issues you report the better.
|
327
|
+
NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is 100% feature-complete and in beta mode (though the C [libui](https://github.com/andlabs/libui) is still mid-alpha). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. The more feedback and issues you report the better.
|
328
328
|
|
329
329
|
Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
|
330
330
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
@@ -409,6 +409,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
409
409
|
- [Histogram](#histogram)
|
410
410
|
- [Login](#login)
|
411
411
|
- [Method-Based Custom Keyword](#method-based-custom-keyword)
|
412
|
+
- [Area-Based Custom Controls](#area-based-custom-controls)
|
412
413
|
- [Midi Player](#midi-player)
|
413
414
|
- [Snake](#snake)
|
414
415
|
- [Tetris](#tetris)
|
@@ -506,7 +507,7 @@ gem install glimmer-dsl-libui
|
|
506
507
|
Or install via Bundler `Gemfile`:
|
507
508
|
|
508
509
|
```ruby
|
509
|
-
gem 'glimmer-dsl-libui', '~> 0.4.
|
510
|
+
gem 'glimmer-dsl-libui', '~> 0.4.20'
|
510
511
|
```
|
511
512
|
|
512
513
|
Test that installation worked by running the [Meta-Example](#examples):
|
@@ -1365,8 +1366,8 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
|
|
1365
1366
|
- 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.
|
1366
1367
|
- All boolean property writers accept `true`/`false` in addition to `1`/`0` in Ruby
|
1367
1368
|
- All string property readers return a `String` object in Ruby instead of the [libui](https://github.com/andlabs/libui) Fiddle pointer object.
|
1368
|
-
- Automatically allocate font descriptors upon instantiating `font_button` controls and free them when
|
1369
|
-
- Automatically allocate color value pointers upon instantiating `color_button` controls and free them when
|
1369
|
+
- Automatically allocate font descriptors upon instantiating `font_button` controls and free them when destroying `font_button` controls
|
1370
|
+
- Automatically allocate color value pointers upon instantiating `color_button` controls and free them when destroying `color_button` controls
|
1370
1371
|
- On the Mac, if no `menu` items were added, an automatic `quit_menu_item` is added to enable quitting with CTRL+Q
|
1371
1372
|
- When destroying a control nested under a `horizontal_box` or `vertical_box`, it is automatically deleted from the box's children
|
1372
1373
|
- When destroying a control nested under a `form`, it is automatically deleted from the form's children
|
@@ -1396,14 +1397,16 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
|
|
1396
1397
|
|
1397
1398
|
### Custom Keywords
|
1398
1399
|
|
1399
|
-
Custom keywords 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 keywords save a lot of development time, improving productivity and
|
1400
|
-
|
1400
|
+
Custom keywords 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 keywords save a lot of development time, improving productivity and maintainability immensely.
|
1401
|
+
|
1401
1402
|
For example, you can define a custom `address` control as an aggregate of multiple `label` controls to reuse multiple times as a standard address View, displaying street, city, state, and zip code.
|
1402
1403
|
|
1403
1404
|
To define custom keywords, simply define a method representing the custom control you want (e.g. `address`) with any arguments needed (e.g. `address(address_model)`).
|
1404
1405
|
|
1405
1406
|
To make custom keywords externally reusable, you can define in modules and simply include the modules in the view classes that need them.
|
1406
1407
|
|
1408
|
+
It is OK to use terms "custom keyword" and "custom control" 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`).
|
1409
|
+
|
1407
1410
|
Example that defines `form_field`, `address_form`, `label_pair`, and `address` keywords (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
1408
1411
|
|
1409
1412
|
```ruby
|
@@ -1501,11 +1504,11 @@ window('Method-Based Custom Keyword') {
|
|
1501
1504
|
|
1502
1505
|
![glimmer-dsl-libui-mac-method-based-custom-keyword.png](images/glimmer-dsl-libui-mac-method-based-custom-keyword.png)
|
1503
1506
|
|
1504
|
-
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.
|
1507
|
+
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](#area-based-custom-controls) example.
|
1505
1508
|
|
1506
1509
|
Defining custom keywords enables unlimited extension of the [Glimmer GUI DSL](#glimmer-gui-dsl). The sky is the limit on what can be done with custom keywords 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.
|
1507
1510
|
|
1508
|
-
Learn more from custom keyword usage in [Method-Based Custom Keyword](#method-based-custom-keyword), [Histogram](#histogram), and [Tetris](#tetris) examples.
|
1511
|
+
Learn more from custom keyword usage in [Method-Based Custom Keyword](#method-based-custom-keyword), [Area-Based Custom Controls](#area-based-custom-controls), [Basic Scrolling Area](#basic-scrolling-area), [Histogram](#histogram), and [Tetris](#tetris) examples.
|
1509
1512
|
|
1510
1513
|
### Observer Pattern
|
1511
1514
|
|
@@ -1778,9 +1781,9 @@ Data-bound model attribute can be:
|
|
1778
1781
|
- **Indexed:** `String` containing array attribute index (e.g. `[customer, 'addresses[0].street']`). That results in "indexed data-binding"
|
1779
1782
|
|
1780
1783
|
Data-binding options include:
|
1781
|
-
- `before_read {|value| ...}`: performs an operation before reading data from Model to update
|
1784
|
+
- `before_read {|value| ...}`: performs an operation before reading data from Model to update View.
|
1782
1785
|
- `on_read {|value| ...}`: converts value read from Model to update the View.
|
1783
|
-
- `after_read {|converted_value| ...}`: performs an operation after read from Model
|
1786
|
+
- `after_read {|converted_value| ...}`: performs an operation after read from Model to update View.
|
1784
1787
|
- `before_write {|value| ...}`: performs an operation before writing data to Model from View.
|
1785
1788
|
- `on_write {|value| ...}`: converts value read from View to update the Model.
|
1786
1789
|
- `after_write {|converted_value| ...}`: performs an operation after writing to Model from View.
|
@@ -1812,6 +1815,7 @@ Learn more from data-binding usage in [Login](#login) (4 data-binding versions),
|
|
1812
1815
|
- `text` `align` property seems not to work on the Mac ([libui](https://github.com/andlabs/libui) has an [issue](https://github.com/andlabs/libui/pull/407) about it)
|
1813
1816
|
- `text` `string` `background` does not work on Windows due to an [issue in libui](https://github.com/andlabs/libui/issues/347).
|
1814
1817
|
- `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.
|
1818
|
+
- `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.
|
1815
1819
|
- It seems that [libui](https://github.com/andlabs/libui) 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.
|
1816
1820
|
- As per the code of [examples/basic_transform.rb](#basic-transform), Windows requires different ordering of transforms than Mac and Linux.
|
1817
1821
|
- `scrolling_area#scroll_to` does not seem to work on Windows and Linux, but works fine on Mac
|
@@ -8375,7 +8379,7 @@ window('Login') {
|
|
8375
8379
|
|
8376
8380
|
#### Method-Based Custom Keyword
|
8377
8381
|
|
8378
|
-
[Custom keywords](#custom-keywords) can be defined to represent custom controls (components) that provide new features or act as composites of existing controls that need to be reused multiple times in an application or across multiple applications. Custom keywords save a lot of development time, improving productivity and
|
8382
|
+
[Custom keywords](#custom-keywords) can be defined to represent custom controls (components) that provide new features or act as composites of existing controls that need to be reused multiple times in an application or across multiple applications. Custom keywords save a lot of development time, improving productivity and maintainability immensely.
|
8379
8383
|
|
8380
8384
|
This example defines `form_field`, `address_form`, `label_pair`, and `address` as custom control keywords.
|
8381
8385
|
|
@@ -8596,6 +8600,313 @@ window('Method-Based Custom Keyword') {
|
|
8596
8600
|
}.show
|
8597
8601
|
```
|
8598
8602
|
|
8603
|
+
#### Area-Based Custom Controls
|
8604
|
+
|
8605
|
+
[Custom keywords](#custom-keywords) can be defined for graphical custom controls (components) built completely from scratch as vector-graphics on top of the [`area`](#area-api) control while leveraging keyboard and mouse listeners.
|
8606
|
+
|
8607
|
+
This example defines `text_label` and `push_button` as [`area`](#area-api)-based graphical custom controls that can have width, height, font, fill, stroke, border, and custom text location.
|
8608
|
+
|
8609
|
+
[examples/area_based_custom_controls.rb](examples/area_based_custom_controls.rb)
|
8610
|
+
|
8611
|
+
Run with this command from the root of the project if you cloned the project:
|
8612
|
+
|
8613
|
+
```
|
8614
|
+
ruby -r './lib/glimmer-dsl-libui' examples/area_based_custom_controls.rb
|
8615
|
+
```
|
8616
|
+
|
8617
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
8618
|
+
|
8619
|
+
```
|
8620
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/area_based_custom_controls'"
|
8621
|
+
```
|
8622
|
+
|
8623
|
+
Mac | Windows | Linux
|
8624
|
+
----|---------|------
|
8625
|
+
![glimmer-dsl-libui-mac-area-based-custom-controls.png](images/glimmer-dsl-libui-mac-area-based-custom-controls-text-label.png) ![glimmer-dsl-libui-mac-area-based-custom-controls.png](images/glimmer-dsl-libui-mac-area-based-custom-controls-push-button.png) ![glimmer-dsl-libui-mac-area-based-custom-controls.png](images/glimmer-dsl-libui-mac-area-based-custom-controls-push-button-clicked.png) | ![glimmer-dsl-libui-windows-area-based-custom-controls.png](images/glimmer-dsl-libui-windows-area-based-custom-controls-text-label.png) ![glimmer-dsl-libui-windows-area-based-custom-controls.png](images/glimmer-dsl-libui-windows-area-based-custom-controls-push-button.png) ![glimmer-dsl-libui-windows-area-based-custom-controls.png](images/glimmer-dsl-libui-windows-area-based-custom-controls-push-button-clicked.png) | ![glimmer-dsl-libui-linux-area-based-custom-controls.png](images/glimmer-dsl-libui-linux-area-based-custom-controls-text-label.png) ![glimmer-dsl-libui-linux-area-based-custom-controls.png](images/glimmer-dsl-libui-linux-area-based-custom-controls-push-button.png) ![glimmer-dsl-libui-linux-area-based-custom-controls.png](images/glimmer-dsl-libui-linux-area-based-custom-controls-push-button-clicked.png)
|
8626
|
+
|
8627
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
8628
|
+
|
8629
|
+
```ruby
|
8630
|
+
require 'glimmer-dsl-libui'
|
8631
|
+
|
8632
|
+
class AreaBasedCustomControls
|
8633
|
+
include Glimmer
|
8634
|
+
|
8635
|
+
attr_accessor :label_width, :label_height, :label_font_descriptor,
|
8636
|
+
:label_text_color, :label_background_fill, :label_border_stroke,
|
8637
|
+
:label_text_x, :label_text_y,
|
8638
|
+
:button_width, :button_height, :button_font_descriptor,
|
8639
|
+
:button_text_color, :button_background_fill, :button_border_stroke,
|
8640
|
+
:button_text_x, :button_text_y
|
8641
|
+
|
8642
|
+
def initialize
|
8643
|
+
self.label_width = 335
|
8644
|
+
self.label_height = 50
|
8645
|
+
self.label_font_descriptor = {family: OS.linux? ? 'Bitstream Vera Sans Mono' : 'Courier New', size: 16, weight: :bold, italic: :italic}
|
8646
|
+
self.label_text_color = :red
|
8647
|
+
self.label_background_fill = :yellow
|
8648
|
+
self.label_border_stroke = :limegreen
|
8649
|
+
|
8650
|
+
self.button_width = 130
|
8651
|
+
self.button_height = 50
|
8652
|
+
self.button_font_descriptor = {family: OS.linux? ? 'Bitstream Vera Sans Mono' : 'Courier New', size: 36, weight: :bold, italic: :italic}
|
8653
|
+
self.button_text_color = :green
|
8654
|
+
self.button_background_fill = :yellow
|
8655
|
+
self.button_border_stroke = :limegreen
|
8656
|
+
end
|
8657
|
+
|
8658
|
+
def rebuild_text_label
|
8659
|
+
@text_label.destroy
|
8660
|
+
@text_label_vertical_box.content { # re-open vertical box content and shove in a new button
|
8661
|
+
@text_label = text_label('This is a text label.',
|
8662
|
+
width: label_width, height: label_height, font_descriptor: label_font_descriptor,
|
8663
|
+
background_fill: label_background_fill, text_color: label_text_color, border_stroke: label_border_stroke,
|
8664
|
+
text_x: label_text_x, text_y: label_text_y)
|
8665
|
+
}
|
8666
|
+
end
|
8667
|
+
|
8668
|
+
def rebuild_push_button
|
8669
|
+
@push_button.destroy
|
8670
|
+
@push_button_vertical_box.content { # re-open vertical box content and shove in a new button
|
8671
|
+
@push_button = push_button('Push',
|
8672
|
+
width: button_width, height: button_height, font_descriptor: button_font_descriptor,
|
8673
|
+
background_fill: button_background_fill, text_color: button_text_color, border_stroke: button_border_stroke,
|
8674
|
+
text_x: button_text_x, text_y: button_text_y) {
|
8675
|
+
on_mouse_up do
|
8676
|
+
message_box('Button Pushed', 'Thank you for pushing the button!')
|
8677
|
+
end
|
8678
|
+
}
|
8679
|
+
}
|
8680
|
+
end
|
8681
|
+
|
8682
|
+
def launch
|
8683
|
+
window('Area-Based Custom Controls', 385, 385) { |w|
|
8684
|
+
margined true
|
8685
|
+
|
8686
|
+
tab {
|
8687
|
+
tab_item('Text Label') {
|
8688
|
+
@text_label_vertical_box = vertical_box {
|
8689
|
+
vertical_box {
|
8690
|
+
text_label('Text Label Construction Form:', width: 250, height: 30, font_descriptor: {size: 16, weight: :bold}, text_x: 0, text_y: 0)
|
8691
|
+
|
8692
|
+
horizontal_box {
|
8693
|
+
label('Width')
|
8694
|
+
spinbox(1, 1000) {
|
8695
|
+
value <=> [self, :label_width, after_write: method(:rebuild_text_label)]
|
8696
|
+
}
|
8697
|
+
}
|
8698
|
+
|
8699
|
+
horizontal_box {
|
8700
|
+
label('Height')
|
8701
|
+
spinbox(1, 1000) {
|
8702
|
+
value <=> [self, :label_height, after_write: method(:rebuild_text_label)]
|
8703
|
+
}
|
8704
|
+
}
|
8705
|
+
|
8706
|
+
horizontal_box {
|
8707
|
+
label('Font')
|
8708
|
+
font_button {
|
8709
|
+
font <=> [self, :label_font_descriptor, after_write: method(:rebuild_text_label)]
|
8710
|
+
}
|
8711
|
+
}
|
8712
|
+
|
8713
|
+
horizontal_box {
|
8714
|
+
label('Text Color')
|
8715
|
+
color_button {
|
8716
|
+
color <=> [self, :label_text_color, after_write: method(:rebuild_text_label)]
|
8717
|
+
}
|
8718
|
+
}
|
8719
|
+
|
8720
|
+
horizontal_box {
|
8721
|
+
label('Background Color')
|
8722
|
+
color_button {
|
8723
|
+
color <=> [self, :label_background_fill, after_write: method(:rebuild_text_label)]
|
8724
|
+
}
|
8725
|
+
}
|
8726
|
+
|
8727
|
+
horizontal_box {
|
8728
|
+
label('Border Color')
|
8729
|
+
color_button {
|
8730
|
+
color <=> [self, :label_border_stroke, after_write: method(:rebuild_text_label)]
|
8731
|
+
}
|
8732
|
+
}
|
8733
|
+
|
8734
|
+
horizontal_box {
|
8735
|
+
label('Text X (0=centered)')
|
8736
|
+
spinbox(0, 1000) {
|
8737
|
+
value <=> [self, :label_text_x, on_read: ->(x) {x.nil? ? 0 : x}, on_write: ->(x) {x == 0 ? nil : x}, after_write: method(:rebuild_text_label)]
|
8738
|
+
}
|
8739
|
+
}
|
8740
|
+
|
8741
|
+
horizontal_box {
|
8742
|
+
label('Text Y (0=centered)')
|
8743
|
+
spinbox(0, 1000) {
|
8744
|
+
value <=> [self, :label_text_y, on_read: ->(y) {y.nil? ? 0 : y}, on_write: ->(y) {y == 0 ? nil : y}, after_write: method(:rebuild_text_label)]
|
8745
|
+
}
|
8746
|
+
}
|
8747
|
+
}
|
8748
|
+
|
8749
|
+
@text_label = text_label('This is a text label.',
|
8750
|
+
width: label_width, height: label_height, font_descriptor: label_font_descriptor,
|
8751
|
+
background_fill: label_background_fill, text_color: label_text_color, border_stroke: label_border_stroke,
|
8752
|
+
text_x: label_text_x, text_y: label_text_y)
|
8753
|
+
}
|
8754
|
+
}
|
8755
|
+
|
8756
|
+
tab_item('Push Button') {
|
8757
|
+
@push_button_vertical_box = vertical_box {
|
8758
|
+
vertical_box {
|
8759
|
+
text_label('Push Button Construction Form:', width: 250, height: 30, font_descriptor: {size: 16, weight: :bold}, text_x: 0, text_y: 0)
|
8760
|
+
|
8761
|
+
horizontal_box {
|
8762
|
+
label('Width')
|
8763
|
+
spinbox(1, 1000) {
|
8764
|
+
value <=> [self, :button_width, after_write: method(:rebuild_push_button)]
|
8765
|
+
}
|
8766
|
+
}
|
8767
|
+
|
8768
|
+
horizontal_box {
|
8769
|
+
label('Height')
|
8770
|
+
spinbox(1, 1000) {
|
8771
|
+
value <=> [self, :button_height, after_write: method(:rebuild_push_button)]
|
8772
|
+
}
|
8773
|
+
}
|
8774
|
+
|
8775
|
+
horizontal_box {
|
8776
|
+
label('Font')
|
8777
|
+
font_button {
|
8778
|
+
font <=> [self, :button_font_descriptor, after_write: method(:rebuild_push_button)]
|
8779
|
+
}
|
8780
|
+
}
|
8781
|
+
|
8782
|
+
horizontal_box {
|
8783
|
+
label('Text Color')
|
8784
|
+
color_button {
|
8785
|
+
color <=> [self, :button_text_color, after_write: method(:rebuild_push_button)]
|
8786
|
+
}
|
8787
|
+
}
|
8788
|
+
|
8789
|
+
horizontal_box {
|
8790
|
+
label('Background Color')
|
8791
|
+
color_button {
|
8792
|
+
color <=> [self, :button_background_fill, after_write: method(:rebuild_push_button)]
|
8793
|
+
}
|
8794
|
+
}
|
8795
|
+
|
8796
|
+
horizontal_box {
|
8797
|
+
label('Border Color')
|
8798
|
+
color_button {
|
8799
|
+
color <=> [self, :button_border_stroke, after_write: method(:rebuild_push_button)]
|
8800
|
+
}
|
8801
|
+
}
|
8802
|
+
|
8803
|
+
horizontal_box {
|
8804
|
+
label('Text X (0=centered)')
|
8805
|
+
spinbox(0, 1000) {
|
8806
|
+
value <=> [self, :button_text_x, on_read: ->(x) {x.nil? ? 0 : x}, on_write: ->(x) {x == 0 ? nil : x}, after_write: method(:rebuild_push_button)]
|
8807
|
+
}
|
8808
|
+
}
|
8809
|
+
|
8810
|
+
horizontal_box {
|
8811
|
+
label('Text Y (0=centered)')
|
8812
|
+
spinbox(0, 1000) {
|
8813
|
+
value <=> [self, :button_text_y, on_read: ->(y) {y.nil? ? 0 : y}, on_write: ->(y) {y == 0 ? nil : y}, after_write: method(:rebuild_push_button)]
|
8814
|
+
}
|
8815
|
+
}
|
8816
|
+
}
|
8817
|
+
|
8818
|
+
@push_button = push_button('Push',
|
8819
|
+
width: button_width, height: button_height, font_descriptor: button_font_descriptor,
|
8820
|
+
background_fill: button_background_fill, text_color: button_text_color, border_stroke: button_border_stroke,
|
8821
|
+
text_x: button_text_x, text_y: button_text_y) {
|
8822
|
+
on_mouse_up do
|
8823
|
+
message_box('Button Pushed', 'Thank you for pushing the button!')
|
8824
|
+
end
|
8825
|
+
}
|
8826
|
+
}
|
8827
|
+
}
|
8828
|
+
}
|
8829
|
+
}.show
|
8830
|
+
end
|
8831
|
+
|
8832
|
+
# text label (area-based custom control) built with vector graphics on top of area.
|
8833
|
+
#
|
8834
|
+
# background_fill is transparent by default.
|
8835
|
+
# background_fill can accept a single color or gradient stops just as per `fill` property in README.
|
8836
|
+
# border_stroke is transparent by default.
|
8837
|
+
# border_stroke can accept thickness and dashes in addition to color just as per `stroke` property in README.
|
8838
|
+
def text_label(label_text,
|
8839
|
+
width: 80, height: 30, font_descriptor: {},
|
8840
|
+
background_fill: {a: 0}, text_color: :black, border_stroke: {a: 0},
|
8841
|
+
text_x: nil, text_y: nil,
|
8842
|
+
&content)
|
8843
|
+
area { |the_area|
|
8844
|
+
rectangle(1, 1, width, height) {
|
8845
|
+
fill background_fill
|
8846
|
+
}
|
8847
|
+
rectangle(1, 1, width, height) {
|
8848
|
+
stroke border_stroke
|
8849
|
+
}
|
8850
|
+
|
8851
|
+
text_height = (font_descriptor[:size] || 12) * 0.75
|
8852
|
+
text_width = (text_height * label_text.size) * 0.75
|
8853
|
+
text_x ||= (width - text_width) / 2.0
|
8854
|
+
text_y ||= (height - 4 - text_height) / 2.0
|
8855
|
+
text(text_x, text_y, width) {
|
8856
|
+
string(label_text) {
|
8857
|
+
color text_color
|
8858
|
+
font font_descriptor
|
8859
|
+
}
|
8860
|
+
}
|
8861
|
+
|
8862
|
+
content&.call(the_area)
|
8863
|
+
}
|
8864
|
+
end
|
8865
|
+
|
8866
|
+
# push button (area-based custom control) built with vector graphics on top of area.
|
8867
|
+
#
|
8868
|
+
# background_fill is white by default.
|
8869
|
+
# background_fill can accept a single color or gradient stops just as per `fill` property in README.
|
8870
|
+
# border_stroke is black by default.
|
8871
|
+
# border_stroke can accept thickness and dashes in addition to color just as per `stroke` property in README.
|
8872
|
+
# text_x and text_y are the offset of the button text in releation to its top-left corner
|
8873
|
+
# When text_x, text_y are left nil, the text is automatically centered in the button area.
|
8874
|
+
# Sometimes, the centering calculation is not perfect due to using a custom font, so
|
8875
|
+
# in that case, pass in text_x, and text_y manually
|
8876
|
+
#
|
8877
|
+
# reuses the text_label custom control
|
8878
|
+
def push_button(button_text,
|
8879
|
+
width: 80, height: 30, font_descriptor: {},
|
8880
|
+
background_fill: :white, text_color: :black, border_stroke: {r: 201, g: 201, b: 201},
|
8881
|
+
text_x: nil, text_y: nil,
|
8882
|
+
&content)
|
8883
|
+
text_label(button_text,
|
8884
|
+
width: width, height: height, font_descriptor: font_descriptor,
|
8885
|
+
background_fill: background_fill, text_color: text_color, border_stroke: border_stroke,
|
8886
|
+
text_x: text_x, text_y: text_y) { |the_area|
|
8887
|
+
|
8888
|
+
# dig into the_area content and grab elements to modify in mouse listeners below
|
8889
|
+
background_rectangle = the_area.children[0]
|
8890
|
+
button_string = the_area.children[2].children[0]
|
8891
|
+
|
8892
|
+
on_mouse_down do
|
8893
|
+
background_rectangle.fill = {x0: 0, y0: 0, x1: 0, y1: height, stops: [{pos: 0, r: 72, g: 146, b: 247}, {pos: 1, r: 12, g: 85, b: 214}]}
|
8894
|
+
button_string.color = :white
|
8895
|
+
end
|
8896
|
+
|
8897
|
+
on_mouse_up do
|
8898
|
+
background_rectangle.fill = background_fill
|
8899
|
+
button_string.color = text_color
|
8900
|
+
end
|
8901
|
+
|
8902
|
+
content&.call(the_area)
|
8903
|
+
}
|
8904
|
+
end
|
8905
|
+
end
|
8906
|
+
|
8907
|
+
AreaBasedCustomControls.new.launch
|
8908
|
+
```
|
8909
|
+
|
8599
8910
|
#### Midi Player
|
8600
8911
|
|
8601
8912
|
To run this example, 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).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.20
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class AreaBasedCustomControls
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
attr_accessor :label_width, :label_height, :label_font_descriptor,
|
7
|
+
:label_text_color, :label_background_fill, :label_border_stroke,
|
8
|
+
:label_text_x, :label_text_y,
|
9
|
+
:button_width, :button_height, :button_font_descriptor,
|
10
|
+
:button_text_color, :button_background_fill, :button_border_stroke,
|
11
|
+
:button_text_x, :button_text_y
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
self.label_width = 335
|
15
|
+
self.label_height = 50
|
16
|
+
self.label_font_descriptor = {family: OS.linux? ? 'Monospace Bold Italic' : 'Courier New', size: 16, weight: :bold, italic: :italic}
|
17
|
+
self.label_text_color = :red
|
18
|
+
self.label_background_fill = :yellow
|
19
|
+
self.label_border_stroke = :limegreen
|
20
|
+
|
21
|
+
self.button_width = 150
|
22
|
+
self.button_height = 50
|
23
|
+
self.button_font_descriptor = {family: OS.linux? ? 'Monospace Bold Italic' : 'Courier New', size: 36, weight: OS.linux? ? :normal : :bold, italic: :italic}
|
24
|
+
self.button_text_color = :green
|
25
|
+
self.button_background_fill = :yellow
|
26
|
+
self.button_border_stroke = :limegreen
|
27
|
+
end
|
28
|
+
|
29
|
+
def rebuild_text_label
|
30
|
+
@text_label.destroy
|
31
|
+
@text_label_vertical_box.content { # re-open vertical box content and shove in a new button
|
32
|
+
@text_label = text_label('This is a text label.',
|
33
|
+
width: label_width, height: label_height, font_descriptor: label_font_descriptor,
|
34
|
+
background_fill: label_background_fill, text_color: label_text_color, border_stroke: label_border_stroke,
|
35
|
+
text_x: label_text_x, text_y: label_text_y)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def rebuild_push_button
|
40
|
+
@push_button.destroy
|
41
|
+
@push_button_vertical_box.content { # re-open vertical box content and shove in a new button
|
42
|
+
@push_button = push_button('Push',
|
43
|
+
width: button_width, height: button_height, font_descriptor: button_font_descriptor,
|
44
|
+
background_fill: button_background_fill, text_color: button_text_color, border_stroke: button_border_stroke,
|
45
|
+
text_x: button_text_x, text_y: button_text_y) {
|
46
|
+
on_mouse_up do
|
47
|
+
message_box('Button Pushed', 'Thank you for pushing the button!')
|
48
|
+
end
|
49
|
+
}
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def launch
|
54
|
+
window('Area-Based Custom Controls', 385, 385) { |w|
|
55
|
+
margined true
|
56
|
+
|
57
|
+
tab {
|
58
|
+
tab_item('Text Label') {
|
59
|
+
@text_label_vertical_box = vertical_box {
|
60
|
+
vertical_box {
|
61
|
+
text_label('Text Label Form:', width: 385, height: 30, background_fill: OS.windows? ? :white : {a: 0}, border_stroke: OS.windows? ? :white : {a: 0}, font_descriptor: {size: 16, weight: :bold}, text_x: 0, text_y: OS.windows? ? 0 : 5)
|
62
|
+
|
63
|
+
horizontal_box {
|
64
|
+
label('Width')
|
65
|
+
spinbox(1, 1000) {
|
66
|
+
value <=> [self, :label_width, after_write: method(:rebuild_text_label)]
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
horizontal_box {
|
71
|
+
label('Height')
|
72
|
+
spinbox(1, 1000) {
|
73
|
+
value <=> [self, :label_height, after_write: method(:rebuild_text_label)]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
horizontal_box {
|
78
|
+
label('Font')
|
79
|
+
font_button {
|
80
|
+
font <=> [self, :label_font_descriptor, after_write: method(:rebuild_text_label)]
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
horizontal_box {
|
85
|
+
label('Text Color')
|
86
|
+
color_button {
|
87
|
+
color <=> [self, :label_text_color, after_write: method(:rebuild_text_label)]
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
horizontal_box {
|
92
|
+
label('Background Color')
|
93
|
+
color_button {
|
94
|
+
color <=> [self, :label_background_fill, after_write: method(:rebuild_text_label)]
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
horizontal_box {
|
99
|
+
label('Border Color')
|
100
|
+
color_button {
|
101
|
+
color <=> [self, :label_border_stroke, after_write: method(:rebuild_text_label)]
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
horizontal_box {
|
106
|
+
label('Text X (0=centered)')
|
107
|
+
spinbox(0, 1000) {
|
108
|
+
value <=> [self, :label_text_x, on_read: ->(x) {x.nil? ? 0 : x}, on_write: ->(x) {x == 0 ? nil : x}, after_write: method(:rebuild_text_label)]
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
horizontal_box {
|
113
|
+
label('Text Y (0=centered)')
|
114
|
+
spinbox(0, 1000) {
|
115
|
+
value <=> [self, :label_text_y, on_read: ->(y) {y.nil? ? 0 : y}, on_write: ->(y) {y == 0 ? nil : y}, after_write: method(:rebuild_text_label)]
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
@text_label = text_label('This is a text label.',
|
121
|
+
width: label_width, height: label_height, font_descriptor: label_font_descriptor,
|
122
|
+
background_fill: label_background_fill, text_color: label_text_color, border_stroke: label_border_stroke,
|
123
|
+
text_x: label_text_x, text_y: label_text_y)
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
tab_item('Push Button') {
|
128
|
+
@push_button_vertical_box = vertical_box {
|
129
|
+
vertical_box {
|
130
|
+
text_label('Push Button Form:', width: 385, height: 30, background_fill: OS.windows? ? :white : {a: 0}, border_stroke: OS.windows? ? :white : {a: 0}, font_descriptor: {size: 16, weight: :bold}, text_x: 0, text_y: OS.windows? ? 0 : 5)
|
131
|
+
|
132
|
+
horizontal_box {
|
133
|
+
label('Width')
|
134
|
+
spinbox(1, 1000) {
|
135
|
+
value <=> [self, :button_width, after_write: method(:rebuild_push_button)]
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
horizontal_box {
|
140
|
+
label('Height')
|
141
|
+
spinbox(1, 1000) {
|
142
|
+
value <=> [self, :button_height, after_write: method(:rebuild_push_button)]
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
horizontal_box {
|
147
|
+
label('Font')
|
148
|
+
font_button {
|
149
|
+
font <=> [self, :button_font_descriptor, after_write: method(:rebuild_push_button)]
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
horizontal_box {
|
154
|
+
label('Text Color')
|
155
|
+
color_button {
|
156
|
+
color <=> [self, :button_text_color, after_write: method(:rebuild_push_button)]
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
horizontal_box {
|
161
|
+
label('Background Color')
|
162
|
+
color_button {
|
163
|
+
color <=> [self, :button_background_fill, after_write: method(:rebuild_push_button)]
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
horizontal_box {
|
168
|
+
label('Border Color')
|
169
|
+
color_button {
|
170
|
+
color <=> [self, :button_border_stroke, after_write: method(:rebuild_push_button)]
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
horizontal_box {
|
175
|
+
label('Text X (0=centered)')
|
176
|
+
spinbox(0, 1000) {
|
177
|
+
value <=> [self, :button_text_x, on_read: ->(x) {x.nil? ? 0 : x}, on_write: ->(x) {x == 0 ? nil : x}, after_write: method(:rebuild_push_button)]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
horizontal_box {
|
182
|
+
label('Text Y (0=centered)')
|
183
|
+
spinbox(0, 1000) {
|
184
|
+
value <=> [self, :button_text_y, on_read: ->(y) {y.nil? ? 0 : y}, on_write: ->(y) {y == 0 ? nil : y}, after_write: method(:rebuild_push_button)]
|
185
|
+
}
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
@push_button = push_button('Push',
|
190
|
+
width: button_width, height: button_height, font_descriptor: button_font_descriptor,
|
191
|
+
background_fill: button_background_fill, text_color: button_text_color, border_stroke: button_border_stroke,
|
192
|
+
text_x: button_text_x, text_y: button_text_y) {
|
193
|
+
on_mouse_up do
|
194
|
+
message_box('Button Pushed', 'Thank you for pushing the button!')
|
195
|
+
end
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}.show
|
201
|
+
end
|
202
|
+
|
203
|
+
# text label (area-based custom control) built with vector graphics on top of area.
|
204
|
+
#
|
205
|
+
# background_fill is transparent by default.
|
206
|
+
# background_fill can accept a single color or gradient stops just as per `fill` property in README.
|
207
|
+
# border_stroke is transparent by default.
|
208
|
+
# border_stroke can accept thickness and dashes in addition to color just as per `stroke` property in README.
|
209
|
+
def text_label(label_text,
|
210
|
+
width: 80, height: 30, font_descriptor: {},
|
211
|
+
background_fill: {a: 0}, text_color: :black, border_stroke: {a: 0},
|
212
|
+
text_x: nil, text_y: nil,
|
213
|
+
&content)
|
214
|
+
area { |the_area|
|
215
|
+
rectangle(1, 1, width, height) {
|
216
|
+
fill background_fill
|
217
|
+
}
|
218
|
+
rectangle(1, 1, width, height) {
|
219
|
+
stroke border_stroke
|
220
|
+
}
|
221
|
+
|
222
|
+
text_height = (font_descriptor[:size] || 12) * (OS.mac? ? 0.75 : 1.35)
|
223
|
+
text_width = (text_height * label_text.size) * (OS.mac? ? 0.75 : 0.60)
|
224
|
+
text_x ||= (width - text_width) / 2.0
|
225
|
+
text_y ||= (height - 4 - text_height) / 2.0
|
226
|
+
text(text_x, text_y, width) {
|
227
|
+
string(label_text) {
|
228
|
+
color text_color
|
229
|
+
font font_descriptor
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
content&.call(the_area)
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
# push button (area-based custom control) built with vector graphics on top of area.
|
238
|
+
#
|
239
|
+
# background_fill is white by default.
|
240
|
+
# background_fill can accept a single color or gradient stops just as per `fill` property in README.
|
241
|
+
# border_stroke is black by default.
|
242
|
+
# border_stroke can accept thickness and dashes in addition to color just as per `stroke` property in README.
|
243
|
+
# text_x and text_y are the offset of the button text in releation to its top-left corner
|
244
|
+
# When text_x, text_y are left nil, the text is automatically centered in the button area.
|
245
|
+
# Sometimes, the centering calculation is not perfect due to using a custom font, so
|
246
|
+
# in that case, pass in text_x, and text_y manually
|
247
|
+
#
|
248
|
+
# reuses the text_label custom control
|
249
|
+
def push_button(button_text,
|
250
|
+
width: 80, height: 30, font_descriptor: {},
|
251
|
+
background_fill: :white, text_color: :black, border_stroke: {r: 201, g: 201, b: 201},
|
252
|
+
text_x: nil, text_y: nil,
|
253
|
+
&content)
|
254
|
+
text_label(button_text,
|
255
|
+
width: width, height: height, font_descriptor: font_descriptor,
|
256
|
+
background_fill: background_fill, text_color: text_color, border_stroke: border_stroke,
|
257
|
+
text_x: text_x, text_y: text_y) { |the_area|
|
258
|
+
|
259
|
+
# dig into the_area content and grab elements to modify in mouse listeners below
|
260
|
+
background_rectangle = the_area.children[0]
|
261
|
+
button_string = the_area.children[2].children[0]
|
262
|
+
|
263
|
+
on_mouse_down do
|
264
|
+
background_rectangle.fill = {x0: 0, y0: 0, x1: 0, y1: height, stops: [{pos: 0, r: 72, g: 146, b: 247}, {pos: 1, r: 12, g: 85, b: 214}]}
|
265
|
+
button_string.color = :white
|
266
|
+
end
|
267
|
+
|
268
|
+
on_mouse_up do
|
269
|
+
background_rectangle.fill = background_fill
|
270
|
+
button_string.color = text_color
|
271
|
+
end
|
272
|
+
|
273
|
+
content&.call(the_area)
|
274
|
+
}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
AreaBasedCustomControls.new.launch
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -226,6 +226,7 @@ files:
|
|
226
226
|
- VERSION
|
227
227
|
- bin/girb
|
228
228
|
- bin/girb_runner.rb
|
229
|
+
- examples/area_based_custom_controls.rb
|
229
230
|
- examples/area_gallery.rb
|
230
231
|
- examples/area_gallery2.rb
|
231
232
|
- examples/area_gallery3.rb
|
@@ -450,7 +451,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
450
451
|
- !ruby/object:Gem::Version
|
451
452
|
version: '0'
|
452
453
|
requirements: []
|
453
|
-
rubygems_version: 3.
|
454
|
+
rubygems_version: 3.3.1
|
454
455
|
signing_key:
|
455
456
|
specification_version: 4
|
456
457
|
summary: Glimmer DSL for LibUI
|