ecasa: first step towards a gui
[enigma2-plugins.git] / ecasa / src / EcasaGui.py
1 from __future__ import print_function
2
3 #pragma mark - GUI
4
5 #pragma mark Screens
6 from Screens.Screen import Screen
7 from Screens.HelpMenu import HelpableScreen
8
9 #pragma mark Components
10 from Components.ActionMap import HelpableActionMap
11 from Components.AVSwitch import AVSwitch
12 from Components.Pixmap import Pixmap, MovingPixmap
13 from Components.Sources.StaticText import StaticText
14 from Components.Sources.List import List
15
16 #pragma mark Configuration
17 from Components.config import config
18
19 #pragma mark Picasa
20 from .PicasaApi import PicasaApi
21
22 from enigma import ePicLoad
23 from collections import deque
24
25 try:
26         xrange = xrange
27 except NameError:
28         xrange = range
29
30 our_print = lambda *args, **kwargs: print("[EcasaGui]", *args, **kwargs)
31
32 class EcasaPictureWall(Screen, HelpableScreen):
33         skin = """<screen position="center,center" size="600,400">
34                 <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on"/>
35                 <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on"/>
36                 <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on"/>
37                 <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on"/>
38                 <ePixmap position="565,10" size="35,25" pixmap="skin_default/buttons/key_menu.png" alphatest="on"/>
39                 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"/>
40                 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"/>
41                 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"/>
42                 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"/>
43                 <!-- TODO: check size! -->
44                 <widget name="image0" position="30,50" size="72,72"/>
45                 <widget name="image1" position="110,50" size="72,72"/>
46                 <widget name="image2" position="190,50" size="72,72"/>
47                 <widget name="image3" position="30,150" size="72,72"/>
48                 <widget name="image4" position="110,150" size="72,72"/>
49                 <widget name="image5" position="190,150" size="72,72"/>
50                 <widget name="image6" position="30,250" size="72,72"/>
51                 <widget name="image7" position="110,250" size="72,72"/>
52                 <widget name="image8" position="190,250" size="72,72"/>
53                 <!-- TODO: find/create :P -->
54                 <widget name="highlight" position="20,40" size="92,92"/>
55                 </screen>"""
56         def __init__(self, session, api=None):
57                 Screen.__init__(self, session)
58                 HelpableScreen.__init__(self)
59
60                 if api is None:
61                         self.api = PicasaApi(
62                                         config.plugins.ecasa.google_username.value,
63                                         config.plugins.ecasa.google_password.value,
64                                         config.plugins.ecasa.cache.value)
65
66                 self["key_red"] = StaticText(_("Close"))
67                 self["key_green"] = StaticText()
68                 self["key_yellow"] = StaticText()
69                 self["key_blue"] = StaticText()
70                 for i in xrange(9):
71                         self['image%d' % i] = Pixmap()
72                         self['title%d' % i] = StaticText()
73                 self["highlight"] = MovingPixmap()
74
75                 self["overviewActions"] = HelpableActionMap(self, "EcasaOverviewActions", {
76                         "up": self.up,
77                         "down": self.down,
78                         "left": self.left,
79                         "right": self.right,
80                         "nextPage": (self.nextPage, _("show next page")),
81                         "prevPage": (self.prevPage, _("show previous page")),
82                         "select": self.select,
83                         "exit":self.close,
84                         }, -1)
85
86                 self.offset = 0
87                 self.highlighted = 0
88
89                 # thumbnail loader
90                 self.picload = ePicLoad()
91                 self.picload.PictureData.get().append(self.gotPicture)
92                 sc = AVSwitch().getFramebufferScale()
93                 self.picload.setPara((72, 72, sc[0], sc[1], False, 1, '#ff000000')) # TODO: hardcoded size is evil!
94                 self.currentphoto = None
95                 self.queue = deque()
96
97         def gotPicture(self, picInfo=None):
98                 our_print("picture decoded")
99                 ptr = self.picload.getData()
100                 if ptr is not None:
101                         idx = self.pictures.index(self.currentphoto)
102                         realIdx = idx - self.offset
103                         self['image%d' % realIdx].instance.setPixmap(ptr.__deref__())
104                 self.currentphoto = None
105                 self.maybeDecode()
106
107         def maybeDecode(self):
108                 our_print("maybeDecode")
109                 if self.currentphoto is not None: return
110                 our_print("no current photo, checking for queued ones")
111                 try:
112                         filename, self.currentphoto = self.queue.pop()
113                 except IndexError:
114                         our_print("no queued photos")
115                         # no more pictures
116                         pass
117                 else:
118                         self.picload.startDecode(filename)
119
120         def pictureDownloaded(self, tup):
121                 filename, photo = tup
122                 our_print("pictureDownloaded", filename, photo)
123                 self.queue.append((filename, photo))
124                 self.maybeDecode()
125
126         def pictureDownloadFailed(self, tup):
127                 error, photo = tup
128                 our_print("pictureDownloadFailed", error, photo)
129                 # TODO: indicate in gui
130
131         def setup(self):
132                 our_print("setup")
133                 self.queue.clear()
134                 pictures = self.pictures
135                 for i in xrange(9):
136                         try:
137                                 our_print("trying to initiate download of idx", i+self.offset)
138                                 self.api.downloadThumbnail(pictures[i+self.offset]).addCallbacks(self.pictureDownloaded, self.pictureDownloadFailed)
139                         except IndexError:
140                                 # no more pictures
141                                 our_print("no more pictures in setup")
142                                 break
143
144         def up(self):
145                 our_print("UP")
146         def down(self):
147                 our_print("DOWN")
148         def left(self):
149                 our_print("LEFT")
150         def right(self):
151                 our_print("RIGHT")
152         def nextPage(self):
153                 our_print("NEXT PAGE")
154         def prevPage(self):
155                 our_print("PREV PAGE")
156         def select(self):
157                 our_print("SELECT")
158
159 class EcasaOverview(EcasaPictureWall):
160         def __init__(self, session):
161                 EcasaPictureWall.__init__(self, session)
162                 self.skinName = ["EcasaOverview", "EcasaPictureWall"]
163                 self.onLayoutFinish.append(self.go)
164
165         def go(self):
166                 self.onLayoutFinish.remove(self.go)
167                 self.pictures = self.api.getFeatured()
168                 self.setup()
169