0a7573d212de4231d3802238df9e9ec648f8fa94
[drlaunch] / widget.py
1 #!/usr/bin/env python
2 # coding=UTF-8
3
4 # Copyright (C) 2010 Stefanos Harhalakis
5 #
6 # This file is part of wifieye.
7 #
8 # wifieye is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # wifieye is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with wifieye.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 # $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
22
23 __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
24
25 import gtk
26 import gobject
27 import hildon
28 from hildondesktop import *
29 from gtk import gdk
30 from math import pi
31 import cairo
32 import time
33
34 from portrait import FremantleRotation
35 import launcher
36 from xdg.IconTheme import getIconPath
37
38
39 import config
40 import apps
41
42
43 class Icons:
44     def __init__(self):
45         self.mode='l'
46
47
48     def load(self):
49         x=0
50         y=0
51         fn=["maegirls", "wifieye"]*3
52         for f in fn:
53             dt=apps.readOne(f)
54             ico=getIconPath(dt['icon'], config.iconsize)
55             print "ico:", ico
56             p=gtk.gdk.pixbuf_new_from_file_at_size(ico, config.iconsize,
57                 config.iconsize)
58             print x, y
59             #dt={'icon2': p}
60             dt['icon2']=p
61             print x, y, dt
62             self.icons[x][y].setApp(dt)
63             x+=1
64             if x>=config.size:
65                 x=0
66                 y+=1
67 #           self.icons.append(p)
68
69         print "end of Icons init"
70
71     def setMode(self, mode):
72         self.mode=mode
73
74 class Icon:
75     def __init__(self):
76         self.icon=None
77         self.lastpress=0
78         self.ispressed=False
79
80         self.x=0
81         self.y=0
82
83         self.presstime=0.25
84
85         self.window=None
86
87         self.clickcount=0
88
89     def timePressed(self):
90         """ return how much time a button is pressed """
91         dt=time.time() - self.lastpress
92
93         return(dt)
94
95     def setApp(self, dt):
96         self.name=dt['id']
97         self.icon=dt['icon2']
98
99     def draw(self, cr, x, y, mode):
100         self.x=x
101         self.y=y
102
103         if self.icon==None:
104             return
105
106         cr.save()
107         cr.set_source_rgba(0.1, 0.1, 0.1, 1)
108         cr.set_line_width(5)
109
110         if self.ispressed:
111             t=1.0 * min(self.timePressed(), self.presstime) / self.presstime
112             g=0.3+0.5*t
113             b=0.3+0.7*t
114             cr.set_source_rgba(0, g, b, 0.7)
115         else:
116             cr.set_source_rgba(0.3, 0.3, 0.3, 0.7)
117         x3=x + (config.iconspace/6)
118         y3=y + (config.iconspace/6)
119
120         r=10    # Radius
121         w=config.iconsize+(config.iconspace*2/3)
122
123         cr.move_to(x3+r, y3)
124         cr.arc(x3+w-r,  y3+r,   r,          pi*1.5, pi*2)
125         cr.arc(x3+w-r,  y3+w-r, r,          0,      pi*0.5)
126         cr.arc(x3+r,    y3+w-r, r,          pi*0.5, pi)
127         cr.arc(x3+r,    y3+r,   r,          pi,     pi*1.5)
128
129         cr.stroke_preserve()
130         cr.fill()
131 #           cr.paint()
132         cr.restore()
133
134         icon=self.icon
135
136         if mode=='l':
137             icon2=icon
138         else:
139             icon2=icon.rotate_simple(gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE)
140
141         cr.save()
142         x3=x + (config.iconspace/2)
143         y3=y + (config.iconspace/2)
144         cr.set_source_pixbuf(icon2, x3, y3)
145         cr.paint()
146         cr.restore()
147
148     def timerPressed(self):
149         #print "timer"
150         if not self.ispressed:
151             return(False)
152
153         self.invalidate()
154
155         if self.timePressed()>self.presstime:
156             ret=False
157         else:
158             ret=True
159         return(ret)
160
161     def doPress(self):
162         # Double-time: time for pressed and time for not-pressed
163         if time.time() - self.lastpress > self.presstime*2:
164             self.clickcount=0
165
166         self.lastpress=time.time()
167         self.ispressed=True
168         gobject.timeout_add(20, self.timerPressed)
169
170     def doLaunch(self):
171         print "launch:", self.name
172         launcher.launch(self.name)
173
174     def doTrippleClick(self):
175         print "tripple"
176         aps=apps.scan()
177         
178         lst=[aps[x]['name'] for x in aps]
179         lst.sort()
180
181         # TODO: EDO EDO EDO
182         # Na doylevei o selector, na dialegei efarmogi kai na
183         # efarmozetai sto sygkekrimeno eikonidio
184         #
185         # Na brethei lysh kai gia ta kena
186         dialog=gtk.Dialog('App select', None,
187             gtk.DIALOG_DESTROY_WITH_PARENT, buttons=())
188
189         selector=hildon.TouchSelectorEntry(text=True)
190         selector.set_column_selection_mode(
191             hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
192         dialog.vbox.pack_start(selector, True, True, 0)
193         dialog.set_size_request(0,900)
194
195         for app in lst:
196             if app==None:
197                 continue
198             selector.append_text(app)
199
200         dialog.show_all()
201
202         r=dialog.run()
203         print "r:", r
204 #       prog=hildon.Program.get_instance()
205
206         print lst
207
208     def doRelease(self):
209         dt=time.time() - self.lastpress
210         self.ispressed=False
211         if dt>self.presstime and dt<2:
212             self.doLaunch()
213         elif dt<self.presstime:
214             self.clickcount+=1
215             if self.clickcount==3:
216                 self.doTrippleClick()
217                 self.clickcount=0
218     
219     def doCancel(self):
220         self.ispressed=False
221
222     def invalidate(self, window=None):
223         if window==None:
224             window=self.window
225         else:
226             self.window=window
227         w=config.iconsize + config.iconspace
228         rect=gdk.Rectangle(self.x, self.y, w, w)
229         gdk.Window.invalidate_rect(window, rect, True)
230
231 class DrlaunchPlugin(HomePluginItem, Icons, FremantleRotation):
232     def __init__(self):
233         HomePluginItem.__init__(self)
234         Icons.__init__(self)
235         FremantleRotation.__init__(self, 'DrlaunchPlugin')
236
237         launcher.init()
238
239         self.setMode('l')
240
241         w=config.size * config.iconsize + (config.size) * config.iconspace
242         self.set_size_request(w, w)
243
244         sz=config.size
245         icons=[]
246         for x in xrange(sz):
247             icons.append([])
248             for y in xrange(config.size):
249                 icons[x].append(Icon())
250
251         self.icons=icons
252
253         self.lasticon=None  # The last icon that got selected
254
255         self.load()
256
257     def iconAt(self, x, y):
258         """ Get icon at coordinates x,y. X and Y are in pixels """
259
260         w=config.iconsize + config.iconspace
261
262         if self.mode=='l':
263             x2=int(x / w)
264             y2=int(y / w)
265         else:
266             x2=config.size - int(y/w) - 1
267             y2=int(x/w)
268
269         #print x2, y2
270         ret=self.icons[x2][y2]
271
272         return(ret)
273
274     def _draw(self, cr):
275         x=0
276         y=0
277
278 #       print "mode:", self.mode
279 #       print "icons", len(self.icons)
280         for l in self.icons:
281             for i in l:
282 #               print x, y
283
284                 if self.mode=='l':
285                     x2=x * (config.iconsize + config.iconspace)
286                     y2=y * (config.iconsize + config.iconspace)
287                 else:
288                     x2=y * (config.iconsize + config.iconspace)
289                     y2=(config.size-x-1) * (config.iconsize + config.iconspace)
290
291 #               print "draw:", x, y
292                 ico=self.icons[x][y]
293                 ico.draw(cr, x2, y2, self.mode)
294
295                 x+=1
296                 if x>=config.size:
297                     x=0
298                     y+=1
299
300     def do_expose_event(self, event):
301         #print "do_expose"
302
303         cr=self.window.cairo_create()
304
305         cr.rectangle(event.area.x, event.area.y,
306             event.area.width, event.area.height)
307
308         cr.clip()
309
310         self._draw(cr)
311
312 #       HomePluginItem.do_expose_event(self, event)
313
314     def setLastIcon(self, icon):
315         if icon==self.lasticon:
316             return
317
318         if self.lasticon!=None:
319             self.lasticon.doCancel()
320             self.lasticon.invalidate(self.window)
321         self.lasticon=icon
322
323     def do_realize(self):
324         screen=self.get_screen()
325         self.set_colormap(screen.get_rgba_colormap())
326         self.set_app_paintable(True)
327
328         HomePluginItem.do_realize(self)
329
330     def do_button_press_event(self, event):
331         #print "press", event.type
332         icon=self.iconAt(event.x, event.y)
333 #       rect=gdk.Rectangle(event.x,event.y,1,1)
334 #       rect=gdk.Rectangle(0, 0, 100, 100)
335         icon.doPress()
336         icon.invalidate(self.window)
337         self.setLastIcon(icon)
338
339 #       gdk.Window.invalidate_rect(self.window, rect, True)
340
341         return(True)
342
343     def do_button_release_event(self, event):
344         #print "release"
345         icon=self.iconAt(event.x, event.y)
346         icon.doRelease()
347         icon.invalidate(self.window)
348         self.setLastIcon(None)
349         return(True)
350
351     def do_leave_notify_event(self, event):
352         #print "leave", event.x, event.y
353         self.setLastIcon(None)
354         return(True)
355
356     def do_pproperty_notify_event(self, event):
357         #print "property"
358         icon=self.iconAt(event.x, event.y)
359         icon.doCancel()
360         icon.invalidate(self.window)
361         return(True)
362
363     def do_motion_notify_event(self, event):
364         #print "motion"
365         self.setLastIcon(None)
366 #       icon=self.iconAt(event.x, event.y)
367 #       icon.doCancel()
368 #       icon.invalidate(self.window)
369         return(True)
370
371     def do_button_press_event_old(self, event):
372         #print "press"
373         if event.type==gdk.BUTTON_PRESS:
374             print "press", event.type
375             if self.mode=='p':
376                 self.setMode('l')
377             else:
378                 self.setMode('p')
379             self.queue_draw()
380         return True
381
382     # For debugging
383     def do_event1(self, event):
384         print "event:", event, event.type
385
386     def butTest(self, arg):
387         print "but", arg
388
389     def on_orientation_changed(self, orientation):
390         print "orch:", orientation
391         o=orientation[0]
392         self.setMode(o)
393         self.queue_draw()
394
395 hd_plugin_type = DrlaunchPlugin
396
397 def do1():
398 #    gobject.type_register(MyQ)
399     gobject.type_register(hd_plugin_type)
400     obj=gobject.new(hd_plugin_type, plugin_id="plugin_id")
401     obj.show_all()
402     gtk.main()
403
404 def do2():
405     win=DrlaunchPlugin()
406     win.connect('delete-event', gtk.main_quit)
407
408     print "win:", win
409
410 #    t=DrlaunchPlugin()
411 #    win.add(t)
412
413     win.show_all()
414     gtk.main()
415
416 if __name__=="__main__":
417     do1()
418
419
420
421 # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
422