27543eb51d725d64ca61364ea93f8cc3108c740c
[matches/honours.git] / research / transmission_spectroscopy / simulator / pgu-0.18 / pgu / gui / slider.py
1 import pygame
2 from pygame.locals import *
3
4 from .const import *
5 from . import widget
6 from . import table
7 from . import basic
8 from . import pguglobals
9 from .errors import PguError
10
11 _SLIDER_HORIZONTAL = 0
12 _SLIDER_VERTICAL = 1
13
14 class _slider(widget.Widget):
15     _value = None
16
17     def __init__(self,value,orient,min,max,size,step=1,**params):
18         params.setdefault('cls','slider')
19         widget.Widget.__init__(self,**params)
20         self.min,self.max,self.value,self.orient,self.size,self.step = min,max,value,orient,size,step
21         self.style.check("bar")
22     
23     def paint(self,s):
24         
25         self.value = self.value
26         r = pygame.rect.Rect(0,0,self.style.width,self.style.height)
27         if self.orient == _SLIDER_HORIZONTAL:
28             r.x = (self.value-self.min) * (r.w-self.size) / max(1,self.max-self.min);
29             r.w = self.size;
30         else:
31             r.y = (self.value-self.min) * (r.h-self.size) / max(1,self.max-self.min);
32             r.h = self.size;
33             
34         self.bar = r
35
36         pguglobals.app.theme.render(s,self.style.bar,r)
37     
38     def event(self,e):
39         used = None
40         r = pygame.rect.Rect(0,0,self.style.width,self.style.height)
41         adj = 0
42         if e.type == ENTER: self.repaint()
43         elif e.type == EXIT: self.repaint()
44         elif e.type == MOUSEBUTTONDOWN:
45             if self.bar.collidepoint(e.pos):
46                 self.grab = e.pos[0],e.pos[1]
47                 self.grab_value = self.value
48             else:
49                 x,y,adj = e.pos[0],e.pos[1],1
50                 self.grab = None
51             self.repaint()
52         elif e.type == MOUSEBUTTONUP:
53             #x,y,adj = e.pos[0],e.pos[1],1
54             self.repaint()
55         elif e.type == MOUSEMOTION:
56             if 1 in e.buttons and self.container.myfocus is self:
57                 if self.grab != None:
58                     rel = e.pos[0]-self.grab[0],e.pos[1]-self.grab[1]
59                     if self.orient == _SLIDER_HORIZONTAL:
60                         d = (r.w - self.size)
61                         if d != 0: self.value = self.grab_value + ((self.max-self.min) * rel[0] / d)
62                     else:
63                         d = (r.h - self.size)
64                         if d != 0: self.value = self.grab_value + ((self.max-self.min) * rel[1] / d)
65                 else:
66                     x,y,adj = e.pos[0],e.pos[1],1
67                     
68         elif e.type is KEYDOWN:
69             if self.orient == _SLIDER_HORIZONTAL and e.key == K_LEFT:
70                 self.value -= self.step
71                 used = True
72             elif self.orient == _SLIDER_HORIZONTAL and e.key == K_RIGHT:
73                 self.value += self.step
74                 used = True
75             elif self.orient == _SLIDER_VERTICAL and e.key == K_UP:
76                 self.value -= self.step
77                 used = True
78             elif self.orient == _SLIDER_VERTICAL and e.key == K_DOWN:
79                 self.value += self.step
80                 used = True
81
82         if adj:
83             if self.orient == _SLIDER_HORIZONTAL:
84                 d = self.size/2 - (r.w/(self.max-self.min+1))/2
85                 self.value = (x-d) * (self.max-self.min) / (r.w-self.size+1) + self.min
86             else:
87                 d = self.size/2 - (r.h/(self.max-self.min+1))/2
88                 self.value = (y-d) * (self.max-self.min) / (r.h-self.size+1) + self.min
89                 
90         self.pcls = ""
91         if self.container.myhover is self: self.pcls = "hover"
92         if (self.container.myfocus is self and 1 in pygame.mouse.get_pressed()): self.pcls = "down"
93         
94         return used
95
96     # TODO - replace this with property functions and setters
97     def __setattr__(self,k,v):
98         if k == 'value':
99             v = int(v)
100             v = max(v,self.min)
101             v = min(v,self.max)
102         _v = self.__dict__.get(k,NOATTR)
103         self.__dict__[k]=v
104         if k == 'value' and _v != NOATTR and _v != v: 
105             self.send(CHANGE)
106             self.repaint()
107         if hasattr(self,'size'):
108             sz = min(self.size,max(self.style.width,self.style.height))
109             sz = max(sz,min(self.style.width,self.style.height))
110             self.__dict__['size'] = sz
111             #self.size = sz
112         if hasattr(self,'max') and hasattr(self,'min'):
113             if self.max < self.min: self.max = self.min
114
115 #    @property
116 #    def value(self):
117 #        return self._value
118 #
119 #    @value.setter
120 #    def value(self, val):
121 #        val = int(val)
122 #        val = max(val, self.min)
123 #        val = min(val, self.max)
124 #
125 #        oldval = self._value
126 #        self._value = val
127 #        if (oldval != val):
128 #            self.send(CHANGE)
129 #            self.repaint()
130 #            
131 #        if hasattr(self,'size'):
132 #            sz = min(self.size,max(self.style.width,self.style.height))
133 #            sz = max(sz,min(self.style.width,self.style.height))
134 #            self.size = sz
135 #            
136 #        if hasattr(self,'max') and hasattr(self,'min'):
137 #            if self.max < self.min: self.max = self.min
138     
139
140 class VSlider(_slider):
141     """A verticle slider."""
142
143     def __init__(self,value,min,max,size,step=1,**params):
144         """Construct a veritcal slider widget.
145
146         Arguments:
147             value -- the default position of the slider, between min and max
148             min -- the minimum value for the slider
149             max -- the maximum value
150             size -- the length of the slider bar in pixels
151             step -- how much to jump when using the keyboard
152
153         """
154         params.setdefault('cls','vslider')
155         _slider.__init__(self,value,_SLIDER_VERTICAL,min,max,size,step,**params)
156
157 class HSlider(_slider):
158     """A horizontal slider."""
159
160     def __init__(self,value,min,max,size,step=1,**params):
161         params.setdefault('cls','hslider')
162         _slider.__init__(self,value,_SLIDER_HORIZONTAL,min,max,size,step,**params)
163
164 class HScrollBar(table.Table):
165     """A horizontal scroll bar."""
166
167     def __init__(self,value,min,max,size,step=1,**params):
168         params.setdefault('cls','hscrollbar')
169         
170         table.Table.__init__(self,**params)
171
172         # Check that these styles are defined
173         self.style.check("minus")
174         self.style.check("plus")
175
176         self.slider = _slider(value,_SLIDER_HORIZONTAL,min,max,size,step=step,cls=self.cls+'.slider')
177         self.minus = basic.Image(self.style.minus)
178         self.minus.connect(MOUSEBUTTONDOWN,self._click,-1)
179         self.slider.connect(CHANGE,self.send,CHANGE)
180         
181         self.minus2 = basic.Image(self.style.minus)
182         self.minus2.connect(MOUSEBUTTONDOWN,self._click,-1)
183         
184         self.plus = basic.Image(self.style.plus)
185         self.plus.connect(MOUSEBUTTONDOWN,self._click,1)
186         
187         self.size = size
188         
189     def _click(self,value):
190         self.slider.value += self.slider.step*value
191         
192     def resize(self,width=None,height=None):
193         self.clear()
194         self.tr()
195         
196         w = self.style.width
197         h = self.slider.style.height
198         ww = 0
199         
200         if w > (h*2 + self.minus.style.width+self.plus.style.width):
201             self.td(self.minus)
202             ww += self.minus.style.width
203         
204         self.td(self.slider)
205         
206         if w > (h*2 + self.minus.style.width+self.minus2.style.width+self.plus.style.width):
207             self.td(self.minus2)
208             ww += self.minus2.style.width
209         
210         if w > (h*2 + self.minus.style.width+self.plus.style.width):
211             self.td(self.plus)
212             ww += self.plus.style.width
213             
214             
215         #HACK: handle theme sizing properly
216         xt,xr,xb,xl = pguglobals.app.theme.getspacing(self.slider)
217         ww += xr+xl
218
219         self.slider.style.width = self.style.width - ww
220         setattr(self.slider,'size',self.size * self.slider.style.width / max(1,self.style.width))
221         #self.slider.size = self.size * self.slider.style.width / max(1,self.style.width)
222         return table.Table.resize(self,width,height)
223
224     @property
225     def min(self):
226         return self.slider.min
227
228     @min.setter
229     def min(self, value):
230         self.slider.min = value
231
232     @property
233     def max(self):
234         return self.slider.max
235
236     @max.setter
237     def max(self, value):
238         self.slider.max = value
239
240     @property
241     def value(self):
242         return self.slider.value
243
244     @value.setter
245     def value(self, value):
246         self.slider.value = value
247
248     @property
249     def step(self):
250         return self.slider.step
251
252     @step.setter
253     def step(self, value):
254         self.slider.step = value
255         
256 #    def __setattr__(self,k,v):
257 #        if k in ('min','max','value','step'):
258 #            return setattr(self.slider,k,v)
259 #        self.__dict__[k]=v
260             
261 #    def __getattr__(self,k):
262 #        if k in ('min','max','value','step'):
263 #            return getattr(self.slider,k)
264 #        return table.Table.__getattr__(self,k) #self.__dict__[k]
265
266 class VScrollBar(table.Table):
267     """A vertical scroll bar."""
268
269     def __init__(self,value,min,max,size,step=1,**params):
270         params.setdefault('cls','vscrollbar')
271         
272         table.Table.__init__(self,**params)
273
274         # Check that these styles are defined
275         self.style.check("minus")
276         self.style.check("plus")
277
278         self.minus = basic.Image(self.style.minus)
279         self.minus.connect(MOUSEBUTTONDOWN,self._click,-1)
280         
281         self.minus2 = basic.Image(self.style.minus)
282         self.minus2.connect(MOUSEBUTTONDOWN,self._click,-1)
283         
284         self.plus = basic.Image(self.style.plus)
285         self.plus.connect(MOUSEBUTTONDOWN,self._click,1)
286         
287         self.slider = _slider(value,_SLIDER_VERTICAL,min,max,size,step=step,cls=self.cls+'.slider')
288         self.slider.connect(CHANGE,self.send,CHANGE)
289         
290         self.size = size
291         
292     def _click(self,value):
293         self.slider.value += self.slider.step*value
294         
295     def resize(self,width=None,height=None):
296         self.clear()
297         
298         h = self.style.height
299         w = self.slider.style.width
300         hh = 0
301         
302         if h > (w*2 + self.minus.style.height+self.plus.style.height):
303             self.tr()
304             self.td(self.minus)
305             hh += self.minus.style.height
306         
307         self.tr()
308         self.td(self.slider)
309         
310         if h > (w*2 + self.minus.style.height+self.minus2.style.height+self.plus.style.height):
311             self.tr()
312             self.td(self.minus2)
313             hh += self.minus2.style.height
314         
315         if h > (w*2 + self.minus.style.height+self.plus.style.height):
316             self.tr()
317             self.td(self.plus)
318             hh += self.plus.style.height
319             
320             
321         #HACK: handle theme sizing properly
322         xt,xr,xb,xl = pguglobals.app.theme.getspacing(self.slider)
323         hh += xt+xb
324
325         self.slider.style.height = self.style.height - hh
326         setattr(self.slider,'size',self.size * self.slider.style.height / max(1,self.style.height))
327         return table.Table.resize(self,width,height)
328         
329     def __setattr__(self,k,v):
330         if k in ('min','max','value','step'):
331             return setattr(self.slider,k,v)
332         self.__dict__[k]=v
333             
334     def __getattr__(self,k):
335         if k in ('min','max','value','step'):
336             return getattr(self.slider,k)
337         return table.Table.__getattr__(self,k)
338

UCC git Repository :: git.ucc.asn.au