source: subversion/applications/routing/pyroute/overlay.py @ 5939

Last change on this file since 5939 was 5939, checked in by ojw, 12 years ago

allow brightness control (not that it should be needed on mobile device, but nice on my laptop)

File size: 13.2 KB
Line 
1import cairo
2import os
3from base import pyrouteModule
4from pyrouteMenu import *
5from menuIcons import menuIcons
6from overlayArea import overlayArea
7from colorsys import hsv_to_rgb
8
9class guiOverlay(pyrouteModule):
10    def __init__(self, modules):
11        pyrouteModule.__init__(self, modules)
12        self.modules = modules
13        self.icons = menuIcons()
14        self.menus = loadMenus('Menus')
15        self.dragbar = None
16        self.dragpos = 0
17
18    def fullscreen(self):
19        """Asks if the menu is fullscreen -- if it is, then the
20        map doesn't need to be drawn underneath"""
21        return(self.get('menu'))
22   
23    def handleDrag(self,dx,dy,startX,startY):
24      if(self.dragbar):
25        if(self.dragbar.contains(startX,startY)):
26          scale = -20.0 / float(self.rect.h)
27          self.dragpos = self.dragpos + dy * scale
28          if(self.dragpos < 0):
29            self.dragpos = 0
30          #print "Dragging %1.2f (by %1.2f * %1.2f)" % (self.dragpos, dy,scale)
31          return(True)
32      return(False)
33   
34    def handleClick(self,x,y):
35        """return 1 if click was handled"""
36        for cell in self.clickable:
37            if(cell.contains(x,y)):
38                if(cell.handleClick(x,y)):
39                    return(1)
40        if(self.fullscreen()):
41            return(1)
42        return(0)
43    def draw(self, cr, rect):
44        self.cr = cr
45        self.rect = overlayArea(cr,rect.x,rect.y,rect.width,rect.height,self.modules,self.icons)
46        nx = 3
47        ny = 4
48        self.clickable = []
49        self.cells = {}
50        rotate = (rect.width > rect.height)
51        if(not rotate):
52          dx = rect.width / nx
53          dy = rect.height / ny
54          for i in range(0,nx):
55              x1 = rect.x + i * dx
56              self.cells[i] = {}
57              for j in range(0,ny):
58                  y1 = rect.y + j * dy
59                  self.cells[i][j] = overlayArea(cr,x1,y1,dx,dy,self.modules, self.icons)
60                  self.clickable.append(self.cells[i][j])
61        else:
62          dy = rect.height / nx
63          dx = rect.width / ny
64          for i in range(0,nx):
65              y1 = rect.y + i * dy
66              self.cells[i] = {}
67              for j in range(0,ny):
68                  x1 = rect.x + j * dx
69                  self.cells[i][j] = overlayArea(cr,x1,y1,dx,dy,self.modules, self.icons)
70                  self.clickable.append(self.cells[i][j])
71         
72
73         
74        currentMenu = self.get('menu')
75        if(currentMenu):
76            self.drawMenu(currentMenu)
77        else:
78          self.mapOverlay()
79
80    def mapOverlay(self):
81      if(self.get("shaded")):
82        self.rect.fill(0,0,0,False,self.get("shade_amount",0.5))
83     
84      if(1):
85        self.cells[0][0].button("Menu",None,"hint")
86        self.cells[1][0].button("","zoom:out","zoom_out")
87        self.cells[2][0].button("","zoom:in","zoom_in")
88      else:
89              # Tickmark to show where the active button is
90              self.cr.set_line_width(2)
91              self.cr.set_dash((10,5), 0);
92              self.cr.set_source_rgba(0.4,0,0)
93              button = self.cells[0][0]
94              self.cr.move_to(button.xc(0.5),button.y2)
95              self.cr.line_to(button.x2,button.y2)
96              self.cr.line_to(button.x2,button.yc(0.5))
97              self.cr.stroke()
98   
99      # Make the buttons clickable
100      self.cells[0][0].setEvent("menu:main")
101     
102      # New-style zoom buttons on map: much smaller
103      if(0):
104        z1 = self.cells[2][0].copyself(0.5,0,1,0.5)
105        z2 = self.cells[2][0].copyself(0.5,0.5,1,1)
106        z1.button("ZOUT",None,None)
107        z2.button("ZIN",None,None)
108
109
110    def drawMenu(self, menu):
111      try:
112        self.genericMenu(self.menus[menu])
113        return
114      except KeyError:
115        menuName = 'menu_%s' % menu
116        try:
117          function = getattr(self, menuName)
118        except AttributeError:
119          print "Error: %s not defined" % menuName
120          self.set('menu','')
121          return
122        function()
123
124    def sketchOverlay(self):
125      colourMenu = self.cells[2][3]
126      r = float(self.get('sketch_r',0))
127      g = float(self.get('sketch_g',0))
128      b = float(self.get('sketch_b',0))
129      colourMenu.fill(r,g,b)
130      colourMenu.setEvent("menu:sketch_colour")
131      # TODO: all clickable places to global array/module
132         
133    def menu_gps(self):
134      self.backButton(0,0)
135     
136      selectLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
137      selectLine.icon("3h")
138      mode = self.get("PositionMode")
139      self.cells[0][1].button( \
140        "GPSd",
141        "option:set:PositionMode:gpsd",
142        mode == 'gpsd' and 'selected' or 'unselected')
143      self.cells[1][1].button( \
144        "Manual",
145        "option:set:PositionMode:manual",
146        mode == 'manual' and 'selected' or 'unselected')
147      self.cells[2][1].button( \
148        "pos.txt",
149        "option:set:PositionMode:txt",
150        mode == 'txt' and 'selected' or 'unselected')
151     
152    def menu_download(self):
153      self.backButton(0,0)
154
155      centreLine = self.cells[1][0].copyAndExtendTo(self.cells[2][0])
156      centreLine.icon("2h")
157     
158      self.cells[1][0].button( \
159        "Around me",
160        "option:set:DownloadCentre:pos",
161        self.get('DownloadCentre') == 'pos' and 'selected' or 'unselected')
162      self.cells[2][0].button( \
163        "Destination",
164        "option:set:DownloadRange:dest",
165        self.get('DownloadCentre') == 'dest' and 'selected' or 'unselected')
166       
167      dataTypeLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
168      dataTypeLine.icon("3h")
169     
170      self.cells[0][1].button( \
171        "Data",
172        "option:toggle:DownloadData",
173        self.get('DownloadData') and 'checked' or 'unchecked')
174      self.cells[1][1].button( \
175        "Maps",
176        "option:toggle:DownloadMaps",
177        self.get('DownloadMaps') and 'checked' or 'unchecked')
178      self.cells[2][1].button( \
179        "POI",
180        "option:toggle:DownloadPOI",
181        self.get('DownloadPOI') and 'checked' or 'unchecked')
182
183      distanceLine = self.cells[0][2].copyAndExtendTo(self.cells[2][2])
184      distanceLine.icon("3h")
185     
186      self.cells[0][2].button( \
187        "20km",
188        "option:set:DownloadRange:20",
189        self.get('DownloadRange') == '20' and 'selected' or 'unselected')
190      self.cells[1][2].button( \
191        "100km",
192        "option:set:DownloadRange:100",
193        self.get('DownloadRange') == '100' and 'selected' or 'unselected')
194      self.cells[2][2].button( \
195        "500km",
196        "option:set:DownloadRange:500",
197        self.get('DownloadRange') == '500' and 'selected' or 'unselected')
198     
199      detailLine = self.cells[0][3].copyAndExtendTo(self.cells[1][3])
200      detailLine.icon("2h")
201     
202      self.cells[0][3].button( \
203        "This zoom",
204        "option:set:DownloadDetail:selected",
205        self.get('DownloadDetail') == 'selected' and 'selected' or 'unselected')
206      self.cells[1][3].button( \
207        "All zoom",
208        "option:set:DownloadDetail:all",
209        self.get('DownloadDetail') == 'all' and 'selected' or 'unselected')
210     
211      self.cells[2][3].button("Go","download:","download")
212
213
214    def menu_sketch_colour(self):
215      self.backButton(0,0)
216      self.colourMenu(1,0, 0,1,0, 'sketch')
217      self.colourMenu(2,0, 0,0,1, 'sketch')
218      self.colourMenu(0,1, 1,1,0, 'sketch')
219      self.colourMenu(1,1, 0,1,1, 'sketch')
220      self.colourMenu(2,1, 1,0,1, 'sketch')
221      self.colourMenu(0,2, 1,0,0, 'sketch')
222      self.colourMenu(1,2, 0,0,0, 'sketch')
223      self.colourMenu(2,2, 1,1,1, 'sketch')
224     
225    def colourMenu(self,x,y,r,g,b,use):
226      self.cells[x][y].fill(r,g,b)
227      self.cells[x][y].setEvent("+set_colour:%s:%1.2f:%1.2f:%1.2f" % (use,r,g,b))
228     
229   
230    def backButton(self,i,j):
231        self.cells[i][j].button("","menu:","up")
232    def genericMenu(self, menu):
233      for y in range(4):
234        for x in range(3):
235          item = menu["%d,%d"%(x,y)]
236          if item['name'] == 'Up':
237            self.backButton(x,y)
238          else:
239            self.cells[x][y].button(item['name'],item['action'],item['icon'])
240
241    def menu_feeds(self):
242      self.menu_list("rss")
243    def menu_geonames(self):
244      self.menu_list("geonames")
245    def menu_waypoints(self):
246      self.menu_list("waypoints")
247    def menu_poi(self):
248      self.menu_list("osm")
249     
250    def menu_list(self, module):
251      self.backButton(0,0)
252      n = 9
253      offset = int(self.dragpos)
254      selectedFeed = int(self.get('selectedFeed',0))
255      titlebar = self.rect.copyself(1.0/3.0,0,1,0.25)
256      line1, line2 = titlebar.ysplit(0.5)
257      back = line1.copyself(0,0,0.25,1)
258      next = line1.copyself(0.75,0,1,1)
259      back.button("","option:add:selectedFeed:-1","back")
260      next.button("","option:add:selectedFeed:1","next")
261      self.clickable.append(back)
262      self.clickable.append(next)
263
264      self.dragbar = self.rect.copyself(0.0,0.25,0.88,1.0)
265
266      try:
267        group = self.modules['poi'][module].groups[selectedFeed]
268      except KeyError:
269        line2.drawText("\"%s\" not loaded"%module)
270        return
271      except IndexError:
272        line2.drawText("No such set #%d"%selectedFeed)
273        return
274       
275      group.sort(self.get('ownpos'))
276     
277      line1.copyself(0.28,0,0.73,1).drawText("Set %d of %d" % (selectedFeed + 1, len(self.modules['poi'][module].groups)))
278     
279      line2.drawText(group.name)
280     
281      listrect = self.rect.ysplitn(0, 0.25, 1.0, 1, n)
282      ownpos = self.get('ownpos')
283      for i in range(0,n):
284        textarea, button = listrect[i].xsplit(0.88)
285        color, textarea = textarea.xsplit(0.025)
286       
287        # Pattern for the left hand side to show how far down the list
288        # we are - model it as a colour, where red is the top, and purple
289        # is bottom
290        h = float(i + offset) / float(len(group.items))
291        v = (((i + offset) % 2) == 0) and 1.0 or 0.95
292        r,g,b = hsv_to_rgb(h, 1, v)
293        color.fill(r,g,b)
294       
295        if(i > 0):
296          self.cr.set_line_width(0.5)
297          self.cr.set_dash((2,2,2), 0);
298          self.cr.set_source_rgb(0,0,0)
299          self.cr.move_to(textarea.x1,textarea.y1)
300          self.cr.line_to(textarea.x2,textarea.y1)
301          self.cr.stroke()
302        try:
303          item = group.items[i + offset]
304          textarea.drawTextSomewhere(item.formatText(), 0.1,0.1,0.9,0.5)
305          textarea.drawTextSomewhere(item.formatPos(ownpos), 0.1,0.6,0.9,0.9)
306          button.button("", "+route:%1.5f:%1.5f" % (item.lat, item.lon), "goto")
307          self.clickable.append(button)
308        except IndexError:
309          pass
310
311    def menu_main(self):
312        self.backButton(0,0)
313
314
315        self.cells[0][1].button("View","menu:view","view")
316        self.cells[1][1].button("GPS","menu:gps","gps")
317        self.cells[2][1].button("Download","menu:download","download")
318
319        self.cells[0][2].button("Data","menu:data","data")
320        self.cells[1][2].button("","",None)
321        self.checkbox(2,2,"Sketch mode","sketch",True)
322
323        self.checkbox(0,3, "Centre me","centred")
324        #self.cells[1][3].button("Options","menu:options",None)
325        self.cells[1][3].button(None,None,None)
326        self.cells[2][3].button("Mode","menu:mode","mode")
327
328    def checkbox(self, x,y, label, setting, returnToMap = False):
329      button = self.cells[x][y]
330      button.icon("generic")
331      action = "option:toggle:%s" % setting
332      if(returnToMap):
333        action = "+" + action
334      button.button(label, action, self.get(setting) and "checked" or "unchecked")
335   
336    def menu_click(self):
337        self.backButton(0,0)
338       
339        latlonRect = self.rect.copyself(0.33,0,1,0.25)
340        latRect = latlonRect.copyself(0,0,1,0.5)
341        lonRect = latlonRect.copyself(0,0.5,1,1)
342       
343        lat,lon = self.get('clicked')
344       
345        NS = lat > 0 and 'N' or 'S'
346        EW = lon > 0 and 'E' or 'W'
347       
348        latRect.drawTextSomewhere('%1.4f %s' % (abs(lat), NS), 0.05, 0.05, 0.7, 0.95)
349        lonRect.drawTextSomewhere('%1.4f %s' % (abs(lon), EW), 0.3, 0.05, 0.95, 0.95)
350        #def drawTextSomewhere(self,text,px1,py1,px2,py2):
351        #innerBox = self.copyself(px1,py1,px2,py2)
352        #innerBox.drawText(text)
353   
354        #self.cells[1][0].button("(lat)",None,None)
355        #self.cells[2][0].button("(lon)",None,None)
356
357        self.cells[0][1].button("set pos","+ownpos:clicked","set_pos")
358        self.cells[1][1].button("route to","+route:clicked","route_to")
359        self.cells[2][1].button("direct to","+direct:clicked","direct_to")
360
361        self.cells[0][2].button("waypoint", "+add_waypoint:clicked", "bookmarks")
362        self.cells[1][2].button("extend route", "+extend:route:clicked", "extend_route")
363        self.cells[2][2].button("extend direct", "+extend:direct:clicked", "extend_direct")
364
365        self.cells[0][3].button("",None,None)
366        self.cells[1][3].button("",None,None)
367        self.cells[2][3].button("",None,None)
368
369    def menu_options(self):
370        view,scroll = self.rect.xsplit(0.8)
371        view.fill(1,0,0)
372        scroll.fill(0,1,0)
373        self.backButton(0,0)
374
375
376if __name__ == "__main__":
377    a = guiOverlay(None,None)
378    print dir(a)
Note: See TracBrowser for help on using the repository browser.