commit do server
[remotepc] / pcremote-client / edje_objects.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 # ****************************************************************************
5 # Copyright (c) 2008 INdT/Fucapi.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10
11 #  This program is distributed in the hope that it will be useful,
12 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #  GNU Lesser General Public License for more details.
15
16 #  You should have received a copy of the GNU Lesser General Public License
17 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 # ============================================================================
20 # Project Name :PC Remote
21 # Author       :André Portela
22 # Email        :andre_portela_@hotmail.com
23 # Version      :1.0
24 # Module       :main
25 # Class        :PCRemote custom Edje object with it's own call backs for the
26 #               main screen
27 # ============================================================================
28
29 import thread
30 import ecore
31 import ecore.evas
32 import evas.decorators
33 import edje
34 import edje.decorators
35 import time
36 from connection.iconnection import Iconnection
37 from kineticlist import *
38
39 class EvasCanvas(object):
40
41     def __init__(self, fullscreen, engine, size):
42         #f = ecore.evas.SoftwareX11
43         self.evas_obj = engine(w=size[0], h=size[1])
44         self.evas_obj.callback_delete_request = self.on_delete_request
45         self.evas_obj.callback_resize = self.on_resize
46
47         self.evas_obj.title = "PCRemote"
48         self.evas_obj.name_class = ('PC Remote', 'main')
49         self.evas_obj.fullscreen = fullscreen
50         self.evas_obj.size = size
51         self.evas_obj.show()
52         
53     def on_resize(self, evas_obj):
54         x, y, w, h = evas_obj.evas.viewport
55         size = (w, h)
56         for key in evas_obj.data.keys():
57             evas_obj.data[key].size = size
58
59     def on_delete_request(self, evas_obj):
60         ecore.main_loop_quit()
61         
62     def show(self):
63         self.evas_obj.show()
64
65 class EdjeObject(edje.Edje):
66
67     def __init__(self, canvas_class, file, group='main',name='edje'):
68         self.canvas_class = canvas_class
69         self.x11 = canvas_class.evas_obj
70         self.canvas = self.x11.evas
71         edje.Edje.__init__(self, self.canvas, file = file, group = group)
72         self.size = self.canvas.size
73         self.x11.data[name] = self
74
75 class MainScreen(EdjeObject):
76
77     def __init__(self, canvas, file, group, name, connection):
78         EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
79
80         self.file = file
81         self.on_key_down_add(self.key_down_cb, self.x11)
82         self.sock_address = None
83         #flag that sync the discovery device's thread
84         self.flag = False
85         #flag that sync the connecting device's thread
86         self.connecting_flag = False
87         #lista de dispositivos descobertos
88         self.lista_dispositivos = []
89         #objeto que cria a conexao bluetooth
90         self.conexao = connection
91         self.kineticlist = False
92         #portela mock object
93         self.lista_teste = ['Andre Portela', 'Juliana Dias', 'Victor Hugo', 'Lucina Dias', 'Rosa Dias', 'James Italiano', 'Nona Izvi', 'Fergus Mao', 'Mauricio Brilhante', 'Edward Ordonez', 'Brankinhu', 'Banco Real', 'Banco Itaú', 'ABN-AMRO BANK']
94
95     def key_down_cb(self, bg, event, ee):
96         k = event.key
97         if k == "Escape":
98             ecore.main_loop_quit()
99         elif k == "F6":
100             ee.fullscreen = not ee.fullscreen
101         elif k == "F8":
102             print "-"
103         elif k == "F7":
104             print "+"
105       
106     def mkKineticList(self):
107         #kinetic list (the item values are tied with the part "item_background" of the "list_item" group)
108         #self.kineticlist = KineticList(self.canvas, file=self.file, item_width=407, item_height=38, father=self)
109         self.kineticlist = KineticList(self.canvas, file=self.file, item_height=57, father=self)
110         self.kineticlist.freeze()
111         #portela - test kinetic list with several devices
112         #for item in self.lista_teste:
113         #populates the list with the device's names
114         for item in self.lista_dispositivos:
115             self.kineticlist.row_add(item)
116         #reorganize and draw the list
117         self.kineticlist.thaw()
118         #embed the list in the edje object
119         self.part_swallow("list", self.kineticlist);
120
121     @edje.decorators.signal_callback("connect_to","choice")
122     def connect_to(self, emission, source):
123         self.sock_address = self.part_text_get(source)
124         #flag that sync the connecting device's thread
125         self.connecting_flag = False
126         self.signal_emit("start","device_connect")
127         thread.start_new_thread(MainScreen.threaded_connection,(self,))
128         
129     def threaded_connection(self):
130         self.conexao.create_socket('l2cap')
131         print 'connecting to: %s' % self.sock_address
132         self.conexao.set_address(self.conexao.bt_find_device_address_by_name(self.sock_address))
133         self.conexao.set_port(0x1001)
134         self.conexao.connect()
135         self.connecting_flag = True
136
137     @edje.decorators.signal_callback("connecting","device")
138     def connecting_check(self, emission, source):
139         if self.connecting_flag:
140             self.connecting_flag = False
141             self.signal_emit("stop","device_connect")
142             #we are sending a signal to main edje (there is time to animate the device locking)
143             self.signal_emit("begin","init")
144  
145     @edje.decorators.signal_callback("animation_still_loading", "loading")
146     def still_loading_cb(self, emission, source):
147         if self.flag:
148             self.flag = False
149             self.signal_emit("program,stop","loading")
150             if self.lista_dispositivos != []:
151                 self.mkKineticList()
152             else:
153                 self.no_device_found()
154
155     @edje.decorators.signal_callback("animation_sair_ended", "sair")
156     def saida(self, signal, source):
157         ecore.main_loop_quit()
158
159     @edje.decorators.signal_callback("animation_rastrear_ended", "rastrear")
160     def rastrear_key_down(self, signal, source):
161         thread.start_new_thread(MainScreen.rastrear_dispositivos,(self,None))
162
163     @edje.decorators.signal_callback("program,start", "novodevice")
164     def search_devices_again(self, signal, source):
165         self.part_unswallow(self.kineticlist)
166         del self.kineticlist
167         MainScreen.rastrear_key_down(self, None, None)
168
169     def rastrear_dispositivos(self,arg):
170         try:
171             self.lista_dispositivos = self.conexao.bt_find_devices_only_names()
172         except:
173             self.lista_dispositivos = []
174         self.flag = True
175
176     def no_device_found(self):
177         self.signal_emit("program,start","no_device")
178
179 class TabletScreen(EdjeObject):
180
181     def __init__(self, canvas, file, group,name, connection):
182         EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
183         self.on_key_down_add(self.key_down_cb, self.x11)
184         #emitt events only if the mouse is inside the touch object area
185         (self.part_object_get('touch')).pointer_mode_set(evas.EVAS_OBJECT_POINTER_MODE_NOGRAB)
186         #assign the mouse_move_cb method as a mouse move callback for the touch part of the edje object
187         (self.part_object_get('touch')).on_mouse_move_add(self.mouse_move_cb)
188         #self.on_mouse_move_add(TabletScreen.mouse_move_cb)
189         self.sock = connection
190         #this flag indicates either the user are grabing something or not on the target
191         self.drag_flag = False
192         #this float indicates the wich the method left_click_down was called, and will be
193         #calculated against lcu_time in left_click_up method
194         self.lcd_time = 0.0
195         #tecla alt
196         self.alt_flag = False
197         #tecla shift
198         self.iso_shift_flag = False
199         #lista de aliases das teclas de comando Alt+F(x)
200         #self.fletters = ['p', 'q', 'w', '', 'r', '', '', '', '', 'o'] 
201         self.keys_dict = {'q':1, 'w':2, 'e':3, 'r':4, 't':5, 'y':6, 'u':7, 'i':8, 'o':9, 'p':0, \
202                           'a':'Shift_L+1', 's':'', 'd':'Shift_L+2', 'f':'Shift_L+3', 'g':'backslash', \
203                           'h':'slash', 'j':'Shift_L+9', 'k': 'Shift_L+0', 'l':'Shift_L+8', '\'':'Shift_L+slash',\
204                           'z':'', 'x':'Shift_L+6', 'c':'', 'v':'Shift_L+5', 'b':'Shift_L+7', 'n':'Shift_L+4', \
205                           'm':'', ';':'', '-':'Shift_L+minus', '+':'equal'}
206
207     @edje.decorators.signal_callback('mouse,down,1', 'tablet_bt-L_area')
208     def left_click_down(self, signal, source):
209         self.lcd_time = time.time()
210         #if the user are grabing something, release it
211         if self.drag_flag:
212             self.drag_flag = False
213             self.sock.send_message("Mouse:#left_click")
214
215     @edje.decorators.signal_callback('mouse,up,1', 'tablet_bt-L_area')
216     def left_click_up(self, signal, source):
217         lcu_time = time.time()
218         #threshold of 0.5 seconds to grab something on the target
219         elapsed_time = lcu_time - self.lcd_time
220         if elapsed_time < 0.5:
221             #do a simple click
222             self.sock.send_message("Mouse:#left_click")
223             self.sock.send_message("Mouse:#left_click")
224         else:
225             #do mouse grab
226             self.sock.send_message("Mouse:#left_click")
227             self.drag_flag = True
228
229     @edje.decorators.signal_callback('mouse,up,1', 'tablet_bt-R_area')
230     def rigth_click(self, signal, source):
231         self.sock.send_message("Mouse:#right_click")
232         self.sock.send_message("Mouse:#right_click")
233
234     def key_down_cb(self, bg, event, ee):
235         k = event.key
236         print k
237         if k == "Escape":
238             self.sock.send_message("Keyboard:Escape")
239         elif k == "F6":
240             ee.fullscreen = not ee.fullscreen
241         elif k == "F8":
242             self.sock.send_message("Keyboard:Up")
243         elif k == "F7":
244             self.sock.send_message("Keyboard:Down")
245         elif k == "Return":
246             self.alt_flag = True
247         elif k == "ISO_Level3_Shift":
248             self.iso_shift_flag = True
249         else:
250             if self.alt_flag:
251                 #if k in self.fletters:
252                 #    self.sock.send_message("Keyboard:Alt+F%s" % (self.fletters.index(k)))
253                 #    self.alt_flag = False
254                 #elif k == 'space':
255                 #    self.sock.send_message("Keyboard:Alt+Space")
256                 #    self.alt_flag = False
257                 #else:
258                 #    self.alt_flag = False
259                 if self.keys_dict.has_key(k) and isinstance(self.keys_dict[k], int):
260                     self.sock.send_message("Keyboard:Alt_L")
261                     self.sock.send_message("Keyboard:F%s" % (self.keys_dict[k]))
262                     self.alt_flag = False
263                 elif k == 'space':
264                     self.sock.send_message("Keyboard:Alt_L")
265                     self.sock.send_message("Keyboard:space")
266                     self.alt_flag = False
267                 else:
268                     self.alt_flag = False
269             #else:
270                 #self.sock.send_message("Keyboard:%s" % k)
271             elif self.iso_shift_flag:
272                 if self.keys_dict.has_key(k) and self.keys_dict[k] and isinstance(self.keys_dict[k], str):
273                     lst = self.keys_dict[k].split('+')
274                     for cmd in lst:
275                         self.sock.send_message("Keyboard:%s" % cmd)
276                         self.iso_shift_flag = False
277                 elif self.keys_dict.has_key(k) and self.keys_dict and isinstance(self.keys_dict[k], int):
278                     self.sock.send_message("Keyboard:%s" % self.keys_dict[k])
279                     self.iso_shift_flag = False
280                 else:
281                     self.iso_shift_flag = False
282             else:
283                 self.sock.send_message("Keyboard:%s" % k)
284
285     def mouse_move_cb(self, part, event):
286         x, y = event.position.output[0], event.position.output[1]
287         self.sock.send_message("Mouse:"+str(x)+","+str(y))
288
289 class SlideScreen(EdjeObject):
290
291     def __init__(self, canvas, file, group,name, connection):
292         EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
293         self.on_key_down_add(self.key_down_cb, self.x11)
294         #emitt events only if the mouse is inside the touch object area
295         (self.part_object_get('touch')).pointer_mode_set(evas.EVAS_OBJECT_POINTER_MODE_NOGRAB)
296         #assign the mouse_move_cb method as a mouse move callback for the touch part of the edje object
297         (self.part_object_get('touch')).on_mouse_move_add(self.mouse_move_cb)
298         #self.on_mouse_move_add(TabletScreen.mouse_move_cb)
299         self.sock = connection
300         #this flag indicates either the user are grabing something or not on the target
301         self.drag_flag = False
302         #helps to coordenate presentation
303         self.keyboard_flag = True
304         #this float indicates the wich the method left_click_down was called, and will be
305         #calculated against lcu_time in left_click_up method
306         self.lcd_time = 0.0
307
308     @edje.decorators.signal_callback('mouse,down,1', 'slide_bt-left_area')
309     def left_click_down(self, signal, source):
310         if self.keyboard_flag:
311             self.lcd_time = time.time()
312             #if the user are grabing something, release it
313             if self.drag_flag:
314                 self.drag_flag = False
315                 self.sock.send_message("Mouse:#left_click")
316
317     @edje.decorators.signal_callback('mouse,up,1', 'slide_bt-left_area')
318     def left_click_up(self, signal, source):
319         if self.keyboard_flag:
320             lcu_time = time.time()
321             #threshold of 0.5 seconds to grab something on the target
322             elapsed_time = lcu_time - self.lcd_time
323             if elapsed_time < 0.5:
324                 #do a simple click
325                 self.sock.send_message("Mouse:#left_click")
326                 self.sock.send_message("Mouse:#left_click")
327             else:
328                 #do mouse grab
329                 self.sock.send_message("Mouse:#left_click")
330                 self.drag_flag = True
331         else:
332             self.sock.send_message("Keyboard:%s" % "Left")
333
334     @edje.decorators.signal_callback('mouse,up,1', 'slide_bt-right_area')
335     def rigth_click(self, signal, source):
336         if self.keyboard_flag:
337             self.sock.send_message("Mouse:#right_click")
338             self.sock.send_message("Mouse:#right_click")
339         else:
340             self.sock.send_message("Keyboard:%s" % "Right")
341
342     def key_down_cb(self, bg, event, ee):
343         k = event.key
344         print k
345         if k == "Escape":
346             self.sock.send_message("Keyboard:Escape")
347         elif k == "F6":
348             self.keyboard_flag = not self.keyboard_flag
349             self.sock.send_message("Keyboard:F5")
350         elif k == "F8":
351             self.sock.send_message("Keyboard:Up")
352         elif k == "F7":
353             self.sock.send_message("Keyboard:Down")
354         else:
355             self.sock.send_message("Keyboard:%s" % k)
356
357     def mouse_move_cb(self, part, event):
358         x, y = event.position.output[0], event.position.output[1]
359         self.sock.send_message("Mouse:"+str(x)+","+str(y))