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

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

Make zoom in/out buttons the right way around

File size: 12.9 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    def drawMenu(self, menu):
100      try:
101        self.genericMenu(self.menus[menu])
102        return
103      except KeyError:
104        menuName = 'menu_%s' % menu
105        try:
106          function = getattr(self, menuName)
107        except AttributeError:
108          print "Error: %s not defined" % menuName
109          self.set('menu','')
110          return
111        function()
112
113    def sketchOverlay(self):
114      colourMenu = self.cells[2][3]
115      r = float(self.get('sketch_r',0))
116      g = float(self.get('sketch_g',0))
117      b = float(self.get('sketch_b',0))
118      colourMenu.fill(r,g,b)
119      colourMenu.setEvent("menu:sketch_colour")
120      # TODO: all clickable places to global array/module
121         
122    def menu_gps(self):
123      self.backButton(0,0)
124     
125      selectLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
126      selectLine.icon("3h")
127      mode = self.get("PositionMode")
128      self.cells[0][1].button( \
129        "GPSd",
130        "option:set:PositionMode:gpsd",
131        mode == 'gpsd' and 'selected' or 'unselected')
132      self.cells[1][1].button( \
133        "Manual",
134        "option:set:PositionMode:manual",
135        mode == 'manual' and 'selected' or 'unselected')
136      self.cells[2][1].button( \
137        "pos.txt",
138        "option:set:PositionMode:txt",
139        mode == 'txt' and 'selected' or 'unselected')
140     
141    def menu_download(self):
142      self.backButton(0,0)
143
144      centreLine = self.cells[1][0].copyAndExtendTo(self.cells[2][0])
145      centreLine.icon("2h")
146     
147      self.cells[1][0].button( \
148        "Around me",
149        "option:set:DownloadCentre:pos",
150        self.get('DownloadCentre') == 'pos' and 'selected' or 'unselected')
151      self.cells[2][0].button( \
152        "Destination",
153        "option:set:DownloadRange:dest",
154        self.get('DownloadCentre') == 'dest' and 'selected' or 'unselected')
155       
156      dataTypeLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
157      dataTypeLine.icon("3h")
158     
159      self.cells[0][1].button( \
160        "Data",
161        "option:toggle:DownloadData",
162        self.get('DownloadData') and 'checked' or 'unchecked')
163      self.cells[1][1].button( \
164        "Maps",
165        "option:toggle:DownloadMaps",
166        self.get('DownloadMaps') and 'checked' or 'unchecked')
167      self.cells[2][1].button( \
168        "POI",
169        "option:toggle:DownloadPOI",
170        self.get('DownloadPOI') and 'checked' or 'unchecked')
171
172      distanceLine = self.cells[0][2].copyAndExtendTo(self.cells[2][2])
173      distanceLine.icon("3h")
174     
175      self.cells[0][2].button( \
176        "20km",
177        "option:set:DownloadRange:20",
178        self.get('DownloadRange') == '20' and 'selected' or 'unselected')
179      self.cells[1][2].button( \
180        "100km",
181        "option:set:DownloadRange:100",
182        self.get('DownloadRange') == '100' and 'selected' or 'unselected')
183      self.cells[2][2].button( \
184        "500km",
185        "option:set:DownloadRange:500",
186        self.get('DownloadRange') == '500' and 'selected' or 'unselected')
187     
188      detailLine = self.cells[0][3].copyAndExtendTo(self.cells[1][3])
189      detailLine.icon("2h")
190     
191      self.cells[0][3].button( \
192        "This zoom",
193        "option:set:DownloadDetail:selected",
194        self.get('DownloadDetail') == 'selected' and 'selected' or 'unselected')
195      self.cells[1][3].button( \
196        "All zoom",
197        "option:set:DownloadDetail:all",
198        self.get('DownloadDetail') == 'all' and 'selected' or 'unselected')
199     
200      self.cells[2][3].button("Go","download:","download")
201
202
203    def menu_sketch_colour(self):
204      self.backButton(0,0)
205      self.colourMenu(1,0, 0,1,0, 'sketch')
206      self.colourMenu(2,0, 0,0,1, 'sketch')
207      self.colourMenu(0,1, 1,1,0, 'sketch')
208      self.colourMenu(1,1, 0,1,1, 'sketch')
209      self.colourMenu(2,1, 1,0,1, 'sketch')
210      self.colourMenu(0,2, 1,0,0, 'sketch')
211      self.colourMenu(1,2, 0,0,0, 'sketch')
212      self.colourMenu(2,2, 1,1,1, 'sketch')
213     
214    def colourMenu(self,x,y,r,g,b,use):
215      self.cells[x][y].fill(r,g,b)
216      self.cells[x][y].setEvent("+set_colour:%s:%1.2f:%1.2f:%1.2f" % (use,r,g,b))
217     
218   
219    def backButton(self,i,j):
220        self.cells[i][j].button("","menu:","up")
221    def genericMenu(self, menu):
222      for y in range(4):
223        for x in range(3):
224          item = menu["%d,%d"%(x,y)]
225          if item['name'] == 'Up':
226            self.backButton(x,y)
227          else:
228            self.cells[x][y].button(item['name'],item['action'],item['icon'])
229
230    def menu_feeds(self):
231      self.menu_list("rss")
232    def menu_geonames(self):
233      self.menu_list("geonames")
234    def menu_waypoints(self):
235      self.menu_list("waypoints")
236     
237    def menu_list(self, module):
238      self.backButton(0,0)
239      n = 9
240      offset = int(self.dragpos)
241      selectedFeed = int(self.get('selectedFeed',0))
242      titlebar = self.rect.copyself(1.0/3.0,0,1,0.25)
243      line1, line2 = titlebar.ysplit(0.5)
244      back = line1.copyself(0,0,0.25,1)
245      next = line1.copyself(0.75,0,1,1)
246      back.button("","option:add:selectedFeed:-1","back")
247      next.button("","option:add:selectedFeed:1","next")
248      self.clickable.append(back)
249      self.clickable.append(next)
250
251
252      self.dragbar = self.rect.copyself(0.0,0.25,0.88,1.0)
253
254      try:
255        group = self.modules['poi'][module].groups[selectedFeed]
256      except KeyError:
257        line2.drawText("\"%s\" not loaded"%module)
258        return
259      except IndexError:
260        line2.drawText("No such set #%d"%selectedFeed)
261        return
262     
263      line1.copyself(0.28,0,0.73,1).drawText("Set %d of %d" % (selectedFeed + 1, len(self.modules['poi'][module].groups)))
264     
265      line2.drawText(group.name)
266     
267      listrect = self.rect.ysplitn(0, 0.25, 1.0, 1, n)
268      ownpos = self.get('ownpos')
269      for i in range(0,n):
270        textarea, button = listrect[i].xsplit(0.88)
271        color, textarea = textarea.xsplit(0.025)
272       
273        # Pattern for the left hand side to show how far down the list
274        # we are - model it as a colour, where red is the top, and purple
275        # is bottom
276        h = float(i + offset) / float(len(group.items))
277        v = (((i + offset) % 2) == 0) and 1.0 or 0.95
278        r,g,b = hsv_to_rgb(h, 1, v)
279        color.fill(r,g,b)
280       
281        if(i > 0):
282          self.cr.set_line_width(0.5)
283          self.cr.set_dash((2,2,2), 0);
284          self.cr.set_source_rgb(0,0,0)
285          self.cr.move_to(textarea.x1,textarea.y1)
286          self.cr.line_to(textarea.x2,textarea.y1)
287          self.cr.stroke()
288        try:
289          item = group.items[i + offset]
290          textarea.drawTextSomewhere(item.formatText(), 0.1,0.1,0.9,0.5)
291          textarea.drawTextSomewhere(item.formatPos(ownpos), 0.1,0.6,0.9,0.9)
292          button.button("", "+route:%1.5f:%1.5f" % (item.lat, item.lon), "goto")
293          self.clickable.append(button)
294        except IndexError:
295          pass
296
297    def menu_main(self):
298        self.backButton(0,0)
299        self.cells[1][0].button("Zoom out","+zoom:out",None)
300        self.cells[2][0].button("Zoom in","+zoom:in",None)
301
302        self.cells[0][1].button("View","menu:view","view")
303        self.cells[1][1].button("GPS","menu:gps","gps")
304        self.cells[2][1].button("Download","menu:download","download")
305
306        self.cells[0][2].button("Data","menu:data","data")
307        self.cells[1][2].button("","",None)
308        self.checkbox(2,2,"Sketch mode","sketch",True)
309
310        self.checkbox(0,3, "Centre me","centred")
311        #self.cells[1][3].button("Options","menu:options",None)
312        self.cells[1][3].button(None,None,None)
313        self.cells[2][3].button("Mode","menu:mode","mode")
314
315    def checkbox(self, x,y, label, setting, returnToMap = False):
316      button = self.cells[x][y]
317      button.icon("generic")
318      action = "option:toggle:%s" % setting
319      if(returnToMap):
320        action = "+" + action
321      button.button(label, action, self.get(setting) and "checked" or "unchecked")
322   
323    def menu_click(self):
324        self.backButton(0,0)
325       
326        latlonRect = self.rect.copyself(0.33,0,1,0.25)
327        latRect = latlonRect.copyself(0,0,1,0.5)
328        lonRect = latlonRect.copyself(0,0.5,1,1)
329       
330        lat,lon = self.get('clicked')
331       
332        NS = lat > 0 and 'N' or 'S'
333        EW = lon > 0 and 'E' or 'W'
334       
335        latRect.drawTextSomewhere('%1.4f %s' % (abs(lat), NS), 0.05, 0.05, 0.7, 0.95)
336        lonRect.drawTextSomewhere('%1.4f %s' % (abs(lon), EW), 0.3, 0.05, 0.95, 0.95)
337        #def drawTextSomewhere(self,text,px1,py1,px2,py2):
338        #innerBox = self.copyself(px1,py1,px2,py2)
339        #innerBox.drawText(text)
340   
341        #self.cells[1][0].button("(lat)",None,None)
342        #self.cells[2][0].button("(lon)",None,None)
343
344        self.cells[0][1].button("set pos","+ownpos:clicked","set_pos")
345        self.cells[1][1].button("route to","+route:clicked","route_to")
346        self.cells[2][1].button("direct to","+direct:clicked","direct_to")
347
348        self.cells[0][2].button("waypoint", "+add_waypoint:clicked", "bookmarks")
349        self.cells[1][2].button("extend route", "+extend:route:clicked", "extend_route")
350        self.cells[2][2].button("extend direct", "+extend:direct:clicked", "extend_direct")
351
352        self.cells[0][3].button("",None,None)
353        self.cells[1][3].button("",None,None)
354        self.cells[2][3].button("",None,None)
355
356    def menu_options(self):
357        view,scroll = self.rect.xsplit(0.8)
358        view.fill(1,0,0)
359        scroll.fill(0,1,0)
360        self.backButton(0,0)
361
362
363if __name__ == "__main__":
364    a = guiOverlay(None,None)
365    print dir(a)
Note: See TracBrowser for help on using the repository browser.