whirled_peas 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +309 -33
- data/bin/easing +33 -0
- data/examples/graph.rb +54 -0
- data/examples/scrolling.rb +1 -1
- data/lib/whirled_peas/animator/frameset.rb +1 -1
- data/lib/whirled_peas/animator/producer.rb +1 -1
- data/lib/whirled_peas/graphics/composer.rb +18 -0
- data/lib/whirled_peas/graphics/content_dimensions.rb +19 -0
- data/lib/whirled_peas/graphics/content_painter.rb +20 -0
- data/lib/whirled_peas/graphics/graph_dimensions.rb +12 -0
- data/lib/whirled_peas/graphics/graph_painter.rb +95 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +0 -3
- data/lib/whirled_peas/graphics/text_painter.rb +7 -11
- data/lib/whirled_peas/settings/container_settings.rb +0 -2
- data/lib/whirled_peas/settings/element_settings.rb +5 -0
- data/lib/whirled_peas/settings/graph_settings.rb +21 -0
- data/lib/whirled_peas/settings/grid_settings.rb +7 -0
- data/lib/whirled_peas/utils/ansi.rb +1 -1
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/elements/graph.frame +1 -0
- data/screen_test/elements/graph.rb +12 -0
- metadata +10 -2
- data/lib/whirled_peas/graphics/text_dimensions.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7553fd2ea78bf560098d8be8cd3987f1e8a686cb000cf6ea082a922512764069
|
4
|
+
data.tar.gz: 8fa1e64c35b311ae9346badc0198f556528c53dad9bfa0b99b2805c901369b8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 531b93061429918f99dc5aa7de09a53a7fda218c97bac57b47d5a450ad22510207f71ba5a095f5a1939e4cce9d1f13d70a981e15b4e3209d0786ba12be048bd6
|
7
|
+
data.tar.gz: ea7daec0ccd65894bec99bfff75219d55dfc2cd9fc7b80d1e593b60e7a15a3e8eb7cbfa49e8ef20e8da5acbce2738d054cf56a9b0231661e46a5c399c83b8906
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.9.0 - 2021-01-29
|
4
|
+
|
5
|
+
BREAKING: `Frameset#add_frame` signature changed
|
6
|
+
|
7
|
+
- [1c28947](https://github.com/tcollier/whirled_peas/tree/1c28947980eedce034d2596732ee4860717904c5): Add graph support
|
8
|
+
|
3
9
|
## v0.8.0 - 2021-01-29
|
4
10
|
|
5
11
|
BREAKING: `Producer` now responds to `#add_frame` instead of `#send_frame`
|
data/README.md
CHANGED
@@ -93,16 +93,33 @@ def start(producer)
|
|
93
93
|
end
|
94
94
|
```
|
95
95
|
|
96
|
-
The producer provides
|
96
|
+
The producer provides the following methods
|
97
97
|
|
98
98
|
```ruby
|
99
|
-
#
|
99
|
+
# Add a frame to be displayed
|
100
100
|
#
|
101
101
|
# @param name [String] application defined name for the frame. The template factory will be provided this name
|
102
102
|
# @param duration [Number] time in seconds this frame should be displayed for (defaults to 1 frame)
|
103
103
|
# @param args [Hash<Symbol, Object>] key value pairs to send as arguments to the template factory
|
104
104
|
def add_frame(name, duration:, args:)
|
105
|
-
|
105
|
+
end
|
106
|
+
|
107
|
+
# Create and yield a frameset instance that allows applications to add multiple frames to play over the
|
108
|
+
# given duration. Adding frames to the yielded frameset will result in playback that is eased by the
|
109
|
+
# gvien `easing` and `effect` arguments (default is `:linear` easing)
|
110
|
+
def frameset(duration, easing:, effect:, &block)
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
A frameset instance provides one method
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
# Add a frame to be displayed, the duration will be determine by the number of frames in the frameset along
|
118
|
+
# with the duration and easing of the frameset
|
119
|
+
#
|
120
|
+
# @param name [String] application defined name for the frame. The template factory will be provided this name
|
121
|
+
# @param args [Hash<Symbol, Object>] key value pairs to send as arguments to the template factory
|
122
|
+
def add_frame(name, args:)
|
106
123
|
end
|
107
124
|
```
|
108
125
|
|
@@ -155,6 +172,7 @@ A template is created with `WhirledPeas.template`, which yields a `Composer` obj
|
|
155
172
|
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
173
|
|
157
174
|
- `add_box` - yields a `Composer` for a `Box` and a `BoxSettings`, which will be added to the parent's children
|
175
|
+
- `add_graph` - yields a `nil` and a `GraphSettings`, which will be added to the parent's children, the block should return an array of numbers
|
158
176
|
- `add_grid` - yields a `Composer` for a `Grid` and a `GridSettings`, which will be added to the parent's children
|
159
177
|
- `add_text` - yields `nil` and a `TextSettings`, which will be added to the parent's children
|
160
178
|
|
@@ -217,25 +235,26 @@ end
|
|
217
235
|
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
|
218
236
|
The available settigs are
|
219
237
|
|
220
|
-
| Setting | Description | Default | Availability
|
221
|
-
| ------------ | -------------------------------------------------------------------------------- | ---------- |
|
222
|
-
| `align` | Justifies the content in the horizontal direction | `:left` | `
|
223
|
-
| `
|
224
|
-
| `
|
225
|
-
| `
|
226
|
-
| `
|
227
|
-
| `
|
228
|
-
| `
|
229
|
-
| `
|
230
|
-
| `
|
231
|
-
| `
|
232
|
-
| `
|
233
|
-
| `
|
234
|
-
| `
|
235
|
-
| `
|
236
|
-
| `
|
237
|
-
| `
|
238
|
-
| `
|
238
|
+
| Setting | Description | Default | Availability | Inherited |
|
239
|
+
| ------------ | -------------------------------------------------------------------------------- | ---------- | ------------ | -------------------- |
|
240
|
+
| `align` | Justifies the content in the horizontal direction | `:left` | `Container` | No |
|
241
|
+
| `axis_color` | Color used to paint the axes of the graph (see [Colors](#colors)) | | `Graph` | No |
|
242
|
+
| `bg_color` | Background color (see [Colors](#colors)) | | all | Yes |
|
243
|
+
| `bold` | `true` makes the font bold | `false` | all | Yes |
|
244
|
+
| `border` | Set the border for the lements | none | `Container`, | Only style and color |
|
245
|
+
| `color` | Foreground text color (see [Colors](#colors)) | | all | Yes |
|
246
|
+
| `flow` | Flow to display child elements (see [Display Flow](#display-flow)) | `:l2r` | `Container` | No |
|
247
|
+
| `height` | Override the calculated height of an element's content area | | all | No |
|
248
|
+
| `margin` | Set the (left, top, right, bottom) margin of the element | `0` | `Container` | No |
|
249
|
+
| `num_cols` | Number of columns in the grid (must be set!) | | `Grid` | No |
|
250
|
+
| `padding` | Set the (left, top, right, bottom) padding of the element | `0` | `Container` | No |
|
251
|
+
| `position` | Set the (left, top) position of the element relative to parent content area | `0` | `Container` | No |
|
252
|
+
| `scrollbar` | Display a scroll bar for vertical or horizontal scrolling | | `Box` | No |
|
253
|
+
| `sizing` | Sizing model (`:content` or `:border`) used in conjunction with `width`/`height` | `:content` | `Box` | No |
|
254
|
+
| `title_font` | Font used for "large" text (see [Large Text](#large-text), ignores `underline`) | | `Text` | No |
|
255
|
+
| `underline` | `true` underlines the font | `false` | all | Yes |
|
256
|
+
| `width` | Override the calculated width of an element's content area | | all | No |
|
257
|
+
| `valign` | Justifies the content in the vertical direction | `:top` | `Container` | No |
|
239
258
|
|
240
259
|
##### Alignment
|
241
260
|
|
@@ -671,7 +690,265 @@ $ whirled_peas title_fonts
|
|
671
690
|
|
672
691
|
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.
|
673
692
|
|
674
|
-
|
693
|
+
#### Easing
|
694
|
+
|
695
|
+
The play duration of a frame within a frameset is determined by the easing function and effect along with the frames relative position within the frameset. The three effects are
|
696
|
+
|
697
|
+
- `:in` - apply easing only to the start of the frameset
|
698
|
+
- `:out` - apply easing only to the end of the frameset
|
699
|
+
- `:in_out` - apply easing to the start and end of the frameset
|
700
|
+
|
701
|
+
The available easing functions are
|
702
|
+
|
703
|
+
- `:bezier`
|
704
|
+
|
705
|
+
```
|
706
|
+
# bezier (in)
|
707
|
+
┃ ▄▀
|
708
|
+
┃ ▄▄▀
|
709
|
+
┃ ▄▀
|
710
|
+
┃ ▄▀▀
|
711
|
+
┃ ▄▄▀
|
712
|
+
┃ ▄▄▀
|
713
|
+
┃ ▄▄▀
|
714
|
+
┃ ▄▀
|
715
|
+
┃ ▄▄▀▀
|
716
|
+
┃ ▄▄▀
|
717
|
+
┃ ▄▀▀
|
718
|
+
┃ ▄▄▀▀
|
719
|
+
┃ ▄▄▀▀▀
|
720
|
+
┃ ▄▄▄▀▀▀
|
721
|
+
┃▄▄▄▄▄▄▄▄▄▄▀▀▀
|
722
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
723
|
+
```
|
724
|
+
|
725
|
+
```
|
726
|
+
# bezier (out)
|
727
|
+
┃ ▄▄▄▀▀▀▀▀▀▀▀▀
|
728
|
+
┃ ▄▄▄▀▀▀
|
729
|
+
┃ ▄▄▄▀▀
|
730
|
+
┃ ▄▄▀▀
|
731
|
+
┃ ▄▄▀
|
732
|
+
┃ ▄▀▀
|
733
|
+
┃ ▄▄▀▀
|
734
|
+
┃ ▄▀
|
735
|
+
┃ ▄▀▀
|
736
|
+
┃ ▄▀▀
|
737
|
+
┃ ▄▀▀
|
738
|
+
┃ ▄▄▀
|
739
|
+
┃ ▄▀
|
740
|
+
┃ ▄▀▀
|
741
|
+
┃▄▄▀
|
742
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
743
|
+
```
|
744
|
+
|
745
|
+
```
|
746
|
+
# bezier (in_out)
|
747
|
+
┃ ▄▄▄▀▀▀▀▀▀
|
748
|
+
┃ ▄▄▀▀
|
749
|
+
┃ ▄▀▀
|
750
|
+
┃ ▄▀▀
|
751
|
+
┃ ▄▀▀
|
752
|
+
┃ ▄▀▀
|
753
|
+
┃ ▄▄▀
|
754
|
+
┃ ▄▀
|
755
|
+
┃ ▄▀▀
|
756
|
+
┃ ▄▄▀
|
757
|
+
┃ ▄▄▀
|
758
|
+
┃ ▄▄▀
|
759
|
+
┃ ▄▄▀
|
760
|
+
┃ ▄▄▀▀
|
761
|
+
┃▄▄▄▄▄▄▄▀▀▀
|
762
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
763
|
+
```
|
764
|
+
|
765
|
+
`:linear`
|
766
|
+
|
767
|
+
```
|
768
|
+
# linear (in)
|
769
|
+
┃ ▄▄▀
|
770
|
+
┃ ▄▄▀▀
|
771
|
+
┃ ▄▄▀▀
|
772
|
+
┃ ▄▄▀▀
|
773
|
+
┃ ▄▄▀▀
|
774
|
+
┃ ▄▄▀▀
|
775
|
+
┃ ▄▄▀▀
|
776
|
+
┃ ▄▄▀▀
|
777
|
+
┃ ▄▄▀▀
|
778
|
+
┃ ▄▄▀▀
|
779
|
+
┃ ▄▄▀▀
|
780
|
+
┃ ▄▄▀▀
|
781
|
+
┃ ▄▄▀▀
|
782
|
+
┃ ▄▄▀▀
|
783
|
+
┃▄▄▀▀
|
784
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
785
|
+
```
|
786
|
+
|
787
|
+
```
|
788
|
+
# linear (out)
|
789
|
+
┃ ▄▄▀
|
790
|
+
┃ ▄▄▀▀
|
791
|
+
┃ ▄▄▀▀
|
792
|
+
┃ ▄▄▀▀
|
793
|
+
┃ ▄▄▀▀
|
794
|
+
┃ ▄▄▀▀
|
795
|
+
┃ ▄▄▀▀
|
796
|
+
┃ ▄▄▀▀
|
797
|
+
┃ ▄▄▀▀
|
798
|
+
┃ ▄▄▀▀
|
799
|
+
┃ ▄▄▀▀
|
800
|
+
┃ ▄▄▀▀
|
801
|
+
┃ ▄▄▀▀
|
802
|
+
┃ ▄▄▀▀
|
803
|
+
┃▄▄▀▀
|
804
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
805
|
+
```
|
806
|
+
|
807
|
+
```
|
808
|
+
# linear (in_out)
|
809
|
+
┃ ▄▄▀
|
810
|
+
┃ ▄▄▀▀
|
811
|
+
┃ ▄▄▀▀
|
812
|
+
┃ ▄▄▀▀
|
813
|
+
┃ ▄▄▀▀
|
814
|
+
┃ ▄▄▀▀
|
815
|
+
┃ ▄▄▀▀
|
816
|
+
┃ ▄▄▀▀
|
817
|
+
┃ ▄▄▀▀
|
818
|
+
┃ ▄▄▀▀
|
819
|
+
┃ ▄▄▀▀
|
820
|
+
┃ ▄▄▀▀
|
821
|
+
┃ ▄▄▀▀
|
822
|
+
┃ ▄▄▀▀
|
823
|
+
┃▄▄▀▀
|
824
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
825
|
+
```
|
826
|
+
|
827
|
+
`:parametric`
|
828
|
+
|
829
|
+
```
|
830
|
+
# parametric (in)
|
831
|
+
┃ ▄
|
832
|
+
┃ ▄▀
|
833
|
+
┃ ▄▀
|
834
|
+
┃ ▄▄▀
|
835
|
+
┃ ▄▀
|
836
|
+
┃ ▄▀
|
837
|
+
┃ ▄▀
|
838
|
+
┃ ▄▄▀
|
839
|
+
┃ ▄▀
|
840
|
+
┃ ▄▀▀
|
841
|
+
┃ ▄▀▀
|
842
|
+
┃ ▄▄▀▀
|
843
|
+
┃ ▄▄▄▀▀
|
844
|
+
┃ ▄▄▄▄▀▀
|
845
|
+
┃▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀▀▀▀
|
846
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
847
|
+
```
|
848
|
+
|
849
|
+
```
|
850
|
+
# parametric (out)
|
851
|
+
┃ ▄▄▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀
|
852
|
+
┃ ▄▄▀▀▀▀
|
853
|
+
┃ ▄▄▀▀▀
|
854
|
+
┃ ▄▄▀▀
|
855
|
+
┃ ▄▄▀
|
856
|
+
┃ ▄▄▀
|
857
|
+
┃ ▄▀
|
858
|
+
┃ ▄▀▀
|
859
|
+
┃ ▄▀
|
860
|
+
┃ ▄▀
|
861
|
+
┃ ▄▀
|
862
|
+
┃ ▄▀▀
|
863
|
+
┃ ▄▀
|
864
|
+
┃ ▄▀
|
865
|
+
┃▄▀
|
866
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
867
|
+
```
|
868
|
+
|
869
|
+
```
|
870
|
+
# parametric (in_out)
|
871
|
+
┃ ▄▄▄▀▀▀▀▀▀▀▀▀
|
872
|
+
┃ ▄▄▀▀
|
873
|
+
┃ ▄▀▀
|
874
|
+
┃ ▄▄▀
|
875
|
+
┃ ▄▀
|
876
|
+
┃ ▄▀
|
877
|
+
┃ ▄▀
|
878
|
+
┃ ▄▀
|
879
|
+
┃ ▄▀
|
880
|
+
┃ ▄▀
|
881
|
+
┃ ▄▀
|
882
|
+
┃ ▄▀▀
|
883
|
+
┃ ▄▄▀
|
884
|
+
┃ ▄▄▀▀
|
885
|
+
┃▄▄▄▄▄▄▄▄▄▄▀▀▀
|
886
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
887
|
+
```
|
888
|
+
|
889
|
+
`:quadratic`
|
890
|
+
|
891
|
+
```
|
892
|
+
# quadratic (in)
|
893
|
+
┃ ▄▄
|
894
|
+
┃ ▄▀
|
895
|
+
┃ ▄▀
|
896
|
+
┃ ▄▀
|
897
|
+
┃ ▄▀
|
898
|
+
┃ ▄▀▀
|
899
|
+
┃ ▄▀
|
900
|
+
┃ ▄▀▀
|
901
|
+
┃ ▄▀▀
|
902
|
+
┃ ▄▀▀
|
903
|
+
┃ ▄▄▀▀
|
904
|
+
┃ ▄▄▀▀
|
905
|
+
┃ ▄▄▄▀▀
|
906
|
+
┃ ▄▄▄▀▀▀
|
907
|
+
┃▄▄▄▄▄▄▄▄▄▄▄▀▀▀▀▀
|
908
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
909
|
+
```
|
910
|
+
|
911
|
+
```
|
912
|
+
# quadratic (out)
|
913
|
+
┃ ▄▄▄▄▄▀▀▀▀▀▀▀▀▀▀
|
914
|
+
┃ ▄▄▄▀▀▀
|
915
|
+
┃ ▄▄▀▀▀
|
916
|
+
┃ ▄▄▀▀
|
917
|
+
┃ ▄▄▀▀
|
918
|
+
┃ ▄▄▀
|
919
|
+
┃ ▄▄▀
|
920
|
+
┃ ▄▄▀
|
921
|
+
┃ ▄▀
|
922
|
+
┃ ▄▄▀
|
923
|
+
┃ ▄▀
|
924
|
+
┃ ▄▀
|
925
|
+
┃ ▄▀
|
926
|
+
┃ ▄▀
|
927
|
+
┃▄▀▀
|
928
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
929
|
+
```
|
930
|
+
|
931
|
+
```
|
932
|
+
# quadratic (in_out)
|
933
|
+
┃ ▄▄▄▀▀▀▀▀▀▀
|
934
|
+
┃ ▄▄▀▀▀
|
935
|
+
┃ ▄▀▀
|
936
|
+
┃ ▄▀▀
|
937
|
+
┃ ▄▄▀
|
938
|
+
┃ ▄▀
|
939
|
+
┃ ▄▀
|
940
|
+
┃ ▄▀
|
941
|
+
┃ ▄▀
|
942
|
+
┃ ▄▀
|
943
|
+
┃ ▄▀▀
|
944
|
+
┃ ▄▄▀
|
945
|
+
┃ ▄▄▀
|
946
|
+
┃ ▄▄▄▀▀
|
947
|
+
┃▄▄▄▄▄▄▄▄▀▀▀
|
948
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
949
|
+
```
|
950
|
+
|
951
|
+
### Full template example
|
675
952
|
|
676
953
|
```ruby
|
677
954
|
class TemplateFactory
|
@@ -840,16 +1117,15 @@ Usage: screen_test [file] [options]
|
|
840
1117
|
If not file or options are provide, all tests are run
|
841
1118
|
|
842
1119
|
If no file is provided, the supported options are
|
843
|
-
--help
|
844
|
-
--view-pending
|
845
|
-
--view-failed
|
846
|
-
|
847
|
-
If
|
848
|
-
--run
|
849
|
-
--view
|
850
|
-
--template
|
851
|
-
--debug
|
852
|
-
|
1120
|
+
--help print this usage statement and exit
|
1121
|
+
--view-pending interactively display and optionally save rendered output for each pending test
|
1122
|
+
--view-failed interactively display and optionally save rendered output for each faiing test
|
1123
|
+
|
1124
|
+
If a screen test file is provided as the first argument, the supported options are
|
1125
|
+
--run run screen test for given file
|
1126
|
+
--view interactively display and optionally save the file's test output
|
1127
|
+
--template print out template tree for the test template
|
1128
|
+
--debug render the test template without displying it, printing out debug information
|
853
1129
|
```
|
854
1130
|
|
855
1131
|
## Contributing
|
data/bin/easing
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'whirled_peas'
|
5
|
+
require 'whirled_peas/animator/easing'
|
6
|
+
|
7
|
+
module WhirledPeas
|
8
|
+
NUM_POINTS = 60
|
9
|
+
|
10
|
+
Animator::Easing::EASING.keys.each do |func|
|
11
|
+
Animator::Easing::EFFECTS.each do |effect|
|
12
|
+
easing = Animator::Easing.new(func, effect)
|
13
|
+
graph = Array.new(NUM_POINTS / ASPECT_RATIO) { '┃' }
|
14
|
+
NUM_POINTS.times.each do |i|
|
15
|
+
input = i.to_f / (NUM_POINTS - 1)
|
16
|
+
eased_value = ((easing.ease(input) * NUM_POINTS * 2) / ASPECT_RATIO).floor
|
17
|
+
graph.each.with_index do |row, row_num|
|
18
|
+
y_value = NUM_POINTS.to_f / ASPECT_RATIO - row_num - 1
|
19
|
+
row << if eased_value == 2 * y_value
|
20
|
+
'▄'
|
21
|
+
elsif eased_value == 2 * y_value + 1
|
22
|
+
'▀'
|
23
|
+
else
|
24
|
+
' '
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
graph << '┗' + '━' * NUM_POINTS
|
29
|
+
puts "#{func} (#{effect})"
|
30
|
+
puts graph.join("\n")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/examples/graph.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'whirled_peas'
|
3
|
+
require 'whirled_peas/animator/easing'
|
4
|
+
|
5
|
+
module WhirledPeas
|
6
|
+
PublicEasing = Animator::Easing
|
7
|
+
end
|
8
|
+
|
9
|
+
class TemplateFactory
|
10
|
+
INNER_WIDTH = 60
|
11
|
+
|
12
|
+
def build(name, args)
|
13
|
+
WhirledPeas.template do |composer, settings|
|
14
|
+
settings.bg_color = :bright_white
|
15
|
+
settings.align = :center
|
16
|
+
settings.valign = :middle
|
17
|
+
composer.add_grid do |composer, settings|
|
18
|
+
settings.num_cols = 2
|
19
|
+
WhirledPeas::PublicEasing::EASING.keys.each do |func|
|
20
|
+
easing = WhirledPeas::PublicEasing.new(func, :in_out)
|
21
|
+
composer.add_box do |composer, settings|
|
22
|
+
settings.flow = :t2b
|
23
|
+
settings.set_padding(horiz: 4, vert: 2)
|
24
|
+
composer.add_box do |_, settings|
|
25
|
+
settings.margin.bottom = 1
|
26
|
+
settings.color = :blue
|
27
|
+
settings.underline = true
|
28
|
+
"#{func} (in_out)"
|
29
|
+
end
|
30
|
+
composer.add_graph do |composer, settings|
|
31
|
+
settings.axis_color = :black
|
32
|
+
settings.color = :bright_blue
|
33
|
+
settings.height = 15
|
34
|
+
INNER_WIDTH.times.map do |i|
|
35
|
+
easing.ease(i.to_f / (INNER_WIDTH - 1))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Application
|
46
|
+
def start(producer)
|
47
|
+
producer.add_frame('intro', duration: 5)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
WhirledPeas.configure do |config|
|
52
|
+
config.template_factory = TemplateFactory.new
|
53
|
+
config.application = Application.new
|
54
|
+
end
|
data/examples/scrolling.rb
CHANGED
@@ -42,7 +42,7 @@ end
|
|
42
42
|
class Application
|
43
43
|
def start(producer)
|
44
44
|
producer.frameset(5, easing: :bezier) do |fs|
|
45
|
-
53.times { |i| fs.add_frame('intro', { top: -i }) }
|
45
|
+
53.times { |i| fs.add_frame('intro', args: { top: -i }) }
|
46
46
|
end
|
47
47
|
producer.add_frame('hold', duration: 1, args: { top: -52})
|
48
48
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'whirled_peas/settings/box_settings'
|
2
|
+
require 'whirled_peas/settings/graph_settings'
|
2
3
|
require 'whirled_peas/settings/grid_settings'
|
3
4
|
require 'whirled_peas/settings/text_settings'
|
4
5
|
|
5
6
|
require_relative 'box_painter'
|
7
|
+
require_relative 'graph_painter'
|
6
8
|
require_relative 'grid_painter'
|
7
9
|
require_relative 'text_painter'
|
8
10
|
|
@@ -45,6 +47,7 @@ module WhirledPeas
|
|
45
47
|
child = TextPainter.new(name, child_settings)
|
46
48
|
# TextPainters are not composable, so yield nil
|
47
49
|
content = yield nil, child_settings
|
50
|
+
child_settings.validate!
|
48
51
|
unless self.class.stringable?(content)
|
49
52
|
raise ArgumentError, "Unsupported type for text: #{content.class}"
|
50
53
|
end
|
@@ -52,11 +55,25 @@ module WhirledPeas
|
|
52
55
|
painter.add_child(child)
|
53
56
|
end
|
54
57
|
|
58
|
+
def add_graph(name=self.class.next_name, &block)
|
59
|
+
child_settings = Settings::GraphSettings.inherit(painter.settings)
|
60
|
+
child = GraphPainter.new(name, child_settings)
|
61
|
+
# GraphPainters are not composable, so yield nil
|
62
|
+
content = yield nil, child_settings
|
63
|
+
child_settings.validate!
|
64
|
+
unless content.is_a?(Array) && content.length > 0
|
65
|
+
raise ArgumentError, 'Graphs require a non-empty array as the content'
|
66
|
+
end
|
67
|
+
child.content = content
|
68
|
+
painter.add_child(child)
|
69
|
+
end
|
70
|
+
|
55
71
|
def add_box(name=self.class.next_name, &block)
|
56
72
|
child_settings = Settings::BoxSettings.inherit(painter.settings)
|
57
73
|
child = BoxPainter.new(name, child_settings)
|
58
74
|
composer = self.class.new(child)
|
59
75
|
value = yield composer, child.settings
|
76
|
+
child_settings.validate!
|
60
77
|
painter.add_child(child)
|
61
78
|
if !child.children? && self.class.stringable?(value)
|
62
79
|
composer.add_text("#{name}-Text") { value.to_s }
|
@@ -68,6 +85,7 @@ module WhirledPeas
|
|
68
85
|
child = GridPainter.new(name, child_settings)
|
69
86
|
composer = self.class.new(child)
|
70
87
|
values = yield composer, child.settings
|
88
|
+
child_settings.validate!
|
71
89
|
painter.add_child(child)
|
72
90
|
if !child.children? && values.is_a?(Array)
|
73
91
|
values.each.with_index do |value, index|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Graphics
|
3
|
+
class ContentDimensions
|
4
|
+
attr_reader :outer_width, :outer_height
|
5
|
+
|
6
|
+
def initialize(settings, content)
|
7
|
+
if settings.width
|
8
|
+
@outer_width = settings.width
|
9
|
+
else
|
10
|
+
@outer_width = 0
|
11
|
+
content.each do |line|
|
12
|
+
@outer_width = line.length if line.length > @outer_width
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@outer_height = settings.height || content.length
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'painter'
|
2
|
+
|
3
|
+
module WhirledPeas
|
4
|
+
module Graphics
|
5
|
+
class ContentPainter < Painter
|
6
|
+
attr_accessor :content
|
7
|
+
|
8
|
+
def dimensions
|
9
|
+
ContentDimensions.new(settings, content_lines)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def content_lines
|
15
|
+
raise NotImplementedError, "#{self.class} must implement #content_lines"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
private_constant :ContentPainter
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'whirled_peas/utils/ansi'
|
2
|
+
|
3
|
+
require_relative 'content_painter'
|
4
|
+
|
5
|
+
module WhirledPeas
|
6
|
+
module Graphics
|
7
|
+
class GraphPainter < ContentPainter
|
8
|
+
def paint(canvas, left, top, &block)
|
9
|
+
axis_formatting = [*settings.axis_color, *settings.bg_color]
|
10
|
+
plot_formatting = [*settings.color, *settings.bg_color]
|
11
|
+
axes_lines.each.with_index do |axis_line, row_index|
|
12
|
+
canvas.stroke(left, top + row_index, axis_line, axis_formatting, &block)
|
13
|
+
next if row_index >= plot_lines.length
|
14
|
+
canvas.stroke(left + 1, top + row_index, plot_lines[row_index], plot_formatting, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def content_lines
|
21
|
+
axes_lines
|
22
|
+
end
|
23
|
+
|
24
|
+
def plot_lines
|
25
|
+
return @plot_lines if @plot_lines
|
26
|
+
min_y = 1.0 / 0
|
27
|
+
max_y = -1.0 / 0
|
28
|
+
if settings.width
|
29
|
+
interpolated = inner_width.times.map do |i|
|
30
|
+
x = (i * (content.length - 1).to_f / inner_width).floor
|
31
|
+
max_y = content[x] if content[x] > max_y
|
32
|
+
min_y = content[x] if content[x] < min_y
|
33
|
+
content[x]
|
34
|
+
end
|
35
|
+
else
|
36
|
+
interpolated = content
|
37
|
+
content.each do |y|
|
38
|
+
max_y = y if y > max_y
|
39
|
+
min_y = y if y < min_y
|
40
|
+
end
|
41
|
+
end
|
42
|
+
scaled = interpolated.map do |y|
|
43
|
+
(2 * inner_height * (y - min_y).to_f / (max_y - min_y)).floor
|
44
|
+
end
|
45
|
+
@plot_lines = Array.new(inner_height) { '' }
|
46
|
+
scaled.each.with_index do |y, x_index|
|
47
|
+
@plot_lines.each.with_index do |row, row_index|
|
48
|
+
y_index = inner_height - row_index - 1
|
49
|
+
asc, next_y = if scaled.length == 1
|
50
|
+
[true, y]
|
51
|
+
elsif x_index == scaled.length - 1
|
52
|
+
y >= scaled[x_index - 1]
|
53
|
+
[true, y]
|
54
|
+
else
|
55
|
+
scaled[x_index + 1] >= y
|
56
|
+
[true, scaled[x_index + 1]]
|
57
|
+
end
|
58
|
+
if asc
|
59
|
+
top_half = (y...next_y).include?(2 * y_index + 1)
|
60
|
+
bottom_half = (y...next_y).include?(2 * y_index)
|
61
|
+
else
|
62
|
+
top_half = (next_y...y).include?(2 * y_index + 1)
|
63
|
+
bottom_half = (next_y...y).include?(2 * y_index)
|
64
|
+
end
|
65
|
+
row << if top_half && bottom_half
|
66
|
+
'█'
|
67
|
+
elsif top_half
|
68
|
+
'▀'
|
69
|
+
elsif bottom_half
|
70
|
+
'▄'
|
71
|
+
else
|
72
|
+
' '
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@plot_lines
|
77
|
+
end
|
78
|
+
|
79
|
+
def inner_height
|
80
|
+
settings.height - 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def inner_width
|
84
|
+
settings.width.nil? ? content.length : settings.width - 1
|
85
|
+
end
|
86
|
+
|
87
|
+
def axes_lines
|
88
|
+
return @axes_lines if @axes_lines
|
89
|
+
@axes_lines = inner_height.times.map { '┃' }
|
90
|
+
@axes_lines << '┗' + '━' * inner_width
|
91
|
+
@axes_lines
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -28,9 +28,6 @@ module WhirledPeas
|
|
28
28
|
|
29
29
|
def dimensions
|
30
30
|
@dimensions ||= begin
|
31
|
-
if settings.num_cols.nil? || settings.num_cols == 0
|
32
|
-
raise SettingsError, "`num_cols` must be set for GridSettings(#{name})"
|
33
|
-
end
|
34
31
|
num_cols = settings.num_cols
|
35
32
|
num_rows = (num_children.to_f / num_cols).ceil
|
36
33
|
content_width = 0
|
@@ -1,14 +1,12 @@
|
|
1
1
|
require 'whirled_peas/utils/formatted_string'
|
2
2
|
require 'whirled_peas/utils/title_font'
|
3
3
|
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
4
|
+
require_relative 'content_dimensions'
|
5
|
+
require_relative 'content_painter'
|
6
6
|
|
7
7
|
module WhirledPeas
|
8
8
|
module Graphics
|
9
|
-
class TextPainter <
|
10
|
-
attr_reader :content
|
11
|
-
|
9
|
+
class TextPainter < ContentPainter
|
12
10
|
def paint(canvas, left, top, &block)
|
13
11
|
return unless canvas.writable?
|
14
12
|
formatting = [*settings.color, *settings.bg_color]
|
@@ -16,17 +14,15 @@ module WhirledPeas
|
|
16
14
|
if settings.underline? && settings.title_font.nil?
|
17
15
|
formatting << Utils::Ansi::UNDERLINE
|
18
16
|
end
|
19
|
-
|
17
|
+
content_lines.each.with_index do |line, index|
|
20
18
|
canvas.stroke(left, top + index, line, formatting, &block)
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
|
-
|
25
|
-
TextDimensions.new(content)
|
26
|
-
end
|
22
|
+
private
|
27
23
|
|
28
|
-
def
|
29
|
-
@
|
24
|
+
def content_lines
|
25
|
+
@content_lines = if settings.title_font
|
30
26
|
Utils::TitleFont.to_s(
|
31
27
|
content, settings.title_font
|
32
28
|
).split("\n")
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'text_color'
|
2
|
+
require_relative 'element_settings'
|
3
|
+
|
4
|
+
module WhirledPeas
|
5
|
+
module Settings
|
6
|
+
class GraphSettings < ElementSettings
|
7
|
+
def axis_color
|
8
|
+
@_axis_color || color
|
9
|
+
end
|
10
|
+
|
11
|
+
def axis_color=(color)
|
12
|
+
@_axis_color = TextColor.validate!(color)
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate!
|
16
|
+
super
|
17
|
+
raise SettingsError, "`height` must be set for GraphSettings" if height.nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -7,6 +7,13 @@ module WhirledPeas
|
|
7
7
|
class GridSettings < ContainerSettings
|
8
8
|
attr_accessor :num_cols
|
9
9
|
|
10
|
+
def validate!
|
11
|
+
super
|
12
|
+
if num_cols.nil? || num_cols <= 0
|
13
|
+
raise SettingsError, "`num_cols` must be set to a positive number for GridSettings"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
10
17
|
def set_scrollbar(*)
|
11
18
|
raise NotImplementedError, 'Grids do not support scrollbars'
|
12
19
|
end
|
@@ -28,7 +28,7 @@ module WhirledPeas
|
|
28
28
|
BRIGHT_OFFSET = 60
|
29
29
|
|
30
30
|
class << self
|
31
|
-
def with_screen(output, width: nil, height: nil, &block)
|
31
|
+
def with_screen(output=STDOUT, width: nil, height: nil, &block)
|
32
32
|
require 'highline'
|
33
33
|
unless width && height
|
34
34
|
width, height = HighLine.new.terminal.terminal_size
|
data/lib/whirled_peas/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
[?25l[1;1H[J[1;1H┃[1;2H █ [2;1H┃[2;2H █ [3;1H┃[3;2H ▄▀ [4;1H┃[4;2H █ [5;1H┃[5;2H ▄▀ [6;1H┃[6;2H █ [7;1H┃[7;2H ▄▀ [8;1H┃[8;2H █ [9;1H┃[9;2H █ [10;1H┃[10;2H █ [11;1H┃[11;2H ▄▀ [12;1H┗━━━━━━━━━━[0m[24;1H[?25h
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whirled_peas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Collier
|
@@ -70,9 +70,11 @@ files:
|
|
70
70
|
- README.md
|
71
71
|
- Rakefile
|
72
72
|
- bin/console
|
73
|
+
- bin/easing
|
73
74
|
- bin/reset_cursor
|
74
75
|
- bin/screen_test
|
75
76
|
- bin/setup
|
77
|
+
- examples/graph.rb
|
76
78
|
- examples/intro.rb
|
77
79
|
- examples/scrolling.rb
|
78
80
|
- exe/whirled_peas
|
@@ -109,12 +111,15 @@ files:
|
|
109
111
|
- lib/whirled_peas/graphics/container_coords.rb
|
110
112
|
- lib/whirled_peas/graphics/container_dimensions.rb
|
111
113
|
- lib/whirled_peas/graphics/container_painter.rb
|
114
|
+
- lib/whirled_peas/graphics/content_dimensions.rb
|
115
|
+
- lib/whirled_peas/graphics/content_painter.rb
|
112
116
|
- lib/whirled_peas/graphics/debugger.rb
|
117
|
+
- lib/whirled_peas/graphics/graph_dimensions.rb
|
118
|
+
- lib/whirled_peas/graphics/graph_painter.rb
|
113
119
|
- lib/whirled_peas/graphics/grid_painter.rb
|
114
120
|
- lib/whirled_peas/graphics/mock_screen.rb
|
115
121
|
- lib/whirled_peas/graphics/painter.rb
|
116
122
|
- lib/whirled_peas/graphics/renderer.rb
|
117
|
-
- lib/whirled_peas/graphics/text_dimensions.rb
|
118
123
|
- lib/whirled_peas/graphics/text_painter.rb
|
119
124
|
- lib/whirled_peas/null_logger.rb
|
120
125
|
- lib/whirled_peas/settings.rb
|
@@ -127,6 +132,7 @@ files:
|
|
127
132
|
- lib/whirled_peas/settings/debugger.rb
|
128
133
|
- lib/whirled_peas/settings/display_flow.rb
|
129
134
|
- lib/whirled_peas/settings/element_settings.rb
|
135
|
+
- lib/whirled_peas/settings/graph_settings.rb
|
130
136
|
- lib/whirled_peas/settings/grid_settings.rb
|
131
137
|
- lib/whirled_peas/settings/margin.rb
|
132
138
|
- lib/whirled_peas/settings/padding.rb
|
@@ -145,6 +151,8 @@ files:
|
|
145
151
|
- lib/whirled_peas/version.rb
|
146
152
|
- screen_test/elements/box.frame
|
147
153
|
- screen_test/elements/box.rb
|
154
|
+
- screen_test/elements/graph.frame
|
155
|
+
- screen_test/elements/graph.rb
|
148
156
|
- screen_test/elements/grid.frame
|
149
157
|
- screen_test/elements/grid.rb
|
150
158
|
- screen_test/elements/screen_overflow_x.frame
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module WhirledPeas
|
2
|
-
module Graphics
|
3
|
-
class TextDimensions
|
4
|
-
attr_reader :outer_width, :outer_height
|
5
|
-
|
6
|
-
def initialize(content)
|
7
|
-
@outer_width = 0
|
8
|
-
content.each do |line|
|
9
|
-
@outer_width = line.length if line.length > @outer_width
|
10
|
-
end
|
11
|
-
@outer_height = content.length
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|