summaryrefslogtreecommitdiff
path: root/presentty/transition.py
diff options
context:
space:
mode:
Diffstat (limited to 'presentty/transition.py')
-rw-r--r--presentty/transition.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/presentty/transition.py b/presentty/transition.py
new file mode 100644
index 0000000..9133629
--- /dev/null
+++ b/presentty/transition.py
@@ -0,0 +1,153 @@
1# Copyright (C) 2015 James E. Blair <corvus@gnu.org>
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 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16import urwid
17
18class Transition(urwid.Widget):
19 def __init__(self, duration=0.4):
20 super(Transition, self).__init__()
21 self.duration = 0.4
22 self.old = None
23 self.new = None
24 self.progress = 0.0
25
26 def getDuration(self):
27 return self.duration
28
29 def setTargets(self, old, new):
30 self.old = old
31 self.new = new
32 self.setProgress(0.0)
33
34 def setProgress(self, progress):
35 self.progress = progress
36 self._invalidate()
37
38class PanTransition(Transition):
39 def render(self, size, focus=False):
40 old = self.old.render((size[0], size[1]))
41 new = self.new.render((size[0], size[1]))
42 c = urwid.CanvasJoin([(old, None, False, size[0]),
43 (new, None, False, size[0])])
44 #c = urwid.CanvasOverlay(new, old, 6, 0)
45 offset = int(size[0] * self.progress)
46 c.pad_trim_left_right(0-offset, 0-(size[0]-offset))
47 return c
48
49class DissolveTransition(Transition):
50 def __init__(self, *args, **kw):
51 super(DissolveTransition, self).__init__(*args, **kw)
52 self._oldbuf = None
53 self._newbuf = None
54 self._cache_size = None
55
56 def setTargets(self, old, new):
57 if old != self.old:
58 self._oldbuf = None
59 self._cache_size = None
60 if new != self.new:
61 self._newbuf = None
62 self._cache_size = None
63 super(DissolveTransition, self).setTargets(old, new)
64
65 def _to_buf(self, canvas):
66 buf = []
67 for line in canvas.content():
68 for (attr, cs, text) in line:
69 for char in unicode(text, 'utf8'):
70 buf.append((attr, cs, char))
71 return buf
72
73 def render(self, size, focus=False):
74 if self._cache_size != size:
75 old = self.old.render((size[0], size[1]))
76 new = self.new.render((size[0], size[1]))
77 self._oldbuf = self._to_buf(old)
78 self._newbuf = self._to_buf(new)
79 self._cache_size = size
80 line_list = []
81 attr_list = []
82 line_text = ''
83 line_attrs = []
84 current_attr = [None, 0]
85 current_rgb = None
86 current_props = None
87 background = urwid.AttrSpec('light gray', 'black')
88 for i in range(len(self._oldbuf)):
89 oldattr, oldcs, oldchar = self._oldbuf[i]
90 newattr, newcs, newchar = self._newbuf[i]
91 oldrgb = oldattr.get_rgb_values()
92 newrgb = newattr.get_rgb_values()
93 if None in oldrgb:
94 oldrgb = background.get_rgb_values()
95 if None in newrgb:
96 newrgb = background.get_rgb_values()
97 if newchar == ' ':
98 char = oldchar
99 charattr = oldattr
100 newrgb = newrgb[3:]*2
101 elif oldchar == ' ':
102 char = newchar
103 charattr = newattr
104 oldrgb = oldrgb[3:]*2
105 elif self.progress >= 0.5:
106 char = newchar
107 charattr = newattr
108 else:
109 char = oldchar
110 charattr = oldattr
111 char = char.encode('utf8')
112 line_text += char
113 rgb = []
114 props = []
115 if charattr.bold:
116 props.append('bold')
117 if charattr.underline:
118 props.append('underline')
119 if charattr.standout:
120 props.append('standout')
121 if charattr.blink:
122 props.append('blink')
123 for x in range(len(oldrgb)):
124 rgb.append(int(((newrgb[x]-oldrgb[x])*self.progress)+oldrgb[x])>>4)
125 if current_rgb == rgb and current_props == props:
126 current_attr[1] += len(char)
127 else:
128 if current_attr[0]:
129 line_attrs.append(tuple(current_attr))
130 fg = ', '.join(props + ['#%x%x%x' % tuple(rgb[:3])])
131 bg = '#%x%x%x' % tuple(rgb[3:])
132 attr = urwid.AttrSpec(fg, bg)
133 current_attr = [attr, len(char)]
134 current_rgb = rgb
135 current_props = props
136 if (i+1) % size[0] == 0:
137 line_attrs.append(tuple(current_attr))
138 current_attr = [None, 0]
139 current_rgb = None
140 line_list.append(line_text)
141 line_text = ''
142 attr_list.append(line_attrs)
143 line_attrs = []
144 canvas = urwid.TextCanvas(line_list, attr_list)
145 return canvas
146
147class CutTransition(Transition):
148 def __init__(self, *args, **kw):
149 super(CutTransition, self).__init__(*args, **kw)
150 self.duration = 0.0
151
152 def render(self, size, focus=False):
153 return self.new.render(size, focus)