whirled_peas 0.11.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/CHANGELOG.md +5 -0
  4. data/README.md +7 -1156
  5. data/doc/application.md +92 -0
  6. data/doc/cli.md +115 -0
  7. data/doc/components.md +55 -0
  8. data/doc/easing.md +257 -0
  9. data/doc/elements.md +69 -0
  10. data/doc/screen_test.md +23 -0
  11. data/doc/settings.md +466 -0
  12. data/doc/template_factory.md +53 -0
  13. data/doc/themes.md +15 -0
  14. data/lib/data/themes.yaml +8 -4
  15. data/lib/whirled_peas/component/list_with_active.rb +3 -3
  16. data/lib/whirled_peas/graphics/container_coords.rb +2 -26
  17. data/lib/whirled_peas/graphics/container_dimensions.rb +24 -0
  18. data/lib/whirled_peas/graphics/container_painter.rb +26 -28
  19. data/lib/whirled_peas/graphics/debugger.rb +1 -0
  20. data/lib/whirled_peas/graphics/graph_painter.rb +31 -24
  21. data/lib/whirled_peas/graphics/scrollbar_helper.rb +31 -29
  22. data/lib/whirled_peas/settings/bg_color.rb +5 -1
  23. data/lib/whirled_peas/settings/border.rb +1 -1
  24. data/lib/whirled_peas/settings/color.rb +8 -4
  25. data/lib/whirled_peas/settings/debugger.rb +2 -0
  26. data/lib/whirled_peas/settings/element_settings.rb +10 -2
  27. data/lib/whirled_peas/settings/text_color.rb +5 -0
  28. data/lib/whirled_peas/settings/theme.rb +28 -7
  29. data/lib/whirled_peas/settings/theme_library.rb +10 -4
  30. data/lib/whirled_peas/version.rb +1 -1
  31. data/screen_test/components/list_with_active/l2r_position_start.frame +1 -1
  32. data/screen_test/components/list_with_active/l2r_separator.frame +1 -1
  33. data/screen_test/components/list_with_active/t2b_position_start.frame +1 -1
  34. data/screen_test/components/list_with_active/t2b_separator.frame +1 -1
  35. data/screen_test/elements/{graph.frame → graph_asc.frame} +1 -1
  36. data/screen_test/elements/{graph.rb → graph_asc.rb} +0 -0
  37. data/screen_test/elements/graph_desc.frame +1 -0
  38. data/screen_test/elements/graph_desc.rb +12 -0
  39. data/screen_test/elements/graph_horiz.frame +1 -0
  40. data/screen_test/elements/graph_horiz.rb +12 -0
  41. data/screen_test/elements/graph_sin.frame +1 -0
  42. data/screen_test/elements/graph_sin.rb +12 -0
  43. data/screen_test/elements/theme.frame +1 -1
  44. data/screen_test/settings/scroll/horiz_box.frame +1 -1
  45. data/screen_test/settings/scroll/vert_box.frame +1 -1
  46. metadata +19 -6
  47. data/bin/easing +0 -33
  48. data/lib/whirled_peas/graphics/mock_screen.rb +0 -26
@@ -0,0 +1,92 @@
1
+ ## Application
2
+
3
+ The application is code to be visualized that integrates with Whirled Peas by providing the signature below
4
+
5
+ ```ruby
6
+ # Start the application and pass frame events to the producer to be rendered
7
+ # by the UI
8
+ #
9
+ # @param producer [Producer] frame producer that sends events to the UI
10
+ def start(producer)
11
+ # application code here
12
+ end
13
+ ```
14
+
15
+ The producer provides the following methods
16
+
17
+ ```ruby
18
+ # Add a frame to be displayed
19
+ #
20
+ # @param name [String] (required) application defined name for the frame. The
21
+ # template factory will be provided this name
22
+ # @param duration [Number] (optional) time in seconds this frame should be
23
+ # displayed for (defaults to 1 frame)
24
+ # @param args [Hash<Symbol, Object>] (optional) key/value pairs to send as
25
+ # arguments to the template factory
26
+ def add_frame(name, duration:, args:)
27
+ end
28
+
29
+ # Create and yield a frameset instance that allows applications to add multiple
30
+ # frames to play over the given duration. Adding frames to the yielded frameset
31
+ # will result in playback that is eased by the given `easing` and `effect`
32
+ # arguments (default is `:linear` easing)
33
+ #
34
+ # @param duration [Number] (required) total duration for which all frames in
35
+ # frameset will be displayed
36
+ # @param easing [Symbol] (optional) easing function to be used to transition
37
+ # through all frames (defaults to `:linear`)
38
+ # @param effect [Symbol] (optional) how to apply the easing function (defaults
39
+ # to `:in_out`, also available are `:in` and `:out`)
40
+ # @yield [Frameset] instance that provides `#add_frame(name, args:)`
41
+ def frameset(duration, easing:, effect:, &block)
42
+ end
43
+ ```
44
+
45
+ See the [easing documentation](easing.md) for more details on the various easing functions.
46
+
47
+ A frameset instance provides one method
48
+
49
+ ```ruby
50
+ # Add a frame to be displayed, the duration will be determine by the number of
51
+ # frames in the frameset along with the duration and easing of the frameset
52
+ #
53
+ # @param name [String] (required) application defined name for the frame. The
54
+ # template factory will be provided this name
55
+ # @param args [Hash<Symbol, Object>] (optional) key/value pairs to send as
56
+ # arguments to the template factory
57
+ def add_frame(name, args:)
58
+ end
59
+ ```
60
+
61
+ **IMPORTANT**: the keys in the `args` hash must be symbols!
62
+
63
+ ### Example
64
+
65
+ Simple application that loads a set of numbers and looks for a pair that adds up to 1,000
66
+
67
+ ```ruby
68
+ class Application
69
+ def start(producer)
70
+ numbers = File.readlines('/path/to/numbers.txt').map(&:to_i)
71
+ producer.add_frame('load-numbers', duration: 3, args: { numbers: numbers })
72
+ numbers.sort!
73
+ producer.add_frame('sort-numbers', duration: 3, args: { numbers: numbers })
74
+ low = 0
75
+ high = numbers.length - 1
76
+ while low < high
77
+ sum = numbers[low] + numbers[high]
78
+ if sum == 1000
79
+ producer.add_frame('found-pair', duration: 5, args: { low: low, high: high, sum: sum })
80
+ return
81
+ elsif sum < 1000
82
+ producer.add_frame('too-low', args: { low: low, high: high, sum: sum })
83
+ low += 1
84
+ else
85
+ producer.add_frame('too-high', args: { low: low, high: high, sum: sum })
86
+ high -= 1
87
+ end
88
+ end
89
+ producer.add_frame('no-solution', duration: 5)
90
+ end
91
+ end
92
+ ```
@@ -0,0 +1,115 @@
1
+ ## Full usage
2
+
3
+ ```
4
+ Usage: whirled_peas <command> [command options]
5
+
6
+ Available commands:
7
+
8
+ debug Print template tree for specified frame
9
+ fonts List installed title fonts with sample text
10
+ frames Print out list of frames generated by application
11
+ help Show detailed help for a command
12
+ play Play an animation from an application or prerecorded file
13
+ record Record animation to a file
14
+ still Show the specified still frame
15
+ themes List all themes with sample template rendered in the theme
16
+ ```
17
+
18
+ ### `debug`
19
+
20
+ Print the template tree for specified frame.
21
+
22
+ ```
23
+ # Usage: whirled_peas debug <config file> <frame> [args as a JSON string]
24
+ % whirled_peas debug my_app.rb greeting '{"name":"World"}'
25
+ * WhirledPeas::Graphics::BoxPainter(TEMPLATE)
26
+ - Dimensions(outer=140x27, content=120x15, grid=1x1)
27
+ - Settings
28
+ WhirledPeas::Settings::BoxSettings
29
+ padding: Padding(left: 10, top: 6, right: 10, bottom: 6)
30
+ align: :center
31
+ width: 120
32
+ flow: :t2b
33
+ bold: true
34
+ bg_color: BgColor(code=107, bright=true)
35
+ - Children
36
+ * WhirledPeas::Graphics::BoxPainter(Element-1)
37
+ - Dimensions(outer=64x6, content=64x6, grid=1x1)
38
+ ```
39
+
40
+ ### `fonts`
41
+
42
+ List all installed title fonts with sample text.
43
+
44
+ ```
45
+ # Usage: whirled_peas fonts
46
+ ```
47
+
48
+ ### `frames`
49
+
50
+ Print out list of frames generated by application.
51
+
52
+ ```
53
+ # Usage: whirled_peas frames <config file>
54
+ % whirled_peas frames my_app.rb
55
+ Frame 'intro' displayed for 3 second(s) '{"title":"Foo"}'
56
+ Frame 'greet' displayed for 0.3 second(s)
57
+ ...
58
+ ```
59
+
60
+ ### `help`
61
+
62
+ Print out command-specific help message
63
+
64
+ ```
65
+ Usage: whirled_peas help <command>
66
+ ```
67
+
68
+ ### `play`
69
+
70
+ Play an animation from an application or prerecorded file
71
+
72
+ ```
73
+ # Usage: whirled_peas play <config/wpz file>
74
+
75
+ # Play animation directly from app
76
+ % whirled_peas play my_app.rb
77
+ # Animation plays
78
+
79
+ # Play animation from previously recorded file
80
+ % whirled_peas play my_animation.wpz
81
+ # Animation plays
82
+ ```
83
+
84
+ ### `record`
85
+
86
+ Record animation to a file
87
+
88
+ ```
89
+ # Usage: whirled_peas record <config file> <output file>
90
+ % whirled_peas record my_app.rb my_animation.wpz
91
+ # Record animation to my_animation.wpz
92
+ ```
93
+
94
+ ### `still`
95
+
96
+ Show the specified still frame
97
+
98
+ ```
99
+ # Usage: whirled_peas still <config file> <frame> [args as a JSON string]
100
+ % whirled_peas still my_app.rb greeting '{"name":"World"}'
101
+ # Still frame is displayed
102
+ ```
103
+
104
+ ### `themes`
105
+
106
+ List all themes and display a small sample screen in each. Running this with no extra command line arguments will display all the built-in themes. Adding the path to a Whirled Peas configuration file will inlcude any themes defined in that configuration.
107
+
108
+ ```
109
+ # Usage: whirled_peas themes [config file]
110
+ % whirled_peas themes
111
+ # Display all system themes
112
+
113
+ % whirled_peas themes my_app.rb
114
+ # Display app-defined themes and all system themes
115
+ ```
@@ -0,0 +1,55 @@
1
+ ## Components
2
+
3
+ A component is a composition of the core building blocks. This gem includes a handful of components and third parties can also add components using `WhirledPeas.register_component(name, component_class)` (the convention for `name` is a snake cased symbol). A component class must be constructed with no arguments, though can supply basic setters to allow for customizations. A component must also implement `#compose(composer, settings)`, which should attach elements to the composer. Thus a template can integrate with the component like
4
+
5
+ ```ruby
6
+ WhirledPeas.template do |composer, settings|
7
+ # Attach the component registered with the name `:my_component` to the template
8
+ WhirledPeas.component(composer, settings, :my_component) do |component|
9
+ # Configure the component
10
+ end
11
+ end
12
+ ```
13
+
14
+ ### `:list_with_active`
15
+
16
+ This component presents a list of content (either horizontally of vertically) and places the item specified by `active_index` in the preferred position.
17
+
18
+ ```
19
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
20
+ ┃ green, blue, *indigo*, viole┃
21
+ ┃ ▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ ┃
22
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
23
+ ```
24
+
25
+ Note: in the diagram above, the item specified by the active index is highlighted with `*`s, these are for illustration onlhy. The component can highlight the item with a color and/or background color, but will _not_ add the `*`s.
26
+
27
+ This component takes the following options
28
+
29
+ #### Required
30
+
31
+ - `active_index` - the index of the active item
32
+ - `items` - the array of items to be displayed in the box
33
+
34
+ #### Optional
35
+
36
+ - `active_bg_color` - background color of the active item
37
+ - `active_color` - text color of the active item
38
+ - `flow` - `:l2r` or `:t2b`
39
+ - `separator` - string used to separate items in the list, e.g. `", "` for a horizontal list or `"----"` for a vertical list
40
+ - `viewport_size` - number of characters of the viewport in the flow direction
41
+
42
+ ### Example
43
+
44
+ ```ruby
45
+ WhirledPeas.template do |composer, settings|
46
+ WhirledPeas.component(composer, settings, :list_with_active) do |component|
47
+ component.items = %w[red orange yellow green blue indigo violet]
48
+ component.separator = ', '
49
+ component.active_index = active
50
+ component.viewport_size = 27
51
+ component.active_color = :blue
52
+ component.active_bg_color = :bright_yellow
53
+ end
54
+ end
55
+ ```
@@ -0,0 +1,257 @@
1
+ ## Easing
2
+
3
+ The duration that a frame within a frameset is displayed is determined by the easing function and effect along with the frames relative position within the frameset. The three effects are
4
+
5
+ - `:in` - apply easing only to the start of the frameset
6
+ - `:out` - apply easing only to the end of the frameset
7
+ - `:in_out` - apply easing to the start and end of the frameset
8
+
9
+ The available easing functions are
10
+
11
+ - `:bezier`
12
+
13
+ ```
14
+ # bezier (in)
15
+ ┃ ▄▀
16
+ ┃ ▄▄▀
17
+ ┃ ▄▀
18
+ ┃ ▄▀▀
19
+ ┃ ▄▄▀
20
+ ┃ ▄▄▀
21
+ ┃ ▄▄▀
22
+ ┃ ▄▀
23
+ ┃ ▄▄▀▀
24
+ ┃ ▄▄▀
25
+ ┃ ▄▀▀
26
+ ┃ ▄▄▀▀
27
+ ┃ ▄▄▀▀▀
28
+ ┃ ▄▄▄▀▀▀
29
+ ┃▄▄▄▄▄▄▄▄▄▄▀▀▀
30
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
31
+ ```
32
+
33
+ ```
34
+ # bezier (out)
35
+ ┃ ▄▄▄▀▀▀▀▀▀▀▀▀
36
+ ┃ ▄▄▄▀▀▀
37
+ ┃ ▄▄▄▀▀
38
+ ┃ ▄▄▀▀
39
+ ┃ ▄▄▀
40
+ ┃ ▄▀▀
41
+ ┃ ▄▄▀▀
42
+ ┃ ▄▀
43
+ ┃ ▄▀▀
44
+ ┃ ▄▀▀
45
+ ┃ ▄▀▀
46
+ ┃ ▄▄▀
47
+ ┃ ▄▀
48
+ ┃ ▄▀▀
49
+ ┃▄▄▀
50
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
51
+ ```
52
+
53
+ ```
54
+ # bezier (in_out)
55
+ ┃ ▄▄▄▀▀▀▀▀▀
56
+ ┃ ▄▄▀▀
57
+ ┃ ▄▀▀
58
+ ┃ ▄▀▀
59
+ ┃ ▄▀▀
60
+ ┃ ▄▀▀
61
+ ┃ ▄▄▀
62
+ ┃ ▄▀
63
+ ┃ ▄▀▀
64
+ ┃ ▄▄▀
65
+ ┃ ▄▄▀
66
+ ┃ ▄▄▀
67
+ ┃ ▄▄▀
68
+ ┃ ▄▄▀▀
69
+ ┃▄▄▄▄▄▄▄▀▀▀
70
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
71
+ ```
72
+
73
+ `:linear`
74
+
75
+ ```
76
+ # linear (in)
77
+ ┃ ▄▄▀
78
+ ┃ ▄▄▀▀
79
+ ┃ ▄▄▀▀
80
+ ┃ ▄▄▀▀
81
+ ┃ ▄▄▀▀
82
+ ┃ ▄▄▀▀
83
+ ┃ ▄▄▀▀
84
+ ┃ ▄▄▀▀
85
+ ┃ ▄▄▀▀
86
+ ┃ ▄▄▀▀
87
+ ┃ ▄▄▀▀
88
+ ┃ ▄▄▀▀
89
+ ┃ ▄▄▀▀
90
+ ┃ ▄▄▀▀
91
+ ┃▄▄▀▀
92
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
93
+ ```
94
+
95
+ ```
96
+ # linear (out)
97
+ ┃ ▄▄▀
98
+ ┃ ▄▄▀▀
99
+ ┃ ▄▄▀▀
100
+ ┃ ▄▄▀▀
101
+ ┃ ▄▄▀▀
102
+ ┃ ▄▄▀▀
103
+ ┃ ▄▄▀▀
104
+ ┃ ▄▄▀▀
105
+ ┃ ▄▄▀▀
106
+ ┃ ▄▄▀▀
107
+ ┃ ▄▄▀▀
108
+ ┃ ▄▄▀▀
109
+ ┃ ▄▄▀▀
110
+ ┃ ▄▄▀▀
111
+ ┃▄▄▀▀
112
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
113
+ ```
114
+
115
+ ```
116
+ # linear (in_out)
117
+ ┃ ▄▄▀
118
+ ┃ ▄▄▀▀
119
+ ┃ ▄▄▀▀
120
+ ┃ ▄▄▀▀
121
+ ┃ ▄▄▀▀
122
+ ┃ ▄▄▀▀
123
+ ┃ ▄▄▀▀
124
+ ┃ ▄▄▀▀
125
+ ┃ ▄▄▀▀
126
+ ┃ ▄▄▀▀
127
+ ┃ ▄▄▀▀
128
+ ┃ ▄▄▀▀
129
+ ┃ ▄▄▀▀
130
+ ┃ ▄▄▀▀
131
+ ┃▄▄▀▀
132
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
133
+ ```
134
+
135
+ `:parametric`
136
+
137
+ ```
138
+ # parametric (in)
139
+ ┃ ▄
140
+ ┃ ▄▀
141
+ ┃ ▄▀
142
+ ┃ ▄▄▀
143
+ ┃ ▄▀
144
+ ┃ ▄▀
145
+ ┃ ▄▀
146
+ ┃ ▄▄▀
147
+ ┃ ▄▀
148
+ ┃ ▄▀▀
149
+ ┃ ▄▀▀
150
+ ┃ ▄▄▀▀
151
+ ┃ ▄▄▄▀▀
152
+ ┃ ▄▄▄▄▀▀
153
+ ┃▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀▀▀▀
154
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
155
+ ```
156
+
157
+ ```
158
+ # parametric (out)
159
+ ┃ ▄▄▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀
160
+ ┃ ▄▄▀▀▀▀
161
+ ┃ ▄▄▀▀▀
162
+ ┃ ▄▄▀▀
163
+ ┃ ▄▄▀
164
+ ┃ ▄▄▀
165
+ ┃ ▄▀
166
+ ┃ ▄▀▀
167
+ ┃ ▄▀
168
+ ┃ ▄▀
169
+ ┃ ▄▀
170
+ ┃ ▄▀▀
171
+ ┃ ▄▀
172
+ ┃ ▄▀
173
+ ┃▄▀
174
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
175
+ ```
176
+
177
+ ```
178
+ # parametric (in_out)
179
+ ┃ ▄▄▄▀▀▀▀▀▀▀▀▀
180
+ ┃ ▄▄▀▀
181
+ ┃ ▄▀▀
182
+ ┃ ▄▄▀
183
+ ┃ ▄▀
184
+ ┃ ▄▀
185
+ ┃ ▄▀
186
+ ┃ ▄▀
187
+ ┃ ▄▀
188
+ ┃ ▄▀
189
+ ┃ ▄▀
190
+ ┃ ▄▀▀
191
+ ┃ ▄▄▀
192
+ ┃ ▄▄▀▀
193
+ ┃▄▄▄▄▄▄▄▄▄▄▀▀▀
194
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
195
+ ```
196
+
197
+ `:quadratic`
198
+
199
+ ```
200
+ # quadratic (in)
201
+ ┃ ▄▄
202
+ ┃ ▄▀
203
+ ┃ ▄▀
204
+ ┃ ▄▀
205
+ ┃ ▄▀
206
+ ┃ ▄▀▀
207
+ ┃ ▄▀
208
+ ┃ ▄▀▀
209
+ ┃ ▄▀▀
210
+ ┃ ▄▀▀
211
+ ┃ ▄▄▀▀
212
+ ┃ ▄▄▀▀
213
+ ┃ ▄▄▄▀▀
214
+ ┃ ▄▄▄▀▀▀
215
+ ┃▄▄▄▄▄▄▄▄▄▄▄▀▀▀▀▀
216
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
217
+ ```
218
+
219
+ ```
220
+ # quadratic (out)
221
+ ┃ ▄▄▄▄▄▀▀▀▀▀▀▀▀▀▀
222
+ ┃ ▄▄▄▀▀▀
223
+ ┃ ▄▄▀▀▀
224
+ ┃ ▄▄▀▀
225
+ ┃ ▄▄▀▀
226
+ ┃ ▄▄▀
227
+ ┃ ▄▄▀
228
+ ┃ ▄▄▀
229
+ ┃ ▄▀
230
+ ┃ ▄▄▀
231
+ ┃ ▄▀
232
+ ┃ ▄▀
233
+ ┃ ▄▀
234
+ ┃ ▄▀
235
+ ┃▄▀▀
236
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
237
+ ```
238
+
239
+ ```
240
+ # quadratic (in_out)
241
+ ┃ ▄▄▄▀▀▀▀▀▀▀
242
+ ┃ ▄▄▀▀▀
243
+ ┃ ▄▀▀
244
+ ┃ ▄▀▀
245
+ ┃ ▄▄▀
246
+ ┃ ▄▀
247
+ ┃ ▄▀
248
+ ┃ ▄▀
249
+ ┃ ▄▀
250
+ ┃ ▄▀
251
+ ┃ ▄▀▀
252
+ ┃ ▄▄▀
253
+ ┃ ▄▄▀
254
+ ┃ ▄▄▄▀▀
255
+ ┃▄▄▄▄▄▄▄▄▀▀▀
256
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
257
+ ```