[GRASS-SVN] r30878 - grass/trunk/gui/wxpython/gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Apr 6 11:19:31 EDT 2008


Author: martinl
Date: 2008-04-06 11:19:30 -0400 (Sun, 06 Apr 2008)
New Revision: 30878

Modified:
   grass/trunk/gui/wxpython/gui_modules/gdialogs.py
   grass/trunk/gui/wxpython/gui_modules/mapdisp.py
   grass/trunk/gui/wxpython/gui_modules/render.py
Log:
wxGUI: major overlay code cleaning


Modified: grass/trunk/gui/wxpython/gui_modules/gdialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gdialogs.py	2008-04-06 09:04:03 UTC (rev 30877)
+++ grass/trunk/gui/wxpython/gui_modules/gdialogs.py	2008-04-06 15:19:30 UTC (rev 30878)
@@ -202,32 +202,25 @@
     """
     Controls setting options and displaying/hiding map overlay decorations
     """
-    def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
-                 style=wx.DEFAULT_DIALOG_STYLE, ovltype=0, cmd='d.barscale',
-                 drawid=None, checktxt='', ctrltxt='', params=''):
-        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+    def __init__(self, parent, ovlId, title, cmd, name=None,
+                 pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE,
+                 checktxt='', ctrltxt=''):
 
-        self.ovltype = ovltype
-        self.drawid  = drawid
-        self.ovlcmd  = cmd
-        self.parent  = parent
-        self.ovlchk  = self.parent.MapWindow.ovlchk
-        # previously set decoration options to pass back to options dialog
-        self.params  = params 
+        wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
 
-        if self.ovltype not in self.parent.Map.ovlookup:
-            self.parent.Map.AddOverlay(self.ovltype, type='overlay',
-                                       command=[self.ovlcmd], l_active=False, l_render=False)
+        self.ovlId   = ovlId   # PseudoDC id
+        self.cmd     = cmd
+        self.name    = name    # overlay name
+        self.parent  = parent  # MapFrame
 
-        # self.MakeModal(True)
-
         sizer = wx.BoxSizer(wx.VERTICAL)
 
         box = wx.BoxSizer(wx.HORIZONTAL)
         self.chkbox = wx.CheckBox(parent=self, id=wx.ID_ANY, label=checktxt)
-        if not drawid in self.ovlchk:
-            self.ovlchk[drawid] = True
-        self.chkbox.SetValue(self.ovlchk[drawid])
+        if self.parent.Map.GetOverlay(self.ovlId) is None:
+            self.chkbox.SetValue(True)
+        else:
+            self.chkbox.SetValue(self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive())
         box.Add(item=self.chkbox, proportion=0,
                 flag=wx.ALIGN_CENTRE|wx.ALL, border=5)
         sizer.Add(item=box, proportion=0,
@@ -255,64 +248,108 @@
         # buttons
         btnsizer = wx.StdDialogButtonSizer()
 
-        btn = wx.Button(self, wx.ID_OK)
-        btn.SetDefault()
-        btnsizer.AddButton(btn)
+        btnOK = wx.Button(parent=self, id=wx.ID_OK)
+        btnOK.SetDefault()
+        btnsizer.AddButton(btnOK)
 
-        btn = wx.Button(self, wx.ID_CANCEL)
-        btnsizer.AddButton(btn)
+        btnCancel = wx.Button(parent=self, id=wx.ID_CANCEL)
+        btnsizer.AddButton(btnCancel)
         btnsizer.Realize()
 
         sizer.Add(item=btnsizer, proportion=0,
                   flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
 
-
+        #
         # bindings
-        self.Bind(wx.EVT_CHECKBOX, self.OnCheck,   self.chkbox)
+        #
         self.Bind(wx.EVT_BUTTON,   self.OnOptions, optnbtn)
+        self.Bind(wx.EVT_BUTTON,   self.OnCancel,  btnCancel)
+        self.Bind(wx.EVT_BUTTON,   self.OnOK,      btnOK)
 
         self.SetSizer(sizer)
         sizer.Fit(self)
 
-    def OnCheck(self, event):
-        """
-        Handler for checkbox for displaying/hiding decoration
-        """
-        check = event.IsChecked()
-        self.ovlchk[self.drawid] = check
+        # create overlay if doesn't exist
+        self._CreateOverlay()
 
+    def _CreateOverlay(self):
+        if not self.parent.Map.GetOverlay(self.ovlId):
+            overlay = self.parent.Map.AddOverlay(id=self.ovlId, type=self.name,
+                                                 command=[self.cmd],
+                                                 l_active=False, l_render=False, l_hidden=True)
+
+            self.parent.MapWindow.overlays[self.ovlId] = {}
+            self.parent.MapWindow.overlays[self.ovlId] = { 'layer' : overlay,
+                                                           'params' : '',
+                                                           'propwin' : None,
+                                                           'cmd' : [self.cmd],
+                                                           'coords': (10, 10),
+                                                           'pdcType': 'image' }
+
     def OnOptions(self, event):
         """        self.SetSizer(sizer)
         sizer.Fit(self)
 
         Sets option for decoration map overlays
         """
+        if not self.parent.MapWindow.overlays.has_key(self.ovlId) or \
+                self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None:
+            # display properties dialog
+            menuform.GUI().ParseCommand(cmd=[self.cmd],
+                                        completed=(self.GetOptData, self.name, ''),
+                                        parentframe=self.parent)
+        else:
+            if self.parent.MapWindow.overlays[self.ovlId]['propwin'].IsShown():
+                self.parent.MapWindow.overlays[self.ovlId]['propwin'].SetFocus()
+            else:
+                self.parent.MapWindow.overlays[self.ovlId]['propwin'].Show()
+        
+    def OnCancel(self, event):
+        """Cancel dialog"""
+        self.parent.dialogs['barscale'] = None
 
-        # display properties dialog (modal mode)
-        menuform.GUI().ParseCommand(cmd=[self.ovlcmd],
-                                    completed=(self.GetOptData, self.ovltype, self.params),
-                                    parentframe=self.parent)
+        self.Destroy()
 
+    def OnOK(self, event):
+        """Button 'OK' pressed"""
+        # enable or disable overlay
+        self.parent.Map.GetOverlay(self.ovlId).SetActive(self.chkbox.IsChecked())
+
+        # update map
+        self.parent.MapWindow.UpdateMap()
+
+        # close dialog
+        self.OnCancel(None)
+
     def GetOptData(self, dcmd, layer, params, propwin):
         """Process decoration layer data"""
-        pass
+        # update layer data
+        if params:
+            self.parent.MapWindow.overlays[self.ovlId]['params'] = params
+        if dcmd:
+            self.parent.MapWindow.overlays[self.ovlId]['cmd'] = dcmd
+        self.parent.MapWindow.overlays[self.ovlId]['propwin'] = propwin
 
+        # change parameters for item in layers list in render.Map
+        self.parent.Map.ChangeOverlay(id=self.ovlId, type=self.name,
+                                      command=self.parent.MapWindow.overlays[self.ovlId]['cmd'],
+                                      l_active=self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive(),
+                                      l_render=False, l_hidden=True)
+
 class TextLayerDialog(wx.Dialog):
     """
     Controls setting options and displaying/hiding map overlay decorations
     """
 
-    def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
-                 style=wx.DEFAULT_DIALOG_STYLE,
-                 ovltype=2,drawid=None):
+    def __init__(self, parent, ovlId, title, name='text',
+                 pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
 
-        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+        wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
 
-        self.ovltype = ovltype
-        self.drawid  = drawid
-        self.parent  = parent
+        self.ovlId = ovlId
+        self.parent = parent
 
-        if drawid in self.parent.MapWindow.textdict:
+        if self.ovlId in self.parent.MapWindow.textdict:
             self.currText, self.currFont, self.currClr, self.currRot = self.parent.MapWindow.textdict[drawid]
         else:
             self.currClr = wx.BLACK
@@ -321,52 +358,70 @@
             self.currRot = 0.0
 
         sizer = wx.BoxSizer(wx.VERTICAL)
+        box = wx.GridBagSizer(vgap=5, hgap=5)
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, _("Enter text:"))
-        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+        # text entry
+        label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Enter text:"))
+        box.Add(item=label,
+                flag=wx.ALIGN_CENTER_VERTICAL,
+                pos=(0, 0))
 
-        self.textentry = wx.TextCtrl(self, wx.ID_ANY, "", size=(200,-1))
+        self.textentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(300,-1))
         self.textentry.SetFont(self.currFont)
         self.textentry.SetForegroundColour(self.currClr)
         self.textentry.SetValue(self.currText)
-        box.Add(self.textentry, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        box.Add(item=self.textentry,
+                pos=(0, 1))
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, "Rotation:")
-        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        self.rotation = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50),
-                        size=(75,-1), style=wx.SP_ARROW_KEYS)
+        # rotation
+        label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Rotation:"))
+        box.Add(item=label,
+                flag=wx.ALIGN_CENTER_VERTICAL,
+                pos=(1, 0))
+        self.rotation = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
+                                    size=(75,-1), style=wx.SP_ARROW_KEYS)
         self.rotation.SetRange(-360, 360)
         self.rotation.SetValue(int(self.currRot))
-        box.Add(self.rotation, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        box.Add(item=self.rotation,
+                flag=wx.ALIGN_RIGHT,
+                pos=(1, 1))
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        fontbtn = wx.Button(self, wx.ID_ANY, "Set font")
-        box.Add(fontbtn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        # font
+        fontbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set font"))
+        box.Add(item=fontbtn,
+                flag=wx.ALIGN_RIGHT,
+                pos=(2, 1))
 
+        sizer.Add(item=box, proportion=1,
+                  flag=wx.ALL, border=10)
+
+        # note
         box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, ("Drag text with mouse in pointer mode\nto position. Double-click to change options"))
-        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        label = wx.StaticText(parent=self, id=wx.ID_ANY,
+                              label=_("Drag text with mouse in pointer mode "
+                                      "to position.\nDouble-click to change options"))
+        box.Add(item=label, proportion=0,
+                flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
+        sizer.Add(item=box, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER | wx.ALL, border=5)
 
-        line = wx.StaticLine(self, wx.ID_ANY, size=(20,-1), style=wx.LI_HORIZONTAL)
-        sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
+        line = wx.StaticLine(parent=self, id=wx.ID_ANY,
+                             size=(20,-1), style=wx.LI_HORIZONTAL)
+        sizer.Add(item=line, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5)
 
         btnsizer = wx.StdDialogButtonSizer()
 
-        btn = wx.Button(self, wx.ID_OK)
+        btn = wx.Button(parent=self, id=wx.ID_OK)
         btn.SetDefault()
         btnsizer.AddButton(btn)
 
-        btn = wx.Button(self, wx.ID_CANCEL)
+        btn = wx.Button(parent=self, id=wx.ID_CANCEL)
         btnsizer.AddButton(btn)
         btnsizer.Realize()
 
-        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        sizer.Add(item=btnsizer, proportion=0,
+                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
 
         self.SetSizer(sizer)
         sizer.Fit(self)
@@ -383,8 +438,6 @@
     def OnRotation(self, event):
         """Change rotation"""
         self.currRot = event.GetInt()
-        Debug.msg (5, "TextDialog.OnRotation(): rotation=%f" % \
-               self.currRot)
 
         event.Skip()
 
@@ -408,3 +461,8 @@
             self.Layout()
 
         dlg.Destroy()
+
+    def GetValues(self):
+        """Get text properties"""
+        return (self.currText, self.currFont,
+                self.currClr, self.currRot)

Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2008-04-06 09:04:03 UTC (rev 30877)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2008-04-06 15:19:30 UTC (rev 30878)
@@ -2,10 +2,10 @@
 MODULE:    mapdisp.py
 
 CLASSES:
-    * Command
-    * BufferedWindow
-    * MapFrame
-    * MapApp
+ - Command
+ - BufferedWindow
+ - MapFrame
+ - MapApp
 
 PURPOSE:   GIS map display canvas, with toolbar for various display
            management functions, and second toolbar for vector
@@ -14,12 +14,11 @@
            Usage:
             python mapdisp.py monitor-identifier /path/to/command/file
 
-AUTHORS:   The GRASS Development Team
-           Michael Barton
+AUTHORS:   Michael Barton
            Jachym Cepicky
            Martin Landa <landa.martin gmail.com>
 
-COPYRIGHT: (C) 2006-2007 by the GRASS Development Team
+COPYRIGHT: (C) 2006-2008 by the GRASS Development Team
            This program is free software under the GNU General Public
            License (>=v2). Read the file COPYING that comes with GRASS
            for details.
@@ -177,11 +176,10 @@
         self.img = ""         # wx.Image object (self.mapfile)
         # used in digitization tool (do not redraw vector map)
         self.imgVectorMap = None
-        self.ovldict = {}     # list of images for overlays
-        self.ovlcoords = {}   # positioning coordinates for decoration overlay
-        self.ovlchk = {}      # showing/hiding decorations
-        self.imagedict = {}   # images and their PseudoDC ID's for painting and dragging
-        self.crop = {}        # coordinates to crop overlays to their data, indexed by image ID
+        # decoration overlays
+        self.overlays = {}
+        # images and their PseudoDC ID's for painting and dragging
+        self.imagedict = {}   
         self.select = {}      # selecting/unselecting decorations for dragging
         self.textdict = {}    # text, font, and color indexed by id
         self.currtxtid = None # PseudoDC id for currently selected text
@@ -238,17 +236,17 @@
         Draws map and overlay decorations
         """
         if drawid == None:
-            if pdctype == 'image' :
-                drawid = imagedict[img]
+            if pdctype == 'image' and img:
+                drawid = self.imagedict[img]
             elif pdctype == 'clear':
                 drawid == None
             else:
                 drawid = wx.NewId()
-        else:
-            self.ovlcoords[drawid] = coords
-            self.ovlchk[drawid] = True
-            pdc.SetId(drawid)
-            self.select[drawid] = False
+        
+        if img and pdctype == 'image':
+            # self.imagedict[img]['coords'] = coords
+            pdc.SetId(self.imagedict[img]['id'])
+            self.select[self.imagedict[img]['id']] = False # ?
 
         pdc.BeginDrawing()
 
@@ -277,7 +275,7 @@
             bitmap = wx.BitmapFromImage(img)
             w,h = bitmap.GetSize()
             pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map
-            pdc.SetIdBounds(drawid, (coords[0],coords[1],w,h))
+            pdc.SetIdBounds(drawid, (coords[0],coords[1], w, h))
 
         elif pdctype == 'box': # draw a box on top of the map
             if self.pen:
@@ -292,7 +290,7 @@
                 rect = wx.Rect(x1,y1,rwidth,rheight)
                 pdc.DrawRectangleRect(rect)
                 pdc.SetIdBounds(drawid,rect)
-                self.ovlcoords[drawid] = coords
+                # self.ovlcoords[drawid] = coords
 
         elif pdctype == 'line': # draw a line on top of the map
             if self.pen:
@@ -300,7 +298,7 @@
                 pdc.SetPen(self.pen)
                 pdc.DrawLine(coords[0], coords[1], coords[2], coords[3])
                 pdc.SetIdBounds(drawid,(coords[0], coords[1], coords[2], coords[3]))
-                self.ovlcoords[drawid] = coords
+                # self.ovlcoords[drawid] = coords
 
         elif pdctype == 'polyline': # draw a polyline on top of the map
             if self.polypen:
@@ -321,7 +319,7 @@
                     y1=min(ylist)
                     y2=max(ylist)
                     pdc.SetIdBounds(drawid,(x1,y1,x2,y2))
-                    self.ovlcoords[drawid] = [x1,y1,x2,y2]
+                    # self.ovlcoords[drawid] = [x1,y1,x2,y2]
 
         elif pdctype == 'point': # draw point
             if self.pen:
@@ -332,21 +330,21 @@
                                coords[0] + 5,
                                coords[1] + 5)
                 pdc.SetIdBounds(drawid, coordsBound)
-                self.ovlcoords[drawid] = coords
+                # self.ovlcoords[drawid] = coords
 
         elif pdctype == 'text': # draw text on top of map
             text = img[0]
             rotation = float(img[3])
-            w,h = self.GetFullTextExtent(img[0])[0:2]
+            w, h = self.GetFullTextExtent(img[0])[0:2]
             pdc.SetFont(img[1])
             pdc.SetTextForeground(img[2])
-            coords,w,h = self.TextBounds(img,coords)
+            coords, w, h = self.TextBounds(img, coords)
             if rotation == 0:
                 pdc.DrawText(img[0], coords[0], coords[1])
             else:
                 pdc.DrawRotatedText(img[0], coords[0], coords[1], rotation)
             pdc.SetIdBounds(drawid, (coords[0], coords[1], w, h))
-            self.ovlcoords[drawid] = coords
+            # self.ovlcoords[drawid] = coords
 
         pdc.EndDrawing()
         self.Refresh()
@@ -356,6 +354,9 @@
     def TextBounds(self, textinfo, coords):
         """
         Return text boundary data
+
+        @param textinfo text metadata (text, font, color, rotation)
+        @param coords reference point
         """
         rotation = float(textinfo[3])
 
@@ -364,18 +365,22 @@
 
         self.Update()
         self.Refresh()
+
         self.SetFont(textinfo[1])
-        w,h = self.GetTextExtent(textinfo[0])
+
+        w, h = self.GetTextExtent(textinfo[0])
+
         if rotation == 0:
             coords[2], coords[3] = coords[0] + w, coords[1] + h
             return coords, w, h
-        else:
-            boxh = math.fabs(math.sin(math.radians(rotation)) * w) + h
-            boxw = math.fabs(math.cos(math.radians(rotation)) * w) + h
-            coords[2] = coords[0] + boxw
-            coords[3] = coords[1] + boxh
-            return coords, boxw, boxh
 
+        boxh = math.fabs(math.sin(math.radians(rotation)) * w) + h
+        boxw = math.fabs(math.cos(math.radians(rotation)) * w) + h
+        coords[2] = coords[0] + boxw
+        coords[3] = coords[1] + boxh
+        
+        return coords, boxw, boxh
+
     def OnPaint(self, event):
         """
         Draw PseudoDC's to buffered paint DC
@@ -494,34 +499,42 @@
     def GetOverlay(self):
         """
         Converts rendered overlay files to wx.Image
+
+        Updates self.imagedict
+
+        @return list of images
         """
-        self.ovldict = {}
+        imgs = []
         for overlay in self.Map.GetListOfLayers(l_type="overlay", l_active=True):
             if os.path.isfile(overlay.mapfile) and os.path.getsize(overlay.mapfile):
                 img = wx.Image(overlay.mapfile, wx.BITMAP_TYPE_ANY)
-                pdc_id = self.Map.overlays.index(overlay)
-                self.ovldict[pdc_id] = img  # image information for each overlay image
-                self.imagedict[img] = pdc_id # set image PeudoDC ID
+                pdc_id = self.Map.overlays.index(overlay) # ?
+                self.imagedict[img] = { 'id' : pdc_id,
+                                        'layer' : overlay,
+                                        'coords' : wx.Rect(0, 0, 0, 0) }
+                imgs.append(img)
 
-        Debug.msg (3, "BufferedWindow.GetOverlay(): numberof=%d" % len(self.ovldict))
+        return imgs
 
-        return self.ovldict
-
     def GetImage(self):
         """
         Converts redered map files to wx.Image
+
+        Updates self.imagedict (id=99)
+
+        @return wx.Image instance (map composition)
         """
+        imgId = 99
         if self.Map.mapfile and os.path.isfile(self.Map.mapfile) and \
                 os.path.getsize(self.Map.mapfile):
             img = wx.Image(self.Map.mapfile, wx.BITMAP_TYPE_ANY)
         else:
             img = None
 
-        self.imagedict[img] = 99 # set image PseudoDC ID
+        self.imagedict[img] = { 'id': imgId }
 
         return img
 
-
     def UpdateMap(self, render=True, renderVector=True):
         """
         Updates the canvas anytime there is a change to the underlaying images
@@ -578,7 +591,7 @@
             self.Draw(self.pdc, pdctype='clear')
         else:
             try:
-                id = self.imagedict[self.img]
+                id = self.imagedict[self.img]['id']
             except:
                 return False
 
@@ -600,22 +613,18 @@
             self.parent.digit.driver.DrawMap()
 
         #
-        # render overlay
+        # render overlays
         #
-        self.ovldict = self.GetOverlay() # list of decoration overlay images
-        if self.ovldict != {}: # draw scale and legend overlays
-            for id in self.ovldict:
-                img = self.ovldict[id]
-                if id not in self.ovlcoords: self.ovlcoords[id] = wx.Rect(0,0,0,0)
-                if id not in self.ovlchk: self.ovlchk[id] = False
-                if self.ovlchk[id] == True: # draw any active and defined overlays
-                    self.Draw(self.pdc, img=img, drawid=id,
-                             pdctype='image', coords=self.ovlcoords[id])
+        for img in self.GetOverlay():
+            # draw any active and defined overlays
+            if self.imagedict[img]['layer'].IsActive():
+                id = self.imagedict[img]['id']
+                self.Draw(self.pdc, img=img, drawid=id,
+                          pdctype=self.overlays[id]['pdcType'], coords=self.overlays[id]['coords'])
 
-        if self.textdict != None: # draw text overlays
-            for id in self.textdict:
-                self.Draw(self.pdc, img=self.textdict[id], drawid=id,
-                          pdctype='text', coords=self.ovlcoords[id])
+        for id in self.textdict.keys():
+            self.Draw(self.pdc, img=self.textdict[id], drawid=id,
+                      pdctype='text', coords=[10, 10, 10, 10])
 
         self.DrawCompRegionExtent()
 
@@ -717,7 +726,7 @@
         """
         Debug.msg (5, "BufferedWindow.DragItem(): id=%d" % \
                        id)
-        x,y = self.lastpos
+        x, y = self.lastpos
         dx = event.GetX() - x
         dy = event.GetY() - y
         self.pdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
@@ -731,9 +740,10 @@
         r2 = self.pdc.GetIdBounds(id)
         r = r.Union(r2)
         r.Inflate(4,4)
+
         self.Update()
         self.RefreshRect(r, False)
-        self.lastpos = (event.GetX(),event.GetY())
+        self.lastpos = (event.GetX(), event.GetY())
 
     def MouseDraw(self, pdc=None, begin=None, end=None):
         """
@@ -1414,10 +1424,10 @@
 
         elif self.dragid != None:
             # end drag of overlay decoration
-            self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
+            if self.overlays.has_key(self.dragid):
+                self.overlays[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
             self.dragid = None
             self.currtxtid = None
-            id = None
             self.Update()
 
         event.Skip()
@@ -1458,14 +1468,14 @@
                 return
             self.dragid = idlist[0]
 
-            self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
+            # self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
             if self.dragid > 100:
                 self.currtxtid = self.dragid
-                self.parent.AddText(None)
+                self.parent.OnAddText(None)
             elif self.dragid == 0:
-                self.parent.AddBarscale(None)
+                self.parent.OnAddBarscale(None)
             elif self.dragid == 1:
-                self.parent.AddLegend(None)
+                self.parent.OnAddLegend(None)
 
         event.Skip()
 
@@ -2315,16 +2325,6 @@
         self.__InitDisplay() 
 
         #
-        # Decoration overlays
-        #
-        self.ovlchk = self.MapWindow.ovlchk
-        self.ovlcoords = self.MapWindow.ovlcoords
-        # previously set decoration options parameters to insert into options dialog
-        self.params = {}
-        # ID of properties window open for overlay, indexed by overlay ID
-        self.propwin = {}
-
-        #
         # Bind various events
         #
         self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
@@ -3236,37 +3236,32 @@
         AddScale = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addbarscale"].GetLabel())
         AddScale.SetBitmap(Icons["addbarscale"].GetBitmap(self.iconsize))
         decmenu.AppendItem(AddScale)
-        self.Bind(wx.EVT_MENU, self.AddBarscale, AddScale)
+        self.Bind(wx.EVT_MENU, self.OnAddBarscale, AddScale)
 
         AddLegend = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addlegend"].GetLabel())
         AddLegend.SetBitmap(Icons["addlegend"].GetBitmap(self.iconsize))
         decmenu.AppendItem(AddLegend)
-        self.Bind(wx.EVT_MENU, self.AddLegend, AddLegend)
+        self.Bind(wx.EVT_MENU, self.OnAddLegend, AddLegend)
 
         AddText = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addtext"].GetLabel())
         AddText.SetBitmap(Icons["addtext"].GetBitmap(self.iconsize))
         decmenu.AppendItem(AddText)
-        self.Bind(wx.EVT_MENU, self.AddText, AddText)
+        self.Bind(wx.EVT_MENU, self.OnAddText, AddText)
 
         # Popup the menu.  If an item is selected then its handler
         # will be called before PopupMenu returns.
         self.PopupMenu(decmenu)
         decmenu.Destroy()
 
-    def AddBarscale(self, event):
+    def OnAddBarscale(self, event):
         """
         Handler for scale/arrow map decoration menu selection.
         """
         if self.dialogs['barscale']:
             return
 
-        ovltype = id = 0 # index for overlay layer in render
+        id = 0 # unique index for overlay layer
 
-        if ovltype in self.params:
-            params = self.params[ovltype]
-        else:
-            params = ''
-
         # If location is latlon, only display north arrow (scale won't work)
         #        proj = self.projinfo['proj']
         #        if proj == 'll':
@@ -3276,157 +3271,87 @@
 
         # decoration overlay control dialog
         self.dialogs['barscale'] = \
-            gdialogs.DecorationDialog(parent=self, id=wx.ID_ANY, title=_('Scale and North arrow'),
+            gdialogs.DecorationDialog(parent=self, title=_('Scale and North arrow'),
                                       size=(350, 200),
                                       style=wx.DEFAULT_DIALOG_STYLE | wx.CENTRE,
-                                      ovltype=ovltype,
                                       cmd='d.barscale',
-                                      drawid=id,
+                                      ovlId=id,
+                                      name='barscale',
                                       checktxt = _("Show/hide scale and North arrow"),
-                                      ctrltxt = _("scale object"),
-                                      params = params)
+                                      ctrltxt = _("scale object"))
 
-        # if OK button pressed in decoration control dialog
-        if self.dialogs['barscale'].Show() == wx.ID_OK:
-            if self.ovlchk[id] == True:
-                # get overlay images (overlay must be active)
-                if not self.Map.ovlookup[ovltype].active:
-                    self.Map.ovlookup[ovltype].active = True
-                    self.Map.Render(force=True)
+        self.dialogs['barscale'].Show()
 
-                ovldict = self.MapWindow.GetOverlay()
-
-                if id not in ovldict:
-                    self.MapWindow.UpdateMap()
-                    return
-
-                img = ovldict[id]
-
-                if id not in self.ovlcoords:
-                    self.ovlcoords[id] = [10,10]
-
-                self.MapWindow.Draw(self.MapWindow.pdc, drawid=id,
-                                    img=img, pdctype='image',
-                                    coords=self.ovlcoords[id])
-
-        self.MapWindow.UpdateMap()
-
-        # close properties dialog if open
-        #        try:
-        #            self.propwin[ovltype].Close(True)
-        #        except:
-        #            pass
-
-    def AddLegend(self, event):
+    def OnAddLegend(self, event):
         """
         Handler for legend map decoration menu selection.
         """
         if self.dialogs['legend']:
             return
         
-        ovltype = id = 1 # index for overlay layer in render
+        id = 1 # index for overlay layer in render
 
-        if ovltype in self.params:
-            params = self.params[ovltype]
-        else:
-            params = ''
-
         # Decoration overlay control dialog
         self.dialogs['legend'] = \
-            gdialogs.DecorationDialog(parent=self, id=wx.ID_ANY, title=('Legend'),
+            gdialogs.DecorationDialog(parent=self, title=('Legend'),
                                       size=(350, 200),
                                       style=wx.DEFAULT_DIALOG_STYLE | wx.CENTRE,
-                                      ovltype=ovltype,
                                       cmd='d.legend',
-                                      drawid=id,
+                                      ovlId=id,
+                                      name='legend',
                                       checktxt = _("Show/hide legend"),
-                                      ctrltxt = _("legend object"),
-                                      params = params)
+                                      ctrltxt = _("legend object")) 
 
-        # If OK button pressed in decoration control dialog
-        if self.dialogs['legend'].Show() == wx.ID_OK:
-            if self.ovlchk[id] == True:
-                # get overlay images (overlay must be active)
-                if not self.Map.ovlookup[ovltype].active:
-                    self.Map.ovlookup[ovltype].active = True
-                    self.Map.Render(force=True)
+        self.dialogs['legend'].Show()
 
-                ovldict = self.MapWindow.GetOverlay()
-
-                if id not in ovldict:
-                    self.MapWindow.UpdateMap()
-                    return
-
-                img = ovldict[id]
-
-                if id not in self.ovlcoords:
-                    self.ovlcoords[id] = [10,10]
-
-                self.MapWindow.Draw(self.MapWindow.pdc, drawid=id,
-                                    img=img, pdctype='image',
-                                    coords=self.ovlcoords[id])
-
-        self.MapWindow.UpdateMap()
-
-        # close properties dialog if open
-        #        try:
-        #            self.propwin[ovltype].Close(True)
-        #        except:
-        #            pass
-
-    def AddText(self, event):
+    def OnAddText(self, event):
         """
         Handler for text decoration menu selection.
         """
-        ovltype = 2 # index for overlay layer in render
 
+        id = 2 # index for overlay layer in render
+
         # default values
-        maptext = ''
-        textfont = self.GetFont()
-        textcolor = wx.BLACK
-        textcoords = [10, 10, 10, 10]
+        text = ''
+        font = self.GetFont()
+        color = wx.BLACK
+        coords = [10, 10, 10, 10]
         rotation = 0.0
 
-        if self.MapWindow.currtxtid == None: # text doesn't already exist
-            id = wx.NewId() + 100
-        else: # text already exists
-            id = self.MapWindow.currtxtid
-            textcoords = self.ovlcoords[id]
+        # if self.MapWindow.currtxtid == None: # text doesn't already exist
+        #    id = wx.NewId() + 100
+        # else: # text already exists
+        #    id = self.MapWindow.currtxtid
+            # textcoords = self.ovlcoords[id]
 
-        dlg = gdialogs.TextLayerDialog(self, wx.ID_ANY, 'Text', size=(400, 200),
-                                       style=wx.DEFAULT_DIALOG_STYLE,
-                                       ovltype=ovltype,
-                                       drawid=id)
+        dlg = gdialogs.TextLayerDialog(parent=self, ovlId=id, title=_('Add text layer'),
+                                       size=(400, 200))
 
         dlg.CenterOnScreen()
 
         # If OK button pressed in decoration control dialog
-        val = dlg.ShowModal()
-        if val == wx.ID_OK:
-            maptext    = dlg.currText
-            textfont   = dlg.currFont
-            textcolor  = dlg.currClr
-            rotation   = dlg.currRot
-            coords,w,h = self.MapWindow.TextBounds((maptext, textfont, textcolor, rotation),textcoords)
-
-        # delete object if if it has no text
-        if maptext == '':
+        if dlg.ShowModal() == wx.ID_OK:
+            text = dlg.GetValues()[0]
+            coords, w, h = self.MapWindow.TextBounds(dlg.GetValues(),
+                                                     coords)
+        # delete object if it has no text
+        if text == '':
             try:
                 self.MapWindow.pdc.ClearId(id)
                 self.MapWindow.pdc.RemoveId(id)
                 del self.MapWindow.textdict[id]
-                del self.ovlcoords[id]
+                # del self.ovlcoords[id]
             except:
                 pass
             return
 
         self.MapWindow.pdc.ClearId(id)
         self.MapWindow.pdc.SetId(id)
-        self.MapWindow.textdict[id] = (maptext,textfont,textcolor,rotation)
+        self.MapWindow.textdict[id] = (text, font, color, rotation)
         self.MapWindow.Draw(self.MapWindow.pdc, img=self.MapWindow.textdict[id],
-                            drawid=id, pdctype='text', coords=textcoords)
-        self.MapWindow.UpdateMap()
+                            drawid=id, pdctype='text', coords=coords)
 
+        self.MapWindow.UpdateMap(render=False, renderVector=False)
 
     def GetOptData(self, dcmd, type, params, propwin):
         """

Modified: grass/trunk/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/render.py	2008-04-06 09:04:03 UTC (rev 30877)
+++ grass/trunk/gui/wxpython/gui_modules/render.py	2008-04-06 15:19:30 UTC (rev 30878)
@@ -1,10 +1,12 @@
 """
 @package render
 
-Rendering map layers into image
+Rendering map layers and overlays into map composition image
 
 Classes:
+ - Layer
  - MapLayer
+ - Overlay
  - Map
 
 C) 2006-2008 by the GRASS Development Team
@@ -12,7 +14,8 @@
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 
- at author Michael Barton, Jachym Cepicky, Martin Landa
+ at author Michael Barton, Jachym Cepicky,
+Martin Landa <landa.martin gmail.com>
 
 @date 2006-2008
 """
@@ -43,14 +46,21 @@
 #
 USE_GPNMCOMP = True
 
-class MapLayer(object):
-    """Stores information about map layers or overlays to be displayed"""
+class Layer(object):
+    """Virtual class which stores information about layers (map layers and
+    overlays) of the map composition.
+
+    For map layer use MapLayer class.
+    For overlays use Overlay class.
+    """
+
     def __init__(self, type, cmd, name=None,
                  active=True, hidden=False, opacity=1.0):
         """
-        @param type layer type (raster, vector, overlay, command, etc.)
-        @param cmd GRASS command for rendering layer, given as list, e.g. ['d.rast', 'map=elevation at PERMANENT']
-        @param name layer name, e.g. 'elevation at PERMANENT'
+        @param type layer type ('raster', 'vector', 'overlay', 'command', etc.)
+        @param cmd GRASS command to render layer,
+        given as list, e.g. ['d.rast', 'map=elevation at PERMANENT']
+        @param name layer name, e.g. 'elevation at PERMANENT' (for layer tree)
         @param active layer is active, will be rendered only if True
         @param hidden layer is hidden, won't be listed in Layer Manager if True
         @param opacity layer opacity <0;1>
@@ -63,43 +73,41 @@
         self.hidden  = hidden
         self.opacity = opacity
 
-        Debug.msg (3, "MapLayer.__init__(): type=%s, cmd='%s', name=%s, " \
-                   "active=%d, opacity=%d, hidden=%d" % \
-                   (self.type, self.GetCmd(string=True), self.name, self.active,
-                    self.opacity, self.hidden))
+        Debug.msg (3, "Layer.__init__(): type=%s, cmd='%s', name=%s, " \
+                       "active=%d, opacity=%d, hidden=%d" % \
+                       (self.type, self.GetCmd(string=True), self.name, self.active,
+                        self.opacity, self.hidden))
 
         # generated file for layer
-        gtemp = utils.GetTempfile()
-        self.maskfile = gtemp + ".pgm"
-        if self.type == "overlay":
-            self.mapfile = gtemp + ".png"
-        else:
-            self.mapfile = gtemp + ".ppm"
+        self.gtemp = utils.GetTempfile()
+        self.maskfile = self.gtemp + ".pgm"
 
     def __del__(self):
-        Debug.msg (3, "MapLayer.__del__(): layer=%s, cmd='%s'" %
+        Debug.msg (3, "Layer.__del__(): layer=%s, cmd='%s'" %
                    (self.name, self.GetCmd(string=True)))
 
     def Render(self):
-        """Render map layer to image
+        """Render layer to image
 
-        @return name of file with rendered image or None
+        @return rendered image filename
+        @return None on error
         """
         if len(self.cmdlist) == 0:
-            return
+            return None
 
-        Debug.msg (3, "MapLayer.Render(): type=%s" % \
-                   (self.type))
+        Debug.msg (3, "Layer.Render(): type=%s" % \
+                       (self.type))
 
         #
         # to be sure, set temporary file with layer and mask
         #
-        gtemp = utils.GetTempfile()
-        self.maskfile = gtemp + ".pgm"
-        if self.type == 'overlay':
-            self.mapfile  = gtemp + ".png"
-        else:
-            self.mapfile  = gtemp + ".ppm"
+        if not self.gtemp:
+            gtemp = utils.GetTempfile()
+            self.maskfile = gtemp + ".pgm"
+            if self.type == 'overlay':
+                self.mapfile  = gtemp + ".png"
+            else:
+                self.mapfile  = gtemp + ".ppm"
 
         #
         # prepare command for each layer
@@ -152,22 +160,12 @@
 
         return self.mapfile
 
-    def GetMapset(self):
+    def GetCmd(self, string=False):
         """
-        @return mapset name of the layer
-        """
-        if not self.name:
-            return ''
+        Get GRASS command as list of string.
 
-        try:
-            return self.name.split('@')[1]
-        except IndexError:
-            return self.name
+        @param string get command as string if True otherwise as list
 
-    def GetCmd(self, string=False):
-        """
-        @param string get command as string if True otherwise list
-
         @return command list/string
         """
         if string:
@@ -177,7 +175,8 @@
 
     def GetOpacity(self, float=False):
         """
-        Get opacity level
+        Get layer opacity level
+
         @param float get opacity level in <0,1> otherwise <0,100>
 
         @return opacity level
@@ -187,9 +186,69 @@
         
         return int (self.opacity * 100)
 
+    def IsActive(self):
+        """Check if layer is activated for rendering"""
+        return self.active
+
+    def SetActive(self, enable=True):
+        """Active or deactive layer"""
+        self.active = enable
+            
+class MapLayer(Layer):
+    """Represents map layer in the map canvas"""
+    def __init__(self, type, cmd, name=None,
+                 active=True, hidden=False, opacity=1.0):
+        """
+        @param type layer type ('raster', 'vector', 'command', etc.)
+        @param cmd GRASS command to render layer,
+        given as list, e.g. ['d.rast', 'map=elevation at PERMANENT']
+        @param name layer name, e.g. 'elevation at PERMANENT' (for layer tree) or None
+        @param active layer is active, will be rendered only if True
+        @param hidden layer is hidden, won't be listed in Layer Manager if True
+        @param opacity layer opacity <0;1>
+        """
+        Layer.__init__(self, type, cmd, name,
+                       active, hidden, opacity)
+
+        self.mapfile = self.gtemp + ".ppm"
+
+    def GetMapset(self):
+        """
+        Get mapset of map layer
+
+        @return mapset name
+        @return '' on error (no name given)
+        """
+        if not self.name:
+            return ''
+
+        try:
+            return self.name.split('@')[1]
+        except IndexError:
+            return self.name
+
+class Overlay(Layer):
+    """Represents overlay displayed in map canvas"""
+    def __init__(self, id, type, cmd,
+                 active=True, hidden=True, opacity=1.0):
+        """
+        @param id overlay id (for PseudoDC)
+        @param type overlay type ('barscale', 'legend', etc.)
+        @param cmd GRASS command to render overlay,
+        given as list, e.g. ['d.legend', 'map=elevation at PERMANENT']
+        @param active layer is active, will be rendered only if True
+        @param hidden layer is hidden, won't be listed in Layer Manager if True
+        @param opacity layer opacity <0;1>
+        """
+        Layer.__init__(self, 'overlay', cmd, type,
+                       active, hidden, opacity)
+
+        self.id = id
+        self.mapfile = self.gtemp + ".png"
+
 class Map(object):
     """
-    Map composition (stack of map layers)
+    Map composition (stack of map layers and overlays)
     """
     def __init__(self):
         # 
@@ -561,7 +620,7 @@
         layers. 
 
         @param l_type layer type, e.g. raster/vector/wms/overlay
-        @param l_mapset all layers from given mapset
+        @param l_mapset all layers from given mapset (only for maplayers)
         @param l_name all layers with given name
         @param l_active only layers with 'active' attribute set to True or False
         @param l_hidden only layers with 'hidden' attribute set to True or False
@@ -571,14 +630,20 @@
 
         selected = []
 
+        if l_type == 'overlay':
+            list = self.overlays
+        else:
+            list = self.layers
+
         # ["raster", "vector", "wms", ... ]
-        for layer in self.layers + self.overlays:
+        for layer in list:
             # specified type only
             if l_type != None and layer.type != l_type:
                 continue
 
             # mapset
-            if l_mapset != None and layer.GetMapset() != l_mapset:
+            if (l_mapset != None and type != 'overlay') and \
+                    layer.GetMapset() != l_mapset:
                 continue
 
             # name
@@ -721,16 +786,15 @@
     def AddLayer(self, type, command, name=None,
                  l_active=True, l_hidden=False, l_opacity=1.0, l_render=False):
         """
-        Adds generic display command layer to list of layers
+        Adds generic map layer to list of layers
 
-        @param item reference to item in layer tree
-        @param type layer type
+        @param type layer type ('raster', 'vector', etc.)
+        @param command  GRASS command given as list
         @param name layer name
-        @param cmd  GRASS command to render layer
-        @param l_active checked/not checked for display in layer tree
-        @param l_hidden not used here
-        @param l_opacity opacity leve range from 0(transparent)-1(not transparent)
-        @param l_render render an image if False
+        @param l_active layer render only if True
+        @param l_hidden layer not displayed in layer tree if True
+        @param l_opacity opacity level range from 0(transparent) - 1(not transparent)
+        @param l_render render an image if True
 
         @return new layer on success
         @return None on failure
@@ -753,33 +817,44 @@
 
         return self.layers[-1]
 
-    def DeleteLayer(self, layer):
+    def DeleteLayer(self, layer, overlay=False):
         """
-        Removes layer from list of layers,
-        defined by reference to MapLayer instance
+        Removes layer from list of layers
 
-        Returns:
-            Removed layer on success or None
+        @param layer layer instance in layer tree
+        @param overlay delete overlay (use self.DeleteOverlay() instead)
+
+        @return removed layer on success or None
         """
 
         Debug.msg (3, "Map.DeleteLayer(): name=%s" % layer.name)
-        if layer in self.layers:
+
+        if overlay:
+            list = self.overlays
+        else:
+            list = self.list
+
+        if layer in list:
             if layer.mapfile:
                 base = os.path.split(layer.mapfile)[0]
                 mapfile = os.path.split(layer.mapfile)[1]
                 tempbase = mapfile.split('.')[0]
-                basefile = os.path.join(base,tempbase)+r'.*'
+                if base == '' or tempbase == '':
+                    return None
+                basefile = os.path.join(base, tempbase) + r'.*'
                 for f in glob.glob(basefile):
                     os.remove(f)
-            self.layers.remove(layer)
+            list.remove(layer)
+
             return layer
 
         return None
 
     def ReorderLayers(self, layerList):
         """
-        Make a new reordered list to match reordered
-        layer tree - for drag and drop
+        Reorder list to match layer tree
+
+        @param layerList list of layers
         """
         self.layers = layerList
 
@@ -793,7 +868,15 @@
     def ChangeLayer(self, layer, type, command, name=None,
                     l_active=True, l_hidden=False, l_opacity=1, l_render=False):
         """
-        Change the command and other other options for a layer
+        Change layer properties
+
+        @param type layer type ('raster', 'vector', etc.)
+        @param command  GRASS command given as list
+        @param name layer name
+        @param l_active layer render only if True
+        @param l_hidden layer not displayed in layer tree if True
+        @param l_opacity opacity level range from 0(transparent) - 1(not transparent)
+        @param l_render render an image if True
         """
 
         # l_opacity must be <0;1>
@@ -821,7 +904,7 @@
         """
         Changes opacity value of map layer
 
-        @param layer layer instance
+        @param layer layer instance in layer tree
         @param l_opacity opacity level <0;1>
         """
         # l_opacity must be <0;1>
@@ -834,9 +917,9 @@
 
     def ChangeLayerActive(self, layer, active):
         """
-        Change the active state of a layer
+        Enable or disable map layer
 
-        @param layer layer instance
+        @param layer layer instance in layer tree
         @param active to be rendered (True)
         """
         layer.active = active
@@ -848,7 +931,7 @@
         """
         Change name of the layer
 
-        @param layer layer instance
+        @param layer layer instance in layer tree
         @param name  layer name to set up
         """
         Debug.msg (3, "Map.ChangeLayerName(): from=%s to=%s" % \
@@ -857,7 +940,7 @@
 
     def RemoveLayer(self, name=None, id=None):
         """
-        Removes layer from layer list of layers
+        Removes layer from layer list
 
         Layer is defined by name at mapset or id.
 
@@ -886,9 +969,9 @@
 
     def GetLayerIndex(self, layer):
         """
-        Returns index of layer in layer list.
+        Get index of layer in layer list.
 
-        @param layer layer instace
+        @param layer layer instace in layer tree
 
         @return layer index
         @return None
@@ -899,23 +982,25 @@
         else:
             return None
 
-    def AddOverlay(self, ovltype=None, type='overlay', command=None,
-                   l_active=True, l_hidden=False, l_opacity=1, l_render=False):
+    def AddOverlay(self, id, type, command,
+                   l_active=True, l_hidden=True, l_opacity=1.0, l_render=False):
         """
-        Adds overlay (grid, barscale, others?) to list of overlays
-
-        @param ovltype overlay type
+        Adds overlay (grid, barscale, legend, etc.) to list of overlays
+        
+        @param id overlay id (PseudoDC)
+        @param type overlay type (barscale, legend)
         @param command GRASS command to render overlay
         @param l_active overlay activated (True) or disabled (False)
-        @param l_render render an image (True)
+        @param l_hidden overlay is not shown in layer tree (if True)
+        @param l_render render an image (if True)
 
         @return new layer on success
         @retutn None on failure
         """
 
         Debug.msg (2, "Map.AddOverlay(): cmd=%s, render=%d" % (command, l_render))
-        overlay = MapLayer(type='overlay', name=None, cmd=command,
-                           active=l_active, hidden=l_hidden, opacity=l_opacity)
+        overlay = Overlay(id=id, type=type, cmd=command,
+                          active=l_active, hidden=l_hidden, opacity=l_opacity)
 
         # add maplayer to the list of layers
         self.overlays.append(overlay)
@@ -924,56 +1009,78 @@
             raise gcmd.GException(_("Unable render overlay <%s>.") % 
                                   (name))
 
-        self.ovlookup[ovltype] = overlay
-
         return self.overlays[-1]
 
-    def ChangeOverlay(self, ovltype, type, name, command,
+    def ChangeOverlay(self, id, type, command,
                       l_active=True, l_hidden=False, l_opacity=1, l_render=False):
         """
         Change overlay properities
 
-        @param ovltype overlay type
-        @param type layer type
-        @param command GRASS command to render an overlay
-        @param l_active overlay is active (True) or disabled (False)
-        @param l_hidded not used here
-        @param l_opacity opacity level <0,1>
-        @param l_render render overlay (True)
+        Add new overlay if overlay with 'id' doesn't exist.
 
-        @return new overlay instance
+        @param id overlay id (PseudoDC)
+        @param type overlay type (barscale, legend)
+        @param command GRASS command to render overlay
+        @param l_active overlay activated (True) or disabled (False)
+        @param l_hidden overlay is not shown in layer tree (if True)
+        @param l_render render an image (if True)
+
+        @return new layer on success
         """
+        overlay = self.GetOverlay(id, list=False)
+        if  overlay is None:
+            overlay = Overlay(id, type, command,
+                              l_active, l_hidden, l_opacity)
+        else:
+            overlay.id = id
+            overlay.name = type
+            overlay.cmdlist = command
+            overlay.active = l_active
+            overlay.hidden = l_hidden
+            overlay.opacity = l_opacity
 
-        newoverlay = MapLayer(type='overlay', name=name, cmd=command,
-                              active=l_active, hidden=l_hidden, opacity=l_opacity)
+        if l_render and command != [] and not overlay.Render():
+            raise gcmd.GException(_("Unable render overlay <%s>") % 
+                                  (name))
 
-        oldovlindex = self.overlays.index(self.ovlookup[ovltype])
+        return overlay
 
-        # add overlay to the list of layers
-        if self.ovlookup[ovltype]:
-            self.overlays[oldovlindex] = newoverlay
-            self.ovlookup[ovltype] = newoverlay
+    def GetOverlay(self, id, list=False):
+        """Return overlay(s) with 'id'
 
-        if l_render and command != '' and not overlay.Render():
-            raise gcmd.GException(_("Unable render overlay <%s>.") % 
-                                  (name))
+        @param id overlay id
+        @param list return list of overlays of True
+        otherwise suppose 'id' to be unique
+        
+        @return list of overlays (list=True)
+        @return overlay (list=False)
+        @retur None (list=False) if no overlay or more overlays found
+        """
+        ovl = []
+        for overlay in self.overlays:
+            if overlay.id == id:
+                ovl.append(overlay)
+                
+        if not list:
+            if len(ovl) != 1:
+                return None
+            else:
+                return ovl[0]
 
-        return self.overlays[-1]
+        return ovl
 
-    def changeOverlayActive(self, ovltype, activ):
+    def DeleteOverlay(self, overlay):
+        """Delete overlay
+
+        @param id overlay id
+
+        @return removed overlay on success or None
         """
-        Change active status of overlay
-        """
-        try:
-            overlay = self.ovlookup[ovltype]
-            overlay.active = activ
-            Debug.msg (3, "Map.changeOverlayActive(): type=%d, active=%d" % (type, activ))
-        except:
-            sys.stderr.write("Cannot change status of overlay index [%d]\n" % type)
+        return self.DeleteLayer(overlay, overlay=True)
 
     def Clean(self):
         """
-        Go trough all layers and remove them from layer list
+        Clean layer stack - go trough all layers and remove them from layer list
         Removes also l_mapfile and l_maskfile
 
         @return 1 on faulure
@@ -1020,9 +1127,16 @@
     map.width = 640
     map.height = 480
 
-    map.AddLayer(item=None, type="raster", name="elevation.dem", command = "d.rast elevation.dem at PERMANENT catlist=1000-1500 -i", l_opacity=.7)
+    map.AddLayer(item=None,
+                 type="raster",
+                 name="elevation.dem",
+                 command = ["d.rast", "elevation.dem at PERMANENT", "catlist=1000-1500", "-i"],
+                 l_opacity=.7)
 
-    map.AddLayer(item=None, type="vector", name="streams", command = "d.vect streams at PERMANENT color=red width=3 type=line")
+    map.AddLayer(item=None,
+                 type="vector",
+                 name="streams",
+                 command = ["d.vect", "streams at PERMANENT", "color=red", "width=3", "type=line"])
 
     image = map.Render(force=True)
 



More information about the grass-commit mailing list