Bah, c'n'était pas si compliqué tout compte fait :-).
[minwii.git] / src / pgu / gui / input.py
1 """
2 """
3 import pygame
4 from pygame.locals import *
5
6 from const import *
7 import widget
8
9 class Input(widget.Widget):
10 """A single line text input.
11
12 <pre>Input(value="",size=20)</pre>
13
14 <dl>
15 <dt>value<dd>initial text
16 <dt>size<dd>size for the text box, in characters
17 </dl>
18
19 <strong>Example</strong>
20 <code>
21 w = Input(value="Cuzco the Goat",size=20)
22
23 w = Input("Marbles")
24 </code>
25
26 """
27 def __init__(self,value="",size=20,customFont = None,**params):
28 params.setdefault('cls','input')
29 widget.Widget.__init__(self,**params)
30 self.value = value
31 self.pos = len(str(value))
32 self.vpos = 0
33 if customFont != None:
34 self.font = customFont
35 else:
36 self.font = self.style.font
37 w,h = self.font.size("e"*size)
38 if not self.style.height: self.style.height = h
39 if not self.style.width: self.style.width = w
40 #self.style.height = max(self.style.height,h)
41 #self.style.width = max(self.style.width,w)
42 #self.rect.w=w+self.style.padding_left+self.style.padding_right;
43 #self.rect.h=h+self.style.padding_top+self.style.padding_bottom;
44
45 def paint(self,s):
46
47 r = pygame.Rect(0,0,self.rect.w,self.rect.h)
48
49 cs = 2 #NOTE: should be in a style
50
51 w,h = self.font.size(self.value[0:self.pos])
52 x = w-self.vpos
53 if x < 0: self.vpos -= -x
54 if x+cs > s.get_width(): self.vpos += x+cs-s.get_width()
55
56 s.blit(self.font.render(self.value, 1, self.style.color),(-self.vpos,0))
57
58 if self.container.myfocus is self:
59 w,h = self.font.size(self.value[0:self.pos])
60 r.x = w-self.vpos
61 r.w = cs
62 r.h = h
63 s.fill(self.style.color,r)
64
65 def _setvalue(self,v):
66 self.__dict__['value'] = v
67 self.send(CHANGE)
68
69 def event(self,e):
70 used = None
71 if e.type == KEYDOWN:
72 if e.key == K_BACKSPACE:
73 if self.pos:
74 self._setvalue(self.value[:self.pos-1] + self.value[self.pos:])
75 self.pos -= 1
76 elif e.key == K_DELETE:
77 if len(self.value) > self.pos:
78 self._setvalue(self.value[:self.pos] + self.value[self.pos+1:])
79 elif e.key == K_HOME:
80 self.pos = 0
81 elif e.key == K_END:
82 self.pos = len(self.value)
83 elif e.key == K_LEFT:
84 if self.pos > 0: self.pos -= 1
85 used = True
86 elif e.key == K_RIGHT:
87 if self.pos < len(self.value): self.pos += 1
88 used = True
89 elif e.key == K_RETURN:
90 self.next()
91 elif e.key == K_TAB:
92 pass
93 else:
94 #c = str(e.unicode)
95 try:
96 c = (e.unicode).encode('latin-1')
97 if c:
98 self._setvalue(self.value[:self.pos] + c + self.value[self.pos:])
99 self.pos += 1
100 except: #ignore weird characters
101 pass
102 self.repaint()
103 elif e.type == FOCUS:
104 self.repaint()
105 elif e.type == BLUR:
106 self.repaint()
107
108 self.pcls = ""
109 if self.container.myfocus is self: self.pcls = "focus"
110
111 return used
112
113 def __setattr__(self,k,v):
114 if k == 'value':
115 if v == None: v = ''
116 v = str(v)
117 self.pos = len(v)
118 _v = self.__dict__.get(k,NOATTR)
119 self.__dict__[k]=v
120 if k == 'value' and _v != NOATTR and _v != v:
121 self.send(CHANGE)
122 self.repaint()
123
124 class Password(Input):
125 """A password input, text is *-ed out.
126
127 <pre>Password(value="",size=20)</pre>
128
129 <dl>
130 <dt>value<dd>initial text
131 <dt>size<dd>size for the text box, in characters
132 </dl>
133
134 <strong>Example</strong>
135 <code>
136 w = Password(value="password",size=20)
137
138 w = Password("53[r3+")
139 </code>
140
141 """
142
143 def paint(self,s):
144 hidden="*"
145 show=len(self.value)*hidden
146
147 #print "self.value:",self.value
148
149 if self.pos == None: self.pos = len(self.value)
150
151 r = pygame.Rect(0,0,self.rect.w,self.rect.h)
152
153 cs = 2 #NOTE: should be in a style
154
155 w,h = self.font.size(show)
156 x = w-self.vpos
157 if x < 0: self.vpos -= -x
158 if x+cs > s.get_width(): self.vpos += x+cs-s.get_width()
159
160 s.blit(self.font.render(show, 1, self.style.color),(-self.vpos,0))
161
162 if self.container.myfocus is self:
163 #w,h = self.font.size(self.value[0:self.pos])
164 w,h = self.font.size(show[0:self.pos])
165 r.x = w-self.vpos
166 r.w = cs
167 r.h = h
168 s.fill(self.style.color,r)
169