whirled_peas 0.1.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +32 -0
- data/Gemfile +1 -0
- data/README.md +240 -79
- data/Rakefile +37 -3
- data/bin/debug +35 -0
- data/exe/whirled_peas +7 -0
- data/lib/whirled_peas.rb +17 -37
- data/lib/whirled_peas/command_line.rb +263 -0
- data/lib/whirled_peas/config.rb +21 -0
- data/lib/whirled_peas/debugger.rb +80 -0
- data/lib/whirled_peas/errors.rb +7 -0
- data/lib/whirled_peas/frame.rb +0 -8
- data/lib/whirled_peas/frame/consumer.rb +14 -51
- data/lib/whirled_peas/frame/debug_consumer.rb +30 -0
- data/lib/whirled_peas/frame/event_loop.rb +68 -38
- data/lib/whirled_peas/frame/producer.rb +37 -34
- data/lib/whirled_peas/graphics.rb +5 -0
- data/lib/whirled_peas/graphics/box_painter.rb +100 -0
- data/lib/whirled_peas/graphics/canvas.rb +107 -0
- data/lib/whirled_peas/graphics/container_coords.rb +61 -0
- data/lib/whirled_peas/graphics/container_dimensions.rb +65 -0
- data/lib/whirled_peas/graphics/container_painter.rb +116 -0
- data/lib/whirled_peas/graphics/debugger.rb +43 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +56 -0
- data/lib/whirled_peas/graphics/mock_screen.rb +26 -0
- data/lib/whirled_peas/graphics/painter.rb +24 -0
- data/lib/whirled_peas/graphics/renderer.rb +49 -0
- data/lib/whirled_peas/graphics/screen.rb +65 -0
- data/lib/whirled_peas/graphics/text_dimensions.rb +15 -0
- data/lib/whirled_peas/graphics/text_painter.rb +38 -0
- data/lib/whirled_peas/settings.rb +5 -0
- data/lib/whirled_peas/settings/bg_color.rb +22 -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 +69 -0
- data/lib/whirled_peas/settings/container_settings.rb +128 -0
- data/lib/whirled_peas/settings/debugger.rb +87 -0
- data/lib/whirled_peas/settings/display_flow.rb +25 -0
- data/lib/whirled_peas/settings/element_settings.rb +61 -0
- data/lib/whirled_peas/settings/grid_settings.rb +11 -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/spacing.rb +24 -0
- data/lib/whirled_peas/settings/text_align.rb +19 -0
- data/lib/whirled_peas/settings/text_color.rb +19 -0
- data/lib/whirled_peas/settings/text_settings.rb +15 -0
- data/lib/whirled_peas/template.rb +5 -0
- data/lib/whirled_peas/template/box_element.rb +8 -0
- data/lib/whirled_peas/template/composer.rb +68 -0
- data/lib/whirled_peas/template/container.rb +28 -0
- data/lib/whirled_peas/template/debugger.rb +34 -0
- data/lib/whirled_peas/template/element.rb +13 -0
- data/lib/whirled_peas/template/grid_element.rb +8 -0
- data/lib/whirled_peas/template/text_element.rb +24 -0
- data/lib/whirled_peas/utils.rb +5 -0
- data/lib/whirled_peas/utils/ansi.rb +53 -0
- data/lib/whirled_peas/utils/formatted_string.rb +64 -0
- data/lib/whirled_peas/utils/title_font.rb +75 -0
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/rendered/elements/box.frame +1 -0
- data/screen_test/rendered/elements/box.rb +20 -0
- data/screen_test/rendered/elements/grid.frame +1 -0
- data/screen_test/rendered/elements/grid.rb +13 -0
- data/screen_test/rendered/elements/screen_overflow.rb +9 -0
- data/screen_test/rendered/elements/text.frame +1 -0
- data/screen_test/rendered/elements/text.rb +9 -0
- data/screen_test/rendered/elements/text_multiline.frame +1 -0
- data/screen_test/rendered/elements/text_multiline.rb +9 -0
- data/screen_test/rendered/settings/align/box.frame +1 -0
- data/screen_test/rendered/settings/align/box.rb +20 -0
- data/screen_test/rendered/settings/align/children_center.frame +1 -0
- data/screen_test/rendered/settings/align/children_center.rb +13 -0
- data/screen_test/rendered/settings/align/children_left.frame +1 -0
- data/screen_test/rendered/settings/align/children_left.rb +13 -0
- data/screen_test/rendered/settings/align/children_right.frame +1 -0
- data/screen_test/rendered/settings/align/children_right.rb +13 -0
- data/screen_test/rendered/settings/align/grid.frame +1 -0
- data/screen_test/rendered/settings/align/grid.rb +20 -0
- data/screen_test/rendered/settings/ansi/bold.frame +1 -0
- data/screen_test/rendered/settings/ansi/bold.rb +15 -0
- data/screen_test/rendered/settings/ansi/color.frame +1 -0
- data/screen_test/rendered/settings/ansi/color.rb +37 -0
- data/screen_test/rendered/settings/ansi/underline.frame +1 -0
- data/screen_test/rendered/settings/ansi/underline.rb +15 -0
- data/screen_test/rendered/settings/border.frame +1 -0
- data/screen_test/rendered/settings/border.rb +13 -0
- data/screen_test/rendered/settings/flow/l2r.frame +1 -0
- data/screen_test/rendered/settings/flow/l2r.rb +24 -0
- data/screen_test/rendered/settings/flow/t2b.frame +1 -0
- data/screen_test/rendered/settings/flow/t2b.rb +24 -0
- data/screen_test/rendered/settings/height/box.frame +1 -0
- data/screen_test/rendered/settings/height/box.rb +13 -0
- data/screen_test/rendered/settings/height/grid.frame +1 -0
- data/screen_test/rendered/settings/height/grid.rb +14 -0
- data/screen_test/rendered/settings/height/overflow_box.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box.rb +13 -0
- data/screen_test/rendered/settings/height/overflow_box_l2r.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box_l2r.rb +15 -0
- data/screen_test/rendered/settings/height/overflow_box_t2b.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box_t2b.rb +14 -0
- data/screen_test/rendered/settings/height/overflow_grid.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_grid.rb +16 -0
- data/screen_test/rendered/settings/margin.frame +1 -0
- data/screen_test/rendered/settings/margin.rb +14 -0
- data/screen_test/rendered/settings/padding.frame +1 -0
- data/screen_test/rendered/settings/padding.rb +11 -0
- data/screen_test/rendered/settings/position/box_left.frame +1 -0
- data/screen_test/rendered/settings/position/box_left.rb +17 -0
- data/screen_test/rendered/settings/position/box_left_negative.frame +1 -0
- data/screen_test/rendered/settings/position/box_left_negative.rb +17 -0
- data/screen_test/rendered/settings/position/box_top.frame +1 -0
- data/screen_test/rendered/settings/position/box_top.rb +17 -0
- data/screen_test/rendered/settings/position/box_top_negative.frame +1 -0
- data/screen_test/rendered/settings/position/box_top_negative.rb +17 -0
- data/screen_test/rendered/settings/position/grid_left.frame +1 -0
- data/screen_test/rendered/settings/position/grid_left.rb +18 -0
- data/screen_test/rendered/settings/position/grid_left_negative.frame +1 -0
- data/screen_test/rendered/settings/position/grid_left_negative.rb +18 -0
- data/screen_test/rendered/settings/position/grid_top.frame +1 -0
- data/screen_test/rendered/settings/position/grid_top.rb +18 -0
- data/screen_test/rendered/settings/position/grid_top_negative.frame +1 -0
- data/screen_test/rendered/settings/position/grid_top_negative.rb +18 -0
- data/screen_test/rendered/settings/title_font.frame +1 -0
- data/screen_test/rendered/settings/title_font.rb +12 -0
- data/screen_test/rendered/settings/width/box.frame +1 -0
- data/screen_test/rendered/settings/width/box.rb +13 -0
- data/screen_test/rendered/settings/width/grid.frame +1 -0
- data/screen_test/rendered/settings/width/grid.rb +14 -0
- data/screen_test/rendered/settings/width/overflow_box.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box.rb +11 -0
- data/screen_test/rendered/settings/width/overflow_box_l2r.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box_l2r.rb +14 -0
- data/screen_test/rendered/settings/width/overflow_box_t2b.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box_t2b.rb +15 -0
- data/screen_test/rendered/settings/width/overflow_grid.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_grid.rb +14 -0
- data/screen_test/screen_tester.rb +191 -0
- data/whirled_peas.gemspec +4 -2
- metadata +136 -20
- data/lib/whirled_peas/ui.rb +0 -7
- data/lib/whirled_peas/ui/ansi.rb +0 -154
- data/lib/whirled_peas/ui/canvas.rb +0 -35
- data/lib/whirled_peas/ui/element.rb +0 -199
- data/lib/whirled_peas/ui/painter.rb +0 -283
- data/lib/whirled_peas/ui/screen.rb +0 -62
- data/lib/whirled_peas/ui/settings.rb +0 -512
- data/lib/whirled_peas/ui/stroke.rb +0 -29
- data/sandbox/auto.rb +0 -13
- data/sandbox/box.rb +0 -19
- data/sandbox/grid.rb +0 -13
- data/sandbox/sandbox.rb +0 -17
- data/sandbox/text.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b374c9d4250b281d3f87284f446e82c01ece7ff2fe196687be50502b2e42960
|
4
|
+
data.tar.gz: 0ebd7b96a154277121767eb8c33d63b831db37770ff0172b76f28fcf89c5dec9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6dcc7dc00852a343f55056646db886903bc5735a21bd9af71a885e28ff70aa85bb3f26ff4f97c23dc4292fa401c1c624284c347b17fb957fb8e0069301b7ef9
|
7
|
+
data.tar.gz: 1f0ae0e07baf45703dff90396be7b6c705f17f8c9cb4fcd4e0b4b433513efc94dd8c3a056f50f1d3f47f7e3179c308d36264ef4e4be0c179815e650a6136a11a
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.5.0 - 2021-01-25
|
4
|
+
|
5
|
+
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.
|
6
|
+
|
7
|
+
- [3ddfede](https://github.com/tcollier/whirled_peas/tree/3ddfedee4ab2fadeecbe82c7c9caf25c2988f095): Allow relative positioning of containers
|
8
|
+
- [507e77c](https://github.com/tcollier/whirled_peas/tree/507e77c551bcb9cc832d5c24e2f24eb1afe4eddc): Add height attribute for container settings
|
9
|
+
- [af8ef19](https://github.com/tcollier/whirled_peas/tree/af8ef1950edebcd23a57a04982b22a56296ee09b): Add automated screen testing
|
10
|
+
|
11
|
+
## v0.4.1 - 2021-01-22
|
12
|
+
|
13
|
+
- [0f7aa6c](https://github.com/tcollier/whirled_peas/tree/0f7aa6ccc07323230dd602cb43e0341de5a69ad8): Allow relative path for config files
|
14
|
+
|
15
|
+
## v0.4.0 - 2021-01-22
|
16
|
+
|
17
|
+
- [7fd6712](https://github.com/tcollier/whirled_peas/tree/7fd6712818c94cdbfd81828277ca67c705e01793): BREAKING: replace `WhirledPeas.start` with command line executable
|
18
|
+
- [2535342](https://github.com/tcollier/whirled_peas/tree/25353424f1ab4af4880f44eb7ddd28afefbbb9b2): Add support for loading screen
|
19
|
+
- [7388fc2](https://github.com/tcollier/whirled_peas/tree/7388fc2eacdc8045b725311c11d650d6b8654be8): Add support for title fonts
|
20
|
+
- [b345155](https://github.com/tcollier/whirled_peas/tree/b345155b1c212cabe73f9a2562ac8dbbedbbb6df): Add command to list title fonts to executable
|
21
|
+
- [d3a8324](https://github.com/tcollier/whirled_peas/tree/d3a832496c36985993217ff11b6d83dd4697c4ed): Add commands for debugging application to executable
|
22
|
+
|
23
|
+
## v0.3.0 - 2021-01-21
|
24
|
+
|
25
|
+
- [617f802](https://github.com/tcollier/whirled_peas/tree/617f8027d6688a2ec81a3e594e529c94485cee85): BREAKING: send frames directly to EventLoop (`Producer#send` renamed to `Producer#send_frame`)
|
26
|
+
|
27
|
+
## v0.2.0 - 2021-01-20
|
28
|
+
|
29
|
+
- [73eb326](https://github.com/tcollier/whirled_peas/tree/73eb326426f9814e91e3bc7a60dfd87be3d69f7e): Convert "primitive" data types to strings
|
30
|
+
- [f28b69d](https://github.com/tcollier/whirled_peas/tree/f28b69df8b6cfc973da2ebc0b8da29b278f23433): Give elements names
|
31
|
+
- [1ae1c929](https://github.com/tcollier/whirled_peas/tree/1ae1c929429c2f8520054d33a064c2b6d71955fe): Consistently format exceptions in logs
|
32
|
+
- [4c2114f](https://github.com/tcollier/whirled_peas/tree/4c2114fd360fd98c65e6e32f905a377f09b919ee): Fix bug with negative sleep times
|
33
|
+
- [627bf12](https://github.com/tcollier/whirled_peas/tree/627bf126dd7f9c845f65105e0826d14a35a0a953): Don't reraise pipe error
|
34
|
+
|
3
35
|
## v0.1.1 - 2021-01-20
|
4
36
|
|
5
37
|
- [3852c8c](https://github.com/tcollier/whirled_peas/tree/3852c8c700c2e8fb92e65bbca1c99be74304c6d0): Improve error handling
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[![Build Status](https://travis-ci.com/tcollier/whirled_peas.svg?branch=main)](https://travis-ci.com/tcollier/whirled_peas)
|
2
|
+
|
1
3
|
# WhirledPeas
|
2
4
|
|
3
5
|
Visualize your code's execution with Whirled Peas!
|
@@ -20,15 +22,24 @@ Or install it yourself as:
|
|
20
22
|
|
21
23
|
## Usage
|
22
24
|
|
25
|
+
A Whirled Peas application consists of the following pieces
|
26
|
+
|
27
|
+
- The driver (required) - the code that is to be visualized, it emits lightweight frame events through a producer
|
28
|
+
- The main template factory (required) - builds templates to convert frame events from the driver into terminal graphics
|
29
|
+
- A loading screen template factory (optional) - builds templates to display while content is loading
|
30
|
+
|
31
|
+
These pieces are configured as following
|
32
|
+
|
23
33
|
```ruby
|
34
|
+
# visualize.rb
|
24
35
|
require 'whirled_peas'
|
25
36
|
|
26
37
|
class TemplateFactory
|
27
38
|
def build(frame, args)
|
28
|
-
WhirledPeas.template do |
|
29
|
-
|
39
|
+
WhirledPeas.template do |composer|
|
40
|
+
composer.add_box('Title') do |_, settings|
|
30
41
|
settings.underline = true
|
31
|
-
"Hello #{args[
|
42
|
+
"Hello #{args[:name]}"
|
32
43
|
end
|
33
44
|
# ...
|
34
45
|
end
|
@@ -37,18 +48,44 @@ end
|
|
37
48
|
|
38
49
|
class Driver
|
39
50
|
def start(producer)
|
40
|
-
producer.
|
51
|
+
producer.send_frame('starting', args: { name: 'World' })
|
41
52
|
# ...
|
42
53
|
end
|
43
54
|
end
|
44
55
|
|
45
|
-
WhirledPeas.
|
56
|
+
WhirledPeas.configure do |config|
|
57
|
+
config.driver = Driver.new
|
58
|
+
config.template_factory = TemplateFactory.new
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Then the visualizer is started on the command line with
|
63
|
+
|
46
64
|
```
|
65
|
+
$ whirled_peas start visualize.rb
|
66
|
+
```
|
67
|
+
|
68
|
+
The optional loading screen can be configured like
|
47
69
|
|
48
|
-
|
70
|
+
```ruby
|
71
|
+
class LoadingTemplateFactory
|
72
|
+
def build
|
73
|
+
WhirledPeas.template do |composer|
|
74
|
+
composer.add_box('Loading') do |_, settings|
|
75
|
+
settings.set_margin(top: 15)
|
76
|
+
settings.align = :center
|
77
|
+
settings.full_border(color: :blue, style: :double)
|
78
|
+
"Loading..."
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
49
83
|
|
50
|
-
|
51
|
-
|
84
|
+
WhirledPeas.configure do |config|
|
85
|
+
# ...
|
86
|
+
config.loading_template_factory = LoadingTemplateFactory.new
|
87
|
+
end
|
88
|
+
```
|
52
89
|
|
53
90
|
### Driver
|
54
91
|
|
@@ -70,13 +107,14 @@ The producer provides a single method
|
|
70
107
|
#
|
71
108
|
# @param name [String] application defined name for the frame. The template factory will be provided this name
|
72
109
|
# @param duration [Number] time in seconds this frame should be displayed for (defaults to 1 frame)
|
73
|
-
# @param args [Hash] key value pairs to send as arguments to the template factory
|
74
|
-
|
75
|
-
def send(name, duration:, args:)
|
110
|
+
# @param args [Hash<Symbol, Object>] key value pairs to send as arguments to the template factory
|
111
|
+
def send_frame(name, duration:, args:)
|
76
112
|
# implementation
|
77
113
|
end
|
78
114
|
```
|
79
115
|
|
116
|
+
**IMPORTANT**: the keys in the `args` hash must be symbols!
|
117
|
+
|
80
118
|
#### Example
|
81
119
|
|
82
120
|
Simple application that loads a set of numbers and looks for a pair that adds up to 1,000
|
@@ -85,52 +123,56 @@ Simple application that loads a set of numbers and looks for a pair that adds up
|
|
85
123
|
class Driver
|
86
124
|
def start(producer)
|
87
125
|
numbers = File.readlines('/path/to/numbers.txt').map(&:to_i)
|
88
|
-
producer.
|
126
|
+
producer.send_frame('load-numbers', duration: 3, args: { numbers: numbers })
|
89
127
|
numbers.sort!
|
90
|
-
producer.
|
128
|
+
producer.send_frame('sort-numbers', duration: 3, args: { numbers: numbers })
|
91
129
|
low = 0
|
92
130
|
high = numbers.length - 1
|
93
131
|
while low < high
|
94
132
|
sum = numbers[low] + numbers[high]
|
95
133
|
if sum == 1000
|
96
|
-
producer.
|
134
|
+
producer.send_frame('found-pair', duration: 5, args: { low: low, high: high, sum: sum })
|
97
135
|
return
|
98
136
|
elsif sum < 1000
|
99
|
-
producer.
|
137
|
+
producer.send_frame('too-low', args: { low: low, high: high, sum: sum })
|
100
138
|
low += 1
|
101
139
|
else
|
102
|
-
producer.
|
140
|
+
producer.send_frame('too-high', args: { low: low, high: high, sum: sum })
|
103
141
|
high -= 1
|
104
142
|
end
|
105
143
|
end
|
106
|
-
producer.
|
144
|
+
producer.send_frame('no-solution', duration: 5)
|
107
145
|
end
|
108
146
|
end
|
109
147
|
```
|
110
148
|
|
111
149
|
### Template Factory
|
112
150
|
|
113
|
-
To render the frame events sent by the driver, 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 driver. A template factory can be
|
151
|
+
To render the frame events sent by the driver, 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 driver. 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.
|
152
|
+
|
153
|
+
#### Loading Template Factory
|
154
|
+
|
155
|
+
`WhirledPeas.configure` takes an optional template factory 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.
|
114
156
|
|
115
157
|
#### Building Blocks
|
116
158
|
|
117
|
-
A template is created with `WhirledPeas.template`, which yields a `
|
159
|
+
A template is created with `WhirledPeas.template`, which yields a `Composer` object for a `BoxElement` and `BoxSettings`. The composer allows for attaching child elements and the settings for setting layout options.
|
118
160
|
|
119
|
-
A `
|
161
|
+
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).
|
120
162
|
|
121
|
-
- `add_box` - yields a `
|
122
|
-
- `add_grid` - yields a `
|
163
|
+
- `add_box` - yields a `Composer` and a `BoxSettings`, which will be added to the parent's children
|
164
|
+
- `add_grid` - yields a `Composer` and a `GridSettings`, which will be added to the parent's children
|
123
165
|
- `add_text` - yields `nil` and a `TextSettings`, which will be added to the parent's children
|
124
166
|
|
125
167
|
E.g.
|
126
168
|
|
127
169
|
```ruby
|
128
|
-
WhirledPeas.template do |
|
129
|
-
|
130
|
-
|
131
|
-
|
170
|
+
WhirledPeas.template do |composer, settings|
|
171
|
+
settings.bg_color = :blue
|
172
|
+
composer.add_grid do |composer, settings|
|
173
|
+
settings.num_cols = 10
|
132
174
|
100.times do |i|
|
133
|
-
|
175
|
+
composer.add_text { i }
|
134
176
|
end
|
135
177
|
end
|
136
178
|
end
|
@@ -139,79 +181,93 @@ end
|
|
139
181
|
The above template can also be broken down into more manageable methods, e.g.
|
140
182
|
|
141
183
|
```ruby
|
142
|
-
def number_grid(
|
184
|
+
def number_grid(_composer, settings)
|
143
185
|
settings.num_cols = 10
|
144
|
-
100.times
|
145
|
-
grid.add_text { i.to_s }
|
146
|
-
end
|
186
|
+
100.times.map(&:itself)
|
147
187
|
end
|
148
188
|
|
149
|
-
WhirledPeas.template do |
|
189
|
+
WhirledPeas.template do |composer, settings|
|
150
190
|
settings.bg_color = :blue
|
151
|
-
|
191
|
+
composer.add_grid(&method(:number_grid))
|
152
192
|
end
|
153
193
|
```
|
154
194
|
|
155
195
|
Additionally, if no child element is explicitly added to a `GridElement`, but the block returns an array of strings or numbers, those will be converted to `TextElements` and added as children to the `GridElement`. For example, these are identical ways to create a grid of strings
|
156
196
|
|
157
197
|
```ruby
|
158
|
-
template.add_grid do |
|
198
|
+
template.add_grid do |composer|
|
159
199
|
100.times do |i|
|
160
|
-
|
200
|
+
composer.add_text { i }
|
161
201
|
end
|
162
202
|
end
|
163
203
|
|
164
|
-
template.add_grid do
|
165
|
-
100.times.map(&:
|
204
|
+
template.add_grid do
|
205
|
+
100.times.map(&:itself)
|
166
206
|
end
|
167
207
|
```
|
168
208
|
|
169
209
|
Similarly, if no child element is explicilty added to a `BoxElement`, but the block returns a string or number, that value will be converted to a `TextElement` and added as a child. For example, these are identical ways to create a box with string content
|
170
210
|
|
171
211
|
```ruby
|
172
|
-
template.add_box do |
|
173
|
-
|
212
|
+
template.add_box do |composer|
|
213
|
+
composer.add_text { "Hello!" }
|
174
214
|
end
|
175
215
|
|
176
|
-
template.add_box do
|
216
|
+
template.add_box do
|
177
217
|
"Hello!"
|
178
218
|
end
|
179
219
|
```
|
180
220
|
|
181
221
|
#### Settings
|
182
222
|
|
183
|
-
Each element type has an associated settings type, which provide a custom set of options to format the output.
|
223
|
+
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
|
184
224
|
The available settigs are
|
185
225
|
|
186
|
-
| Setting
|
187
|
-
|
|
188
|
-
| `align`
|
189
|
-
| `
|
190
|
-
| `
|
191
|
-
| `
|
192
|
-
| `
|
193
|
-
| `
|
194
|
-
| `
|
195
|
-
| `margin`
|
196
|
-
| `
|
197
|
-
| `
|
198
|
-
| `
|
199
|
-
| `
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
226
|
+
| Setting | Description | Default | Availability | Inherited |
|
227
|
+
| ------------ | ------------------------------------------------------------------------------- | ------- | --------------------- | -------------------- |
|
228
|
+
| `align` | Justifies the content (allowed values: `:left`, `:center`, `:right`) | `:left` | `Box`, `Grid` | Yes |
|
229
|
+
| `bg_color` | Background color (see [Colors](#colors)) | | `Box`, `Grid`, `Text` | Yes |
|
230
|
+
| `bold` | `true` makes the font bold | `false` | `Box`, `Grid`, `Text` | Yes |
|
231
|
+
| `border` | Set the border for the lements | none | `Box`, `Grid`, | Only style and color |
|
232
|
+
| `color` | Foreground text color (see [Colors](#colors)) | | `Box`, `Grid`, `Text` | Yes |
|
233
|
+
| `flow` | Flow to display child elements (see [Display Flow](#display-flow)) | `:l2r` | `Box`, `Grid` | Yes |
|
234
|
+
| `height` | Override the calculated height of an element's content area | | `Box`, `Grid` | No |
|
235
|
+
| `margin` | Set the (left, top, right, bottom) margin of the element | `0` | `Box`, `Grid` | No |
|
236
|
+
| `num_cols` | Number of columns in the grid (must be set!) | | `Grid` | No |
|
237
|
+
| `padding` | Set the (left, top, right, bottom) padding of the element | `0` | `Box`, `Grid` | No |
|
238
|
+
| `position` | Set the (left, top) position of the element relative to parent content area | `0` | `Box`, `Grid` | No |
|
239
|
+
| `title_font` | Font used for "large" text (see [Large Text](#large-text), ignores `underline`) | | `Text` | No |
|
240
|
+
| `underline` | `true` underlines the font | `false` | `Box`, `Grid`, `Text` | Yes |
|
241
|
+
| `width` | Override the calculated width of an element's content area | | `Box`, `Grid` | No |
|
242
|
+
|
243
|
+
##### Position
|
244
|
+
|
245
|
+
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
|
246
|
+
|
247
|
+
- `set_position(left:, top:)`
|
248
|
+
|
249
|
+
##### Margin
|
250
|
+
|
251
|
+
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
|
204
252
|
|
205
253
|
- `set_margin(left:, top:, right:, bottom:)`
|
254
|
+
|
255
|
+
Note: values cannot be negative
|
256
|
+
|
257
|
+
##### Padding
|
258
|
+
|
259
|
+
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
|
260
|
+
|
206
261
|
- `set_padding(left:, top:, right:, bottom:)`
|
207
262
|
|
208
|
-
|
263
|
+
Note: values cannot be negative
|
209
264
|
|
210
265
|
##### Border
|
211
266
|
|
212
267
|
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
|
213
268
|
|
214
269
|
- `set_border(left:, top:, right:, bottom:, inner_horiz:, inner_vert:, color:, style:)`
|
270
|
+
- `full_border(style:, color:)`
|
215
271
|
|
216
272
|
Available border styles are
|
217
273
|
|
@@ -302,14 +358,40 @@ Many of these also have a "bright" option:
|
|
302
358
|
- `:bright_red`
|
303
359
|
- `:bright_yellow`
|
304
360
|
|
361
|
+
##### Large Text
|
362
|
+
|
363
|
+
The `title_font` setting for `TextElement`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
|
364
|
+
|
365
|
+
```
|
366
|
+
██████╗ ███████╗███████╗ █████╗ ██╗ ██╗██╗ ████████╗
|
367
|
+
██╔══██╗██╔════╝██╔════╝██╔══██╗██║ ██║██║ ╚══██╔══╝
|
368
|
+
██║ ██║█████╗ █████╗ ███████║██║ ██║██║ ██║
|
369
|
+
██║ ██║██╔══╝ ██╔══╝ ██╔══██║██║ ██║██║ ██║
|
370
|
+
██████╔╝███████╗██║ ██║ ██║╚██████╔╝███████╗ ██║
|
371
|
+
╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝
|
372
|
+
```
|
373
|
+
|
374
|
+
To print out a list of all available fonts as well as sample text in that font, run
|
375
|
+
|
376
|
+
```
|
377
|
+
$ whirled_peas title_fonts
|
378
|
+
```
|
379
|
+
|
380
|
+
Note: when using a title font with WhirledPeas for the first time on a system, the gem loads all fonts to check which ones are available. This can be a slow process and may cause a noticeable delay when running a visualization. Running the command above will cache the results and thus when a WhirledPeas visualization is run, there will be no lag from loading fonts.
|
381
|
+
|
305
382
|
### Example
|
306
383
|
|
307
384
|
```ruby
|
308
385
|
class TemplateFactory
|
309
386
|
def build(frame, args)
|
310
387
|
set_state(frame, args)
|
311
|
-
WhirledPeas.template do |
|
312
|
-
|
388
|
+
WhirledPeas.template do |composer, settings|
|
389
|
+
settings.flow = :l2r
|
390
|
+
settings.align = :center
|
391
|
+
|
392
|
+
composer.add_box('Title', &method(:title))
|
393
|
+
composer.add_box('Sum', &method(:sum))
|
394
|
+
composer.add_grid('NumberGrid', &method(:number_grid))
|
313
395
|
end
|
314
396
|
end
|
315
397
|
|
@@ -317,41 +399,105 @@ class TemplateFactory
|
|
317
399
|
|
318
400
|
def set_state(frame, args)
|
319
401
|
@frame = frame
|
320
|
-
@numbers = args.key?(
|
321
|
-
@sum = args[
|
322
|
-
@low = args[
|
323
|
-
@high = args[
|
402
|
+
@numbers = args.key?(:numbers) ? args[:numbers] || []
|
403
|
+
@sum = args[:sum] if args.key?(:sum)
|
404
|
+
@low = args[:low] if args.key?(:low)
|
405
|
+
@high = args[:high] if args.key?(:high)
|
324
406
|
end
|
325
407
|
|
326
|
-
def title(
|
408
|
+
def title(_composer, settings)
|
327
409
|
settings.underline = true
|
328
410
|
"Pair Finder"
|
329
411
|
end
|
330
412
|
|
331
|
-
def sum(
|
413
|
+
def sum(_composer, settings)
|
332
414
|
settings.color = @frame == 'found-pair' ? :green : :red
|
333
415
|
@sum ? "Sum: #{@sum}" : 'N/A'
|
334
416
|
end
|
335
417
|
|
336
|
-
def number_grid(
|
418
|
+
def number_grid(composer, settings)
|
337
419
|
settings.full_border
|
338
420
|
@numbers.each.with_index do |num, index|
|
339
|
-
|
421
|
+
composer.add_text do |_, settings|
|
340
422
|
settings.bg_color = (@low == index || @high == index) ? :cyan : :white
|
341
|
-
num
|
423
|
+
num
|
342
424
|
end
|
343
425
|
end
|
344
426
|
end
|
427
|
+
end
|
428
|
+
```
|
345
429
|
|
346
|
-
|
347
|
-
settings.flow = :l2r
|
348
|
-
settings.auto_margin = true
|
430
|
+
### Debugging
|
349
431
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
432
|
+
The `whirled_peas` executable provides some commands that are helpful for debugging.
|
433
|
+
|
434
|
+
#### list_frames
|
435
|
+
|
436
|
+
List the frames sent by the driver
|
437
|
+
|
438
|
+
```
|
439
|
+
$ whirled_peas <config file> list_frames
|
440
|
+
Frame 'start' displayed for 5 second(s)
|
441
|
+
Frame 'move' displayed for 1 frame ({:direction=>'N'})
|
442
|
+
...
|
443
|
+
EOF frame detected
|
444
|
+
```
|
445
|
+
|
446
|
+
#### play_frame
|
447
|
+
|
448
|
+
Displays a single frame for several seconds
|
449
|
+
|
450
|
+
```
|
451
|
+
$ whirled_peas <config file> play_frame move '{"direction":"N"}'
|
452
|
+
```
|
453
|
+
|
454
|
+
Adding the `--template` flag will result in printing out debug information for the template, e.g.
|
455
|
+
|
456
|
+
```
|
457
|
+
$ whirled_peas <config file> play_frame move '{"direction":"N"}' --template
|
458
|
+
+ TEMPLATE [WhirledPeas::Template::BoxElement]
|
459
|
+
- Settings
|
460
|
+
WhirledPeas::Settings::BoxSettings
|
461
|
+
<default>
|
462
|
+
- Children
|
463
|
+
+ TitleContainer [WhirledPeas::Template::BoxElement]
|
464
|
+
...
|
465
|
+
```
|
466
|
+
|
467
|
+
Adding the `--painter` flag will result in printing out debug information the painter (the rendered template), e.g.
|
468
|
+
|
469
|
+
```
|
470
|
+
$ whirled_peas <config file> play_frame move '{"direction":"N"}' --painter
|
471
|
+
+ TEMPLATE [WhirledPeas::Graphics::BoxPainter]
|
472
|
+
- Settings
|
473
|
+
WhirledPeas::Settings::BoxSettings
|
474
|
+
<default>
|
475
|
+
- Dimensions
|
476
|
+
- Canvas:
|
477
|
+
- Children
|
478
|
+
+ TitleContainer [WhirledPeas::Graphics::BoxPainter]
|
479
|
+
...
|
480
|
+
```
|
481
|
+
|
482
|
+
#### loading
|
483
|
+
|
484
|
+
Displays the configured loading screen for several seconds
|
485
|
+
|
486
|
+
```
|
487
|
+
$ whirled_peas <config file> loading
|
488
|
+
```
|
489
|
+
|
490
|
+
Adding the `--debug` flag will result in just printing out the loading template's debug information, e.g.
|
491
|
+
|
492
|
+
```
|
493
|
+
$ whirled_peas <config file> loading --debug
|
494
|
+
+ TEMPLATE [WhirledPeas::UI::Template]
|
495
|
+
- Settings
|
496
|
+
WhirledPeas::UI::TemplateSettings
|
497
|
+
<default>
|
498
|
+
- Children
|
499
|
+
+ TitleContainer [WhirledPeas::UI::BoxElement]
|
500
|
+
...
|
355
501
|
```
|
356
502
|
|
357
503
|
## Development
|
@@ -360,6 +506,21 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
360
506
|
|
361
507
|
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).
|
362
508
|
|
509
|
+
### Testing
|
510
|
+
|
511
|
+
In addition to standard RSpec tests, WhirledPeas has custom tests for rendered templates. These files live in `screen_test/rendered`. 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.
|
512
|
+
|
513
|
+
Note: viewing `.frame` files with `cat` works better than most other text editors.
|
514
|
+
|
515
|
+
The following rake tasks are provided to interact with the screen tests
|
516
|
+
|
517
|
+
- `screen_test` runs all screen tests in the `screen_test/rendered` directory
|
518
|
+
- `screen_test:debug[path/to/file.rb]` print the rendered template debug tree
|
519
|
+
- `screen_test:run[path/to/file.rb]` runs a single screen test
|
520
|
+
- `screen_test:save[path/to/file.rb]` saves the output generated by the template in the `.frame` file, overwriting any existing file
|
521
|
+
- `screen_test:view[path/to/file.rb]` views the output generated by the template
|
522
|
+
- `screen_test:update_all[path/to/file.rb]` interactively step through each pending or failed screen test to compare/set the expected output
|
523
|
+
|
363
524
|
## Contributing
|
364
525
|
|
365
526
|
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).
|