whirled_peas 0.4.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
data/Rakefile
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
task :
|
6
|
+
task :screen_test do
|
7
|
+
require_relative 'tools/whirled_peas/tools/screen_tester'
|
8
|
+
WhirledPeas::Tools::ScreenTester.run_all
|
9
|
+
end
|
10
|
+
|
11
|
+
task ci: %i[spec screen_test]
|
12
|
+
task default: :ci
|
data/bin/reset_cursor
ADDED
data/bin/screen_test
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'whirled_peas'
|
5
|
+
require 'whirled_peas/utils/formatted_string'
|
6
|
+
|
7
|
+
require_relative '../tools/whirled_peas/tools/screen_tester'
|
8
|
+
|
9
|
+
def print_usage(exit_code=0)
|
10
|
+
puts "Usage: #{$0} [file] [options]"
|
11
|
+
puts
|
12
|
+
puts 'If not file or options are provide, all tests are run'
|
13
|
+
puts
|
14
|
+
puts 'If no file is provided, the supported options are'
|
15
|
+
puts ' --help print this usage statement and exit'
|
16
|
+
puts ' --view-pending interactively display and optionally save rendered output for each pending test'
|
17
|
+
puts ' --view-failed interactively display and optionally save rendered output for each faiing test'
|
18
|
+
puts
|
19
|
+
puts 'If a screen test file is provided as the first argument, the supported options are'
|
20
|
+
puts ' --run run screen test for given file'
|
21
|
+
puts ' --view interactively display and optionally save the file\'s test output'
|
22
|
+
puts ' --template print out template tree for the test template'
|
23
|
+
puts ' --debug render the test template without displying it, printing out debug information'
|
24
|
+
exit(exit_code)
|
25
|
+
end
|
26
|
+
|
27
|
+
module WhirledPeas
|
28
|
+
if ARGV.length == 0
|
29
|
+
Tools::ScreenTester.run_all
|
30
|
+
elsif ARGV.length == 1
|
31
|
+
option = ARGV[0]
|
32
|
+
case option
|
33
|
+
when '--help'
|
34
|
+
print_usage
|
35
|
+
when '--view-pending'
|
36
|
+
Tools::ScreenTester.view_pending
|
37
|
+
when '--view-failed'
|
38
|
+
Tools::ScreenTester.view_failed
|
39
|
+
else
|
40
|
+
print_usage(1)
|
41
|
+
end
|
42
|
+
elsif ARGV.length == 2
|
43
|
+
file, option = ARGV
|
44
|
+
case option
|
45
|
+
when '--run'
|
46
|
+
tester = Tools::ScreenTester.new(file)
|
47
|
+
if tester.pending?
|
48
|
+
puts Utils::FormattedString.new('Pending', Settings::TextColor::YELLOW)
|
49
|
+
puts "Run `#{$0} #{file} --view` to view and optionally save ouput."
|
50
|
+
elsif tester.failed?
|
51
|
+
puts Utils::FormattedString.new('Failed', Settings::TextColor::RED)
|
52
|
+
puts "Run `#{$0} #{file} --view` to compare and optionally save ouput."
|
53
|
+
else
|
54
|
+
puts Utils::FormattedString.new('Pass', Settings::TextColor::GREEN)
|
55
|
+
end
|
56
|
+
when '--view'
|
57
|
+
Tools::ScreenTester.new(file).view
|
58
|
+
when '--template'
|
59
|
+
Tools::ScreenTester.new(file).template
|
60
|
+
when '--debug'
|
61
|
+
Tools::ScreenTester.new(file).debug
|
62
|
+
else
|
63
|
+
print_usage(1)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
print_usage(1)
|
67
|
+
end
|
68
|
+
end
|
data/examples/intro.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'whirled_peas'
|
3
|
+
|
4
|
+
class TemplateFactory
|
5
|
+
TITLE_FONT = :default #roman
|
6
|
+
PRIMARY_COLOR = :bright_blue
|
7
|
+
SECONDARY_COLOR = :blue
|
8
|
+
BG_COLOR = :bright_white
|
9
|
+
|
10
|
+
def build(name, args)
|
11
|
+
WhirledPeas.template do |composer, settings|
|
12
|
+
settings.set_padding(left: 10, top: 6, right: 10, bottom: 6)
|
13
|
+
settings.align = :center
|
14
|
+
settings.width = 120
|
15
|
+
settings.flow = :t2b
|
16
|
+
settings.bold = true
|
17
|
+
settings.bg_color = BG_COLOR
|
18
|
+
|
19
|
+
composer.add_box do |composer, settings|
|
20
|
+
composer.add_text do |_, settings|
|
21
|
+
settings.title_font = TITLE_FONT
|
22
|
+
settings.color = PRIMARY_COLOR
|
23
|
+
'Visualize'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
composer.add_box do |_, settings|
|
27
|
+
settings.set_margin(top: 1)
|
28
|
+
settings.color = SECONDARY_COLOR
|
29
|
+
"your code's execution with"
|
30
|
+
end
|
31
|
+
composer.add_box do |composer, settings|
|
32
|
+
settings.set_margin(top: 1)
|
33
|
+
composer.add_text do |_, settings|
|
34
|
+
settings.title_font = TITLE_FONT
|
35
|
+
settings.color = PRIMARY_COLOR
|
36
|
+
'Whirled Peas'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Application
|
44
|
+
def start(producer)
|
45
|
+
producer.add_frame('intro', duration: 5)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
WhirledPeas.configure do |config|
|
50
|
+
config.template_factory = TemplateFactory.new
|
51
|
+
config.application = Application.new
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'whirled_peas'
|
3
|
+
|
4
|
+
class TemplateFactory
|
5
|
+
HPADDING = 0
|
6
|
+
VPADDING = 0
|
7
|
+
ITEM_COUNT = 64
|
8
|
+
|
9
|
+
def build(name, args)
|
10
|
+
top = args[:top]
|
11
|
+
WhirledPeas.template do |composer, settings|
|
12
|
+
settings.color = :green
|
13
|
+
composer.add_box('Vert') do |composer, settings|
|
14
|
+
settings.bg_color = :bright_red
|
15
|
+
settings.full_border(color: :blue)
|
16
|
+
settings.set_scrollbar(vert: true)
|
17
|
+
settings.height = 12
|
18
|
+
composer.add_box('Inner') do |composer, settings|
|
19
|
+
settings.flow = :t2b
|
20
|
+
settings.set_padding(left: HPADDING, right: HPADDING, top: VPADDING, bottom: VPADDING)
|
21
|
+
settings.set_position(top: top)
|
22
|
+
ITEM_COUNT.times do |i|
|
23
|
+
composer.add_text { "%2d" % i }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
composer.add_box('Horiz') do |composer, settings|
|
28
|
+
settings.bg_color = :bright_red
|
29
|
+
settings.full_border(color: :blue)
|
30
|
+
settings.set_padding(left: HPADDING, right: HPADDING, top: VPADDING, bottom: VPADDING)
|
31
|
+
settings.set_scrollbar(horiz: true)
|
32
|
+
settings.width = 12
|
33
|
+
composer.add_box('Inner') do |composer, settings|
|
34
|
+
settings.set_position(left: top)
|
35
|
+
ITEM_COUNT.times.map { |i| (i % 10).to_s }.join
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Application
|
43
|
+
def start(producer)
|
44
|
+
producer.frameset(5, easing: :bezier) do |fs|
|
45
|
+
53.times { |i| fs.add_frame('intro', { top: -i }) }
|
46
|
+
end
|
47
|
+
producer.add_frame('hold', duration: 1, args: { top: -52})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
WhirledPeas.configure do |config|
|
52
|
+
config.template_factory = TemplateFactory.new
|
53
|
+
config.application = Application.new
|
54
|
+
end
|
data/lib/whirled_peas.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'whirled_peas/errors'
|
4
|
-
|
1
|
+
require 'whirled_peas/animator'
|
5
2
|
require 'whirled_peas/config'
|
6
|
-
require 'whirled_peas/
|
7
|
-
require 'whirled_peas/
|
8
|
-
require 'whirled_peas/
|
3
|
+
require 'whirled_peas/errors'
|
4
|
+
require 'whirled_peas/graphics'
|
5
|
+
require 'whirled_peas/settings'
|
9
6
|
require 'whirled_peas/utils'
|
10
7
|
require 'whirled_peas/version'
|
11
8
|
|
@@ -19,10 +16,7 @@ module WhirledPeas
|
|
19
16
|
end
|
20
17
|
|
21
18
|
def self.template(&block)
|
22
|
-
require 'whirled_peas/
|
23
|
-
|
24
|
-
template = UI::Template.new
|
25
|
-
yield template, template.settings
|
26
|
-
template
|
19
|
+
require 'whirled_peas/graphics/composer'
|
20
|
+
Graphics::Composer.build(&block)
|
27
21
|
end
|
28
22
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Animator
|
3
|
+
class DebugConsumer
|
4
|
+
def add_frameset(frameset)
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
frameset.each_frame do |frame, args|
|
8
|
+
puts [frame, *(JSON.generate(args) unless args.empty?)].join(' ')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def process
|
13
|
+
# no op
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Animator
|
3
|
+
class Easing
|
4
|
+
# Implementations of available ease-in functions. Ease-out and ease-in-out can all be
|
5
|
+
# derived from ease-in.
|
6
|
+
EASING = {
|
7
|
+
bezier: proc do |value|
|
8
|
+
value /= 2
|
9
|
+
2 * value * value * (3 - 2 * value)
|
10
|
+
end,
|
11
|
+
linear: proc { |value| value },
|
12
|
+
parametric: proc do |value|
|
13
|
+
value /= 2
|
14
|
+
squared = value * value
|
15
|
+
2 * squared / (2 * (squared - value) + 1)
|
16
|
+
end,
|
17
|
+
quadratic: proc do |value|
|
18
|
+
value * value
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
22
|
+
EFFECTS = %i[in out in_out]
|
23
|
+
|
24
|
+
def initialize(easing=:linear, effect=:in_out)
|
25
|
+
unless EASING.key?(easing)
|
26
|
+
raise ArgumentError,
|
27
|
+
"Invalid easing function: #{easing}, expecting one of #{EASING.keys.join(', ')}"
|
28
|
+
end
|
29
|
+
unless EFFECTS.include?(effect)
|
30
|
+
raise ArgumentError,
|
31
|
+
"Invalid effect: #{effect}, expecting one of #{EFFECTS.join(', ')}"
|
32
|
+
end
|
33
|
+
@easing = easing
|
34
|
+
@effect = effect
|
35
|
+
end
|
36
|
+
|
37
|
+
def ease(value)
|
38
|
+
case effect
|
39
|
+
when :in
|
40
|
+
ease_in(value)
|
41
|
+
when :out
|
42
|
+
ease_out(value)
|
43
|
+
else
|
44
|
+
ease_in_out(value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :easing, :effect
|
51
|
+
|
52
|
+
# The procs in EASING define the ease-in functions, so we simply need
|
53
|
+
# to invoke the function with the given normalized value
|
54
|
+
def ease_in(value)
|
55
|
+
EASING[easing].call(value)
|
56
|
+
end
|
57
|
+
|
58
|
+
# The ease-out function will be the ease-in function rotated 180 degrees.
|
59
|
+
def ease_out(value)
|
60
|
+
1 - EASING[easing].call(1 - value)
|
61
|
+
end
|
62
|
+
|
63
|
+
def ease_in_out(value)
|
64
|
+
if value < 0.5
|
65
|
+
ease_in(value * 2) / 2
|
66
|
+
else
|
67
|
+
0.5 + ease_out(2 * value - 1) / 2
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'easing'
|
2
|
+
require_relative 'frame'
|
3
|
+
|
4
|
+
module WhirledPeas
|
5
|
+
module Animator
|
6
|
+
class Frameset
|
7
|
+
def initialize(frame_slots, easing, effect)
|
8
|
+
@frame_slots = frame_slots
|
9
|
+
@easing = Easing.new(easing, effect)
|
10
|
+
@frames = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_frame(name, args={})
|
14
|
+
frames << [name, args]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Yield each frame in an "eased" order
|
18
|
+
def each_frame(&block)
|
19
|
+
frame_slots.times do |i|
|
20
|
+
input = i.to_f / (frame_slots - 1)
|
21
|
+
eased_value = @easing.ease(input)
|
22
|
+
index = (eased_value * (frames.length - 1)).floor
|
23
|
+
yield *frames[index]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :frame_slots, :easing, :frames
|
30
|
+
end
|
31
|
+
private_constant :Frameset
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'easing'
|
2
|
+
require_relative 'frameset'
|
3
|
+
|
4
|
+
module WhirledPeas
|
5
|
+
module Animator
|
6
|
+
class Producer
|
7
|
+
def self.produce(consumer, refresh_rate)
|
8
|
+
producer = new(consumer, refresh_rate)
|
9
|
+
yield producer
|
10
|
+
consumer.process
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(consumer, refresh_rate)
|
14
|
+
@consumer = consumer
|
15
|
+
@refresh_rate = refresh_rate
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_frame(name, duration: nil, args: {})
|
19
|
+
frameset(duration || 1 / refresh_rate) do |fs|
|
20
|
+
fs.add_frame(name, args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def frameset(duration, easing: :linear, effect: :in_out, &block)
|
25
|
+
fs = Frameset.new((duration * refresh_rate).round, easing, effect)
|
26
|
+
yield fs
|
27
|
+
consumer.add_frameset(fs)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :consumer, :refresh_rate
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'whirled_peas/graphics/renderer'
|
2
|
+
require 'whirled_peas/utils/ansi'
|
3
|
+
|
4
|
+
module WhirledPeas
|
5
|
+
module Animator
|
6
|
+
class RendererConsumer
|
7
|
+
def initialize(template_factory, device, width, height)
|
8
|
+
@template_factory = template_factory
|
9
|
+
@device = device
|
10
|
+
@width = width
|
11
|
+
@height = height
|
12
|
+
@renders = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_frameset(frameset)
|
16
|
+
frameset.each_frame do |frame, args|
|
17
|
+
template = template_factory.build(frame, args)
|
18
|
+
renders << Graphics::Renderer.new(template, width, height).paint
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def process
|
23
|
+
device.handle_renders(renders)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :template_factory, :device, :width, :height, :renders
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|