source: subversion/applications/routing/pyroute-dev/overlay.py @ 18447

Last change on this file since 18447 was 18447, checked in by buerste, 10 years ago

-modifying file intro

File size: 15.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5"""
6
7__version__ = "$Rev$"
8__license__ = """This program is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>."""
20_debug = 0
21
22
23import cairo
24import os
25from base import pyrouteModule
26from pyrouteMenu import *
27from menuIcons import menuIcons
28from overlayArea import overlayArea
29from colorsys import hsv_to_rgb
30import geometry
31
32class guiOverlay(pyrouteModule):
33    def __init__(self, modules):
34        pyrouteModule.__init__(self, modules)
35        self.modules = modules
36        self.icons = menuIcons()
37        self.menus = loadMenus(os.path.join(os.path.dirname(__file__), 'Menus'))
38        self.dragbar = None
39        self.dragpos = 0
40
41    def fullscreen(self):
42        """Asks if the menu is fullscreen -- if it is, then the
43        map doesn't need to be drawn underneath"""
44        return(self.get('menu'))
45   
46    def handleDrag(self,dx,dy,startX,startY):
47      if(self.dragbar):
48        if(self.dragbar.contains(startX,startY)):
49          scale = -20.0 / float(self.rect.h)
50          self.dragpos = self.dragpos + dy * scale
51          if(self.dragpos < 0):
52            self.dragpos = 0
53          #print "Dragging %1.2f (by %1.2f * %1.2f)" % (self.dragpos, dy,scale)
54          return(True)
55      return(False)
56   
57    def handleClick(self,x,y):
58        """return 1 if click was handled"""
59        for cell in self.clickable:
60            if(cell.contains(x,y)):
61                if(cell.handleClick(x,y)):
62                    return(1)
63        if(self.fullscreen()):
64            return(1)
65        return(0)
66    def draw(self, cr, rect):
67        self.cr = cr
68        self.rect = overlayArea(cr,rect.x,rect.y,rect.width,rect.height,self.modules,self.icons)
69        nx = 3
70        ny = 4
71        self.clickable = []
72        self.cells = {}
73        rotate = (rect.width > rect.height)
74        if(not rotate):
75          dx = rect.width / nx
76          dy = rect.height / ny
77          for i in range(0,nx):
78              x1 = rect.x + i * dx
79              self.cells[i] = {}
80              for j in range(0,ny):
81                  y1 = rect.y + j * dy
82                  self.cells[i][j] = overlayArea(cr,x1,y1,dx,dy,self.modules, self.icons)
83                  self.clickable.append(self.cells[i][j])
84        else:
85          dy = rect.height / nx
86          dx = rect.width / ny
87          for i in range(0,nx):
88              y1 = rect.y + i * dy
89              self.cells[i] = {}
90              for j in range(0,ny):
91                  x1 = rect.x + j * dx
92                  self.cells[i][j] = overlayArea(cr,x1,y1,dx,dy,self.modules, self.icons)
93                  self.clickable.append(self.cells[i][j])
94         
95
96         
97        currentMenu = self.get('menu')
98        if(currentMenu):
99            self.drawMenu(currentMenu)
100        else:
101          self.mapOverlay()
102
103    def mapOverlay(self):
104      if(self.get("shaded")):
105        self.rect.fill(0,0,0,False,self.get("shade_amount",0.5))
106     
107      if(1):
108        self.cells[0][0].button("Menu",None,"hint")
109        self.cells[1][0].button("","zoom:out","zoom_out")
110        self.cells[2][0].button("","zoom:in","zoom_in")
111      else:
112              # Tickmark to show where the active button is
113              self.cr.set_line_width(2)
114              self.cr.set_dash((10,5), 0);
115              self.cr.set_source_rgba(0.4,0,0)
116              button = self.cells[0][0]
117              self.cr.move_to(button.xc(0.5),button.y2)
118              self.cr.line_to(button.x2,button.y2)
119              self.cr.line_to(button.x2,button.yc(0.5))
120              self.cr.stroke()
121   
122      # Make the buttons clickable
123      self.cells[0][0].setEvent("menu:main")
124     
125      # New-style zoom buttons on map: much smaller
126      if(0):
127        z1 = self.cells[2][0].copyself(0.5,0,1,0.5)
128        z2 = self.cells[2][0].copyself(0.5,0.5,1,1)
129        z1.button("ZOUT",None,None)
130        z2.button("ZIN",None,None)
131
132
133    def drawMenu(self, menu):
134      try:
135        self.genericMenu(self.menus[menu])
136        return
137      except KeyError:
138        menuName = 'menu_%s' % menu
139        try:
140          function = getattr(self, menuName)
141        except AttributeError:
142          print "Error: %s not defined" % menuName
143          self.set('menu','')
144          return
145        function()
146
147    def sketchOverlay(self):
148      colourMenu = self.cells[2][3]
149      r = float(self.get('sketch_r',0))
150      g = float(self.get('sketch_g',0))
151      b = float(self.get('sketch_b',0))
152      colourMenu.fill(r,g,b)
153      colourMenu.setEvent("menu:sketch_colour")
154      # TODO: all clickable places to global array/module
155         
156    def menu_gps(self):
157      self.backButton(0,0)
158     
159      selectLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
160      selectLine.icon("3h")
161      mode = self.get("PositionMode")
162      self.cells[0][1].button( \
163        "GPSd",
164        "option:set:PositionMode:gpsd",
165        mode == 'gpsd' and 'selected' or 'unselected')
166      self.cells[1][1].button( \
167        "Manual",
168        "option:set:PositionMode:manual",
169        mode == 'manual' and 'selected' or 'unselected')
170      self.cells[2][1].button( \
171        "pos.txt",
172        "option:set:PositionMode:txt",
173        mode == 'txt' and 'selected' or 'unselected')
174     
175    def menu_download(self):
176      self.backButton(0,0)
177      self.cells[0][1].button('Routes', 'menu:download_data', None)
178      self.cells[1][1].button('Tiles', 'menu:download_tiles', None)
179      self.cells[2][1].button('POI', None, None)
180
181    def menu_download_data(self):
182      self.backButton(0,0)
183
184
185      distanceLine = self.cells[0][2].copyAndExtendTo(self.cells[2][2])
186      distanceLine.icon("3h")
187     
188      self.cells[0][2].button( \
189        "20km",
190        "option:set:DownloadRange:20",
191        self.get('DownloadRange') == '20' and 'selected' or 'unselected')
192      self.cells[1][2].button( \
193        "100km",
194        "option:set:DownloadRange:100",
195        self.get('DownloadRange') == '100' and 'selected' or 'unselected')
196      self.cells[2][2].button( \
197        "500km",
198        "option:set:DownloadRange:500",
199        self.get('DownloadRange') == '500' and 'selected' or 'unselected')
200     
201      self.cells[2][3].button("Go","+download:","download")
202
203    def menu_download_tiles(self):
204      self.backButton(0,0)
205     
206
207      distanceLine = self.cells[0][1].copyAndExtendTo(self.cells[2][1])
208      distanceLine.icon("3h")
209     
210      self.cells[0][1].button( \
211        "20km",
212        "option:set:DownloadRange:20",
213        self.get('DownloadRange') == '20' and 'selected' or 'unselected')
214      self.cells[1][1].button( \
215        "100km",
216        "option:set:DownloadRange:70",
217        self.get('DownloadRange') == '70' and 'selected' or 'unselected')
218      self.cells[2][1].button( \
219        "500km",
220        "option:set:DownloadRange:150",
221        self.get('DownloadRange') == '150' and 'selected' or 'unselected')
222           
223      centreLine = self.cells[0][2].copyAndExtendTo(self.cells[2][2])
224      centreLine.icon("3h")
225     
226      self.cells[0][2].button( \
227        "Around me",
228        "option:set:DownloadCentre:pos",
229        self.get('DownloadCentre') == 'pos' and 'selected' or 'unselected')
230      self.cells[1][2].button( \
231        "Around route",
232        "option:set:DownloadCentre:route",
233        self.get('DownloadCentre') == 'route' and 'selected' or 'unselected')
234      self.cells[2][2].button( \
235        "Destination",
236        "option:set:DownloadCentre:dest",
237        self.get('DownloadCentre') == 'dest' and 'selected' or 'unselected')
238       
239      detailLine = self.cells[0][3].copyAndExtendTo(self.cells[1][3])
240      detailLine.icon("2h")
241     
242      self.cells[0][3].button( \
243        "This zoom",
244        "option:set:DownloadDetail:selected",
245        self.get('DownloadDetail') == 'selected' and 'selected' or 'unselected')
246      self.cells[1][3].button( \
247        "All zoom",
248        "option:set:DownloadDetail:all",
249        self.get('DownloadDetail') == 'all' and 'selected' or 'unselected')
250     
251      self.cells[2][3].button("Go","+download_tiles:","download")
252
253
254    def menu_sketch_colour(self):
255      self.backButton(0,0)
256      self.colourMenu(1,0, 0,1,0, 'sketch')
257      self.colourMenu(2,0, 0,0,1, 'sketch')
258      self.colourMenu(0,1, 1,1,0, 'sketch')
259      self.colourMenu(1,1, 0,1,1, 'sketch')
260      self.colourMenu(2,1, 1,0,1, 'sketch')
261      self.colourMenu(0,2, 1,0,0, 'sketch')
262      self.colourMenu(1,2, 0,0,0, 'sketch')
263      self.colourMenu(2,2, 1,1,1, 'sketch')
264     
265    def colourMenu(self,x,y,r,g,b,use):
266      self.cells[x][y].fill(r,g,b)
267      self.cells[x][y].setEvent("+set_colour:%s:%1.2f:%1.2f:%1.2f" % (use,r,g,b))
268     
269   
270    def backButton(self,i,j):
271        self.cells[i][j].button("","menu:","up")
272    def genericMenu(self, menu):
273      for y in range(4):
274        for x in range(3):
275          item = menu["%d,%d"%(x,y)]
276          if item['name'] == 'Up':
277            self.backButton(x,y)
278          else:
279            self.cells[x][y].button(item['name'],item['action'],item['icon'])
280
281    def menu_feeds(self):
282      self.menu_list("rss")
283    def menu_geonames(self):
284      self.menu_list("geonames")
285    def menu_waypoints(self):
286      self.menu_list("waypoints")
287    def menu_poi(self):
288      self.menu_list("osm")
289     
290    def menu_list(self, module):
291      self.backButton(0,0)
292      selectedFeed = int(self.get('selectedFeed',0))
293      titlebar = self.rect.copyself(1.0/3.0,0,1,0.25)
294      line1, line2 = titlebar.ysplit(0.5)
295      back = line1.copyself(0,0,0.25,1)
296      next = line1.copyself(0.75,0,1,1)
297      back.button("","option:add:selectedFeed:-1","back")
298      next.button("","option:add:selectedFeed:1","next")
299      self.clickable.append(back)
300      self.clickable.append(next)
301
302      try:
303        group = self.modules['poi'][module].groups[selectedFeed]
304      except KeyError:
305        line2.drawText("\"%s\" not loaded"%module)
306        return
307      except IndexError:
308        line2.drawText("No such set #%d"%selectedFeed)
309        return
310       
311      group.sort(self.get('ownpos'))
312     
313      line1.copyself(0.28,0,0.73,1).drawText("Set %d of %d" % (selectedFeed + 1, len(self.modules['poi'][module].groups)))
314     
315      line2.drawText(group.name)
316      self.drawListableItem(group)
317     
318    def drawListableItem(self,group):
319      n = 9
320      offset = int(self.dragpos)
321      listrect = self.rect.ysplitn(0, 0.25, 1.0, 1, n)
322      ownpos = self.get('ownpos')
323     
324      self.dragbar = self.rect.copyself(0.0,0.25,0.88,1.0)
325     
326      listLen = group.numItems()
327      for i in range(0,n):
328       
329        itemNum = i + offset
330        if(itemNum >= listLen):
331          return
332
333        # Separate area
334        textarea, button = listrect[i].xsplit(0.88)
335        color, textarea = textarea.xsplit(0.025)
336       
337        # Pattern for the left hand side to show how far down the list
338        # we are - model it as a colour, where red is the top, and purple
339        # is bottom
340        h = float(itemNum) / float(listLen)
341        v = (((i + offset) % 2) == 0) and 1.0 or 0.95
342        r,g,b = hsv_to_rgb(h, 1, v)
343        color.fill(r,g,b)
344       
345        if(i > 0):
346          # Line between list items
347          self.cr.set_line_width(0.5)
348          self.cr.set_dash((2,2,2), 0);
349          self.cr.set_source_rgb(0,0,0)
350          self.cr.move_to(textarea.x1,textarea.y1)
351          self.cr.line_to(textarea.x2,textarea.y1)
352          self.cr.stroke()
353        try:
354          # Draw each item
355          label = group.getItemText(itemNum)
356          textarea.drawTextSomewhere(label, 0.1,0.1,0.9,0.5)
357         
358          action = None
359          if(group.isLocation(itemNum)):
360            location = group.getItemLatLon(itemNum)
361            subtitleText = self.formatPosition(location, ownpos)
362            action = "+route:%1.5f:%1.5f" % (location[0], location[1])
363          else:
364            subtitleText = group.getItemStatus(itemNum)
365            if(group.getItemClickable(itemNum)):
366              action = group.getItemAction(itemNum)
367          textarea.drawTextSomewhere(subtitleText, 0.1,0.6,0.9,0.9)
368         
369          if(action != None):
370            button.button("", action, "goto")
371            self.clickable.append(button)
372           
373        except IndexError:
374          pass
375       
376    def formatPosition(self,pos, ownPos = None):
377      if(ownPos and ownPos['valid']):
378        a = (ownPos['lat'], ownPos['lon'])
379        b = pos
380        return("%1.2fkm %s" % \
381          (geometry.distance(a,b),
382          geometry.compassPoint(geometry.bearing(a,b))))
383      else:
384        return("%f,%f" % (self.lat,self.lon))
385   
386    def menu_meta(self):
387      self.backButton(0,0)
388      self.drawListableItem(self.m["meta"])
389     
390    def menu_main(self):
391        self.backButton(0,0)
392        self.checkbox(2,0,"Sketch mode","sketch",True)
393
394        self.cells[0][1].button("View","menu:view","view")
395        self.cells[1][1].button("GPS","menu:gps","gps")
396        self.cells[2][1].button("Download","menu:download","download")
397
398        self.cells[0][2].button("Data","menu:data","data")
399        self.cells[1][2].button("","",None)
400        self.cells[1][2].button("","",None)
401
402        self.checkbox(0,3, "Centre me","centred")
403        #self.cells[1][3].button("Options","menu:options",None)
404        self.cells[1][3].button("Meta","menu:meta",None)
405        self.cells[2][3].button("Mode","menu:mode","mode")
406
407    def checkbox(self, x,y, label, setting, returnToMap = False):
408      button = self.cells[x][y]
409      button.icon("generic")
410      action = "option:toggle:%s" % setting
411      if(returnToMap):
412        action = "+" + action
413      button.button(label, action, self.get(setting) and "checked" or "unchecked")
414   
415    def menu_click(self):
416        self.backButton(0,0)
417       
418        latlonRect = self.rect.copyself(0.33,0,1,0.25)
419        latRect = latlonRect.copyself(0,0,1,0.5)
420        lonRect = latlonRect.copyself(0,0.5,1,1)
421       
422        lat,lon = self.get('clicked')
423       
424        NS = lat > 0 and 'N' or 'S'
425        EW = lon > 0 and 'E' or 'W'
426       
427        latRect.drawTextSomewhere('%1.4f %s' % (abs(lat), NS), 0.05, 0.05, 0.7, 0.95)
428        lonRect.drawTextSomewhere('%1.4f %s' % (abs(lon), EW), 0.3, 0.05, 0.95, 0.95)
429        #def drawTextSomewhere(self,text,px1,py1,px2,py2):
430        #innerBox = self.copyself(px1,py1,px2,py2)
431        #innerBox.drawText(text)
432   
433        #self.cells[1][0].button("(lat)",None,None)
434        #self.cells[2][0].button("(lon)",None,None)
435
436        self.cells[0][1].button("set pos","+ownpos:clicked","set_pos")
437        self.cells[1][1].button("route to","+route:clicked","route_to")
438        self.cells[2][1].button("direct to","+direct:clicked","direct_to")
439
440        self.cells[0][2].button("waypoint", "+add_waypoint:clicked", "bookmarks")
441        self.cells[1][2].button("extend route", "+extend:route:clicked", "extend_route")
442        self.cells[2][2].button("extend direct", "+extend:direct:clicked", "extend_direct")
443
444        self.cells[0][3].button("",None,None)
445        self.cells[1][3].button("",None,None)
446        self.cells[2][3].button("",None,None)
447
448    def menu_options(self):
449        view,scroll = self.rect.xsplit(0.8)
450        view.fill(1,0,0)
451        scroll.fill(0,1,0)
452        self.backButton(0,0)
453
454
455if __name__ == "__main__":
456    a = guiOverlay(None,None)
457    print dir(a)
Note: See TracBrowser for help on using the repository browser.