initial import of ussd-pad
[ussd-widget] / ussd-pad / src / opt / ussd-pad / ui / Label.py
1 """
2 A text label with autoscrolling.
3 """
4
5 from Widget import Widget
6 from Pixmap import Pixmap, pixmap_for_text
7
8 import gobject
9 import pango
10 import time
11
12
13
14 class Label(Widget):
15
16     # text alignments
17     LEFT = 0
18     RIGHT = 1
19     CENTERED = 2
20
21     def __init__(self, text, font, color):
22     
23         self.__text_pmap = None
24         self.__bg = None
25         self.__is_new_text = True
26         self.__alignment = self.LEFT
27         self.__render_timer = None
28     
29         self.__text = text
30         self.__font = font
31         self.__color = color
32     
33         Widget.__init__(self)
34         self.__create_text_pmap()
35
36
37     def _reload(self):
38     
39         self.__is_new_text = True
40         self.__bg = None
41         #self.__create_text_pmap()
42
43
44     def set_size(self, w, h):
45     
46         Widget.set_size(self, w, h)
47         self.__is_new_text = True
48         self.__bg = None
49
50
51     def __create_text_pmap(self):
52     
53         if (not self.__is_new_text): return
54         
55         self.__text_pmap = pixmap_for_text(self.__text or " ", self.__font)
56
57
58     def __acquire_background(self):
59     
60         if (not self.__is_new_text): return
61     
62         x, y = self.get_screen_pos()
63         w, h = self.get_size()
64         screen = self.get_screen()
65         text_w, text_h = self.__text_pmap.get_size()
66
67         if (w <= 0): w = text_w
68         if (h <= 0): h = text_h
69         
70         self.__bg = Pixmap(None, w, text_h)
71         y += (h - text_h) / 2
72         self.__bg.copy_buffer(screen, x, y, 0, 0, w, text_h)
73
74
75     def __restore_background(self):
76     
77         if (not self.__is_new_text or not self.__bg): return
78         if (not self.may_render()): return
79         
80         x, y = self.get_screen_pos()
81         w, h = self.get_size()
82         screen = self.get_screen()
83         text_w, text_h = self.__text_pmap.get_size()
84
85         if (not w): w = text_w
86         if (not h): h = text_h
87
88         bg_w, bg_h = self.__bg.get_size()
89         y += (h - text_h) / 2
90         screen.copy_pixmap(self.__bg, 0, 0, x, y, bg_w, bg_h)
91                 
92
93     def __create_text(self):
94     
95         if (not self.__is_new_text): return
96     
97         x, y = self.get_screen_pos()
98         w, h = self.get_size()
99         screen = self.get_screen()
100         text_w, text_h = self.__text_pmap.get_size()
101
102         if (not w): w = text_w
103         if (not h): h = text_h        
104
105         if (text_w <= w):
106             if (self.__alignment == self.LEFT): text_x = 0
107             elif (self.__alignment == self.CENTERED): text_x = (w - text_w) / 2
108             else: text_x = w - text_w
109         else:
110             text_x = 0
111
112         # tile background
113         for i in range(0, text_w, w):
114             self.__text_pmap.copy_pixmap(self.__bg, 0, 0, i - text_x, 0,
115                                             w, text_h)
116         
117         # draw text
118         self.__text_pmap.draw_text(self.__text, self.__font, 0, 0, self.__color)
119
120
121     def set_alignment(self, alignment):
122     
123         self.__alignment = alignment
124
125
126     def get_physical_size(self):
127
128         w, h = self.get_size()
129         if (self.__text_pmap):
130             text_w, text_h = self.__text_pmap.get_size()    
131             if (not w): w = text_w
132             if (not h): h = text_h
133
134         return (w, h)
135         
136
137     def set_text(self, text):
138
139         if (self.__text == text): return
140
141         self.__is_new_text = True
142         self.__text = text
143
144         if (self.may_render()):
145             if (self.__render_timer):
146                 gobject.source_remove(self.__render_timer)        
147             self.__render_text(0, 1)
148
149
150     def get_text(self):
151     
152         return self.__text
153             
154
155     def render_this(self):
156
157         self.__is_new_text = True
158         self.__create_text_pmap()
159         self.__acquire_background()
160         self.__create_text()
161         self.__is_new_text = False
162
163         if (self.may_render()):
164             if (self.__render_timer):
165                 gobject.source_remove(self.__render_timer)        
166             self.__render_text(0, 1)    
167         
168         
169     def __render_text(self, pos, direction, begin_time = 0):
170
171         if (not self.may_render()): return
172
173         if (not begin_time): begin_time = time.time()
174
175         if (self.__is_new_text):
176             self.__restore_background()
177             self.__create_text_pmap()
178             self.__acquire_background()
179             self.__create_text()
180             self.__is_new_text = False
181             pos = 0
182             direction = 1
183         #end if            
184
185         text_w, text_h = self.__text_pmap.get_size()
186         x, y = self.get_screen_pos()
187         w, h = self.get_size()    
188         screen = self.get_screen()
189
190         if (not w): w = text_w
191         if (not h): h = text_h
192
193         # render currently visible text portion
194         if (text_w <= w):
195             if (self.__alignment == self.LEFT): text_x = 0
196             elif (self.__alignment == self.CENTERED): text_x = (w - text_w) / 2
197             else: text_x = w - text_w
198         else:
199             text_x = 0
200             
201         if (self.may_render()):
202             text_y = (h - text_h) / 2
203             #self.use_clipping(True)
204             screen.copy_pixmap(self.__text_pmap, pos, 0, x + text_x, y + text_y,
205                                min(text_w, w), text_h)
206             #self.use_clipping(False)
207
208         # handle scrolling
209         # (only scroll for 10 minutes, then stop to save battery)
210         if (text_w > w and self.may_render() and begin_time + 600 > time.time()):
211             if (pos == 0):
212                 direction = 1
213                 delay = 1500
214             elif (pos == text_w - w):
215                 direction = -1
216                 delay = 1500
217             else:
218                 delay = 50
219             
220             if (direction == 1):
221                 pos += 1
222             else:
223                 pos -= 1
224
225             self.__render_timer = \
226               gobject.timeout_add(delay, self.__render_text, pos, direction,
227                                   begin_time)
228             
229         else:
230             self.__render_timer = None
231         #end if
232