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

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

Use tickmarks instead of circles to show the 3 transparent buttons (menu, zoom in, zoom out) on the main map

File size: 8.5 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        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        currentMenu = self.get('menu')
62        if(currentMenu):
63            self.drawMenu(currentMenu)
64        else:
65          self.mapOverlay()
66
67    def mapOverlay(self):
68      # Tickmarks to show where the 3 active buttons are
69      self.cr.set_line_width(2)
70      self.cr.set_dash((10,5), 0);
71      self.cr.set_source_rgba(0.4,0,0)
72      for x in (0,1,2):
73        button = self.cells[x][0]
74        self.cr.move_to(button.x1,button.y2)
75        self.cr.line_to(button.x2,button.y2)
76        if(x < 2):
77          self.cr.line_to(button.x2,button.yc(0.7))
78      self.cr.stroke()
79     
80      # Make the buttons clickable
81      self.cells[0][0].setEvent("menu:main")
82      self.cells[1][0].setEvent("zoom:out")
83      self.cells[2][0].setEvent("zoom:in")
84
85     
86    def drawMenu(self, menu):
87      try:
88        self.genericMenu(self.menus[menu])
89        return
90      except KeyError:
91        menuName = 'menu_%s' % menu
92        try:
93          function = getattr(self, menuName)
94        except AttributeError:
95          print "Error: %s not defined" % menuName
96          self.set('menu','')
97          return
98        function()
99
100    def sketchOverlay(self):
101      colourMenu = self.cells[2][3]
102      r = float(self.get('sketch_r',0))
103      g = float(self.get('sketch_g',0))
104      b = float(self.get('sketch_b',0))
105      colourMenu.fill(r,g,b)
106      colourMenu.setEvent("menu:sketch_colour")
107      # TODO: all clickable places to global array/module
108         
109    def menu_sketch_colour(self):
110      self.backButton(0,0)
111      self.colourMenu(1,0, 0,1,0, 'sketch')
112      self.colourMenu(2,0, 0,0,1, 'sketch')
113      self.colourMenu(0,1, 1,1,0, 'sketch')
114      self.colourMenu(1,1, 0,1,1, 'sketch')
115      self.colourMenu(2,1, 1,0,1, 'sketch')
116      self.colourMenu(0,2, 1,0,0, 'sketch')
117      self.colourMenu(1,2, 0,0,0, 'sketch')
118      self.colourMenu(2,2, 1,1,1, 'sketch')
119     
120    def colourMenu(self,x,y,r,g,b,use):
121      self.cells[x][y].fill(r,g,b)
122      self.cells[x][y].setEvent("+set_colour:%s:%1.2f:%1.2f:%1.2f" % (use,r,g,b))
123     
124   
125    def backButton(self,i,j):
126        self.cells[i][j].button("","menu:","up")
127    def genericMenu(self, menu):
128      for y in range(4):
129        for x in range(3):
130          item = menu["%d,%d"%(x,y)]
131          if item['name'] == 'Up':
132            self.backButton(x,y)
133          else:
134            self.cells[x][y].button(item['name'],item['action'],item['icon'])
135
136    def menu_feeds(self):
137      self.menu_list("rss")
138    def menu_geonames(self):
139      self.menu_list("geonames")
140    def menu_waypoints(self):
141      self.menu_list("waypoints")
142     
143    def menu_list(self, module):
144      self.backButton(0,0)
145      n = 9
146      offset = int(self.dragpos)
147      selectedFeed = int(self.get('selectedFeed',0))
148      titlebar = self.rect.copyself(1.0/3.0,0,1,0.25)
149      line1, line2 = titlebar.ysplit(0.5)
150      back = line1.copyself(0,0,0.25,1)
151      next = line1.copyself(0.75,0,1,1)
152      back.button("","option:add:selectedFeed:-1","back")
153      next.button("","option:add:selectedFeed:1","next")
154      self.clickable.append(back)
155      self.clickable.append(next)
156
157
158      self.dragbar = self.rect.copyself(0.0,0.25,0.88,1.0)
159
160      try:
161        group = self.modules['poi'][module].groups[selectedFeed]
162      except KeyError:
163        line2.drawText("\"%s\" not loaded"%module)
164        return
165      except IndexError:
166        line2.drawText("No such set #%d"%selectedFeed)
167        return
168     
169      line1.copyself(0.28,0,0.73,1).drawText("Set %d of %d" % (selectedFeed + 1, len(self.modules['poi'][module].groups)))
170     
171      line2.drawText(group.name)
172     
173      listrect = self.rect.ysplitn(0, 0.25, 1.0, 1, n)
174      ownpos = self.get('ownpos')
175      for i in range(0,n):
176        textarea, button = listrect[i].xsplit(0.88)
177        color, textarea = textarea.xsplit(0.025)
178       
179        # Pattern for the left hand side to show how far down the list
180        # we are - model it as a colour, where red is the top, and purple
181        # is bottom
182        h = float(i + offset) / float(len(group.items))
183        v = (((i + offset) % 2) == 0) and 1.0 or 0.95
184        r,g,b = hsv_to_rgb(h, 1, v)
185        color.fill(r,g,b)
186       
187        if(i > 0):
188          self.cr.set_line_width(0.5)
189          self.cr.set_dash((2,2,2), 0);
190          self.cr.set_source_rgb(0,0,0)
191          self.cr.move_to(textarea.x1,textarea.y1)
192          self.cr.line_to(textarea.x2,textarea.y1)
193          self.cr.stroke()
194        try:
195          item = group.items[i + offset]
196          textarea.drawTextSomewhere(item.formatText(), 0.1,0.1,0.9,0.5)
197          textarea.drawTextSomewhere(item.formatPos(ownpos), 0.1,0.6,0.9,0.9)
198          button.button("", "+route:%1.5f:%1.5f" % (item.lat, item.lon), "goto")
199          self.clickable.append(button)
200        except IndexError:
201          pass
202
203    def menu_click(self):
204        self.backButton(0,0)
205       
206        latlonRect = self.rect.copyself(0.33,0,1,0.25)
207        latRect = latlonRect.copyself(0,0,1,0.5)
208        lonRect = latlonRect.copyself(0,0.5,1,1)
209       
210        lat,lon = self.get('clicked')
211       
212        NS = lat > 0 and 'N' or 'S'
213        EW = lon > 0 and 'E' or 'W'
214       
215        latRect.drawTextSomewhere('%1.4f %s' % (abs(lat), NS), 0.05, 0.05, 0.7, 0.95)
216        lonRect.drawTextSomewhere('%1.4f %s' % (abs(lon), EW), 0.3, 0.05, 0.95, 0.95)
217        #def drawTextSomewhere(self,text,px1,py1,px2,py2):
218        #innerBox = self.copyself(px1,py1,px2,py2)
219        #innerBox.drawText(text)
220   
221        #self.cells[1][0].button("(lat)",None,None)
222        #self.cells[2][0].button("(lon)",None,None)
223
224        self.cells[0][1].button("set pos","+ownpos:clicked","set_pos")
225        self.cells[1][1].button("route to","+route:clicked","route_to")
226        self.cells[2][1].button("direct to","+direct:clicked","direct_to")
227
228        self.cells[0][2].button("waypoint", "+add_waypoint:clicked", "bookmarks")
229        self.cells[1][2].button("extend route", "+extend:route:clicked", "extend_route")
230        self.cells[2][2].button("extend direct", "+extend:direct:clicked", "extend_direct")
231
232        self.cells[0][3].button("",None,None)
233        self.cells[1][3].button("",None,None)
234        self.cells[2][3].button("",None,None)
235
236    def menu_options(self):
237        view,scroll = self.rect.xsplit(0.8)
238        view.fill(1,0,0)
239        scroll.fill(0,1,0)
240        self.backButton(0,0)
241
242
243if __name__ == "__main__":
244    a = guiOverlay(None,None)
245    print dir(a)
Note: See TracBrowser for help on using the repository browser.