[GRASS-SVN] r57759 - grass/trunk/gui/wxpython/iclass

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Sep 20 03:31:12 PDT 2013


Author: turek
Date: 2013-09-20 03:31:12 -0700 (Fri, 20 Sep 2013)
New Revision: 57759

Modified:
   grass/trunk/gui/wxpython/iclass/dialogs.py
   grass/trunk/gui/wxpython/iclass/frame.py
   grass/trunk/gui/wxpython/iclass/toolbars.py
Log:
wx.iclass: show colors of classes in class manager, and classes choice, signals for integration with scatter plot

Modified: grass/trunk/gui/wxpython/iclass/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/iclass/dialogs.py	2013-09-20 09:08:03 UTC (rev 57758)
+++ grass/trunk/gui/wxpython/iclass/dialogs.py	2013-09-20 10:31:12 UTC (rev 57759)
@@ -69,7 +69,6 @@
         if subgroup:
             self.subGroupSelect.SetValue(subgroup)
 
-
         self.editGroup = wx.Button(parent = self.panel, id = wx.ID_ANY,
                                    label = _("Create/edit group..."))
 
@@ -158,7 +157,8 @@
             self.GroupSelected()
             wx.CallAfter(self.subGroupSelect.SetValue, s)
         dlg.Destroy()
-        
+        event.Veto()
+
     def GroupSelected(self):
         group = self.GetSelectedGroup()
         self.subGroupSelect.Insert(group)
@@ -337,7 +337,6 @@
     def OnClose(self, event):
         self.catList.DeselectAll()
         
-        self.catList.UpdateChoice()
         self.Hide()
         #if not isinstance(event, wx.CloseEvent):
             #self.Destroy()
@@ -404,11 +403,9 @@
                 GMessage(parent = self, message = _("Please use only ASCII characters."))
                 return
 
-
         cat = self.stats_data.GetCategories()[row]
         self.stats_data.GetStatistics(cat).SetStatistics(stats = {attr : text})
         
-        self.UpdateChoice()
         toolbar = self.mapWindow.toolbars['iClass']
         toolbar.choice.SetSelection(row)
         self.Select(row)
@@ -431,7 +428,6 @@
         self.stats_data.AddStatistics(cat, name, color)
         self.SetItemCount(len(self.stats_data.GetCategories()))
         
-        self.UpdateChoice()
         self.mapWindow.UpdateChangeState(changes = True)
                 
     def DeleteCategory(self):
@@ -452,32 +448,10 @@
             
         self.SetItemCount(len(self.stats_data.GetCategories()))
         
-        self.UpdateChoice()
         self.mapWindow.UpdateChangeState(changes = True)
         
         self.mapWindow.DeleteAreas(cats = del_cats)
-    
-    def UpdateChoice(self):
-        toolbar = self.mapWindow.toolbars['iClass']
-        name = toolbar.GetSelectedCategoryName()
-        catNames = []
-
-        cats = self.stats_data.GetCategories()
-        for cat in cats:
-            stat = self.stats_data.GetStatistics(cat)
-            catNames.append(stat.name)
-        toolbar.SetCategories(catNames = catNames, catIdx = cats)
-        if name in catNames:
-            toolbar.choice.SetStringSelection(name)
-        elif catNames:
-            toolbar.choice.SetSelection(0)
             
-        if toolbar.choice.IsEmpty():
-            toolbar.EnableControls(False)
-        else:
-            toolbar.EnableControls(True)
-        # don't forget to update maps, histo, ...
-        
     def GetSelectedIndices(self, state =  wx.LIST_STATE_SELECTED):
         indices = []
         lastFound = -1
@@ -494,7 +468,13 @@
         currentItem = event.m_itemIndex
         currentCol = event.m_col
         if currentCol == 1:
-            dlg = wx.ColourDialog(self)
+            col = self.OnGetItemText(currentItem, currentCol)
+            col = map(int, col.split(':'))
+
+            col_data =  wx.ColourData()
+            col_data.SetColour(wx.Colour(*col))
+
+            dlg = wx.ColourDialog(self, col_data)
             dlg.GetColourData().SetChooseFull(True)
 
             if dlg.ShowModal() == wx.ID_OK:
@@ -560,6 +540,31 @@
     def OnGetItemAttr(self, item):
         return None
 
+    def OnGetItemAttr(self, item):
+        """!Set correct class color for a item"""
+        back_c = wx.Colour(*map(int, self.OnGetItemText(item, 1).split(':')))
+        text_c = wx.Colour(*ContrastColor(back_c))
+
+        # if it is in scope of the method, gui falls, using self solved it 
+        self.l = wx.ListItemAttr(colText = text_c, colBack =  back_c)
+        return self.l
+    
+def ContrastColor(color):
+    """!Decides which value shoud have text to be contrast with backgroud color 
+        (bright bg -> black, dark bg -> white)
+
+    @todo could be useful by other apps, consider moving it into gui_core 
+    """
+    #gacek, http://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color
+    a = 1 - ( 0.299 * color[0] + 0.587 * color[1] + 0.114 * color[2])/255;
+
+    if a < 0.5:
+        d = 0
+    else:
+        d = 255 
+    # maybe return just bool if text shoud be dark or bright 
+    return (d, d, d)
+
 class IClassSignatureFileDialog(wx.Dialog):
     def __init__(self, parent, group, subgroup, 
                  file = None, title = _("Save signature file"), id = wx.ID_ANY,

Modified: grass/trunk/gui/wxpython/iclass/frame.py
===================================================================
--- grass/trunk/gui/wxpython/iclass/frame.py	2013-09-20 09:08:03 UTC (rev 57758)
+++ grass/trunk/gui/wxpython/iclass/frame.py	2013-09-20 10:31:12 UTC (rev 57759)
@@ -64,6 +64,8 @@
                                IClassExportAreasDialog, IClassMapDialog
 from iclass.plots       import PlotPanel
 
+from grass.pydispatch.signal import Signal
+
 class IClassMapFrame(DoubleMapFrame):
     """! wxIClass main frame
     
@@ -114,7 +116,17 @@
             lambda:
             self.statusbarManager.statusbarItems['coordinates'].SetAdditionalInfo(None))
         self.SetSize(size)
+
         #
+        #Signals
+        #
+
+        self.groupSet = Signal("IClassMapFrame.groupSet")
+        self.categoryChanged = Signal('IClassMapFrame.categoryChanged')
+
+        self.InitStatistics()
+
+        #
         # Add toolbars
         #
         
@@ -162,9 +174,7 @@
                                              Map = self.GetFirstMap())
         self.previewMapManager = MapManager(self, mapWindow = self.GetSecondWindow(),
                                             Map = self.GetSecondMap())
-                                           
-        self.InitStatistics()
-        
+                                                   
         self.changes = False
         self.exportVector = None
         
@@ -177,7 +187,7 @@
         self.dialogs['category']   = None
         
         # PyPlot init
-        self.plotPanel = PlotPanel(self, stats_data = self.stats_data)
+        self.plotPanel = PlotPanel(self, giface = self._giface, stats_data = self.stats_data)
                                    
         self._addPanes()
         self._mgr.Update()
@@ -237,7 +247,7 @@
             return False
         
         return vectorName
-        
+    
     def RemoveTempVector(self):
         """!Removes temporary vector map with training areas"""
         ret = RunCommand(prog = 'g.remove',
@@ -282,7 +292,7 @@
                               BestSize((self.toolbars[name].GetBestSize())))
                               
         if name == "iClass":
-            self.toolbars[name] = IClassToolbar(self)
+            self.toolbars[name] = IClassToolbar(self, stats_data=self.stats_data)
             
             self._mgr.AddPane(self.toolbars[name],
                               wx.aui.AuiPaneInfo().
@@ -334,11 +344,14 @@
             self._addPaneMapWindow(name = 'preview')
             self._addPaneToolbar(name = 'iClassTrainingMapManager')
             self._addPaneMapWindow(name = 'training')
-        
+
+        # otherwise best size was ignored
+        self._mgr.SetDockSizeConstraint(0.5, 0.5) 
+
         self._mgr.AddPane(self.plotPanel, wx.aui.AuiPaneInfo().
                   Name("plots").Caption(_("Plots")).
                   Dockable(False).Floatable(False).CloseButton(False).
-                  Left().Layer(1).BestSize((400, -1)))
+                  Left().Layer(1).BestSize((310, -1)))
         
     def _addPaneToolbar(self, name):
         if name == 'iClassPreviewMapManager':
@@ -489,12 +502,14 @@
                     group = grass.find_file(name=g, element='group')
                     self.g['group'] = group['name']
                     self.g['subgroup'] = s
+                    self.groupSet.emit(group=self.g['group'],
+                                       subgroup=self.g['subgroup'])
                     break
             else: 
                 break
         
         dlg.Destroy()
-    
+
     def OnImportAreas(self, event):
         """!Import training areas"""
         # check if we have any changes
@@ -771,17 +786,20 @@
         
         Updates number of stddev, histograms, layer in preview display. 
         """
-        stat = self.stats_data.GetStatistics(currentCat)
-        nstd = stat.nstd
-        self.toolbars['iClass'].UpdateStddev(nstd)
-        
-        self.plotPanel.UpdateCategory(currentCat)
-        self.plotPanel.OnPlotTypeSelected(None)
+        if currentCat:
+          stat = self.stats_data.GetStatistics(currentCat)
+          nstd = stat.nstd
+          self.toolbars['iClass'].UpdateStddev(nstd)
+          
+          self.plotPanel.UpdateCategory(currentCat)
+          self.plotPanel.OnPlotTypeSelected(None)
                                    
-        name = stat.rasterName
-        name = self.previewMapManager.GetAlias(name)
-        if name:
-            self.previewMapManager.SelectLayer(name)
+          name = stat.rasterName
+          name = self.previewMapManager.GetAlias(name)
+          if name:
+              self.previewMapManager.SelectLayer(name)
+
+        self.categoryChanged.emit(cat = currentCat)
         
     def DeleteAreas(self, cats):
         """!Removes all training areas of given categories
@@ -808,12 +826,12 @@
     def UpdateRasterName(self, newName, cat):
         """!Update alias of raster map when category name is changed"""
         origName = self.stats_data.GetStatistics(cat).rasterName
-        self.previewMapManager.SetAlias(origName, newName)
+        self.previewMapManager.SetAlias(origName, self._addSuffix(newName))
         
     def StddevChanged(self, cat, nstd):
         """!Standard deviation multiplier changed, rerender map, histograms"""
         stat = self.stats_data.GetStatistics(cat)
-        stat.nstd = nstd
+        stat.SetStatistics({"nstd" : nstd})
         
         if not stat.IsReady():
             return
@@ -925,7 +943,7 @@
                 
                 self.ConvertToNull(name = stats.rasterName)
                 self.previewMapManager.AddLayer(name = stats.rasterName,
-                                                alias = stats.name, resultsLayer = True)
+                                                alias = self._addSuffix(stats.name), resultsLayer = True)
                 # write statistics
                 I_iclass_add_signature(self.signatures, statistics)
                 
@@ -938,7 +956,11 @@
         
         self.UpdateChangeState(changes = False)
         return True
-        
+
+    def _addSuffix(self, name):
+        suffix = _('results')
+        return '_'.join((name, suffix))
+
     def OnSaveSigFile(self, event):
         """!Asks for signature file name and saves it."""
         if not self.g['group']:
@@ -1115,27 +1137,13 @@
         self.GetFirstWindow().SetModePointer()
         self.GetSecondWindow().SetModePointer()
 
-    def OnScatterplot(self, event):
-        """!Init interactive scatterplot tools
-        """
-        if self.dialogs['scatt_plot']:
-            self.dialogs['scatt_plot'].Raise()
-            return
+    def GetMapManagers(self):
+      """!Get map managers of wxIClass 
 
-        try:
-          from scatt_plot.dialogs import ScattPlotMainDialog
-        except:
-          GError(parent  = self, message = _("The Scatter Plot Tool is not installed."))
-          return
+      @return trainingMapManager, previewMapManager 
+      """
+      return self.trainingMapManager, self.previewMapManager
 
-        self.dialogs['scatt_plot'] = ScattPlotMainDialog(parent=self, giface=self._giface, iclass_mapwin = self.GetFirstWindow())
-
-        scatt_mgr = self.dialogs['scatt_plot'].GetScattMgr()
-        scatt_mgr.DigitDataChanged(self.toolbars['vdigit'].mapLayer.GetName(), self.GetFirstWindow().GetDigit())
-
-        self.dialogs['scatt_plot'].CenterOnScreen()
-        self.dialogs['scatt_plot'].Show()
-
 class MapManager:
     """! Class for managing map renderer.
     
@@ -1178,7 +1186,6 @@
         self.frame.Render(self.mapWindow)
         
         if alias is not None:
-            alias = self._addSuffix(alias)
             self.layerName[alias] = name
             name = alias
         else:
@@ -1235,7 +1242,11 @@
                 self.toolbar.choice.SetSelection(0)
         
         self.frame.Render(self.mapWindow)
-        
+    
+    def Render(self):
+        """@todo giface shoud be used instead of this method"""
+        self.frame.Render(self.mapWindow)
+
     def RemoveLayer(self, name, idx):
         """!Removes layer from Map and update toolbar"""
         name = self.layerName[name]
@@ -1291,11 +1302,7 @@
     def _changeOpacity(self, layer, opacity):
         self.map.ChangeOpacity(layer=layer, opacity=opacity)
         self.frame.Render(self.mapWindow)
-        
-    def _addSuffix(self, name):
-        suffix = _('results')
-        return '_'.join((name, suffix))
-        
+                
     def GetAlias(self, name):
         """!Returns alias for layer"""
         name =  [k for k, v in self.layerName.iteritems() if v == name]
@@ -1306,11 +1313,11 @@
     def SetAlias(self, original, alias):
         name = self.GetAlias(original)
         if name:
-            self.layerName[self._addSuffix(alias)] = original
+            self.layerName[alias] = original
             del self.layerName[name]
             idx = self.toolbar.choice.FindString(name)
             if idx != wx.NOT_FOUND:
-                self.toolbar.choice.SetString(idx, self._addSuffix(alias))
+                self.toolbar.choice.SetString(idx, alias)
 
 def test():
     import core.render as render

Modified: grass/trunk/gui/wxpython/iclass/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/iclass/toolbars.py	2013-09-20 09:08:03 UTC (rev 57758)
+++ grass/trunk/gui/wxpython/iclass/toolbars.py	2013-09-20 10:31:12 UTC (rev 57759)
@@ -23,7 +23,7 @@
 from core.utils import _
 from gui_core.toolbars import BaseToolbar, BaseIcons
 from icons.icon import MetaIcon
-from iclass.dialogs import IClassMapDialog
+from iclass.dialogs import IClassMapDialog, ContrastColor
 from gui_core.forms import GUI
 
 import grass.script as grass
@@ -46,9 +46,7 @@
         'importAreas' : MetaIcon(img = 'layer-import',
                             label = _('Import training areas from vector map')),
         'addRgb' : MetaIcon(img = 'layer-rgb-add',
-                            label = _('Add RGB map layer')),
-        'scatt_plot'    : MetaIcon(img = 'layer-raster-analyze',
-                                   label = _('Open Scatter Plot Tool (EXPERIMENTAL GSoC 2013)')),
+                            label = _('Add RGB map layer'))
         }
         
 class IClassMapToolbar(BaseToolbar):
@@ -117,17 +115,16 @@
                                      ("zoomBack", icons["zoomBack"],
                                       self.parent.OnZoomBack),
                                      ("zoomToMap", icons["zoomExtent"],
-                                      self.parent.OnZoomToMap),
-                                     (None, ),
-                                     ("scatt_plot", iClassIcons["scatt_plot"],
-                                      self.parent.OnScatterplot)
+                                      self.parent.OnZoomToMap)
                                     ))
 class IClassToolbar(BaseToolbar):
     """!IClass toolbar
     """
-    def __init__(self, parent):
+    def __init__(self, parent, stats_data):
         """!IClass toolbar constructor
         """
+        self.stats_data = stats_data
+
         BaseToolbar.__init__(self, parent)
         self.InitToolbar(self._toolbarData())
         
@@ -148,7 +145,12 @@
         
         self.combo.Bind(wx.EVT_COMBOBOX, self.OnStdChangeSelection)
         self.combo.Bind(wx.EVT_TEXT_ENTER, self.OnStdChangeText)
-        
+    
+        self.stats_data.statisticsAdded.connect(self.Update)
+        self.stats_data.statisticsDeleted.connect(self.Update)
+        self.stats_data.allStatisticsDeleted.connect(self.Update)
+        self.stats_data.statisticsSet.connect(self.Update)
+
         # realize the toolbar
         self.Realize()
         
@@ -171,13 +173,30 @@
                                       ("sigFile", icons['sigFile'],
                                       self.parent.OnSaveSigFile),
                                     ))
-                                    
+
+    def OnMotion(self, event):
+        print self.choice.GetStringSelection()
+                                
     def OnSelectCategory(self, event):
         idx = self.choice.GetSelection()
         cat = self.choice.GetClientData(idx)
-        
+
+        self._updateColor(cat)
         self.parent.CategoryChanged(currentCat = cat)
         
+    def _updateColor(self, cat):
+
+        if cat:
+            stat = self.stats_data.GetStatistics(cat)
+            back_c = wx.Colour(*map(int, stat.color.split(':')))
+            text_c = wx.Colour(*ContrastColor(back_c))
+        else:
+            back_c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
+            text_c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT)
+
+        self.choice.SetForegroundColour(text_c)
+        self.choice.SetBackgroundColour(back_c)
+
     def SetCategories(self, catNames, catIdx):
         self.choice.Clear()
         for name, idx in zip(catNames, catIdx):
@@ -231,6 +250,33 @@
     def EnableControls(self, enable = True):
         self.combo.Enable(enable)
         self.choice.Enable(enable)
+
+    def Update(self, *args, **kwargs):
+        name = self.GetSelectedCategoryName()
+        catNames = []
+
+        cats = self.stats_data.GetCategories()
+        for cat in cats:
+            stat = self.stats_data.GetStatistics(cat)
+            catNames.append(stat.name)
+        self.SetCategories(catNames = catNames, catIdx = cats)
+        if name in catNames:
+            self.choice.SetStringSelection(name)
+            cat = self.GetSelectedCategoryIdx()
+        elif catNames:
+            self.choice.SetSelection(0)
+            cat = self.GetSelectedCategoryIdx()
+        else:
+            cat = None
+
+        if self.choice.IsEmpty():
+            self.EnableControls(False)
+        else:
+            self.EnableControls(True)
+
+        self._updateColor(cat)
+        self.parent.CategoryChanged(cat)
+        # don't forget to update maps, histo, ...
         
 class IClassMapManagerToolbar(BaseToolbar):
     """!IClass toolbar



More information about the grass-commit mailing list