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

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

idea for more zoom buttons (smaller copy, on main map)

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