glimmer-dsl-libui 0.4.6 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[](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
|

|
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
|
  |   |  
|
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
|
+
 |  | 
|
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
|
  |   |  
|
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
|
    |     |    
|
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)
|