whirled_peas 0.7.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +25 -0
- data/README.md +467 -120
- data/Rakefile +1 -20
- data/bin/easing +33 -0
- data/bin/reset_cursor +11 -0
- data/bin/screen_test +68 -0
- data/examples/graph.rb +54 -0
- data/examples/intro.rb +3 -3
- data/examples/scrolling.rb +5 -4
- data/lib/data/themes.yaml +13 -0
- data/lib/whirled_peas.rb +12 -6
- 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 +43 -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 +111 -0
- data/lib/whirled_peas/command/record.rb +57 -0
- data/lib/whirled_peas/command/still.rb +29 -0
- data/lib/whirled_peas/command/themes.rb +76 -0
- data/lib/whirled_peas/command_line.rb +24 -212
- 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/graphics/composer.rb +23 -2
- data/lib/whirled_peas/graphics/container_painter.rb +91 -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 +97 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +1 -4
- data/lib/whirled_peas/graphics/painter.rb +10 -0
- data/lib/whirled_peas/graphics/renderer.rb +8 -2
- data/lib/whirled_peas/graphics/text_painter.rb +7 -11
- data/lib/whirled_peas/settings/border.rb +25 -4
- data/lib/whirled_peas/settings/container_settings.rb +2 -4
- data/lib/whirled_peas/settings/element_settings.rb +12 -3
- data/lib/whirled_peas/settings/graph_settings.rb +21 -0
- data/lib/whirled_peas/settings/grid_settings.rb +7 -0
- data/lib/whirled_peas/settings/text_settings.rb +1 -0
- data/lib/whirled_peas/settings/theme.rb +40 -0
- data/lib/whirled_peas/settings/theme_library.rb +63 -0
- data/lib/whirled_peas/utils/ansi.rb +13 -0
- data/lib/whirled_peas/utils/file_handler.rb +57 -0
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/elements/box.frame +1 -1
- data/screen_test/elements/box.rb +1 -1
- data/screen_test/elements/graph.frame +1 -0
- data/screen_test/elements/graph.rb +12 -0
- data/screen_test/elements/grid.frame +1 -1
- data/screen_test/elements/grid.rb +1 -1
- data/screen_test/elements/screen_overflow_x.frame +1 -1
- data/screen_test/elements/screen_overflow_x.rb +1 -1
- data/screen_test/elements/screen_overflow_y.frame +1 -1
- data/screen_test/elements/screen_overflow_y.rb +1 -1
- data/screen_test/elements/text.frame +1 -1
- data/screen_test/elements/text.rb +1 -1
- data/screen_test/elements/text_multiline.frame +1 -1
- data/screen_test/elements/text_multiline.rb +1 -1
- data/screen_test/elements/theme.frame +1 -0
- data/screen_test/elements/theme.rb +26 -0
- data/screen_test/settings/align/box_around.frame +1 -1
- data/screen_test/settings/align/box_around.rb +1 -1
- data/screen_test/settings/align/box_between.frame +1 -1
- data/screen_test/settings/align/box_between.rb +1 -1
- data/screen_test/settings/align/box_center.frame +1 -1
- data/screen_test/settings/align/box_center.rb +1 -1
- data/screen_test/settings/align/box_default.frame +1 -1
- data/screen_test/settings/align/box_default.rb +1 -1
- data/screen_test/settings/align/box_evenly.frame +1 -1
- data/screen_test/settings/align/box_evenly.rb +1 -1
- data/screen_test/settings/align/box_left.frame +1 -1
- data/screen_test/settings/align/box_left.rb +1 -1
- data/screen_test/settings/align/box_right.frame +1 -1
- data/screen_test/settings/align/box_right.rb +1 -1
- data/screen_test/settings/align/children_center.frame +1 -1
- data/screen_test/settings/align/children_center.rb +1 -1
- data/screen_test/settings/align/children_left.frame +1 -1
- data/screen_test/settings/align/children_left.rb +1 -1
- data/screen_test/settings/align/children_right.frame +1 -1
- data/screen_test/settings/align/children_right.rb +1 -1
- data/screen_test/settings/align/grid_center.frame +1 -1
- data/screen_test/settings/align/grid_center.rb +1 -1
- data/screen_test/settings/align/grid_default.frame +1 -1
- data/screen_test/settings/align/grid_default.rb +1 -1
- data/screen_test/settings/align/grid_left.frame +1 -1
- data/screen_test/settings/align/grid_left.rb +1 -1
- data/screen_test/settings/align/grid_right.frame +1 -1
- data/screen_test/settings/align/grid_right.rb +1 -1
- data/screen_test/settings/ansi/bold.frame +1 -1
- data/screen_test/settings/ansi/bold.rb +1 -1
- data/screen_test/settings/ansi/color.frame +1 -1
- data/screen_test/settings/ansi/color.rb +1 -1
- data/screen_test/settings/ansi/underline.frame +1 -1
- data/screen_test/settings/ansi/underline.rb +1 -1
- data/screen_test/settings/border.frame +1 -1
- data/screen_test/settings/border.rb +1 -1
- data/screen_test/settings/flow/box_b2t.frame +1 -1
- data/screen_test/settings/flow/box_b2t.rb +1 -1
- data/screen_test/settings/flow/box_l2r.frame +1 -1
- data/screen_test/settings/flow/box_l2r.rb +1 -1
- data/screen_test/settings/flow/box_r2l.frame +1 -1
- data/screen_test/settings/flow/box_r2l.rb +1 -1
- data/screen_test/settings/flow/box_t2b.frame +1 -1
- data/screen_test/settings/flow/box_t2b.rb +1 -1
- data/screen_test/settings/flow/grid_b2t.frame +1 -1
- data/screen_test/settings/flow/grid_b2t.rb +2 -2
- data/screen_test/settings/flow/grid_l2r.frame +1 -1
- data/screen_test/settings/flow/grid_l2r.rb +2 -2
- data/screen_test/settings/flow/grid_r2l.frame +1 -1
- data/screen_test/settings/flow/grid_r2l.rb +2 -2
- data/screen_test/settings/flow/grid_t2b.frame +1 -1
- data/screen_test/settings/flow/grid_t2b.rb +2 -2
- data/screen_test/settings/height/box.frame +1 -1
- data/screen_test/settings/height/box.rb +1 -1
- data/screen_test/settings/height/box_border_sizing.frame +1 -1
- data/screen_test/settings/height/box_border_sizing.rb +1 -1
- data/screen_test/settings/height/grid.frame +1 -1
- data/screen_test/settings/height/grid.rb +1 -1
- data/screen_test/settings/height/overflow_box.frame +1 -1
- data/screen_test/settings/height/overflow_box.rb +1 -1
- data/screen_test/settings/height/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/height/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/height/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/height/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/height/overflow_grid.frame +1 -1
- data/screen_test/settings/height/overflow_grid.rb +1 -1
- data/screen_test/settings/margin.frame +1 -1
- data/screen_test/settings/margin.rb +1 -1
- data/screen_test/settings/padding.frame +1 -1
- data/screen_test/settings/padding.rb +1 -1
- data/screen_test/settings/position/box_left.frame +1 -1
- data/screen_test/settings/position/box_left.rb +1 -1
- data/screen_test/settings/position/box_left_negative.frame +1 -1
- data/screen_test/settings/position/box_left_negative.rb +1 -1
- data/screen_test/settings/position/box_top.frame +1 -1
- data/screen_test/settings/position/box_top.rb +1 -1
- data/screen_test/settings/position/box_top_negative.frame +1 -1
- data/screen_test/settings/position/box_top_negative.rb +1 -1
- data/screen_test/settings/position/grid_left.frame +1 -1
- data/screen_test/settings/position/grid_left.rb +1 -1
- data/screen_test/settings/position/grid_left_negative.frame +1 -1
- data/screen_test/settings/position/grid_left_negative.rb +1 -1
- data/screen_test/settings/position/grid_top.frame +1 -1
- data/screen_test/settings/position/grid_top.rb +1 -1
- data/screen_test/settings/position/grid_top_negative.frame +1 -1
- data/screen_test/settings/position/grid_top_negative.rb +1 -1
- data/screen_test/settings/scroll/horiz_box.frame +1 -1
- data/screen_test/settings/scroll/horiz_box.rb +1 -1
- data/screen_test/settings/scroll/horiz_box_align_center.rb +1 -1
- data/screen_test/settings/scroll/horiz_box_align_right.rb +1 -1
- data/screen_test/settings/scroll/vert_box.frame +1 -1
- data/screen_test/settings/scroll/vert_box.rb +1 -1
- data/screen_test/settings/title_font.frame +1 -1
- data/screen_test/settings/title_font.rb +1 -1
- data/screen_test/settings/valign/box_around.frame +1 -1
- data/screen_test/settings/valign/box_around.rb +1 -1
- data/screen_test/settings/valign/box_between.frame +1 -1
- data/screen_test/settings/valign/box_between.rb +1 -1
- data/screen_test/settings/valign/box_bottom.frame +1 -1
- data/screen_test/settings/valign/box_bottom.rb +1 -1
- data/screen_test/settings/valign/box_default.frame +1 -1
- data/screen_test/settings/valign/box_default.rb +1 -1
- data/screen_test/settings/valign/box_evenly.frame +1 -1
- data/screen_test/settings/valign/box_evenly.rb +1 -1
- data/screen_test/settings/valign/box_middle.frame +1 -1
- data/screen_test/settings/valign/box_middle.rb +1 -1
- data/screen_test/settings/valign/box_top.frame +1 -1
- data/screen_test/settings/valign/box_top.rb +1 -1
- data/screen_test/settings/valign/grid_bottom.frame +1 -1
- data/screen_test/settings/valign/grid_bottom.rb +1 -1
- data/screen_test/settings/valign/grid_default.frame +1 -1
- data/screen_test/settings/valign/grid_default.rb +1 -1
- data/screen_test/settings/valign/grid_middle.frame +1 -1
- data/screen_test/settings/valign/grid_middle.rb +1 -1
- data/screen_test/settings/valign/grid_top.frame +1 -1
- data/screen_test/settings/valign/grid_top.rb +1 -1
- data/screen_test/settings/width/box_border_sizing.frame +1 -1
- data/screen_test/settings/width/box_border_sizing.rb +1 -1
- data/screen_test/settings/width/box_content.frame +1 -1
- data/screen_test/settings/width/box_content.rb +1 -1
- data/screen_test/settings/width/box_default.frame +1 -1
- data/screen_test/settings/width/box_default.rb +1 -1
- data/screen_test/settings/width/grid.frame +1 -1
- data/screen_test/settings/width/grid.rb +1 -1
- data/screen_test/settings/width/overflow_align_center.frame +1 -1
- data/screen_test/settings/width/overflow_align_center.rb +1 -1
- data/screen_test/settings/width/overflow_align_right.frame +1 -1
- data/screen_test/settings/width/overflow_align_right.rb +1 -1
- data/screen_test/settings/width/overflow_box.frame +1 -1
- data/screen_test/settings/width/overflow_box.rb +1 -1
- data/screen_test/settings/width/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/width/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/width/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/width/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/width/overflow_grid.frame +1 -1
- data/screen_test/settings/width/overflow_grid.rb +1 -1
- data/tools/whirled_peas/tools/screen_tester.rb +131 -65
- metadata +42 -9
- data/lib/whirled_peas/frame.rb +0 -6
- data/lib/whirled_peas/frame/consumer.rb +0 -30
- data/lib/whirled_peas/frame/debug_consumer.rb +0 -30
- data/lib/whirled_peas/frame/event_loop.rb +0 -90
- data/lib/whirled_peas/frame/producer.rb +0 -67
- data/lib/whirled_peas/graphics/screen.rb +0 -70
- data/lib/whirled_peas/graphics/text_dimensions.rb +0 -15
data/Rakefile
CHANGED
@@ -3,29 +3,10 @@ require 'rspec/core/rake_task'
|
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
def screen_test(file, method)
|
7
|
-
raise ArgumentError, 'Missing argument: file' unless file
|
8
|
-
require_relative 'tools/whirled_peas/tools/screen_tester'
|
9
|
-
WhirledPeas::Tools::ScreenTester.new(file).send(method)
|
10
|
-
end
|
11
|
-
|
12
|
-
namespace :screen_test do
|
13
|
-
%i[template view run save update debug].each do |t|
|
14
|
-
task t, [:file] do |_, args|
|
15
|
-
screen_test(args[:file], t)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
task :update_all do
|
20
|
-
require_relative 'tools/whirled_peas/tools/screen_tester'
|
21
|
-
WhirledPeas::Tools::ScreenTester.update_all
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
6
|
task :screen_test do
|
26
7
|
require_relative 'tools/whirled_peas/tools/screen_tester'
|
27
8
|
WhirledPeas::Tools::ScreenTester.run_all
|
28
9
|
end
|
29
10
|
|
30
|
-
task default: :ci
|
31
11
|
task ci: %i[spec screen_test]
|
12
|
+
task default: :ci
|
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/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/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/intro.rb
CHANGED
@@ -40,13 +40,13 @@ class TemplateFactory
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
class
|
43
|
+
class Application
|
44
44
|
def start(producer)
|
45
|
-
producer.
|
45
|
+
producer.add_frame('intro', duration: 5)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
WhirledPeas.configure do |config|
|
50
50
|
config.template_factory = TemplateFactory.new
|
51
|
-
config.
|
51
|
+
config.application = Application.new
|
52
52
|
end
|
data/examples/scrolling.rb
CHANGED
@@ -39,15 +39,16 @@ class TemplateFactory
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
class
|
42
|
+
class Application
|
43
43
|
def start(producer)
|
44
|
-
|
45
|
-
|
44
|
+
producer.frameset(5, easing: :bezier) do |fs|
|
45
|
+
53.times { |i| fs.add_frame('intro', args: { top: -i }) }
|
46
46
|
end
|
47
|
+
producer.add_frame('hold', duration: 1, args: { top: -52})
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
51
|
WhirledPeas.configure do |config|
|
51
52
|
config.template_factory = TemplateFactory.new
|
52
|
-
config.
|
53
|
+
config.application = Application.new
|
53
54
|
end
|
data/lib/whirled_peas.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'whirled_peas/errors'
|
1
|
+
require 'whirled_peas/animator'
|
4
2
|
require 'whirled_peas/config'
|
5
|
-
require 'whirled_peas/
|
3
|
+
require 'whirled_peas/errors'
|
6
4
|
require 'whirled_peas/graphics'
|
7
5
|
require 'whirled_peas/settings'
|
8
6
|
require 'whirled_peas/utils'
|
@@ -17,8 +15,16 @@ module WhirledPeas
|
|
17
15
|
yield config
|
18
16
|
end
|
19
17
|
|
20
|
-
def self.template(&block)
|
18
|
+
def self.template(theme_name=nil, &block)
|
21
19
|
require 'whirled_peas/graphics/composer'
|
22
|
-
Graphics::Composer.build(&block)
|
20
|
+
Graphics::Composer.build(theme_name, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.define_theme(name, &block)
|
24
|
+
require 'whirled_peas/settings/theme'
|
25
|
+
require 'whirled_peas/settings/theme_library'
|
26
|
+
theme = Settings::Theme.new
|
27
|
+
yield theme
|
28
|
+
Settings::ThemeLibrary.add(name, theme)
|
23
29
|
end
|
24
30
|
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: 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
|