Update connect/disconnect action states.
[kaya.git] / lib / animations.rb
blobd9e1e76d6b1a50d461f5194503c08f5c99e796c0
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'animation_field'
9 require 'factory'
11 module Animations
12   LENGTH = 100
13   EASING = Qt::EasingCurve.new(Qt::EasingCurve::InOutCubic)
15   def group(*animations)
16     unless animations.empty?
17       anim = animations.dup.compact
18       return nil if anim.empty?
19       name = case anim.size
20       when 1
21         anim.first.name
22       else
23         "group (#{anim.map{|a| a.to_s}.join(',')})"
24       end
25       Animation.new(name) do |i|
26         anim.reject! do |a|
27           a[i]
28         end
29         anim.empty?
30       end
31     end
32   end
34   def sequence(*animations)
35     anim = animations.dup.compact
36     return nil if anim.empty?
37     name = case anim.size
38     when 1
39       anim.first.name
40     else
41       "sequence (#{anim.map{|a| a.to_s}.join(',')})"
42     end
43     Animation.new(name) do |i|
44       if anim.first[i]
45         anim.shift
46       end
47       anim.empty?
48     end
49   end
51   def movement(item, src, dst, path_factory)
52     if item
53       name = "move to #{dst}"
54       src = if src
55         board.to_real(src)
56       else
57         item.pos
58       end
60       dst = board.to_real(dst)
61       path = path_factory.new(src, dst)
63       SimpleAnimation.new name, LENGTH,
64         lambda { board.raise(item) },
65         lambda {|i| item.pos = src + path[i] },
66         lambda { item.pos = dst; board.lower(item) },
67         :easing => EASING
68     end
69   end
71   def disappear(item, name, opts = { })
72     if item
73       if opts[:instant]
74         Animation.new(name) { item.visible = false; true }
75       else
76         SimpleAnimation.new name, LENGTH,
77           lambda { item.opacity = 1.0; item.visible = true },
78           lambda {|t| item.opacity = 1.0 - t },
79           lambda { item.remove },
80           :easing => EASING
81       end
82     end
83   end
85   def appear(item, name, opts = { })
86     if opts[:instant]
87       Animation.new(name) { item.opacity = 1.0; item.visible = true; true }
88     else
89       SimpleAnimation.new name, LENGTH,
90         lambda { item.opacity = 0.0; item.visible = true },
91         lambda {|i| item.opacity = i },
92         lambda { item.opacity = 1.0 },
93         :easing => EASING
94     end
95   end
96 end
98 module Path
99   Linear = Factory.new do |src, dst|
100     delta = dst - src
101     lambda {|i| delta * i }
102   end
104   class LShape
105     FACTOR = Math.exp(3.0) - 1
106     def initialize(src, dst)
107       @delta = dst - src
108       nonlin = lambda{|i| (Math.exp(3.0 * i) - 1) / FACTOR }
109       lin = lambda {|i| i }
110       if @delta.x.abs < @delta.y.abs
111         @x = lin
112         @y = nonlin
113       else
114         @y = lin
115         @x = nonlin
116       end
117     end
118     
119     def [](i)
120       Qt::PointF.new(@delta.x * @x[i], @delta.y * @y[i])
121     end
122   end