glimmer-dsl-libui 0.4.6 → 0.4.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +601 -323
- data/VERSION +1 -1
- data/examples/button_counter.rb +2 -1
- data/examples/cpu_percentage.rb +36 -0
- data/examples/date_time_picker.rb +19 -14
- data/examples/date_time_picker2.rb +20 -0
- data/examples/meta_example.rb +17 -6
- data/examples/midi_player.rb +5 -6
- data/examples/midi_player2.rb +83 -0
- data/examples/midi_player3.rb +84 -0
- data/examples/snake.rb +19 -10
- data/examples/snake2.rb +97 -0
- data/examples/tetris.rb +15 -18
- data/examples/tic_tac_toe.rb +1 -0
- data/examples/tic_tac_toe2.rb +84 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/checkbox_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +17 -2
- data/lib/glimmer/libui/control_proxy/date_time_picker_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +5 -1
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/check_menu_item_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +16 -4
- data/lib/glimmer/libui/control_proxy/multiline_entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +19 -0
- data/lib/glimmer/libui/control_proxy/slider_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy.rb +2 -2
- data/lib/glimmer/libui/data_bindable.rb +27 -2
- metadata +8 -2
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.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.10
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
5
|
|
6
|
-
[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!
|
6
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [LibUI](https://github.com/kojix2/LibUI) is a prerequisite-free Ruby 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-independent native GUI that just works!
|
7
7
|
|
8
8
|
Mac | Windows | Linux
|
9
9
|
----|---------|------
|
@@ -267,6 +267,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
267
267
|
- [Button Counter](#button-counter)
|
268
268
|
- [Color The Circles](#color-the-circles)
|
269
269
|
- [Control Gallery](#control-gallery)
|
270
|
+
- [CPU Percentage](#cpu-percentage)
|
270
271
|
- [Custom Draw Text](#custom-draw-text)
|
271
272
|
- [Dynamic Area](#dynamic-area)
|
272
273
|
- [Editable Column Table](#editable-column-table)
|
@@ -373,7 +374,7 @@ gem install glimmer-dsl-libui
|
|
373
374
|
Or install via Bundler `Gemfile`:
|
374
375
|
|
375
376
|
```ruby
|
376
|
-
gem 'glimmer-dsl-libui', '~> 0.4.
|
377
|
+
gem 'glimmer-dsl-libui', '~> 0.4.10'
|
377
378
|
```
|
378
379
|
|
379
380
|
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.
|
@@ -460,7 +461,7 @@ Keyword(Args) | Properties | Listeners
|
|
460
461
|
`checkbox_text_column(name as String)` | `editable` (Boolean), `editable_checkbox` (Boolean), `editable_text` (Boolean) | None
|
461
462
|
`checkbox_text_color_column(name as String)` | `editable` (Boolean), `editable_checkbox` (Boolean), `editable_text` (Boolean) | None
|
462
463
|
`check_menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
|
463
|
-
`combobox` | `items` (`Array` of `String`), `selected` (`Integer`) | `on_selected`
|
464
|
+
`combobox` | `items` (`Array` of `String`), `selected` (`Integer`), `selected_item` (`String`) | `on_selected`
|
464
465
|
`color_button` | `color` (Array of `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float`), `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float` | `on_changed`
|
465
466
|
`date_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`, `mday` as `Integer`, `mon` as `Integer`, `year` as `Integer`, `wday` as `Integer`, `yday` as `Integer`, `dst` as Boolean) | `on_changed`
|
466
467
|
`date_time_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`, `mday` as `Integer`, `mon` as `Integer`, `year` as `Integer`, `wday` as `Integer`, `yday` as `Integer`, `dst` as Boolean) | `on_changed`
|
@@ -627,11 +628,11 @@ class FormTable
|
|
627
628
|
|
628
629
|
def initialize
|
629
630
|
@data = [
|
630
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'
|
631
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'
|
632
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'
|
633
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'
|
634
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'
|
631
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
632
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
633
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
634
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
635
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
635
636
|
]
|
636
637
|
end
|
637
638
|
|
@@ -1382,14 +1383,24 @@ Data-binding supports utilizing the [MVP (Model View Presenter)](https://en.wiki
|
|
1382
1383
|
![MVP](https://www.researchgate.net/profile/Gilles-Perrouin/publication/320249584/figure/fig8/AS:668260987068418@1536337243385/Model-view-presenter-architecture.png)
|
1383
1384
|
|
1384
1385
|
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) supports bidirectional (two-way) data-binding of the following controls/properties via the `<=>` operator (indicating data is moving in both directions between View and Model):
|
1386
|
+
- `checkbox`: `checked`
|
1387
|
+
- `check_menu_item`: `checked`
|
1385
1388
|
- `color_button`: `color`
|
1389
|
+
- `combobox`: `selected`, `selected_item`
|
1390
|
+
- `date_picker`: `time`
|
1391
|
+
- `date_time_picker`: `time`
|
1392
|
+
- `editable_combobox`: `text`
|
1386
1393
|
- `entry`: `text`
|
1387
1394
|
- `font_button`: `font`
|
1388
1395
|
- `multiline_entry`: `text`
|
1389
1396
|
- `non_wrapping_multiline_entry`: `text`
|
1397
|
+
- `radio_buttons`: `selected`
|
1398
|
+
- `radio_menu_item`: `checked`
|
1390
1399
|
- `search_entry`: `text`
|
1391
1400
|
- `slider`: `value`
|
1392
1401
|
- `spinbox`: `value`
|
1402
|
+
- `table`: `cell_rows` (explicit data-binding by using `<=>` and [implicit data-binding](#table-api) by assigning value directly)
|
1403
|
+
- `time_picker`: `time`
|
1393
1404
|
|
1394
1405
|
Example of bidirectional data-binding:
|
1395
1406
|
|
@@ -1439,6 +1450,11 @@ To summarize the data-binding API:
|
|
1439
1450
|
|
1440
1451
|
This is also known as the [Glimmer Shine](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#shine) syntax for data-binding, a [Glimmer](https://github.com/AndyObtiva/glimmer)-only unique innovation that takes advantage of [Ruby](https://www.ruby-lang.org/en/)'s highly expressive syntax and malleable DSL support.
|
1441
1452
|
|
1453
|
+
Data-bound model attribute can be:
|
1454
|
+
- **Direct:** `Symbol` representing attribute reader/writer (e.g. `[person, :name`])
|
1455
|
+
- **Nested:** `String` representing nested attribute path (e.g. `[company, 'address.street']`). That results in "nested data-binding"
|
1456
|
+
- **Indexed:** `String` containing array attribute index (e.g. `[customer, 'addresses[0].street']`). That results in "indexed data-binding"
|
1457
|
+
|
1442
1458
|
Data-binding options include:
|
1443
1459
|
- `before_read {|value| ...}`: performs an operation before reading data from Model to update the View.
|
1444
1460
|
- `on_read {|value| ...}`: converts value read from Model to update the View.
|
@@ -1446,7 +1462,7 @@ Data-binding options include:
|
|
1446
1462
|
- `before_write {|value| ...}`: performs an operation before writing data to Model from View.
|
1447
1463
|
- `on_write {|value| ...}`: converts value read from View to update the Model.
|
1448
1464
|
- `after_write {|converted_value| ...}`: performs an operation after writing to Model from View.
|
1449
|
-
- `computed_by attribute` or `computed_by [attribute1, attribute2, ...]`: indicates model attribute is computed from specified attribute(s), thus updated when they are updated (see in [Login example version 2](/examples/login2.rb))
|
1465
|
+
- `computed_by attribute` or `computed_by [attribute1, attribute2, ...]`: indicates model attribute is computed from specified attribute(s), thus updated when they are updated (see in [Login example version 2](/examples/login2.rb)). That is known as "computed data-binding".
|
1450
1466
|
|
1451
1467
|
Note that with both `on_read` and `on_write` converters, you could pass a `Symbol` representing the name of a method on the value object to invoke.
|
1452
1468
|
|
@@ -1479,268 +1495,7 @@ Learn more from data-binding usage in [Login](#login) (4 data-binding versions),
|
|
1479
1495
|
### Original API
|
1480
1496
|
|
1481
1497
|
Here are all the lower-level [LibUI](https://github.com/kojix2/LibUI) API methods utilized by [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui):
|
1482
|
-
|
1483
|
-
- `area_begin_user_window_move`
|
1484
|
-
- `area_begin_user_window_resize`
|
1485
|
-
- `area_queue_redraw_all`
|
1486
|
-
- `area_scroll_to`
|
1487
|
-
- `area_set_size`
|
1488
|
-
- `attribute_color`
|
1489
|
-
- `attribute_family`
|
1490
|
-
- `attribute_features`
|
1491
|
-
- `attribute_get_type`
|
1492
|
-
- `attribute_italic`
|
1493
|
-
- `attribute_size`
|
1494
|
-
- `attribute_stretch`
|
1495
|
-
- `attribute_underline`
|
1496
|
-
- `attribute_underline_color`
|
1497
|
-
- `attribute_weight`
|
1498
|
-
- `attributed_string_append_unattributed`
|
1499
|
-
- `attributed_string_byte_index_to_grapheme`
|
1500
|
-
- `attributed_string_delete`
|
1501
|
-
- `attributed_string_for_each_attribute`
|
1502
|
-
- `attributed_string_grapheme_to_byte_index`
|
1503
|
-
- `attributed_string_insert_at_unattributed`
|
1504
|
-
- `attributed_string_len`
|
1505
|
-
- `attributed_string_num_graphemes`
|
1506
|
-
- `attributed_string_set_attribute`
|
1507
|
-
- `attributed_string_string`
|
1508
|
-
- `box_append`
|
1509
|
-
- `box_delete`
|
1510
|
-
- `box_padded`
|
1511
|
-
- `box_set_padded`
|
1512
|
-
- `button_on_clicked`
|
1513
|
-
- `button_set_text`
|
1514
|
-
- `button_text`
|
1515
|
-
- `checkbox_checked`
|
1516
|
-
- `checkbox_on_toggled`
|
1517
|
-
- `checkbox_set_checked`
|
1518
|
-
- `checkbox_set_text`
|
1519
|
-
- `checkbox_text`
|
1520
|
-
- `color_button_color`
|
1521
|
-
- `color_button_on_changed`
|
1522
|
-
- `color_button_set_color`
|
1523
|
-
- `combobox_append`
|
1524
|
-
- `combobox_on_selected`
|
1525
|
-
- `combobox_selected`
|
1526
|
-
- `combobox_set_selected`
|
1527
|
-
- `control_destroy`
|
1528
|
-
- `control_disable`
|
1529
|
-
- `control_enable`
|
1530
|
-
- `control_enabled`
|
1531
|
-
- `control_enabled_to_user`
|
1532
|
-
- `control_handle`
|
1533
|
-
- `control_hide`
|
1534
|
-
- `control_parent`
|
1535
|
-
- `control_set_parent`
|
1536
|
-
- `control_show`
|
1537
|
-
- `control_toplevel`
|
1538
|
-
- `control_verify_set_parent`
|
1539
|
-
- `control_visible`
|
1540
|
-
- `date_time_picker_on_changed`
|
1541
|
-
- `date_time_picker_set_time`
|
1542
|
-
- `date_time_picker_time`
|
1543
|
-
- `draw_clip`
|
1544
|
-
- `draw_fill`
|
1545
|
-
- `draw_free_path`
|
1546
|
-
- `draw_free_text_layout`
|
1547
|
-
- `draw_matrix_invert`
|
1548
|
-
- `draw_matrix_invertible`
|
1549
|
-
- `draw_matrix_multiply`
|
1550
|
-
- `draw_matrix_rotate`
|
1551
|
-
- `draw_matrix_scale`
|
1552
|
-
- `draw_matrix_set_identity`
|
1553
|
-
- `draw_matrix_skew`
|
1554
|
-
- `draw_matrix_transform_point`
|
1555
|
-
- `draw_matrix_transform_size`
|
1556
|
-
- `draw_matrix_translate`
|
1557
|
-
- `draw_new_path`
|
1558
|
-
- `draw_new_text_layout`
|
1559
|
-
- `draw_path_add_rectangle`
|
1560
|
-
- `draw_path_arc_to`
|
1561
|
-
- `draw_path_bezier_to`
|
1562
|
-
- `draw_path_close_figure`
|
1563
|
-
- `draw_path_end`
|
1564
|
-
- `draw_path_line_to`
|
1565
|
-
- `draw_path_new_figure`
|
1566
|
-
- `draw_path_new_figure_with_arc`
|
1567
|
-
- `draw_restore`
|
1568
|
-
- `draw_save`
|
1569
|
-
- `draw_stroke`
|
1570
|
-
- `draw_text`
|
1571
|
-
- `draw_text_layout_extents`
|
1572
|
-
- `draw_transform`
|
1573
|
-
- `editable_combobox_append`
|
1574
|
-
- `editable_combobox_on_changed`
|
1575
|
-
- `editable_combobox_set_text`
|
1576
|
-
- `editable_combobox_text`
|
1577
|
-
- `entry_on_changed`
|
1578
|
-
- `entry_read_only`
|
1579
|
-
- `entry_set_read_only`
|
1580
|
-
- `entry_set_text`
|
1581
|
-
- `entry_text`
|
1582
|
-
- `ffi_lib`
|
1583
|
-
- `ffi_lib=`
|
1584
|
-
- `font_button_font`
|
1585
|
-
- `font_button_on_changed`
|
1586
|
-
- `form_append`
|
1587
|
-
- `form_delete`
|
1588
|
-
- `form_padded`
|
1589
|
-
- `form_set_padded`
|
1590
|
-
- `free_attribute`
|
1591
|
-
- `free_attributed_string`
|
1592
|
-
- `free_control`
|
1593
|
-
- `free_font_button_font`
|
1594
|
-
- `free_image`
|
1595
|
-
- `free_init_error`
|
1596
|
-
- `free_open_type_features`
|
1597
|
-
- `free_table_model`
|
1598
|
-
- `free_table_value`
|
1599
|
-
- `free_text`
|
1600
|
-
- `grid_append`
|
1601
|
-
- `grid_insert_at`
|
1602
|
-
- `grid_padded`
|
1603
|
-
- `grid_set_padded`
|
1604
|
-
- `group_margined`
|
1605
|
-
- `group_set_child`
|
1606
|
-
- `group_set_margined`
|
1607
|
-
- `group_set_title`
|
1608
|
-
- `group_title`
|
1609
|
-
- `image_append`
|
1610
|
-
- `init`
|
1611
|
-
- `label_set_text`
|
1612
|
-
- `label_text`
|
1613
|
-
- `main`
|
1614
|
-
- `main_step`
|
1615
|
-
- `main_steps`
|
1616
|
-
- `menu_append_about_item`
|
1617
|
-
- `menu_append_check_item`
|
1618
|
-
- `menu_append_item`
|
1619
|
-
- `menu_append_preferences_item`
|
1620
|
-
- `menu_append_quit_item`
|
1621
|
-
- `menu_append_separator`
|
1622
|
-
- `menu_item_checked`
|
1623
|
-
- `menu_item_disable`
|
1624
|
-
- `menu_item_enable`
|
1625
|
-
- `menu_item_on_clicked`
|
1626
|
-
- `menu_item_set_checked`
|
1627
|
-
- `msg_box`
|
1628
|
-
- `msg_box_error`
|
1629
|
-
- `multiline_entry_append`
|
1630
|
-
- `multiline_entry_on_changed`
|
1631
|
-
- `multiline_entry_read_only`
|
1632
|
-
- `multiline_entry_set_read_only`
|
1633
|
-
- `multiline_entry_set_text`
|
1634
|
-
- `multiline_entry_text`
|
1635
|
-
- `new_area`
|
1636
|
-
- `new_attributed_string`
|
1637
|
-
- `new_background_attribute`
|
1638
|
-
- `new_button`
|
1639
|
-
- `new_checkbox`
|
1640
|
-
- `new_color_attribute`
|
1641
|
-
- `new_color_button`
|
1642
|
-
- `new_combobox`
|
1643
|
-
- `new_date_picker`
|
1644
|
-
- `new_date_time_picker`
|
1645
|
-
- `new_editable_combobox`
|
1646
|
-
- `new_entry`
|
1647
|
-
- `new_family_attribute`
|
1648
|
-
- `new_features_attribute`
|
1649
|
-
- `new_font_button`
|
1650
|
-
- `new_form`
|
1651
|
-
- `new_grid`
|
1652
|
-
- `new_group`
|
1653
|
-
- `new_horizontal_box`
|
1654
|
-
- `new_horizontal_separator`
|
1655
|
-
- `new_image`
|
1656
|
-
- `new_italic_attribute`
|
1657
|
-
- `new_label`
|
1658
|
-
- `new_menu`
|
1659
|
-
- `new_multiline_entry`
|
1660
|
-
- `new_non_wrapping_multiline_entry`
|
1661
|
-
- `new_open_type_features`
|
1662
|
-
- `new_password_entry`
|
1663
|
-
- `new_progress_bar`
|
1664
|
-
- `new_radio_buttons`
|
1665
|
-
- `new_scrolling_area`
|
1666
|
-
- `new_search_entry`
|
1667
|
-
- `new_size_attribute`
|
1668
|
-
- `new_slider`
|
1669
|
-
- `new_spinbox`
|
1670
|
-
- `new_stretch_attribute`
|
1671
|
-
- `new_tab`
|
1672
|
-
- `new_table`
|
1673
|
-
- `new_table_model`
|
1674
|
-
- `new_table_value_color`
|
1675
|
-
- `new_table_value_image`
|
1676
|
-
- `new_table_value_int`
|
1677
|
-
- `new_table_value_string`
|
1678
|
-
- `new_time_picker`
|
1679
|
-
- `new_underline_attribute`
|
1680
|
-
- `new_underline_color_attribute`
|
1681
|
-
- `new_vertical_box`
|
1682
|
-
- `new_vertical_separator`
|
1683
|
-
- `new_weight_attribute`
|
1684
|
-
- `new_window`
|
1685
|
-
- `on_should_quit`
|
1686
|
-
- `open_file`
|
1687
|
-
- `open_type_features_add`
|
1688
|
-
- `open_type_features_clone`
|
1689
|
-
- `open_type_features_for_each`
|
1690
|
-
- `open_type_features_get`
|
1691
|
-
- `open_type_features_remove`
|
1692
|
-
- `progress_bar_set_value`
|
1693
|
-
- `progress_bar_value`
|
1694
|
-
- `queue_main`
|
1695
|
-
- `quit`
|
1696
|
-
- `radio_buttons_append`
|
1697
|
-
- `radio_buttons_on_selected`
|
1698
|
-
- `radio_buttons_selected`
|
1699
|
-
- `radio_buttons_set_selected`
|
1700
|
-
- `save_file`
|
1701
|
-
- `slider_on_changed`
|
1702
|
-
- `slider_set_value`
|
1703
|
-
- `slider_value`
|
1704
|
-
- `spinbox_on_changed`
|
1705
|
-
- `spinbox_set_value`
|
1706
|
-
- `spinbox_value`
|
1707
|
-
- `tab_append`
|
1708
|
-
- `tab_delete`
|
1709
|
-
- `tab_insert_at`
|
1710
|
-
- `tab_margined`
|
1711
|
-
- `tab_num_pages`
|
1712
|
-
- `tab_set_margined`
|
1713
|
-
- `table_append_button_column`
|
1714
|
-
- `table_append_checkbox_column`
|
1715
|
-
- `table_append_checkbox_text_column`
|
1716
|
-
- `table_append_image_column`
|
1717
|
-
- `table_append_image_text_column`
|
1718
|
-
- `table_append_progress_bar_column`
|
1719
|
-
- `table_append_text_column`
|
1720
|
-
- `table_model_row_changed`
|
1721
|
-
- `table_model_row_deleted`
|
1722
|
-
- `table_model_row_inserted`
|
1723
|
-
- `table_value_color`
|
1724
|
-
- `table_value_get_type`
|
1725
|
-
- `table_value_image`
|
1726
|
-
- `table_value_int`
|
1727
|
-
- `table_value_string`
|
1728
|
-
- `timer`
|
1729
|
-
- `uninit`
|
1730
|
-
- `user_bug_cannot_set_parent_on_toplevel`
|
1731
|
-
- `window_borderless`
|
1732
|
-
- `window_content_size`
|
1733
|
-
- `window_fullscreen`
|
1734
|
-
- `window_margined`
|
1735
|
-
- `window_on_closing`
|
1736
|
-
- `window_on_content_size_changed`
|
1737
|
-
- `window_set_borderless`
|
1738
|
-
- `window_set_child`
|
1739
|
-
- `window_set_content_size`
|
1740
|
-
- `window_set_fullscreen`
|
1741
|
-
- `window_set_margined`
|
1742
|
-
- `window_set_title`
|
1743
|
-
- `window_title`
|
1498
|
+
`alloc_control`, `append_features`, `area_begin_user_window_move`, `area_begin_user_window_resize`, `area_queue_redraw_all`, `area_scroll_to`, `area_set_size`, `attribute_color`, `attribute_family`, `attribute_features`, `attribute_get_type`, `attribute_italic`, `attribute_size`, `attribute_stretch`, `attribute_underline`, `attribute_underline_color`, `attribute_weight`, `attributed_string_append_unattributed`, `attributed_string_byte_index_to_grapheme`, `attributed_string_delete`, `attributed_string_for_each_attribute`, `attributed_string_grapheme_to_byte_index`, `attributed_string_insert_at_unattributed`, `attributed_string_len`, `attributed_string_num_graphemes`, `attributed_string_set_attribute`, `attributed_string_string`, `box_append`, `box_delete`, `box_padded`, `box_set_padded`, `button_on_clicked`, `button_set_text`, `button_text`, `checkbox_checked`, `checkbox_on_toggled`, `checkbox_set_checked`, `checkbox_set_text`, `checkbox_text`, `color_button_color`, `color_button_on_changed`, `color_button_set_color`, `combobox_append`, `combobox_on_selected`, `combobox_selected`, `combobox_set_selected`, `control_destroy`, `control_disable`, `control_enable`, `control_enabled`, `control_enabled_to_user`, `control_handle`, `control_hide`, `control_parent`, `control_set_parent`, `control_show`, `control_toplevel`, `control_verify_set_parent`, `control_visible`, `date_time_picker_on_changed`, `date_time_picker_set_time`, `date_time_picker_time`, `draw_clip`, `draw_fill`, `draw_free_path`, `draw_free_text_layout`, `draw_matrix_invert`, `draw_matrix_invertible`, `draw_matrix_multiply`, `draw_matrix_rotate`, `draw_matrix_scale`, `draw_matrix_set_identity`, `draw_matrix_skew`, `draw_matrix_transform_point`, `draw_matrix_transform_size`, `draw_matrix_translate`, `draw_new_path`, `draw_new_text_layout`, `draw_path_add_rectangle`, `draw_path_arc_to`, `draw_path_bezier_to`, `draw_path_close_figure`, `draw_path_end`, `draw_path_line_to`, `draw_path_new_figure`, `draw_path_new_figure_with_arc`, `draw_restore`, `draw_save`, `draw_stroke`, `draw_text`, `draw_text_layout_extents`, `draw_transform`, `editable_combobox_append`, `editable_combobox_on_changed`, `editable_combobox_set_text`, `editable_combobox_text`, `entry_on_changed`, `entry_read_only`, `entry_set_read_only`, `entry_set_text`, `entry_text`, `ffi_lib`, `ffi_lib=`, `font_button_font`, `font_button_on_changed`, `form_append`, `form_delete`, `form_padded`, `form_set_padded`, `free_attribute`, `free_attributed_string`, `free_control`, `free_font_button_font`, `free_image`, `free_init_error`, `free_open_type_features`, `free_table_model`, `free_table_value`, `free_text`, `grid_append`, `grid_insert_at`, `grid_padded`, `grid_set_padded`, `group_margined`, `group_set_child`, `group_set_margined`, `group_set_title`, `group_title`, `image_append`, `init`, `label_set_text`, `label_text`, `main`, `main_step`, `main_steps`, `menu_append_about_item`, `menu_append_check_item`, `menu_append_item`, `menu_append_preferences_item`, `menu_append_quit_item`, `menu_append_separator`, `menu_item_checked`, `menu_item_disable`, `menu_item_enable`, `menu_item_on_clicked`, `menu_item_set_checked`, `msg_box`, `msg_box_error`, `multiline_entry_append`, `multiline_entry_on_changed`, `multiline_entry_read_only`, `multiline_entry_set_read_only`, `multiline_entry_set_text`, `multiline_entry_text`, `new_area`, `new_attributed_string`, `new_background_attribute`, `new_button`, `new_checkbox`, `new_color_attribute`, `new_color_button`, `new_combobox`, `new_date_picker`, `new_date_time_picker`, `new_editable_combobox`, `new_entry`, `new_family_attribute`, `new_features_attribute`, `new_font_button`, `new_form`, `new_grid`, `new_group`, `new_horizontal_box`, `new_horizontal_separator`, `new_image`, `new_italic_attribute`, `new_label`, `new_menu`, `new_multiline_entry`, `new_non_wrapping_multiline_entry`, `new_open_type_features`, `new_password_entry`, `new_progress_bar`, `new_radio_buttons`, `new_scrolling_area`, `new_search_entry`, `new_size_attribute`, `new_slider`, `new_spinbox`, `new_stretch_attribute`, `new_tab`, `new_table`, `new_table_model`, `new_table_value_color`, `new_table_value_image`, `new_table_value_int`, `new_table_value_string`, `new_time_picker`, `new_underline_attribute`, `new_underline_color_attribute`, `new_vertical_box`, `new_vertical_separator`, `new_weight_attribute`, `new_window`, `on_should_quit`, `open_file`, `open_type_features_add`, `open_type_features_clone`, `open_type_features_for_each`, `open_type_features_get`, `open_type_features_remove`, `progress_bar_set_value`, `progress_bar_value`, `queue_main`, `quit`, `radio_buttons_append`, `radio_buttons_on_selected`, `radio_buttons_selected`, `radio_buttons_set_selected`, `save_file`, `slider_on_changed`, `slider_set_value`, `slider_value`, `spinbox_on_changed`, `spinbox_set_value`, `spinbox_value`, `tab_append`, `tab_delete`, `tab_insert_at`, `tab_margined`, `tab_num_pages`, `tab_set_margined`, `table_append_button_column`, `table_append_checkbox_column`, `table_append_checkbox_text_column`, `table_append_image_column`, `table_append_image_text_column`, `table_append_progress_bar_column`, `table_append_text_column`, `table_model_row_changed`, `table_model_row_deleted`, `table_model_row_inserted`, `table_value_color`, `table_value_get_type`, `table_value_image`, `table_value_int`, `table_value_string`, `timer`, `uninit`, `user_bug_cannot_set_parent_on_toplevel`, `window_borderless`, `window_content_size`, `window_fullscreen`, `window_margined`, `window_on_closing`, `window_on_content_size_changed`, `window_set_borderless`, `window_set_child`, `window_set_content_size`, `window_set_fullscreen`, `window_set_margined`, `window_set_title`, `window_title`
|
1744
1499
|
|
1745
1500
|
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):
|
1746
1501
|
- Check out [LibUI ffi.rb](https://github.com/kojix2/LibUI/blob/main/lib/libui/ffi.rb)
|
@@ -1878,7 +1633,7 @@ Example:
|
|
1878
1633
|
|
1879
1634
|
## Examples
|
1880
1635
|
|
1881
|
-
The following examples include reimplementions of the examples in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) (with and without data-binding) as well as brand new examples.
|
1636
|
+
The following examples include reimplementions of the examples in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) (with and without [data-binding](#data-binding)) as well as brand new examples.
|
1882
1637
|
|
1883
1638
|
To browse all examples, simply launch the [Meta-Example](examples/meta_example.rb), which lists all examples and displays each example's code when selected. It also enables code editing to facilitate experimentation and learning.
|
1884
1639
|
|
@@ -2668,7 +2423,35 @@ UI.main
|
|
2668
2423
|
UI.quit
|
2669
2424
|
```
|
2670
2425
|
|
2671
|
-
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
2426
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with [data-binding](#data-binding)):
|
2427
|
+
|
2428
|
+
```ruby
|
2429
|
+
require 'glimmer-dsl-libui'
|
2430
|
+
|
2431
|
+
class DateTimePicker
|
2432
|
+
include Glimmer
|
2433
|
+
|
2434
|
+
attr_accessor :picked_time
|
2435
|
+
|
2436
|
+
def launch
|
2437
|
+
window('Date Time Pickers', 300, 200) {
|
2438
|
+
vertical_box {
|
2439
|
+
date_time_picker {
|
2440
|
+
time <=> [self, :picked_time, after_write: ->(time) { p time }]
|
2441
|
+
}
|
2442
|
+
}
|
2443
|
+
|
2444
|
+
on_closing do
|
2445
|
+
puts 'Bye Bye'
|
2446
|
+
end
|
2447
|
+
}.show
|
2448
|
+
end
|
2449
|
+
end
|
2450
|
+
|
2451
|
+
DateTimePicker.new.launch
|
2452
|
+
```
|
2453
|
+
|
2454
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (without [data-binding](#data-binding)):
|
2672
2455
|
|
2673
2456
|
```ruby
|
2674
2457
|
require 'glimmer-dsl-libui'
|
@@ -3226,7 +3009,62 @@ Mac | Windows | Linux
|
|
3226
3009
|
----|---------|------
|
3227
3010
|
![glimmer-dsl-libui-mac-basic-table-button.png](images/glimmer-dsl-libui-mac-basic-table-button.png) ![glimmer-dsl-libui-mac-basic-table-button-deleted.png](images/glimmer-dsl-libui-mac-basic-table-button-deleted.png) | ![glimmer-dsl-libui-windows-basic-table-button.png](images/glimmer-dsl-libui-windows-basic-table-button.png) ![glimmer-dsl-libui-windows-basic-table-button-deleted.png](images/glimmer-dsl-libui-windows-basic-table-button-deleted.png) | ![glimmer-dsl-libui-linux-basic-table-button.png](images/glimmer-dsl-libui-linux-basic-table-button.png) ![glimmer-dsl-libui-linux-basic-table-button-deleted.png](images/glimmer-dsl-libui-linux-basic-table-button-deleted.png)
|
3228
3011
|
|
3229
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
3012
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with explicit [data-binding](#data-binding)):
|
3013
|
+
|
3014
|
+
```ruby
|
3015
|
+
# frozen_string_literal: true
|
3016
|
+
|
3017
|
+
require 'glimmer-dsl-libui'
|
3018
|
+
|
3019
|
+
class BasicTableButton
|
3020
|
+
include Glimmer
|
3021
|
+
|
3022
|
+
attr_accessor :data
|
3023
|
+
|
3024
|
+
def initialize
|
3025
|
+
@data = [
|
3026
|
+
%w[cat meow delete],
|
3027
|
+
%w[dog woof delete],
|
3028
|
+
%w[chicken cock-a-doodle-doo delete],
|
3029
|
+
%w[horse neigh delete],
|
3030
|
+
%w[cow moo delete]
|
3031
|
+
]
|
3032
|
+
end
|
3033
|
+
|
3034
|
+
def launch
|
3035
|
+
window('Animal sounds', 400, 200) {
|
3036
|
+
horizontal_box {
|
3037
|
+
table {
|
3038
|
+
text_column('Animal')
|
3039
|
+
text_column('Description')
|
3040
|
+
button_column('Action') {
|
3041
|
+
on_clicked do |row|
|
3042
|
+
# Option 1: direct data deletion is the simpler solution
|
3043
|
+
# @data.delete_at(row) # automatically deletes actual table row due to explicit data-binding
|
3044
|
+
|
3045
|
+
# Option 2: cloning only to demonstrate table row deletion upon explicit setting of data attribute (cloning is not recommended beyond demonstrating this point)
|
3046
|
+
new_data = @data.clone
|
3047
|
+
new_data.delete_at(row)
|
3048
|
+
self.data = new_data # automatically loses deleted table row due to explicit data-binding
|
3049
|
+
end
|
3050
|
+
}
|
3051
|
+
|
3052
|
+
cell_rows <=> [self, :data] # explicit data-binding of table cell_rows to self.data
|
3053
|
+
|
3054
|
+
on_changed do |row, type, row_data|
|
3055
|
+
puts "Row #{row} #{type}: #{row_data}"
|
3056
|
+
$stdout.flush
|
3057
|
+
end
|
3058
|
+
}
|
3059
|
+
}
|
3060
|
+
}.show
|
3061
|
+
end
|
3062
|
+
end
|
3063
|
+
|
3064
|
+
BasicTableButton.new.launch
|
3065
|
+
```
|
3066
|
+
|
3067
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (with implicit [data-binding](#data-binding)):
|
3230
3068
|
|
3231
3069
|
```ruby
|
3232
3070
|
require 'glimmer-dsl-libui'
|
@@ -5005,7 +4843,8 @@ class ButtonCounter
|
|
5005
4843
|
def launch
|
5006
4844
|
window('Hello, Button!') {
|
5007
4845
|
button {
|
5008
|
-
|
4846
|
+
# data-bind button text to self count, converting to string on read.
|
4847
|
+
text <= [self, :count, on_read: ->(count) {"Count: #{count}"}]
|
5009
4848
|
|
5010
4849
|
on_clicked do
|
5011
4850
|
self.count += 1
|
@@ -5649,6 +5488,71 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
|
|
5649
5488
|
MAIN_WINDOW.show
|
5650
5489
|
```
|
5651
5490
|
|
5491
|
+
#### CPU Percentage
|
5492
|
+
|
5493
|
+
This example shows CPU usage percentage second by second.
|
5494
|
+
|
5495
|
+
Note that it is highly dependent on low-level OS terminal commands, so if anything changes in their output formatting, the code could break. Please report any issues you might encounter.
|
5496
|
+
|
5497
|
+
[examples/cpu_percentage.rb](examples/cpu_percentage.rb)
|
5498
|
+
|
5499
|
+
Run with this command from the root of the project if you cloned the project:
|
5500
|
+
|
5501
|
+
```
|
5502
|
+
ruby -r './lib/glimmer-dsl-libui' examples/cpu_percentage.rb
|
5503
|
+
```
|
5504
|
+
|
5505
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
5506
|
+
|
5507
|
+
```
|
5508
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/cpu_percentage'"
|
5509
|
+
```
|
5510
|
+
|
5511
|
+
Mac | Windows | Linux
|
5512
|
+
----|---------|------
|
5513
|
+
![glimmer-dsl-libui-mac-cpu-percentage.png](images/glimmer-dsl-libui-mac-cpu-percentage.png) | ![glimmer-dsl-libui-windows-cpu-percentage.png](images/glimmer-dsl-libui-windows-cpu-percentage.png) | ![glimmer-dsl-libui-linux-cpu-percentage.png](images/glimmer-dsl-libui-linux-cpu-percentage.png)
|
5514
|
+
|
5515
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
5516
|
+
|
5517
|
+
```ruby
|
5518
|
+
require 'glimmer-dsl-libui'
|
5519
|
+
require 'bigdecimal'
|
5520
|
+
|
5521
|
+
include Glimmer
|
5522
|
+
|
5523
|
+
data = [
|
5524
|
+
['CPU', '0%', 0],
|
5525
|
+
]
|
5526
|
+
|
5527
|
+
Glimmer::LibUI.timer(1) do
|
5528
|
+
cpu_percentage_value = nil
|
5529
|
+
if OS.windows?
|
5530
|
+
cpu_percentage_raw_value = `wmic cpu get loadpercentage`
|
5531
|
+
cpu_percentage_value = cpu_percentage_raw_value.split("\n")[2].to_i
|
5532
|
+
elsif OS.mac?
|
5533
|
+
cpu_percentage_value = `ps -A -o %cpu | awk '{s+=$1} END {print s}'`.to_i
|
5534
|
+
elsif OS.linux?
|
5535
|
+
stats = `top -n 1`
|
5536
|
+
idle_percentage = stats.split("\n")[2].match(/ni,.* (.*) .*id/)[1]
|
5537
|
+
cpu_percentage_value = (BigDecimal(100) - BigDecimal(idle_percentage)).to_i
|
5538
|
+
end
|
5539
|
+
data[0][1] = "#{cpu_percentage_value}%"
|
5540
|
+
data[0][2] = cpu_percentage_value
|
5541
|
+
end
|
5542
|
+
|
5543
|
+
window('CPU Percentage', 400, 200) {
|
5544
|
+
vertical_box {
|
5545
|
+
table {
|
5546
|
+
text_column('Name')
|
5547
|
+
text_column('Value')
|
5548
|
+
progress_bar_column('Percentage')
|
5549
|
+
|
5550
|
+
cell_rows data # implicit data-binding
|
5551
|
+
}
|
5552
|
+
}
|
5553
|
+
}.show
|
5554
|
+
```
|
5555
|
+
|
5652
5556
|
#### Custom Draw Text
|
5653
5557
|
|
5654
5558
|
[examples/custom_draw_text.rb](examples/custom_draw_text.rb)
|
@@ -6406,15 +6310,15 @@ require 'glimmer-dsl-libui'
|
|
6406
6310
|
class FormTable
|
6407
6311
|
include Glimmer
|
6408
6312
|
|
6409
|
-
attr_accessor :name, :email, :phone, :city, :state, :filter_value
|
6313
|
+
attr_accessor :data, :name, :email, :phone, :city, :state, :filter_value
|
6410
6314
|
|
6411
6315
|
def initialize
|
6412
6316
|
@data = [
|
6413
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'
|
6414
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'
|
6415
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'
|
6416
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'
|
6417
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'
|
6317
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
6318
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
6319
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
6320
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
6321
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
6418
6322
|
]
|
6419
6323
|
end
|
6420
6324
|
|
@@ -6477,10 +6381,10 @@ class FormTable
|
|
6477
6381
|
after_write: ->(filter_value) { # execute after write to self.filter_value
|
6478
6382
|
@unfiltered_data ||= @data.dup
|
6479
6383
|
# Unfilter first to remove any previous filters
|
6480
|
-
|
6384
|
+
self.data = @unfiltered_data # affects table indirectly through explicit data-binding
|
6481
6385
|
# Now, apply filter if entered
|
6482
6386
|
unless filter_value.empty?
|
6483
|
-
@data.filter
|
6387
|
+
self.data = @data.filter do |row_data| # affects table indirectly through explicit data-binding
|
6484
6388
|
row_data.any? do |cell|
|
6485
6389
|
cell.to_s.downcase.include?(filter_value.downcase)
|
6486
6390
|
end
|
@@ -6497,7 +6401,7 @@ class FormTable
|
|
6497
6401
|
text_column('City')
|
6498
6402
|
text_column('State')
|
6499
6403
|
|
6500
|
-
cell_rows
|
6404
|
+
cell_rows <=> [self, :data] # explicit data-binding
|
6501
6405
|
|
6502
6406
|
on_changed do |row, type, row_data|
|
6503
6407
|
puts "Row #{row} #{type}: #{row_data}"
|
@@ -6519,11 +6423,11 @@ require 'glimmer-dsl-libui'
|
|
6519
6423
|
include Glimmer
|
6520
6424
|
|
6521
6425
|
data = [
|
6522
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'
|
6523
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'
|
6524
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'
|
6525
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'
|
6526
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'
|
6426
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
6427
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
6428
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
6429
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
6430
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
6527
6431
|
]
|
6528
6432
|
|
6529
6433
|
window('Contacts', 600, 600) { |w|
|
@@ -7852,7 +7756,181 @@ end
|
|
7852
7756
|
TinyMidiPlayer.new
|
7853
7757
|
```
|
7854
7758
|
|
7855
|
-
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
7759
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with [data-binding](#data-binding)):
|
7760
|
+
|
7761
|
+
```ruby
|
7762
|
+
# frozen_string_literal: true
|
7763
|
+
|
7764
|
+
require 'glimmer-dsl-libui'
|
7765
|
+
|
7766
|
+
class TinyMidiPlayer
|
7767
|
+
include Glimmer
|
7768
|
+
|
7769
|
+
VERSION = '0.0.1'
|
7770
|
+
|
7771
|
+
attr_accessor :selected_file
|
7772
|
+
|
7773
|
+
def initialize
|
7774
|
+
@pid = nil
|
7775
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
7776
|
+
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
7777
|
+
.sort_by { |path| File.basename(path) }
|
7778
|
+
at_exit { stop_midi }
|
7779
|
+
create_gui
|
7780
|
+
end
|
7781
|
+
|
7782
|
+
def stop_midi
|
7783
|
+
if @pid
|
7784
|
+
Process.kill(:SIGKILL, @pid) if @th.alive?
|
7785
|
+
@pid = nil
|
7786
|
+
end
|
7787
|
+
end
|
7788
|
+
|
7789
|
+
def play_midi
|
7790
|
+
stop_midi
|
7791
|
+
if @pid.nil? && @selected_file
|
7792
|
+
begin
|
7793
|
+
@pid = spawn "timidity #{@selected_file}"
|
7794
|
+
@th = Process.detach @pid
|
7795
|
+
rescue Errno::ENOENT
|
7796
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
7797
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
7798
|
+
end
|
7799
|
+
end
|
7800
|
+
end
|
7801
|
+
|
7802
|
+
def show_version
|
7803
|
+
msg_box('Tiny Midi Player',
|
7804
|
+
"Written in Ruby\n" \
|
7805
|
+
"https://github.com/kojix2/libui\n" \
|
7806
|
+
"Version #{VERSION}")
|
7807
|
+
end
|
7808
|
+
|
7809
|
+
def create_gui
|
7810
|
+
menu('Help') {
|
7811
|
+
menu_item('Version') {
|
7812
|
+
on_clicked do
|
7813
|
+
show_version
|
7814
|
+
end
|
7815
|
+
}
|
7816
|
+
}
|
7817
|
+
window('Tiny Midi Player', 200, 50) {
|
7818
|
+
horizontal_box {
|
7819
|
+
vertical_box {
|
7820
|
+
stretchy false
|
7821
|
+
|
7822
|
+
button('▶') {
|
7823
|
+
on_clicked do
|
7824
|
+
play_midi
|
7825
|
+
end
|
7826
|
+
}
|
7827
|
+
button('■') {
|
7828
|
+
on_clicked do
|
7829
|
+
stop_midi
|
7830
|
+
end
|
7831
|
+
}
|
7832
|
+
}
|
7833
|
+
|
7834
|
+
combobox {
|
7835
|
+
items @midi_files.map { |path| File.basename(path) }
|
7836
|
+
# data-bind selected item (String) to self.selected_file with on-read/on-write converters and after_write operation
|
7837
|
+
selected_item <=> [self, :selected_file, on_read: ->(f) {File.basename(f.to_s)}, on_write: ->(f) {File.join(@music_directory, f)}, after_write: -> { play_midi if @th&.alive? }]
|
7838
|
+
}
|
7839
|
+
}
|
7840
|
+
}.show
|
7841
|
+
end
|
7842
|
+
end
|
7843
|
+
|
7844
|
+
TinyMidiPlayer.new
|
7845
|
+
```
|
7846
|
+
|
7847
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (with [data-binding](#data-binding)):
|
7848
|
+
|
7849
|
+
```ruby
|
7850
|
+
require 'glimmer-dsl-libui'
|
7851
|
+
|
7852
|
+
class TinyMidiPlayer
|
7853
|
+
include Glimmer
|
7854
|
+
|
7855
|
+
VERSION = '0.0.1'
|
7856
|
+
|
7857
|
+
attr_accessor :selected_file
|
7858
|
+
|
7859
|
+
def initialize
|
7860
|
+
@pid = nil
|
7861
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
7862
|
+
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
7863
|
+
.sort_by { |path| File.basename(path) }
|
7864
|
+
at_exit { stop_midi }
|
7865
|
+
create_gui
|
7866
|
+
end
|
7867
|
+
|
7868
|
+
def stop_midi
|
7869
|
+
if @pid
|
7870
|
+
Process.kill(:SIGKILL, @pid) if @th.alive?
|
7871
|
+
@pid = nil
|
7872
|
+
end
|
7873
|
+
end
|
7874
|
+
|
7875
|
+
def play_midi
|
7876
|
+
stop_midi
|
7877
|
+
if @pid.nil? && @selected_file
|
7878
|
+
begin
|
7879
|
+
@pid = spawn "timidity #{@selected_file}"
|
7880
|
+
@th = Process.detach @pid
|
7881
|
+
rescue Errno::ENOENT
|
7882
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
7883
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
7884
|
+
end
|
7885
|
+
end
|
7886
|
+
end
|
7887
|
+
|
7888
|
+
def show_version
|
7889
|
+
msg_box('Tiny Midi Player',
|
7890
|
+
"Written in Ruby\n" \
|
7891
|
+
"https://github.com/kojix2/libui\n" \
|
7892
|
+
"Version #{VERSION}")
|
7893
|
+
end
|
7894
|
+
|
7895
|
+
def create_gui
|
7896
|
+
menu('Help') {
|
7897
|
+
menu_item('Version') {
|
7898
|
+
on_clicked do
|
7899
|
+
show_version
|
7900
|
+
end
|
7901
|
+
}
|
7902
|
+
}
|
7903
|
+
window('Tiny Midi Player', 200, 50) {
|
7904
|
+
horizontal_box {
|
7905
|
+
vertical_box {
|
7906
|
+
stretchy false
|
7907
|
+
|
7908
|
+
button('▶') {
|
7909
|
+
on_clicked do
|
7910
|
+
play_midi
|
7911
|
+
end
|
7912
|
+
}
|
7913
|
+
button('■') {
|
7914
|
+
on_clicked do
|
7915
|
+
stop_midi
|
7916
|
+
end
|
7917
|
+
}
|
7918
|
+
}
|
7919
|
+
|
7920
|
+
combobox {
|
7921
|
+
items @midi_files.map { |path| File.basename(path) }
|
7922
|
+
# data-bind selected index (Integer) to self.selected_file with on-read/on-write converters and after_write operation
|
7923
|
+
selected <=> [self, :selected_file, on_read: ->(f) {@midi_files.index(f)}, on_write: ->(i) {@midi_files[i]}, after_write: -> { play_midi if @th&.alive? }]
|
7924
|
+
}
|
7925
|
+
}
|
7926
|
+
}.show
|
7927
|
+
end
|
7928
|
+
end
|
7929
|
+
|
7930
|
+
TinyMidiPlayer.new
|
7931
|
+
```
|
7932
|
+
|
7933
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3 (without [data-binding](#data-binding)):
|
7856
7934
|
|
7857
7935
|
```ruby
|
7858
7936
|
require 'glimmer-dsl-libui'
|
@@ -7961,7 +8039,7 @@ Mac | Windows | Linux
|
|
7961
8039
|
----|---------|------
|
7962
8040
|
![glimmer-dsl-libui-mac-snake.png](images/glimmer-dsl-libui-mac-snake.png) ![glimmer-dsl-libui-mac-snake-game-over.png](images/glimmer-dsl-libui-mac-snake-game-over.png) | ![glimmer-dsl-libui-windows-snake.png](images/glimmer-dsl-libui-windows-snake.png) ![glimmer-dsl-libui-windows-snake-game-over.png](images/glimmer-dsl-libui-windows-snake-game-over.png) | ![glimmer-dsl-libui-linux-snake.png](images/glimmer-dsl-libui-linux-snake.png) ![glimmer-dsl-libui-linux-snake-game-over.png](images/glimmer-dsl-libui-linux-snake-game-over.png)
|
7963
8041
|
|
7964
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
8042
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with [data-binding](#data-binding)):
|
7965
8043
|
|
7966
8044
|
```ruby
|
7967
8045
|
require 'glimmer-dsl-libui'
|
@@ -7978,6 +8056,7 @@ class Snake
|
|
7978
8056
|
@game = Model::Game.new
|
7979
8057
|
@grid = Presenter::Grid.new(@game)
|
7980
8058
|
@game.start
|
8059
|
+
@keypress_queue = []
|
7981
8060
|
create_gui
|
7982
8061
|
register_observers
|
7983
8062
|
end
|
@@ -7997,14 +8076,30 @@ class Snake
|
|
7997
8076
|
end
|
7998
8077
|
|
7999
8078
|
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
8000
|
-
|
8079
|
+
unless @game.over?
|
8080
|
+
process_queued_keypress
|
8081
|
+
@game.snake.move
|
8082
|
+
end
|
8083
|
+
end
|
8084
|
+
end
|
8085
|
+
|
8086
|
+
def process_queued_keypress
|
8087
|
+
# key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
|
8088
|
+
key = @keypress_queue.shift
|
8089
|
+
case [@game.snake.head.orientation, key]
|
8090
|
+
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
8091
|
+
@game.snake.turn_right
|
8092
|
+
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
8093
|
+
@game.snake.turn_left
|
8094
|
+
else
|
8095
|
+
# No Op
|
8001
8096
|
end
|
8002
8097
|
end
|
8003
8098
|
|
8004
8099
|
def create_gui
|
8005
8100
|
@main_window = window {
|
8006
8101
|
# data-bind window title to game score, converting it to a title string on read from the model
|
8007
|
-
title <= [@game, :score, on_read: -> (score) {"
|
8102
|
+
title <= [@game, :score, on_read: -> (score) {"Snake (Score: #{@game.score})"}]
|
8008
8103
|
content_size @game.width * CELL_SIZE, @game.height * CELL_SIZE
|
8009
8104
|
resizable false
|
8010
8105
|
|
@@ -8022,15 +8117,109 @@ class Snake
|
|
8022
8117
|
}
|
8023
8118
|
|
8024
8119
|
on_key_up do |area_key_event|
|
8025
|
-
|
8026
|
-
|
8027
|
-
|
8028
|
-
|
8029
|
-
|
8030
|
-
|
8031
|
-
|
8032
|
-
|
8033
|
-
|
8120
|
+
@keypress_queue << area_key_event[:ext_key]
|
8121
|
+
end
|
8122
|
+
}
|
8123
|
+
end
|
8124
|
+
}
|
8125
|
+
end
|
8126
|
+
}
|
8127
|
+
}
|
8128
|
+
end
|
8129
|
+
end
|
8130
|
+
|
8131
|
+
Snake.new.launch
|
8132
|
+
```
|
8133
|
+
|
8134
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (without [data-binding](#data-binding)):
|
8135
|
+
|
8136
|
+
```ruby
|
8137
|
+
require 'glimmer-dsl-libui'
|
8138
|
+
|
8139
|
+
require_relative 'snake/presenter/grid'
|
8140
|
+
|
8141
|
+
class Snake
|
8142
|
+
include Glimmer
|
8143
|
+
|
8144
|
+
CELL_SIZE = 15
|
8145
|
+
SNAKE_MOVE_DELAY = 0.1
|
8146
|
+
|
8147
|
+
def initialize
|
8148
|
+
@game = Model::Game.new
|
8149
|
+
@grid = Presenter::Grid.new(@game)
|
8150
|
+
@game.start
|
8151
|
+
@keypress_queue = []
|
8152
|
+
create_gui
|
8153
|
+
register_observers
|
8154
|
+
end
|
8155
|
+
|
8156
|
+
def launch
|
8157
|
+
@main_window.show
|
8158
|
+
end
|
8159
|
+
|
8160
|
+
def register_observers
|
8161
|
+
@game.height.times do |row|
|
8162
|
+
@game.width.times do |column|
|
8163
|
+
observe(@grid.cells[row][column], :color) do |new_color|
|
8164
|
+
@cell_grid[row][column].fill = new_color
|
8165
|
+
end
|
8166
|
+
end
|
8167
|
+
end
|
8168
|
+
|
8169
|
+
observe(@game, :over) do |game_over|
|
8170
|
+
Glimmer::LibUI.queue_main do
|
8171
|
+
if game_over
|
8172
|
+
msg_box('Game Over!', "Score: #{@game.score} | High Score: #{@game.high_score}")
|
8173
|
+
@game.start
|
8174
|
+
end
|
8175
|
+
end
|
8176
|
+
end
|
8177
|
+
|
8178
|
+
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
8179
|
+
unless @game.over?
|
8180
|
+
process_queued_keypress
|
8181
|
+
@game.snake.move
|
8182
|
+
end
|
8183
|
+
end
|
8184
|
+
end
|
8185
|
+
|
8186
|
+
def process_queued_keypress
|
8187
|
+
# key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
|
8188
|
+
key = @keypress_queue.shift
|
8189
|
+
case [@game.snake.head.orientation, key]
|
8190
|
+
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
8191
|
+
@game.snake.turn_right
|
8192
|
+
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
8193
|
+
@game.snake.turn_left
|
8194
|
+
else
|
8195
|
+
# No Op
|
8196
|
+
end
|
8197
|
+
end
|
8198
|
+
|
8199
|
+
def create_gui
|
8200
|
+
@cell_grid = []
|
8201
|
+
@main_window = window {
|
8202
|
+
# data-bind window title to game score, converting it to a title string on read from the model
|
8203
|
+
title <= [@game, :score, on_read: -> (score) {"Snake (Score: #{@game.score})"}]
|
8204
|
+
content_size @game.width * CELL_SIZE, @game.height * CELL_SIZE
|
8205
|
+
resizable false
|
8206
|
+
|
8207
|
+
vertical_box {
|
8208
|
+
padded false
|
8209
|
+
|
8210
|
+
@game.height.times do |row|
|
8211
|
+
@cell_grid << []
|
8212
|
+
horizontal_box {
|
8213
|
+
padded false
|
8214
|
+
|
8215
|
+
@game.width.times do |column|
|
8216
|
+
area {
|
8217
|
+
@cell_grid.last << square(0, 0, CELL_SIZE) {
|
8218
|
+
fill Presenter::Cell::COLOR_CLEAR
|
8219
|
+
}
|
8220
|
+
|
8221
|
+
on_key_up do |area_key_event|
|
8222
|
+
@keypress_queue << area_key_event[:ext_key]
|
8034
8223
|
end
|
8035
8224
|
}
|
8036
8225
|
end
|
@@ -8180,22 +8369,23 @@ class Tetris
|
|
8180
8369
|
menu('Game') {
|
8181
8370
|
@pause_menu_item = check_menu_item('Pause') {
|
8182
8371
|
enabled false
|
8183
|
-
|
8184
|
-
on_clicked do
|
8185
|
-
@game.paused = @pause_menu_item.checked?
|
8186
|
-
end
|
8372
|
+
checked <=> [@game, :paused]
|
8187
8373
|
}
|
8374
|
+
|
8188
8375
|
menu_item('Restart') {
|
8189
8376
|
on_clicked do
|
8190
8377
|
@game.restart!
|
8191
8378
|
end
|
8192
8379
|
}
|
8380
|
+
|
8193
8381
|
separator_menu_item
|
8382
|
+
|
8194
8383
|
menu_item('Exit') {
|
8195
8384
|
on_clicked do
|
8196
8385
|
exit(0)
|
8197
8386
|
end
|
8198
8387
|
}
|
8388
|
+
|
8199
8389
|
quit_menu_item if OS.mac?
|
8200
8390
|
}
|
8201
8391
|
|
@@ -8205,6 +8395,7 @@ class Tetris
|
|
8205
8395
|
show_high_scores
|
8206
8396
|
end
|
8207
8397
|
}
|
8398
|
+
|
8208
8399
|
menu_item('Clear High Scores') {
|
8209
8400
|
on_clicked {
|
8210
8401
|
@game.clear_high_scores!
|
@@ -8213,22 +8404,16 @@ class Tetris
|
|
8213
8404
|
}
|
8214
8405
|
|
8215
8406
|
menu('Options') {
|
8216
|
-
radio_menu_item('Instant Down on Up Arrow') {
|
8217
|
-
|
8218
|
-
@game.instant_down_on_up = true
|
8219
|
-
end
|
8407
|
+
radio_menu_item('Instant Down on Up Arrow') { |r|
|
8408
|
+
checked <=> [@game, :instant_down_on_up]
|
8220
8409
|
}
|
8221
|
-
|
8222
|
-
|
8223
|
-
|
8224
|
-
end
|
8410
|
+
|
8411
|
+
radio_menu_item('Rotate Right on Up Arrow') { |r|
|
8412
|
+
checked <=> [@game, :rotate_right_on_up]
|
8225
8413
|
}
|
8226
|
-
|
8227
|
-
|
8228
|
-
|
8229
|
-
on_clicked do
|
8230
|
-
@game.rotate_left_on_up = true
|
8231
|
-
end
|
8414
|
+
|
8415
|
+
radio_menu_item('Rotate Left on Up Arrow') { |r|
|
8416
|
+
checked <=> [@game, :rotate_left_on_up]
|
8232
8417
|
}
|
8233
8418
|
}
|
8234
8419
|
|
@@ -8240,6 +8425,7 @@ class Tetris
|
|
8240
8425
|
end
|
8241
8426
|
}
|
8242
8427
|
end
|
8428
|
+
|
8243
8429
|
menu_item('About') {
|
8244
8430
|
on_clicked do
|
8245
8431
|
show_about_dialog
|
@@ -8462,7 +8648,7 @@ Mac | Windows | Linux
|
|
8462
8648
|
----|---------|------
|
8463
8649
|
![glimmer-dsl-libui-mac-tic-tac-toe.png](images/glimmer-dsl-libui-mac-tic-tac-toe.png) ![glimmer-dsl-libui-mac-tic-tac-toe-player-o-wins.png](images/glimmer-dsl-libui-mac-tic-tac-toe-player-o-wins.png) ![glimmer-dsl-libui-mac-tic-tac-toe-player-x-wins.png](images/glimmer-dsl-libui-mac-tic-tac-toe-player-x-wins.png) ![glimmer-dsl-libui-mac-tic-tac-toe-draw.png](images/glimmer-dsl-libui-mac-tic-tac-toe-draw.png) | ![glimmer-dsl-libui-windows-tic-tac-toe.png](images/glimmer-dsl-libui-windows-tic-tac-toe.png) ![glimmer-dsl-libui-windows-tic-tac-toe-player-o-wins.png](images/glimmer-dsl-libui-windows-tic-tac-toe-player-o-wins.png) ![glimmer-dsl-libui-windows-tic-tac-toe-player-x-wins.png](images/glimmer-dsl-libui-windows-tic-tac-toe-player-x-wins.png) ![glimmer-dsl-libui-windows-tic-tac-toe-draw.png](images/glimmer-dsl-libui-windows-tic-tac-toe-draw.png) | ![glimmer-dsl-libui-linux-tic-tac-toe.png](images/glimmer-dsl-libui-linux-tic-tac-toe.png) ![glimmer-dsl-libui-linux-tic-tac-toe-player-o-wins.png](images/glimmer-dsl-libui-linux-tic-tac-toe-player-o-wins.png) ![glimmer-dsl-libui-linux-tic-tac-toe-player-x-wins.png](images/glimmer-dsl-libui-linux-tic-tac-toe-player-x-wins.png) ![glimmer-dsl-libui-linux-tic-tac-toe-draw.png](images/glimmer-dsl-libui-linux-tic-tac-toe-draw.png)
|
8464
8650
|
|
8465
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
8651
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with [data-binding](#data-binding)):
|
8466
8652
|
|
8467
8653
|
```ruby
|
8468
8654
|
require 'glimmer-dsl-libui'
|
@@ -8508,6 +8694,7 @@ class TicTacToe
|
|
8508
8694
|
text(23, 19) {
|
8509
8695
|
string {
|
8510
8696
|
font family: 'Arial', size: OS.mac? ? 20 : 16
|
8697
|
+
# data-bind string property of area text attributed string to tic tac toe board cell sign
|
8511
8698
|
string <= [@tic_tac_toe_board[row + 1, column + 1], :sign] # board model is 1-based
|
8512
8699
|
}
|
8513
8700
|
}
|
@@ -8541,6 +8728,95 @@ end
|
|
8541
8728
|
TicTacToe.new.launch
|
8542
8729
|
```
|
8543
8730
|
|
8731
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (without [data-binding](#data-binding)):
|
8732
|
+
|
8733
|
+
```ruby
|
8734
|
+
|
8735
|
+
require 'glimmer-dsl-libui'
|
8736
|
+
|
8737
|
+
require_relative "tic_tac_toe/board"
|
8738
|
+
|
8739
|
+
class TicTacToe
|
8740
|
+
include Glimmer
|
8741
|
+
|
8742
|
+
def initialize
|
8743
|
+
@tic_tac_toe_board = Board.new
|
8744
|
+
end
|
8745
|
+
|
8746
|
+
def launch
|
8747
|
+
create_gui
|
8748
|
+
register_observers
|
8749
|
+
@main_window.show
|
8750
|
+
end
|
8751
|
+
|
8752
|
+
def register_observers
|
8753
|
+
observe(@tic_tac_toe_board, :game_status) do |game_status|
|
8754
|
+
display_win_message if game_status == Board::WIN
|
8755
|
+
display_draw_message if game_status == Board::DRAW
|
8756
|
+
end
|
8757
|
+
|
8758
|
+
3.times.map do |row|
|
8759
|
+
3.times.map do |column|
|
8760
|
+
observe(@tic_tac_toe_board[row + 1, column + 1], :sign) do |sign| # board model is 1-based
|
8761
|
+
@cells[row][column].string = sign
|
8762
|
+
end
|
8763
|
+
end
|
8764
|
+
end
|
8765
|
+
end
|
8766
|
+
|
8767
|
+
def create_gui
|
8768
|
+
@main_window = window('Tic-Tac-Toe', 180, 180) {
|
8769
|
+
resizable false
|
8770
|
+
|
8771
|
+
@cells = []
|
8772
|
+
vertical_box {
|
8773
|
+
padded false
|
8774
|
+
|
8775
|
+
3.times.map do |row|
|
8776
|
+
@cells << []
|
8777
|
+
horizontal_box {
|
8778
|
+
padded false
|
8779
|
+
|
8780
|
+
3.times.map do |column|
|
8781
|
+
area {
|
8782
|
+
square(0, 0, 60) {
|
8783
|
+
stroke :black, thickness: 2
|
8784
|
+
}
|
8785
|
+
text(23, 19) {
|
8786
|
+
@cells[row] << string('') {
|
8787
|
+
font family: 'Arial', size: OS.mac? ? 20 : 16
|
8788
|
+
}
|
8789
|
+
}
|
8790
|
+
on_mouse_up do
|
8791
|
+
@tic_tac_toe_board.mark(row + 1, column + 1) # board model is 1-based
|
8792
|
+
end
|
8793
|
+
}
|
8794
|
+
end
|
8795
|
+
}
|
8796
|
+
end
|
8797
|
+
}
|
8798
|
+
}
|
8799
|
+
end
|
8800
|
+
|
8801
|
+
def display_win_message
|
8802
|
+
display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
|
8803
|
+
end
|
8804
|
+
|
8805
|
+
def display_draw_message
|
8806
|
+
display_game_over_message("Draw!")
|
8807
|
+
end
|
8808
|
+
|
8809
|
+
def display_game_over_message(message_text)
|
8810
|
+
Glimmer::LibUI.queue_main do
|
8811
|
+
msg_box('Game Over', message_text)
|
8812
|
+
@tic_tac_toe_board.reset!
|
8813
|
+
end
|
8814
|
+
end
|
8815
|
+
end
|
8816
|
+
|
8817
|
+
TicTacToe.new.launch
|
8818
|
+
```
|
8819
|
+
|
8544
8820
|
#### Timer
|
8545
8821
|
|
8546
8822
|
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).
|
@@ -8869,7 +9145,7 @@ https://github.com/iraamaro/i3off-gtk-ruby
|
|
8869
9145
|
|
8870
9146
|
### Issues
|
8871
9147
|
|
8872
|
-
If you encounter [issues](https://github.com/AndyObtiva/glimmer-dsl-libui/issues) that are not reported, discover missing features that are not mentioned in [TODO.md](TODO.md), or think up better ways to use [libui](https://github.com/andlabs/libui) than what is possible with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), you may submit an [issue](https://github.com/AndyObtiva/glimmer-dsl-libui/issues/new) or [pull request](https://github.com/AndyObtiva/glimmer-dsl-libui/compare) on [GitHub](https://github.com).
|
9148
|
+
If you encounter [issues](https://github.com/AndyObtiva/glimmer-dsl-libui/issues) that are not reported, discover missing features that are not mentioned in [TODO.md](TODO.md), or think up better ways to use [libui](https://github.com/andlabs/libui) than what is possible with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), you may submit an [issue](https://github.com/AndyObtiva/glimmer-dsl-libui/issues/new) or [pull request](https://github.com/AndyObtiva/glimmer-dsl-libui/compare) on [GitHub](https://github.com). In the meantime, you may try older gem versions of [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) till you find one that works until issues are resolved.
|
8873
9149
|
|
8874
9150
|
### Chat
|
8875
9151
|
|
@@ -8901,6 +9177,8 @@ These features have been planned or suggested. You might see them in a future ve
|
|
8901
9177
|
is fine, but please isolate to its own commit so I can cherry-pick
|
8902
9178
|
around it.
|
8903
9179
|
|
9180
|
+
Note that the latest development sometimes takes place in the [development](https://github.com/AndyObtiva/glimmer-dsl-libui/tree/development) branch (usually deleted once merged back to [master](https://github.com/AndyObtiva/glimmer-dsl-libui)).
|
9181
|
+
|
8904
9182
|
## Contributors
|
8905
9183
|
|
8906
9184
|
* [Andy Maleh](https://github.com/AndyObtiva) (Founder)
|