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

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

-further updates of spaces to tabs

  • Property svn:keywords set to Rev
File size: 13.8 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5"""
6
7__version__ = "$Rev: 18454 $"
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.