whirled_peas 0.4.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +37 -0
- data/README.md +529 -156
- data/Rakefile +9 -3
- data/bin/reset_cursor +11 -0
- data/bin/screen_test +68 -0
- data/examples/intro.rb +52 -0
- data/examples/scrolling.rb +54 -0
- data/lib/whirled_peas.rb +6 -12
- data/lib/whirled_peas/animator.rb +5 -0
- data/lib/whirled_peas/animator/debug_consumer.rb +17 -0
- data/lib/whirled_peas/animator/easing.rb +72 -0
- data/lib/whirled_peas/animator/frame.rb +5 -0
- data/lib/whirled_peas/animator/frameset.rb +33 -0
- data/lib/whirled_peas/animator/producer.rb +35 -0
- data/lib/whirled_peas/animator/renderer_consumer.rb +31 -0
- data/lib/whirled_peas/command.rb +5 -0
- data/lib/whirled_peas/command/base.rb +86 -0
- data/lib/whirled_peas/command/config_command.rb +44 -0
- data/lib/whirled_peas/command/debug.rb +21 -0
- data/lib/whirled_peas/command/fonts.rb +22 -0
- data/lib/whirled_peas/command/frame_command.rb +34 -0
- data/lib/whirled_peas/command/frames.rb +24 -0
- data/lib/whirled_peas/command/help.rb +38 -0
- data/lib/whirled_peas/command/play.rb +108 -0
- data/lib/whirled_peas/command/record.rb +57 -0
- data/lib/whirled_peas/command/still.rb +29 -0
- data/lib/whirled_peas/command_line.rb +23 -228
- data/lib/whirled_peas/config.rb +56 -6
- data/lib/whirled_peas/device.rb +5 -0
- data/lib/whirled_peas/device/null_device.rb +8 -0
- data/lib/whirled_peas/device/output_file.rb +19 -0
- data/lib/whirled_peas/device/screen.rb +26 -0
- data/lib/whirled_peas/errors.rb +2 -0
- data/lib/whirled_peas/graphics.rb +19 -0
- data/lib/whirled_peas/graphics/box_painter.rb +101 -0
- data/lib/whirled_peas/graphics/canvas.rb +118 -0
- data/lib/whirled_peas/graphics/composer.rb +80 -0
- data/lib/whirled_peas/graphics/container_coords.rb +72 -0
- data/lib/whirled_peas/graphics/container_dimensions.rb +93 -0
- data/lib/whirled_peas/graphics/container_painter.rb +363 -0
- data/lib/whirled_peas/graphics/debugger.rb +52 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +69 -0
- data/lib/whirled_peas/graphics/mock_screen.rb +26 -0
- data/lib/whirled_peas/graphics/painter.rb +33 -0
- data/lib/whirled_peas/graphics/renderer.rb +32 -0
- data/lib/whirled_peas/graphics/text_dimensions.rb +15 -0
- data/lib/whirled_peas/graphics/text_painter.rb +40 -0
- data/lib/whirled_peas/settings.rb +5 -0
- data/lib/whirled_peas/settings/alignment.rb +24 -0
- data/lib/whirled_peas/settings/bg_color.rb +24 -0
- data/lib/whirled_peas/settings/border.rb +101 -0
- data/lib/whirled_peas/settings/box_settings.rb +8 -0
- data/lib/whirled_peas/settings/color.rb +68 -0
- data/lib/whirled_peas/settings/container_settings.rb +223 -0
- data/lib/whirled_peas/settings/debugger.rb +96 -0
- data/lib/whirled_peas/settings/display_flow.rb +27 -0
- data/lib/whirled_peas/settings/element_settings.rb +61 -0
- data/lib/whirled_peas/settings/grid_settings.rb +19 -0
- data/lib/whirled_peas/settings/margin.rb +8 -0
- data/lib/whirled_peas/settings/padding.rb +8 -0
- data/lib/whirled_peas/settings/position.rb +15 -0
- data/lib/whirled_peas/settings/scrollbar.rb +15 -0
- data/lib/whirled_peas/settings/sizing.rb +19 -0
- data/lib/whirled_peas/settings/spacing.rb +58 -0
- data/lib/whirled_peas/settings/text_color.rb +21 -0
- data/lib/whirled_peas/settings/text_settings.rb +15 -0
- data/lib/whirled_peas/settings/vert_alignment.rb +24 -0
- data/lib/whirled_peas/utils/ansi.rb +19 -56
- data/lib/whirled_peas/utils/file_handler.rb +57 -0
- data/lib/whirled_peas/utils/formatted_string.rb +64 -0
- data/lib/whirled_peas/utils/title_font.rb +1 -1
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/elements/box.frame +1 -0
- data/screen_test/elements/box.rb +20 -0
- data/screen_test/elements/grid.frame +1 -0
- data/screen_test/elements/grid.rb +13 -0
- data/screen_test/elements/screen_overflow_x.frame +1 -0
- data/screen_test/elements/screen_overflow_x.rb +9 -0
- data/screen_test/elements/screen_overflow_y.frame +1 -0
- data/screen_test/elements/screen_overflow_y.rb +9 -0
- data/screen_test/elements/text.frame +1 -0
- data/screen_test/elements/text.rb +9 -0
- data/screen_test/elements/text_multiline.frame +1 -0
- data/screen_test/elements/text_multiline.rb +9 -0
- data/screen_test/settings/align/box_around.frame +1 -0
- data/screen_test/settings/align/box_around.rb +16 -0
- data/screen_test/settings/align/box_between.frame +1 -0
- data/screen_test/settings/align/box_between.rb +16 -0
- data/screen_test/settings/align/box_center.frame +1 -0
- data/screen_test/settings/align/box_center.rb +21 -0
- data/screen_test/settings/align/box_default.frame +1 -0
- data/screen_test/settings/align/box_default.rb +20 -0
- data/screen_test/settings/align/box_evenly.frame +1 -0
- data/screen_test/settings/align/box_evenly.rb +16 -0
- data/screen_test/settings/align/box_left.frame +1 -0
- data/screen_test/settings/align/box_left.rb +21 -0
- data/screen_test/settings/align/box_right.frame +1 -0
- data/screen_test/settings/align/box_right.rb +21 -0
- data/screen_test/settings/align/children_center.frame +1 -0
- data/screen_test/settings/align/children_center.rb +15 -0
- data/screen_test/settings/align/children_left.frame +1 -0
- data/screen_test/settings/align/children_left.rb +15 -0
- data/screen_test/settings/align/children_right.frame +1 -0
- data/screen_test/settings/align/children_right.rb +15 -0
- data/screen_test/settings/align/grid_center.frame +1 -0
- data/screen_test/settings/align/grid_center.rb +18 -0
- data/screen_test/settings/align/grid_default.frame +1 -0
- data/screen_test/settings/align/grid_default.rb +17 -0
- data/screen_test/settings/align/grid_left.frame +1 -0
- data/screen_test/settings/align/grid_left.rb +18 -0
- data/screen_test/settings/align/grid_right.frame +1 -0
- data/screen_test/settings/align/grid_right.rb +18 -0
- data/screen_test/settings/ansi/bold.frame +1 -0
- data/screen_test/settings/ansi/bold.rb +14 -0
- data/screen_test/settings/ansi/color.frame +1 -0
- data/screen_test/settings/ansi/color.rb +37 -0
- data/screen_test/settings/ansi/underline.frame +1 -0
- data/screen_test/settings/ansi/underline.rb +14 -0
- data/screen_test/settings/border.frame +1 -0
- data/screen_test/settings/border.rb +13 -0
- data/screen_test/settings/flow/box_b2t.frame +1 -0
- data/screen_test/settings/flow/box_b2t.rb +26 -0
- data/screen_test/settings/flow/box_l2r.frame +1 -0
- data/screen_test/settings/flow/box_l2r.rb +26 -0
- data/screen_test/settings/flow/box_r2l.frame +1 -0
- data/screen_test/settings/flow/box_r2l.rb +26 -0
- data/screen_test/settings/flow/box_t2b.frame +1 -0
- data/screen_test/settings/flow/box_t2b.rb +26 -0
- data/screen_test/settings/flow/grid_b2t.frame +1 -0
- data/screen_test/settings/flow/grid_b2t.rb +14 -0
- data/screen_test/settings/flow/grid_l2r.frame +1 -0
- data/screen_test/settings/flow/grid_l2r.rb +14 -0
- data/screen_test/settings/flow/grid_r2l.frame +1 -0
- data/screen_test/settings/flow/grid_r2l.rb +14 -0
- data/screen_test/settings/flow/grid_t2b.frame +1 -0
- data/screen_test/settings/flow/grid_t2b.rb +14 -0
- data/screen_test/settings/height/box.frame +1 -0
- data/screen_test/settings/height/box.rb +13 -0
- data/screen_test/settings/height/box_border_sizing.frame +1 -0
- data/screen_test/settings/height/box_border_sizing.rb +15 -0
- data/screen_test/settings/height/grid.frame +1 -0
- data/screen_test/settings/height/grid.rb +14 -0
- data/screen_test/settings/height/overflow_box.frame +1 -0
- data/screen_test/settings/height/overflow_box.rb +13 -0
- data/screen_test/settings/height/overflow_box_l2r.frame +1 -0
- data/screen_test/settings/height/overflow_box_l2r.rb +17 -0
- data/screen_test/settings/height/overflow_box_t2b.frame +1 -0
- data/screen_test/settings/height/overflow_box_t2b.rb +16 -0
- data/screen_test/settings/height/overflow_grid.frame +1 -0
- data/screen_test/settings/height/overflow_grid.rb +16 -0
- data/screen_test/settings/margin.frame +1 -0
- data/screen_test/settings/margin.rb +16 -0
- data/screen_test/settings/padding.frame +1 -0
- data/screen_test/settings/padding.rb +13 -0
- data/screen_test/settings/position/box_left.frame +1 -0
- data/screen_test/settings/position/box_left.rb +17 -0
- data/screen_test/settings/position/box_left_negative.frame +1 -0
- data/screen_test/settings/position/box_left_negative.rb +17 -0
- data/screen_test/settings/position/box_top.frame +1 -0
- data/screen_test/settings/position/box_top.rb +17 -0
- data/screen_test/settings/position/box_top_negative.frame +1 -0
- data/screen_test/settings/position/box_top_negative.rb +17 -0
- data/screen_test/settings/position/grid_left.frame +1 -0
- data/screen_test/settings/position/grid_left.rb +18 -0
- data/screen_test/settings/position/grid_left_negative.frame +1 -0
- data/screen_test/settings/position/grid_left_negative.rb +18 -0
- data/screen_test/settings/position/grid_top.frame +1 -0
- data/screen_test/settings/position/grid_top.rb +18 -0
- data/screen_test/settings/position/grid_top_negative.frame +1 -0
- data/screen_test/settings/position/grid_top_negative.rb +18 -0
- data/screen_test/settings/scroll/horiz_box.frame +1 -0
- data/screen_test/settings/scroll/horiz_box.rb +17 -0
- data/screen_test/settings/scroll/horiz_box_align_center.rb +18 -0
- data/screen_test/settings/scroll/horiz_box_align_right.rb +18 -0
- data/screen_test/settings/scroll/vert_box.frame +1 -0
- data/screen_test/settings/scroll/vert_box.rb +20 -0
- data/screen_test/settings/title_font.frame +1 -0
- data/screen_test/settings/title_font.rb +12 -0
- data/screen_test/settings/valign/box_around.frame +1 -0
- data/screen_test/settings/valign/box_around.rb +17 -0
- data/screen_test/settings/valign/box_between.frame +1 -0
- data/screen_test/settings/valign/box_between.rb +17 -0
- data/screen_test/settings/valign/box_bottom.frame +1 -0
- data/screen_test/settings/valign/box_bottom.rb +17 -0
- data/screen_test/settings/valign/box_default.frame +1 -0
- data/screen_test/settings/valign/box_default.rb +16 -0
- data/screen_test/settings/valign/box_evenly.frame +1 -0
- data/screen_test/settings/valign/box_evenly.rb +17 -0
- data/screen_test/settings/valign/box_middle.frame +1 -0
- data/screen_test/settings/valign/box_middle.rb +17 -0
- data/screen_test/settings/valign/box_top.frame +1 -0
- data/screen_test/settings/valign/box_top.rb +17 -0
- data/screen_test/settings/valign/grid_bottom.frame +1 -0
- data/screen_test/settings/valign/grid_bottom.rb +15 -0
- data/screen_test/settings/valign/grid_default.frame +1 -0
- data/screen_test/settings/valign/grid_default.rb +14 -0
- data/screen_test/settings/valign/grid_middle.frame +1 -0
- data/screen_test/settings/valign/grid_middle.rb +15 -0
- data/screen_test/settings/valign/grid_top.frame +1 -0
- data/screen_test/settings/valign/grid_top.rb +15 -0
- data/screen_test/settings/width/box_border_sizing.frame +1 -0
- data/screen_test/settings/width/box_border_sizing.rb +15 -0
- data/screen_test/settings/width/box_content.frame +1 -0
- data/screen_test/settings/width/box_content.rb +15 -0
- data/screen_test/settings/width/box_default.frame +1 -0
- data/screen_test/settings/width/box_default.rb +14 -0
- data/screen_test/settings/width/grid.frame +1 -0
- data/screen_test/settings/width/grid.rb +14 -0
- data/screen_test/settings/width/overflow_align_center.frame +1 -0
- data/screen_test/settings/width/overflow_align_center.rb +14 -0
- data/screen_test/settings/width/overflow_align_right.frame +1 -0
- data/screen_test/settings/width/overflow_align_right.rb +14 -0
- data/screen_test/settings/width/overflow_box.frame +1 -0
- data/screen_test/settings/width/overflow_box.rb +13 -0
- data/screen_test/settings/width/overflow_box_l2r.frame +1 -0
- data/screen_test/settings/width/overflow_box_l2r.rb +16 -0
- data/screen_test/settings/width/overflow_box_t2b.frame +1 -0
- data/screen_test/settings/width/overflow_box_t2b.rb +17 -0
- data/screen_test/settings/width/overflow_grid.frame +1 -0
- data/screen_test/settings/width/overflow_grid.rb +14 -0
- data/tools/whirled_peas/tools/screen_tester.rb +285 -0
- metadata +213 -15
- data/bin/title_fonts +0 -6
- data/lib/whirled_peas/frame.rb +0 -7
- data/lib/whirled_peas/frame/event_loop.rb +0 -91
- data/lib/whirled_peas/frame/print_consumer.rb +0 -33
- data/lib/whirled_peas/frame/producer.rb +0 -61
- data/lib/whirled_peas/template.rb +0 -5
- data/lib/whirled_peas/template/element.rb +0 -230
- data/lib/whirled_peas/template/settings.rb +0 -530
- data/lib/whirled_peas/ui.rb +0 -5
- data/lib/whirled_peas/ui/canvas.rb +0 -68
- data/lib/whirled_peas/ui/painter.rb +0 -287
- data/lib/whirled_peas/ui/screen.rb +0 -63
- data/lib/whirled_peas/utils/color.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9652a887fc6a68ba5367864a25b4a211674433eae86a2f68db3923e873ab49e8
|
4
|
+
data.tar.gz: 72926cd288adc3c30393990d88dcc0bca53e2fbfe79d56768e438ffaee2cf3ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e0124bd724ece36b76e1d527ffb3ccd5a06e9cd7f00c1ae5d0c39445d0c4ed4804d8c2cdc0c3df250f0d927b9927efd97d118fd0fd76bbc42277fda68a674cb
|
7
|
+
data.tar.gz: '09edc4873598d1363d7d3ef2c548699bcbfa229a8821e458c201608ec9f7e3aba8cf2f081f559edc51c04244267f569e8444b7952b21ab41bfea8a7807c0432a'
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.8.0 - 2021-01-29
|
4
|
+
|
5
|
+
BREAKING: `Producer` now responds to `#add_frame` instead of `#send_frame`
|
6
|
+
|
7
|
+
- [67fdc17](https://github.com/tcollier/whirled_peas/tree/67fdc172434cb97f31ca20a674f28aefec6babb3): Add easing functions for frame transitions
|
8
|
+
- [b888f2e](https://github.com/tcollier/whirled_peas/tree/b888f2e7a3b7c3341300326b417641cc8cf2e89b): Add record and playback functionality to command line tool
|
9
|
+
|
10
|
+
## v0.7.1 - 2021-01-27
|
11
|
+
|
12
|
+
- [b98781d](https://github.com/tcollier/whirled_peas/tree/b98781de23a24b596955f25cfc48936c0cc1efac): Fix num_cols bug for vertical grid flow
|
13
|
+
|
14
|
+
## v0.7.0 - 2021-01-27
|
15
|
+
|
16
|
+
BREAKING: the settings for the template now fills the full screen and disallows margin.
|
17
|
+
|
18
|
+
- [b7c12c2](https://github.com/tcollier/whirled_peas/tree/b7c12c2c34d7077b9c2496d05ddd0c6d1eb90699): Update template to fill full screen with border sizing
|
19
|
+
- [963b819](https://github.com/tcollier/whirled_peas/tree/963b8196f0d046ba03c893f07e5578bf8c88b7a3): Implement vertical alignment
|
20
|
+
- [4bddd54](https://github.com/tcollier/whirled_peas/tree/4bddd54bec5c8f93d145c285379c1816f313f35e): Add `between`, `around`, and `evenly` alignments
|
21
|
+
|
22
|
+
## v0.6.0 - 2021-01-25
|
23
|
+
|
24
|
+
- [73df2af](https://github.com/tcollier/whirled_peas/tree/73df2af1f1eac37fe94f720dce16da1ed568dade): Add support for scroll bars along both axes
|
25
|
+
- [f4f44e1](https://github.com/tcollier/whirled_peas/tree/f4f44e1ff6c75ed03cd682e3fa9921401dcd2d00): Implement remaining 3 flow directions for grids
|
26
|
+
- [c01d083](https://github.com/tcollier/whirled_peas/tree/c01d083e10bf70983109a8def836bb181099f59c): Implement reverse flow directions for grids
|
27
|
+
|
28
|
+
## v0.5.0 - 2021-01-25
|
29
|
+
|
30
|
+
BREAKING: there was a significant amount of structural refactoring in this release. While that aspect did not add or remove any features, it fixed several layout bugs (some known and some unknown), so most template with moderate complexity will now be laid out slightly differently.
|
31
|
+
|
32
|
+
- [3ddfede](https://github.com/tcollier/whirled_peas/tree/3ddfedee4ab2fadeecbe82c7c9caf25c2988f095): Allow relative positioning of containers
|
33
|
+
- [507e77c](https://github.com/tcollier/whirled_peas/tree/507e77c551bcb9cc832d5c24e2f24eb1afe4eddc): Add height attribute for container settings
|
34
|
+
- [af8ef19](https://github.com/tcollier/whirled_peas/tree/af8ef1950edebcd23a57a04982b22a56296ee09b): Add automated screen testing
|
35
|
+
|
36
|
+
## v0.4.1 - 2021-01-22
|
37
|
+
|
38
|
+
- [0f7aa6c](https://github.com/tcollier/whirled_peas/tree/0f7aa6ccc07323230dd602cb43e0341de5a69ad8): Allow relative path for config files
|
39
|
+
|
3
40
|
## v0.4.0 - 2021-01-22
|
4
41
|
|
5
42
|
- [7fd6712](https://github.com/tcollier/whirled_peas/tree/7fd6712818c94cdbfd81828277ca67c705e01793): BREAKING: replace `WhirledPeas.start` with command line executable
|
data/README.md
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
[![Build Status](https://travis-ci.com/tcollier/whirled_peas.svg?branch=main)](https://travis-ci.com/tcollier/whirled_peas)
|
2
2
|
|
3
|
-
|
3
|
+
```
|
4
|
+
██╗ ██╗██╗███████╗██╗ ██╗ █████╗ ██╗ ██╗███████╗███████╗
|
5
|
+
██║ ██║██║██╔════╝██║ ██║██╔══██╗██║ ██║╚══███╔╝██╔════╝
|
6
|
+
██║ ██║██║███████╗██║ ██║███████║██║ ██║ ███╔╝ █████╗
|
7
|
+
╚██╗ ██╔╝██║╚════██║██║ ██║██╔══██║██║ ██║ ███╔╝ ██╔══╝
|
8
|
+
╚████╔╝ ██║███████║╚██████╔╝██║ ██║███████╗██║███████╗███████╗
|
9
|
+
╚═══╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝╚══════╝╚══════╝
|
10
|
+
|
11
|
+
your code's execution with
|
4
12
|
|
5
|
-
|
13
|
+
██╗ ██╗██╗ ██╗██╗██████╗ ██╗ ███████╗██████╗ ██████╗ ███████╗ █████╗ ███████╗
|
14
|
+
██║ ██║██║ ██║██║██╔══██╗██║ ██╔════╝██╔══██╗ ██╔══██╗██╔════╝██╔══██╗██╔════╝
|
15
|
+
██║ █╗ ██║███████║██║██████╔╝██║ █████╗ ██║ ██║ ██████╔╝█████╗ ███████║███████╗
|
16
|
+
██║███╗██║██╔══██║██║██╔══██╗██║ ██╔══╝ ██║ ██║ ██╔═══╝ ██╔══╝ ██╔══██║╚════██║
|
17
|
+
╚███╔███╔╝██║ ██║██║██║ ██║███████╗███████╗██████╔╝ ██║ ███████╗██║ ██║███████║
|
18
|
+
╚══╝╚══╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝
|
19
|
+
```
|
20
|
+
|
21
|
+
Easily create terminal-based graphics to visualize the execution of your code. Whirled Peas offers templating inspired by HTML and CSS and provides a lightweight tie-in for your code to produce visual animations with these templates.
|
6
22
|
|
7
23
|
## Installation
|
8
24
|
|
@@ -24,9 +40,8 @@ Or install it yourself as:
|
|
24
40
|
|
25
41
|
A Whirled Peas application consists of the following pieces
|
26
42
|
|
27
|
-
- The
|
28
|
-
- The main template factory (required) - builds templates to convert frame events from the
|
29
|
-
- A loading screen template factory (optional) - builds templates to display while content is loading
|
43
|
+
- The application (required) - the code that is to be visualized, it emits lightweight frame events through a producer
|
44
|
+
- The main template factory (required) - builds templates to convert frame events from the application into terminal graphics
|
30
45
|
|
31
46
|
These pieces are configured as following
|
32
47
|
|
@@ -36,8 +51,8 @@ require 'whirled_peas'
|
|
36
51
|
|
37
52
|
class TemplateFactory
|
38
53
|
def build(frame, args)
|
39
|
-
WhirledPeas.template do |
|
40
|
-
|
54
|
+
WhirledPeas.template do |composer|
|
55
|
+
composer.add_box('Title') do |_, settings|
|
41
56
|
settings.underline = true
|
42
57
|
"Hello #{args[:name]}"
|
43
58
|
end
|
@@ -46,15 +61,15 @@ class TemplateFactory
|
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
49
|
-
class
|
64
|
+
class Application
|
50
65
|
def start(producer)
|
51
|
-
producer.
|
66
|
+
producer.add_frame('starting', args: { name: 'World' })
|
52
67
|
# ...
|
53
68
|
end
|
54
69
|
end
|
55
70
|
|
56
71
|
WhirledPeas.configure do |config|
|
57
|
-
config.
|
72
|
+
config.application = Application.new
|
58
73
|
config.template_factory = TemplateFactory.new
|
59
74
|
end
|
60
75
|
```
|
@@ -62,34 +77,12 @@ end
|
|
62
77
|
Then the visualizer is started on the command line with
|
63
78
|
|
64
79
|
```
|
65
|
-
$ whirled_peas
|
80
|
+
$ whirled_peas play visualize.rb
|
66
81
|
```
|
67
82
|
|
68
|
-
|
83
|
+
### Application
|
69
84
|
|
70
|
-
|
71
|
-
class LoadingTemplateFactory
|
72
|
-
def build
|
73
|
-
WhirledPeas.template do |t|
|
74
|
-
t.add_box('Loading') do |box, settings|
|
75
|
-
settings.set_margin(top: 15)
|
76
|
-
settings.auto_margin = true
|
77
|
-
settings.full_border(color: :blue, style: :double)
|
78
|
-
"Loading..."
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
WhirledPeas.configure do |config|
|
85
|
-
# ...
|
86
|
-
config.loading_template_factory = LoadingTemplateFactory.new
|
87
|
-
end
|
88
|
-
```
|
89
|
-
|
90
|
-
### Driver
|
91
|
-
|
92
|
-
The driver is the application code to be visualized. This is typically a lightweight wrapper around an existing application that conforms to the signature below.
|
85
|
+
The application is code to be visualized that integrates with Whirled Peas by providing the signature below
|
93
86
|
|
94
87
|
```ruby
|
95
88
|
# Start the application and pass frame events to the producer to be rendered by the UI
|
@@ -108,71 +101,72 @@ The producer provides a single method
|
|
108
101
|
# @param name [String] application defined name for the frame. The template factory will be provided this name
|
109
102
|
# @param duration [Number] time in seconds this frame should be displayed for (defaults to 1 frame)
|
110
103
|
# @param args [Hash<Symbol, Object>] key value pairs to send as arguments to the template factory
|
111
|
-
def
|
104
|
+
def add_frame(name, duration:, args:)
|
112
105
|
# implementation
|
113
106
|
end
|
114
107
|
```
|
115
108
|
|
116
|
-
**IMPORTANT**: the keys
|
109
|
+
**IMPORTANT**: the keys in the `args` hash must be symbols!
|
117
110
|
|
118
111
|
#### Example
|
119
112
|
|
120
113
|
Simple application that loads a set of numbers and looks for a pair that adds up to 1,000
|
121
114
|
|
122
115
|
```ruby
|
123
|
-
class
|
116
|
+
class Application
|
124
117
|
def start(producer)
|
125
118
|
numbers = File.readlines('/path/to/numbers.txt').map(&:to_i)
|
126
|
-
producer.
|
119
|
+
producer.add_frame('load-numbers', duration: 3, args: { numbers: numbers })
|
127
120
|
numbers.sort!
|
128
|
-
producer.
|
121
|
+
producer.add_frame('sort-numbers', duration: 3, args: { numbers: numbers })
|
129
122
|
low = 0
|
130
123
|
high = numbers.length - 1
|
131
124
|
while low < high
|
132
125
|
sum = numbers[low] + numbers[high]
|
133
126
|
if sum == 1000
|
134
|
-
producer.
|
127
|
+
producer.add_frame('found-pair', duration: 5, args: { low: low, high: high, sum: sum })
|
135
128
|
return
|
136
129
|
elsif sum < 1000
|
137
|
-
producer.
|
130
|
+
producer.add_frame('too-low', args: { low: low, high: high, sum: sum })
|
138
131
|
low += 1
|
139
132
|
else
|
140
|
-
producer.
|
133
|
+
producer.add_frame('too-high', args: { low: low, high: high, sum: sum })
|
141
134
|
high -= 1
|
142
135
|
end
|
143
136
|
end
|
144
|
-
producer.
|
137
|
+
producer.add_frame('no-solution', duration: 5)
|
145
138
|
end
|
146
139
|
end
|
147
140
|
```
|
148
141
|
|
149
142
|
### Template Factory
|
150
143
|
|
151
|
-
To render the frame events sent by the
|
152
|
-
|
153
|
-
#### Loading Template Factory
|
154
|
-
|
155
|
-
`WhirledPeas.start` takes an optional template facotry to build a loading screen. This instance must implement `#build` (taking no arguments). The template returned by that method will be painted while the event loop is waiting for frames. The factory method will be called once per refresh cycle, so it's possible to implement animation.
|
144
|
+
To render the frame events sent by the application, the application requires a template factory. This factory will be called for each frame event, with the frame name and the arguments supplied by the application. A template factory can be an instance of ruby class and thus can maintain state. Whirled Peas provides a few basic building blocks to make simple, yet elegant terminal-based UIs.
|
156
145
|
|
157
146
|
#### Building Blocks
|
158
147
|
|
159
|
-
A template is created with `WhirledPeas.template`, which yields a `
|
148
|
+
A template is created with `WhirledPeas.template`, which yields a `Composer` object for a `Box` and `BoxSettings`. The composer allows for attaching child elements and the settings for setting layout options. The following attributes of the template's settings will be overridden before it is rendered to ensure that it fills the screen exactly
|
160
149
|
|
161
|
-
|
150
|
+
- `margin` - all margin will be set to 0
|
151
|
+
- `width` - will be set to the screen's width
|
152
|
+
- `height` - will be set to the screen's height
|
153
|
+
- `sizing` - will be set `:border` to ensure the entire box fits on the screen and fills it entirely.
|
162
154
|
|
163
|
-
|
164
|
-
|
155
|
+
A `Composer` provides the following methods to add child elements, each of these takes an optional string argument that is set as the name of the element (which can be useful when debugging).
|
156
|
+
|
157
|
+
- `add_box` - yields a `Composer` for a `Box` and a `BoxSettings`, which will be added to the parent's children
|
158
|
+
- `add_grid` - yields a `Composer` for a `Grid` and a `GridSettings`, which will be added to the parent's children
|
165
159
|
- `add_text` - yields `nil` and a `TextSettings`, which will be added to the parent's children
|
166
160
|
|
167
161
|
E.g.
|
168
162
|
|
169
163
|
```ruby
|
170
|
-
WhirledPeas.template do |
|
171
|
-
|
172
|
-
|
173
|
-
|
164
|
+
WhirledPeas.template do |composer, settings|
|
165
|
+
settings.bg_color = :blue
|
166
|
+
composer.add_grid do |composer, settings|
|
167
|
+
settings.num_cols = 10
|
174
168
|
100.times do |i|
|
175
|
-
|
169
|
+
composer.add_text { i }
|
176
170
|
end
|
177
171
|
end
|
178
172
|
end
|
@@ -181,81 +175,351 @@ end
|
|
181
175
|
The above template can also be broken down into more manageable methods, e.g.
|
182
176
|
|
183
177
|
```ruby
|
184
|
-
def number_grid(
|
178
|
+
def number_grid(_composer, settings)
|
185
179
|
settings.num_cols = 10
|
186
|
-
100.times
|
187
|
-
grid.add_text { i }
|
188
|
-
end
|
180
|
+
100.times.map(&:itself)
|
189
181
|
end
|
190
182
|
|
191
|
-
WhirledPeas.template do |
|
183
|
+
WhirledPeas.template do |composer, settings|
|
192
184
|
settings.bg_color = :blue
|
193
|
-
|
185
|
+
composer.add_grid(&method(:number_grid))
|
194
186
|
end
|
195
187
|
```
|
196
188
|
|
197
|
-
Additionally, if no child element is explicitly added to a `
|
189
|
+
Additionally, if no child element is explicitly added to a `Grid`, but the block returns an array of strings or numbers, those will be converted to `Text` elements and added as children to the `Grid`. For example, these are identical ways to create a grid of strings
|
198
190
|
|
199
191
|
```ruby
|
200
|
-
template.add_grid do |
|
192
|
+
template.add_grid do |composer|
|
201
193
|
100.times do |i|
|
202
|
-
|
194
|
+
composer.add_text { i }
|
203
195
|
end
|
204
196
|
end
|
205
197
|
|
206
|
-
template.add_grid do
|
198
|
+
template.add_grid do
|
207
199
|
100.times.map(&:itself)
|
208
200
|
end
|
209
201
|
```
|
210
202
|
|
211
|
-
Similarly, if no child element is explicilty added to a `
|
203
|
+
Similarly, if no child element is explicilty added to a `Box`, but the block returns a string or number, that value will be converted to a `Text` and added as a child. For example, these are identical ways to create a box with string content
|
212
204
|
|
213
205
|
```ruby
|
214
|
-
template.add_box do |
|
215
|
-
|
206
|
+
template.add_box do |composer|
|
207
|
+
composer.add_text { "Hello!" }
|
216
208
|
end
|
217
209
|
|
218
|
-
template.add_box do
|
210
|
+
template.add_box do
|
219
211
|
"Hello!"
|
220
212
|
end
|
221
213
|
```
|
222
214
|
|
223
215
|
#### Settings
|
224
216
|
|
225
|
-
Each element type has an associated settings type, which provide a custom set of options to format the output.
|
217
|
+
Each element type has an associated settings type, which provide a custom set of options to format the output. Child settings will inherit from the parent, where applicable
|
226
218
|
The available settigs are
|
227
219
|
|
228
|
-
| Setting
|
229
|
-
|
|
230
|
-
| `align`
|
231
|
-
| `
|
232
|
-
| `
|
233
|
-
| `
|
234
|
-
| `
|
235
|
-
| `
|
236
|
-
| `
|
237
|
-
| `margin`
|
238
|
-
| `
|
239
|
-
| `
|
240
|
-
| `
|
241
|
-
| `
|
242
|
-
| `
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
220
|
+
| Setting | Description | Default | Availability | Inherited |
|
221
|
+
| ------------ | -------------------------------------------------------------------------------- | ---------- | --------------------- | -------------------- |
|
222
|
+
| `align` | Justifies the content in the horizontal direction | `:left` | `Box`, `Grid` | No |
|
223
|
+
| `bg_color` | Background color (see [Colors](#colors)) | | `Box`, `Grid`, `Text` | Yes |
|
224
|
+
| `bold` | `true` makes the font bold | `false` | `Box`, `Grid`, `Text` | Yes |
|
225
|
+
| `border` | Set the border for the lements | none | `Box`, `Grid`, | Only style and color |
|
226
|
+
| `color` | Foreground text color (see [Colors](#colors)) | | `Box`, `Grid`, `Text` | Yes |
|
227
|
+
| `flow` | Flow to display child elements (see [Display Flow](#display-flow)) | `:l2r` | `Box`, `Grid` | No |
|
228
|
+
| `height` | Override the calculated height of an element's content area | | `Box`, `Grid` | No |
|
229
|
+
| `margin` | Set the (left, top, right, bottom) margin of the element | `0` | `Box`, `Grid` | No |
|
230
|
+
| `num_cols` | Number of columns in the grid (must be set!) | | `Grid` | No |
|
231
|
+
| `padding` | Set the (left, top, right, bottom) padding of the element | `0` | `Box`, `Grid` | No |
|
232
|
+
| `position` | Set the (left, top) position of the element relative to parent content area | `0` | `Box`, `Grid` | No |
|
233
|
+
| `scrollbar` | Display a scroll bar for vertical or horizontal scrolling | | `Box` | No |
|
234
|
+
| `sizing` | Sizing model (`:content` or `:border`) used in conjunction with `width`/`height` | `:content` | `Box` | No |
|
235
|
+
| `title_font` | Font used for "large" text (see [Large Text](#large-text), ignores `underline`) | | `Text` | No |
|
236
|
+
| `underline` | `true` underlines the font | `false` | `Box`, `Grid`, `Text` | Yes |
|
237
|
+
| `width` | Override the calculated width of an element's content area | | `Box`, `Grid` | No |
|
238
|
+
| `valign` | Justifies the content in the vertical direction | `:top` | `Box`, `Grid` | No |
|
239
|
+
|
240
|
+
##### Alignment
|
241
|
+
|
242
|
+
The `align` setting takes one of several values
|
243
|
+
|
244
|
+
- `:left` - align content starting at the leftmost edge of the container's content area
|
245
|
+
|
246
|
+
```
|
247
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
248
|
+
┃[child 1][child 2][child 3] ┃
|
249
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
250
|
+
```
|
251
|
+
|
252
|
+
- `:right` - align content starting at the rightmost edge of the container's content area
|
253
|
+
|
254
|
+
```
|
255
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
256
|
+
┃ [child 1][child 2][child 3]┃
|
257
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
258
|
+
```
|
259
|
+
|
260
|
+
- `:center` - align content starting in the horizontal center of the container's content area
|
261
|
+
|
262
|
+
```
|
263
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
264
|
+
┃ [child 1][child 2][child 3] ┃
|
265
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
266
|
+
```
|
267
|
+
|
268
|
+
- `:between` - distribute children so there is equal space between children no space outside of the children
|
269
|
+
|
270
|
+
```
|
271
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
272
|
+
┃[child 1] [child 2] [child 3]┃
|
273
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
274
|
+
```
|
275
|
+
|
276
|
+
- `:around` - distribute children so that they have equal spacing around them, space between two children is twice the space between an edge and a child.
|
277
|
+
|
278
|
+
```
|
279
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
280
|
+
┃ [child 1] [child 2] [child 3] ┃
|
281
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
282
|
+
```
|
283
|
+
|
284
|
+
- `:evenly` - distribute children so there is even spacing between any two children (or space to the edge)
|
285
|
+
|
286
|
+
```
|
287
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
288
|
+
┃ [child 1] [child 2] [child 3] ┃
|
289
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
290
|
+
```
|
291
|
+
|
292
|
+
The `valign` setting takes one of several values
|
293
|
+
|
294
|
+
- `:top` - align content starting at the top of the container's content area
|
295
|
+
|
296
|
+
```
|
297
|
+
┏━━━━━━━━━┓
|
298
|
+
┃[child 1]┃
|
299
|
+
┃[child 2]┃
|
300
|
+
┃[child 3]┃
|
301
|
+
┃ ┃
|
302
|
+
┃ ┃
|
303
|
+
┃ ┃
|
304
|
+
┃ ┃
|
305
|
+
┃ ┃
|
306
|
+
┃ ┃
|
307
|
+
┃ ┃
|
308
|
+
┃ ┃
|
309
|
+
┃ ┃
|
310
|
+
┃ ┃
|
311
|
+
┃ ┃
|
312
|
+
┃ ┃
|
313
|
+
┗━━━━━━━━━┛
|
314
|
+
```
|
315
|
+
|
316
|
+
- `:bottom` - align content starting at the bottom of the container's content area
|
317
|
+
|
318
|
+
```
|
319
|
+
┏━━━━━━━━━┓
|
320
|
+
┃ ┃
|
321
|
+
┃ ┃
|
322
|
+
┃ ┃
|
323
|
+
┃ ┃
|
324
|
+
┃ ┃
|
325
|
+
┃ ┃
|
326
|
+
┃ ┃
|
327
|
+
┃ ┃
|
328
|
+
┃ ┃
|
329
|
+
┃ ┃
|
330
|
+
┃ ┃
|
331
|
+
┃ ┃
|
332
|
+
┃[child 1]┃
|
333
|
+
┃[child 2]┃
|
334
|
+
┃[child 3]┃
|
335
|
+
┗━━━━━━━━━┛
|
336
|
+
```
|
337
|
+
|
338
|
+
- `:middle` - align content starting in the vertical middle of the container's content area
|
339
|
+
|
340
|
+
```
|
341
|
+
┏━━━━━━━━━┓
|
342
|
+
┃ ┃
|
343
|
+
┃ ┃
|
344
|
+
┃ ┃
|
345
|
+
┃ ┃
|
346
|
+
┃ ┃
|
347
|
+
┃ ┃
|
348
|
+
┃[child 1]┃
|
349
|
+
┃[child 2]┃
|
350
|
+
┃[child 3]┃
|
351
|
+
┃ ┃
|
352
|
+
┃ ┃
|
353
|
+
┃ ┃
|
354
|
+
┃ ┃
|
355
|
+
┃ ┃
|
356
|
+
┃ ┃
|
357
|
+
┗━━━━━━━━━┛
|
358
|
+
```
|
359
|
+
|
360
|
+
- `:between` - distribute children so there is equal space between children no space outside of the children
|
361
|
+
|
362
|
+
```
|
363
|
+
┏━━━━━━━━━┓
|
364
|
+
┃[child 1]┃
|
365
|
+
┃ ┃
|
366
|
+
┃ ┃
|
367
|
+
┃ ┃
|
368
|
+
┃ ┃
|
369
|
+
┃ ┃
|
370
|
+
┃ ┃
|
371
|
+
┃[child 2]┃
|
372
|
+
┃ ┃
|
373
|
+
┃ ┃
|
374
|
+
┃ ┃
|
375
|
+
┃ ┃
|
376
|
+
┃ ┃
|
377
|
+
┃ ┃
|
378
|
+
┃[child 3]┃
|
379
|
+
┗━━━━━━━━━┛
|
380
|
+
```
|
381
|
+
|
382
|
+
- `:around` - distribute children so that they have equal spacing around them, space between two children is twice the space between an edge and a child.
|
383
|
+
|
384
|
+
```
|
385
|
+
┏━━━━━━━━━┓
|
386
|
+
┃ ┃
|
387
|
+
┃ ┃
|
388
|
+
┃[child 1]┃
|
389
|
+
┃ ┃
|
390
|
+
┃ ┃
|
391
|
+
┃ ┃
|
392
|
+
┃ ┃
|
393
|
+
┃[child 2]┃
|
394
|
+
┃ ┃
|
395
|
+
┃ ┃
|
396
|
+
┃ ┃
|
397
|
+
┃ ┃
|
398
|
+
┃[child 3]┃
|
399
|
+
┃ ┃
|
400
|
+
┃ ┃
|
401
|
+
┗━━━━━━━━━┛
|
402
|
+
```
|
403
|
+
|
404
|
+
- `:evenly` - distribute children so there is even spacing between any two children (or space to the edge)
|
405
|
+
|
406
|
+
```
|
407
|
+
┏━━━━━━━━━┓
|
408
|
+
┃ ┃
|
409
|
+
┃ ┃
|
410
|
+
┃ ┃
|
411
|
+
┃[child 1]┃
|
412
|
+
┃ ┃
|
413
|
+
┃ ┃
|
414
|
+
┃ ┃
|
415
|
+
┃[child 2]┃
|
416
|
+
┃ ┃
|
417
|
+
┃ ┃
|
418
|
+
┃ ┃
|
419
|
+
┃[child 3]┃
|
420
|
+
┃ ┃
|
421
|
+
┃ ┃
|
422
|
+
┃ ┃
|
423
|
+
┗━━━━━━━━━┛
|
424
|
+
```
|
425
|
+
|
426
|
+
##### Position
|
427
|
+
|
428
|
+
Position settings dictate the relative position from where the painter would have preferred to place the container. Negative numbers move the container left/up and positive numbers move it right/down. To set these values, use
|
429
|
+
|
430
|
+
- `set_position(left:, top:)`
|
431
|
+
|
432
|
+
##### Sizing Model
|
433
|
+
|
434
|
+
The sizing model determines how to interpret the `width` and `height` settings. The default sizing model is `:content`, which sets the width and height of the cotent area, whereas `:border` sets the width and height of the element inlcuding the padding and border and scroll bars.
|
435
|
+
|
436
|
+
###### Examples
|
437
|
+
|
438
|
+
In the examples below, the `~` character represents padding and would not be displayed in the acutal rendered screen.
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
settings.width = 10
|
442
|
+
settings.height = 3
|
443
|
+
settings.set_padding(left: 3, top: 1, right: 3, bottom: 1)
|
444
|
+
settings.full_border
|
445
|
+
|
446
|
+
## Content sizing
|
447
|
+
settings.sizing = :content
|
448
|
+
|
449
|
+
# Results in the box
|
450
|
+
#
|
451
|
+
# ┏━━━━━━━━━━━━━━━━┓
|
452
|
+
# ┃~~~~~~~~~~~~~~~~┃
|
453
|
+
# ┃~~~1234567890~~~┃
|
454
|
+
# ┃~~~1234567890~~~┃
|
455
|
+
# ┃~~~1234567890~~~┃
|
456
|
+
# ┃~~~~~~~~~~~~~~~~┃
|
457
|
+
# ┗━━━━━━━━━━━━━━━━┛
|
458
|
+
|
459
|
+
## Border sizing
|
460
|
+
settings.sizing = :border
|
461
|
+
|
462
|
+
# Results in the box
|
463
|
+
#
|
464
|
+
# ┏━━━━━━━━┓
|
465
|
+
# ┃~~~12~~~┃
|
466
|
+
# ┗━━━━━━━━┛
|
467
|
+
```
|
468
|
+
|
469
|
+
Notice that a box rendered with `:border` sizing would fit exactly in the content area of a box with the same `width` and `height` that is rendered with `:content` sizing. For containers with no padding and no border, the resulting size is the same for either sizing model.
|
470
|
+
|
471
|
+
##### Margin
|
472
|
+
|
473
|
+
Margin settings dictate the spacing on the outside (i.e. outside of the border) of each of the 4 sides of the container independently. To set these values, use
|
474
|
+
|
475
|
+
- `set_margin(left:, top:, right:, bottom:, horiz:, vert:)` - set any combination of margin (note: setting `horiz` and `left`/`right` or setting `vert` and `top`/`bottom` is not allowed)
|
476
|
+
- `margin.left=(value)` - set left margin
|
477
|
+
- `margin.top=(value)` - set top margin
|
478
|
+
- `margin.right=(value)` - set right margin
|
479
|
+
- `margin.bottom=(value)` - set bottom margin
|
480
|
+
- `margin.horiz=(value)` - set left and right margin to the same value
|
481
|
+
- `margin.vert=(value)` - set top and bottom margin to the same value
|
482
|
+
|
483
|
+
Note: values cannot be negative
|
484
|
+
|
485
|
+
##### Padding
|
486
|
+
|
487
|
+
Padding settings dictate the spacing on the inside (i.e. inside of the border) of each of the 4 sides of the container independently. To set these values, use
|
488
|
+
|
489
|
+
- `set_padding(left:, top:, right:, bottom:, horiz:, vert:)` - set any combination of padding (note: setting `horiz` and `left`/`right` or setting `vert` and `top`/`bottom` is not allowed)
|
490
|
+
- `padding.left=(value)` - set left padding
|
491
|
+
- `padding.top=(value)` - set top padding
|
492
|
+
- `padding.right=(value)` - set right padding
|
493
|
+
- `padding.bottom=(value)` - set bottom padding
|
494
|
+
- `padding.horiz=(value)` - set left and right padding to the same value
|
495
|
+
- `padding.vert=(value)` - set top and bottom padding to the same value
|
496
|
+
|
497
|
+
Note: values cannot be negative
|
498
|
+
|
499
|
+
##### Scrollbar
|
500
|
+
|
501
|
+
Scroll settings dictate whether the scrollbar will be shown when child content is larger the the container's viewport. A scrollbar adds a unit to the dimensions of a container (as opposed to overwriting the leftmost/bottommost padding)
|
502
|
+
|
503
|
+
- `set_scrollbar(horiz:, vert:)` - set both scrollbar settings
|
504
|
+
- `scrollbar.horiz=(flag)` - show/hide the horizontal scrollbar
|
505
|
+
- `scrollbar.vert=(flag)` - show/hide the vertical scrollbar
|
506
|
+
|
507
|
+
Note: there is a know bug with scrollbars and `center`/`right` alignments. Using `left` alignment is the supported workaround
|
252
508
|
|
253
509
|
##### Border
|
254
510
|
|
255
511
|
The border settings consist of 6 boolean values (border are either width 1 or not shown), the 4 obvious values (`left`, `top`, `right`, and `bottom`) along with 2 other values for inner borders (`inner_horiz` and `inner_vert`) in a grid. A border also has a foreground color (defaults to `:white`) and a style. The background color is determined by the `bg_color` of the element. Border values can be set with
|
256
512
|
|
257
|
-
- `
|
258
|
-
- `
|
513
|
+
- `set_border(left:, top:, right:, bottom:, inner_horiz:, inner_vert:, color:, style:)` - set any combination of border settings
|
514
|
+
- `full_border(style:, color:)` - set all borders to true and optionally set the style or color
|
515
|
+
- `border.left=(flag)` - show/hide left border
|
516
|
+
- `border.top=(flag)` - show/hide top border
|
517
|
+
- `border.right=(flag)` - show/hide right border
|
518
|
+
- `border.bottom=(flag)` - show/hide bottom border
|
519
|
+
- `border.inner_horiz=(flag)` - show/hide inner horizontal border (dividing grid rows)
|
520
|
+
- `border.inner_vert=(flag)` - show/hide inner vertical border (dividing grid columns)
|
521
|
+
- `border.color=(text_color)` - set the border color
|
522
|
+
- `border.style=(style)` - set the border style
|
259
523
|
|
260
524
|
Available border styles are
|
261
525
|
|
@@ -296,31 +560,71 @@ Child elements can flow in one of 4 directions
|
|
296
560
|
- `:l2r` left-to-right
|
297
561
|
|
298
562
|
```
|
299
|
-
|
563
|
+
# In a Box
|
564
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
565
|
+
┃[child 1] [child 2] ... [child N]┃
|
566
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
567
|
+
|
568
|
+
# In a Grid
|
569
|
+
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
|
570
|
+
┃[child 1]┃[child 2]┃[child 3]┃
|
571
|
+
┣━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫
|
572
|
+
┃[chiid 4]┃[child 5]┃ ┃
|
573
|
+
┗━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┛
|
300
574
|
```
|
301
575
|
|
302
576
|
- `:r2l` right-to-left
|
303
577
|
|
304
578
|
```
|
305
|
-
|
579
|
+
# In a Box
|
580
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
581
|
+
┃[child N] [child N - 1] ... [child 1]┃
|
582
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
583
|
+
|
584
|
+
# In a Grid
|
585
|
+
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
|
586
|
+
┃[child 3]┃[child 2]┃[child 1]┃
|
587
|
+
┣━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫
|
588
|
+
┃ ┃[chiid 5]┃[child 4]┃
|
589
|
+
┗━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┛
|
306
590
|
```
|
307
591
|
|
308
592
|
- `:t2b` top-to-bottom
|
309
593
|
|
310
594
|
```
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
[child
|
595
|
+
# In a Box
|
596
|
+
┏━━━━━━━━━┓
|
597
|
+
┃[child 1]┃
|
598
|
+
┃[child 2]┃
|
599
|
+
┃ ... ┃
|
600
|
+
┃[child N]┃
|
601
|
+
┗━━━━━━━━━┛
|
602
|
+
|
603
|
+
# In a Grid
|
604
|
+
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
|
605
|
+
┃[child 1]┃[child 3]┃[child 5]┃
|
606
|
+
┣━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫
|
607
|
+
┃[child 2]┃[child 4]┃ ┃
|
608
|
+
┗━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┛
|
315
609
|
```
|
316
610
|
|
317
611
|
- `:b2t` bottom-to-top
|
318
612
|
|
319
613
|
```
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
[child 1]
|
614
|
+
# In a Box
|
615
|
+
┏━━━━━━━━━━━━━┓
|
616
|
+
┃[child N] ┃
|
617
|
+
┃[child N - 1]┃
|
618
|
+
┃ ... ┃
|
619
|
+
┃[child 1] ┃
|
620
|
+
┗━━━━━━━━━━━━━┛
|
621
|
+
|
622
|
+
# In a Grid
|
623
|
+
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
|
624
|
+
┃[child 2]┃[child 4]┃ ┃
|
625
|
+
┣━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫
|
626
|
+
┃[child 1]┃[child 3]┃[child 5]┃
|
627
|
+
┗━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┛
|
324
628
|
```
|
325
629
|
|
326
630
|
##### Colors
|
@@ -348,7 +652,7 @@ Many of these also have a "bright" option:
|
|
348
652
|
|
349
653
|
##### Large Text
|
350
654
|
|
351
|
-
The `title_font` setting for `
|
655
|
+
The `title_font` setting for `Text`s converts the standard terminal font into a large block font. The available fonts vary from system to system. Every system will have a `:default` font available, this font could look like
|
352
656
|
|
353
657
|
```
|
354
658
|
██████╗ ███████╗███████╗ █████╗ ██╗ ██╗██╗ ████████╗
|
@@ -373,8 +677,13 @@ Note: when using a title font with WhirledPeas for the first time on a system, t
|
|
373
677
|
class TemplateFactory
|
374
678
|
def build(frame, args)
|
375
679
|
set_state(frame, args)
|
376
|
-
WhirledPeas.template do |
|
377
|
-
|
680
|
+
WhirledPeas.template do |composer, settings|
|
681
|
+
settings.flow = :l2r
|
682
|
+
settings.align = :center
|
683
|
+
|
684
|
+
composer.add_box('Title', &method(:title))
|
685
|
+
composer.add_box('Sum', &method(:sum))
|
686
|
+
composer.add_grid('NumberGrid', &method(:number_grid))
|
378
687
|
end
|
379
688
|
end
|
380
689
|
|
@@ -388,93 +697,128 @@ class TemplateFactory
|
|
388
697
|
@high = args[:high] if args.key?(:high)
|
389
698
|
end
|
390
699
|
|
391
|
-
def title(
|
700
|
+
def title(_composer, settings)
|
392
701
|
settings.underline = true
|
393
702
|
"Pair Finder"
|
394
703
|
end
|
395
704
|
|
396
|
-
def sum(
|
705
|
+
def sum(_composer, settings)
|
397
706
|
settings.color = @frame == 'found-pair' ? :green : :red
|
398
707
|
@sum ? "Sum: #{@sum}" : 'N/A'
|
399
708
|
end
|
400
709
|
|
401
|
-
def number_grid(
|
710
|
+
def number_grid(composer, settings)
|
402
711
|
settings.full_border
|
403
712
|
@numbers.each.with_index do |num, index|
|
404
|
-
|
713
|
+
composer.add_text do |_, settings|
|
405
714
|
settings.bg_color = (@low == index || @high == index) ? :cyan : :white
|
406
715
|
num
|
407
716
|
end
|
408
717
|
end
|
409
718
|
end
|
719
|
+
end
|
720
|
+
```
|
410
721
|
|
411
|
-
|
412
|
-
settings.flow = :l2r
|
413
|
-
settings.auto_margin = true
|
722
|
+
### Full usage
|
414
723
|
|
415
|
-
elem.add_box('Title', &method(:title))
|
416
|
-
elem.add_box('Sum', &method(:sum))
|
417
|
-
elem.add_grid('NumberGrid', &method(:number_grid))
|
418
|
-
end
|
419
|
-
end
|
420
724
|
```
|
725
|
+
Usage: whirled_peas <command> [command options]
|
421
726
|
|
422
|
-
|
727
|
+
Available commands:
|
423
728
|
|
424
|
-
|
729
|
+
debug Print template tree for specified frame
|
730
|
+
fonts List installed title fonts with sample text
|
731
|
+
frames Print out list of frames generated by application
|
732
|
+
help Show detailed help for a command
|
733
|
+
play Play an animation from an application or prerecorded file
|
734
|
+
record Record animation to a file
|
735
|
+
still Show the specified still frame
|
736
|
+
```
|
425
737
|
|
426
|
-
####
|
738
|
+
#### `debug`
|
427
739
|
|
428
|
-
|
740
|
+
Print the template tree for specified frame.
|
429
741
|
|
430
742
|
```
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
743
|
+
# Usage: whirled_peas debug <config file> <frame> [args as a JSON string]
|
744
|
+
% whirled_peas debug my_app.rb greeting '{"name":"World"}'
|
745
|
+
* WhirledPeas::Graphics::BoxPainter(TEMPLATE)
|
746
|
+
- Dimensions(outer=140x27, content=120x15, grid=1x1)
|
747
|
+
- Settings
|
748
|
+
WhirledPeas::Settings::BoxSettings
|
749
|
+
padding: Padding(left: 10, top: 6, right: 10, bottom: 6)
|
750
|
+
align: :center
|
751
|
+
width: 120
|
752
|
+
flow: :t2b
|
753
|
+
bold: true
|
754
|
+
bg_color: BgColor(code=107, bright=true)
|
755
|
+
- Children
|
756
|
+
* WhirledPeas::Graphics::BoxPainter(Element-1)
|
757
|
+
- Dimensions(outer=64x6, content=64x6, grid=1x1)
|
436
758
|
```
|
437
759
|
|
438
|
-
####
|
760
|
+
#### `fonts`
|
439
761
|
|
440
|
-
|
762
|
+
List all installed title fonts with sample text.
|
441
763
|
|
442
764
|
```
|
443
|
-
|
765
|
+
# Usage: whirled_peas fonts
|
444
766
|
```
|
445
767
|
|
446
|
-
|
768
|
+
#### `frames`
|
769
|
+
|
770
|
+
Print out list of frames generated by application.
|
447
771
|
|
448
772
|
```
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
<default>
|
454
|
-
- Children
|
455
|
-
+ TitleContainer [WhirledPeas::UI::BoxElement]
|
773
|
+
# Usage: whirled_peas frames <config file>
|
774
|
+
% whirled_peas frames my_app.rb
|
775
|
+
Frame 'intro' displayed for 3 second(s) '{"title":"Foo"}'
|
776
|
+
Frame 'greet' displayed for 0.3 second(s)
|
456
777
|
...
|
457
778
|
```
|
458
779
|
|
459
|
-
####
|
780
|
+
#### `help`
|
460
781
|
|
461
|
-
|
782
|
+
Print out command-specific help message
|
462
783
|
|
463
784
|
```
|
464
|
-
|
785
|
+
Usage: whirled_peas help <command>
|
465
786
|
```
|
466
787
|
|
467
|
-
|
788
|
+
#### `play`
|
789
|
+
|
790
|
+
Play an animation from an application or prerecorded file
|
468
791
|
|
469
792
|
```
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
793
|
+
# Usage: whirled_peas play <config/wpz file>
|
794
|
+
|
795
|
+
# Play animation directly from app
|
796
|
+
% whirled_peas play my_app.rb
|
797
|
+
# Animation plays
|
798
|
+
|
799
|
+
# Play animation from previously recorded file
|
800
|
+
% whirled_peas play my_animation.wpz
|
801
|
+
# Animation plays
|
802
|
+
```
|
803
|
+
|
804
|
+
#### `record`
|
805
|
+
|
806
|
+
Record animation to a file
|
807
|
+
|
808
|
+
```
|
809
|
+
# Usage: whirled_peas record <config file> <output file>
|
810
|
+
% whirled_peas record my_app.rb my_animation.wpz
|
811
|
+
# Record animation to my_animation.wpz
|
812
|
+
```
|
813
|
+
|
814
|
+
#### `still`
|
815
|
+
|
816
|
+
Show the specified still frame
|
817
|
+
|
818
|
+
```
|
819
|
+
# Usage: whirled_peas still <config file> <frame> [args as a JSON string]
|
820
|
+
% whirled_peas still my_app.rb greeting '{"name":"World"}'
|
821
|
+
# Still frame is displayed
|
478
822
|
```
|
479
823
|
|
480
824
|
## Development
|
@@ -483,6 +827,31 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
483
827
|
|
484
828
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
485
829
|
|
830
|
+
### Testing
|
831
|
+
|
832
|
+
In addition to standard RSpec tests, WhirledPeas has custom tests for rendered templates. These files live in `screen_test/`. Each ruby file is expected to define a class named `TemplateFactory` that responds to `#build(name, args)` returning a template (the standard template factory role). Each file should also be accompanied by a `.frame` file with the same base name. This file will contain the output of the rendered screen and is considered the correct output when running tests.
|
833
|
+
|
834
|
+
Note: viewing `.frame` files with `cat` works better than most other text editors.
|
835
|
+
|
836
|
+
```
|
837
|
+
|
838
|
+
Usage: screen_test [file] [options]
|
839
|
+
|
840
|
+
If not file or options are provide, all tests are run
|
841
|
+
|
842
|
+
If no file is provided, the supported options are
|
843
|
+
--help print this usage statement and exit
|
844
|
+
--view-pending interactively display and optionally save rendered output for each pending test
|
845
|
+
--view-failed interactively display and optionally save rendered output for each faiing test
|
846
|
+
|
847
|
+
If the file provide is a screen test, the supported options are
|
848
|
+
--run run screen test for given file
|
849
|
+
--view interactively display and optionally save the file's test output
|
850
|
+
--template print out template tree for the test template
|
851
|
+
--debug render the test template without displying it, printing out debug information
|
852
|
+
|
853
|
+
```
|
854
|
+
|
486
855
|
## Contributing
|
487
856
|
|
488
857
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/whirled_peas. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/whirled_peas/blob/master/CODE_OF_CONDUCT.md).
|
@@ -494,3 +863,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
494
863
|
## Code of Conduct
|
495
864
|
|
496
865
|
Everyone interacting in the WhirledPeas project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/whirled_peas/blob/master/CODE_OF_CONDUCT.md).
|
866
|
+
|
867
|
+
```
|
868
|
+
|
869
|
+
```
|