[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