[GRASS-SVN] r50111 - in grass/trunk/gui/wxpython: gui_core psmap
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Jan 9 15:09:01 EST 2012
Author: annakrat
Date: 2012-01-09 12:09:01 -0800 (Mon, 09 Jan 2012)
New Revision: 50111
Modified:
grass/trunk/gui/wxpython/gui_core/dialogs.py
grass/trunk/gui/wxpython/gui_core/forms.py
grass/trunk/gui/wxpython/gui_core/widgets.py
grass/trunk/gui/wxpython/psmap/dialogs.py
Log:
wxGUI/wxpsmap bug #1531 fixed
Modified: grass/trunk/gui/wxpython/gui_core/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/dialogs.py 2012-01-09 17:45:28 UTC (rev 50110)
+++ grass/trunk/gui/wxpython/gui_core/dialogs.py 2012-01-09 20:09:01 UTC (rev 50111)
@@ -39,6 +39,10 @@
import wx
import wx.lib.filebrowsebutton as filebrowse
import wx.lib.mixins.listctrl as listmix
+try:
+ from wx.lib.buttons import ThemedGenBitmapToggleButton as BTButton
+except ImportError: # not sure about TGBTButton version
+ from wx.lib.buttons import GenBitmapToggleButton as BTButton
from grass.script import core as grass
from grass.script import task as gtask
@@ -47,6 +51,7 @@
from core.gcmd import GError, RunCommand, GMessage
from gui_core.gselect import ElementSelect, LocationSelect, MapsetSelect, Select, OgrTypeSelect, GdalSelect, MapsetSelect
from gui_core.forms import GUI
+from gui_core.widgets import SingleSymbolPanel, EVT_SYMBOL_SELECTION_CHANGED
from core.utils import GetListOfMapsets, GetLayerNameFromCmd, GetValidLayerName
from core.settings import UserSettings
from core.debug import Debug
@@ -2382,3 +2387,160 @@
"""!Close window
"""
self.Close()
+
+class SymbolDialog(wx.Dialog):
+ """!Dialog for GRASS symbols selection.
+
+ Dialog is called in gui_core::forms module.
+ """
+ def __init__(self, parent, symbolPath, currentSymbol = None, title = _("Symbols")):
+ """!Dialog constructor.
+
+ It is assumed that symbolPath contains folders with symbols.
+
+ @param parent dialog parent
+ @param symbolPath absolute path to symbols
+ @param currentSymbol currently selected symbol (e.g. 'basic/x')
+ @param title dialog title
+ """
+ wx.Dialog.__init__(self, parent = parent, title = title, id = wx.ID_ANY)
+
+ self.symbolPath = symbolPath
+ self.currentSymbol = currentSymbol # default basic/x
+ self.selected = None
+
+ self._layout()
+
+ def _layout(self):
+ mainPanel = wx.Panel(self, id = wx.ID_ANY)
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ staticBox = wx.StaticBox(parent = mainPanel, id = wx.ID_ANY,
+ label = " %s " % _("Symbol selection"))
+ self.staticSizer = wx.StaticBoxSizer(staticBox, wx.VERTICAL)
+
+ hSizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.folderChoice = wx.Choice(mainPanel, id = wx.ID_ANY, choices = os.listdir(self.symbolPath))
+ self.folderChoice.Bind(wx.EVT_CHOICE, self.OnFolderSelect)
+
+ self.staticSizer.Add(self.folderChoice, proportion = 0,
+ flag = wx.ALL, border = 5)
+
+ self.panels = self._createSymbolPanels(mainPanel)
+ for panel in self.panels:
+ self.staticSizer.Add(panel, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+ panel.Bind(EVT_SYMBOL_SELECTION_CHANGED, self.SelectionChanged)
+
+ self.infoLabel = wx.StaticText(mainPanel, id = wx.ID_ANY)
+ self.staticSizer.Add(self.infoLabel, proportion = 0,
+ flag = wx.ALL | wx.ALIGN_CENTRE_VERTICAL, border = 5)
+
+ mainSizer.Add(self.staticSizer, proportion = 1, flag = wx.ALL| wx.EXPAND, border = 5)
+ self.btnCancel = wx.Button(parent = mainPanel, id = wx.ID_CANCEL)
+ self.btnOK = wx.Button(parent = mainPanel, id = wx.ID_OK)
+ self.btnOK.SetDefault()
+ self.btnOK.Enable(False)
+
+
+ # buttons
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(self.btnCancel)
+ btnSizer.AddButton(self.btnOK)
+ btnSizer.Realize()
+ mainSizer.Add(item = btnSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL, border = 5)
+
+
+ # show panel with the largest number of images and fit size
+ count = []
+ for folder in os.listdir(self.symbolPath):
+ count.append(len(os.listdir(os.path.join(self.symbolPath, folder))))
+
+ index = count.index(max(count))
+ self.folderChoice.SetSelection(index)
+ self.OnFolderSelect(None)
+
+ mainPanel.SetSizerAndFit(mainSizer)
+ self.SetSize(self.GetBestSize())
+
+ # show currently selected symbol
+ if self.currentSymbol:
+ selected = os.path.split(self.currentSymbol)[0]
+ self.folderChoice.SetStringSelection(selected)
+ else:
+ self.folderChoice.SetSelection(0)
+
+ self.OnFolderSelect(None)
+
+ def _createSymbolPanels(self, parent):
+ """!Creates multiple panels with symbols.
+
+ Panels are shown/hidden according to selected folder."""
+ folders = os.listdir(self.symbolPath)
+
+ self.panels = []
+ self.symbolPanels = []
+ maxImages = 0
+ for folder in folders:
+ panel = wx.Panel(parent)
+ sizer = wx.GridSizer(cols = 6, vgap = 3, hgap = 3)
+ images = self._getSymbols(path = os.path.join(self.symbolPath, folder))
+
+ symbolPanels = []
+ for img in images:
+ btn = BTButton(parent = panel, id = wx.ID_ANY, bitmap = wx.Bitmap(img), name = img)
+
+ #iP = SingleSymbolPanel(parent = panel, symbolPath = img)
+ sizer.Add(item = btn, proportion = 0, flag = wx.ALL, border = 0)
+ symbolPanels.append(btn)
+
+ panel.SetSizerAndFit(sizer)
+ panel.Hide()
+ self.panels.append(panel)
+ self.symbolPanels.append(symbolPanels)
+ return self.panels
+
+ def _getSymbols(self, path):
+ # we assume that images are in subfolders (1 level only)
+ imageList = []
+ for image in os.listdir(path):
+ imageList.append(os.path.join(path, image))
+
+ return sorted(imageList)
+
+ def OnFolderSelect(self, event):
+ """!Selected folder with symbols changed."""
+ idx = self.folderChoice.GetSelection()
+ for i in range(len(self.panels)):
+ sizer = self.panels[i].GetContainingSizer()
+ sizer.Show(self.panels[i], i == idx, recursive = True)
+ sizer.Layout()
+
+ self.infoLabel.SetLabel('')
+ self.btnOK.Disable()
+
+ def SelectionChanged(self, event):
+ """!Selected symbol changed."""
+ if event.doubleClick:
+ self.EndModal(wx.ID_OK)
+ # deselect all
+ for i in range(len(self.panels)):
+ for panel in self.symbolPanels[i]:
+ if panel.GetName() != event.name:
+ panel.Deselect()
+
+ self.btnOK.Enable()
+
+ self.selected = os.path.join(self.folderChoice.GetStringSelection(), event.name)
+
+ self.infoLabel.SetLabel(event.name)
+
+ def GetSelectedSymbol(self, fullPath = False):
+ """!Returns currently selected symbol.
+
+ @param fullPath true to return absolute path to symbol,
+ otherwise returns e.g. 'basic/x'
+ """
+ if fullPath:
+ return os.path.join(self.symbolPath, self.selected)
+
+ return self.selected
Modified: grass/trunk/gui/wxpython/gui_core/forms.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/forms.py 2012-01-09 17:45:28 UTC (rev 50110)
+++ grass/trunk/gui/wxpython/gui_core/forms.py 2012-01-09 20:09:01 UTC (rev 50111)
@@ -92,6 +92,7 @@
from core.settings import UserSettings
from gui_core.widgets import FloatValidator, GNotebook
+
wxUpdateDialog, EVT_DIALOG_UPDATE = NewEvent()
# From lib/gis/col_str.c, except purple which is mentioned
@@ -152,6 +153,10 @@
"""!Escapes ampersands with additional ampersand for GUI"""
return string.replace(text, "&", "&&")
+def symbolPath():
+ """!Returnes absolute path to symbols"""
+ return "/home/anna/Desktop/symbols"
+
class UpdateThread(Thread):
"""!Update dialog widgets in the thread"""
def __init__(self, parent, event, eventId, task):
@@ -1034,19 +1039,38 @@
p['wxId'] = [ txt2.GetId(), ]
txt2.Bind(wx.EVT_TEXT, self.OnSetValue)
else:
- # list of values (combo)
+
title_txt.SetLabel(title + ':')
- cb = wx.ComboBox(parent = which_panel, id = wx.ID_ANY, value = p.get('default',''),
- size = globalvar.DIALOG_COMBOBOX_SIZE,
- choices = valuelist, style = wx.CB_DROPDOWN)
value = self._getValue(p)
- if value:
- cb.SetValue(value) # parameter previously set
- which_sizer.Add(item = cb, proportion = 0,
- flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
- p['wxId'] = [cb.GetId(),]
- cb.Bind(wx.EVT_COMBOBOX, self.OnSetValue)
- cb.Bind(wx.EVT_TEXT, self.OnSetValue)
+
+ if p['name'] == 'icon': # symbols
+ bitmap = wx.Bitmap(os.path.join(symbolPath(), value) + '.png')
+ bb = wx.BitmapButton(parent = which_panel, id = wx.ID_ANY,
+ bitmap = bitmap)
+ iconLabel = wx.StaticText(parent = which_panel, id = wx.ID_ANY)
+ iconLabel.SetLabel(value)
+ p['value'] = value
+ p['wxId'] = [bb.GetId(),iconLabel.GetId()]
+ bb.Bind(wx.EVT_BUTTON, self.OnSetSymbol)
+ this_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ this_sizer.Add(item = bb, proportion = 0,
+ flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
+ this_sizer.Add(item = iconLabel, proportion = 0,
+ flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border = 5)
+ which_sizer.Add(item = this_sizer, proportion = 0,
+ flag = wx.ADJUST_MINSIZE, border = 0)
+ else:
+ # list of values (combo)
+ cb = wx.ComboBox(parent = which_panel, id = wx.ID_ANY, value = p.get('default',''),
+ size = globalvar.DIALOG_COMBOBOX_SIZE,
+ choices = valuelist, style = wx.CB_DROPDOWN)
+ if value:
+ cb.SetValue(value) # parameter previously set
+ which_sizer.Add(item = cb, proportion = 0,
+ flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
+ p['wxId'] = [cb.GetId(),]
+ cb.Bind(wx.EVT_COMBOBOX, self.OnSetValue)
+ cb.Bind(wx.EVT_TEXT, self.OnSetValue)
# text entry
if (p.get('type','string') in ('string','integer','float')
@@ -1863,6 +1887,26 @@
event.Skip()
+ def OnSetSymbol(self, event):
+ """!Shows dialog for symbol selection"""
+ myId = event.GetId()
+
+ for p in self.task.params:
+ if 'wxId' in p and myId in p['wxId']:
+ from gui_core.dialogs import SymbolDialog
+ dlg = SymbolDialog(self, symbolPath = symbolPath(), currentSymbol = p['value'])
+ if dlg.ShowModal() == wx.ID_OK:
+ img = dlg.GetSelectedSymbol(fullPath = True)
+ bitmapButton = wx.FindWindowById(p['wxId'][0])
+ label = wx.FindWindowById(p['wxId'][1])
+ bitmapButton.SetBitmapLabel(wx.Bitmap(img + '.png'))
+ p['value'] = dlg.GetSelectedSymbol(fullPath = False)
+ label.SetLabel(p['value'])
+
+ self.OnUpdateValues(event)
+
+ dlg.Destroy()
+
def OnUpdateSelection(self, event):
"""!Update dialog (layers, tables, columns, etc.)
"""
Modified: grass/trunk/gui/wxpython/gui_core/widgets.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/widgets.py 2012-01-09 17:45:28 UTC (rev 50110)
+++ grass/trunk/gui/wxpython/gui_core/widgets.py 2012-01-09 20:09:01 UTC (rev 50111)
@@ -25,6 +25,7 @@
@author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
"""
+import os
import string
import wx
@@ -44,6 +45,8 @@
from core import globalvar
from core.debug import Debug
+from wx.lib.newevent import NewEvent
+wxSymbolSelectionChanged, EVT_SYMBOL_SELECTION_CHANGED = NewEvent()
class GNotebook(FN.FlatNotebook):
"""!Generic notebook widget
@@ -409,3 +412,53 @@
if itemSelected:
self.ToggleItemSelection(itemSelected)
self.itemSelected = None
+
+class SingleSymbolPanel(wx.Panel):
+ """!Panel for displaying one symbol.
+
+ Changes background when selected. Assumes that parent will catch
+ events emitted on mouse click. Used in gui_core::dialog::SymbolDialog.
+ """
+ def __init__(self, parent, symbolPath):
+ """!Panel constructor
+
+ @param parent parent (gui_core::dialog::SymbolDialog)
+ @param symbolPath absolute path to symbol
+ """
+ wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.BORDER_RAISED)
+ self.SetName(os.path.splitext(os.path.basename(symbolPath))[0])
+ self.sBmp = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap(symbolPath))
+
+ self.selected = False
+ self.selectionColor = wx.Colour(255, 252, 120)
+
+ sizer = wx.BoxSizer()
+ sizer.Add(item = self.sBmp, proportion = 0, flag = wx.ALL, border = 0)
+ self.SetBackgroundStyle(wx.BG_STYLE_SYSTEM)
+ self.SetMinSize(self.GetBestSize())
+ self.SetSizerAndFit(sizer)
+
+ # binding to both (staticBitmap, Panel) necessary
+ self.sBmp.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+ self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
+ self.sBmp.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
+
+ def OnLeftDown(self, event):
+ """!Panel selected, background changes"""
+ self.selected = True
+ self.SetBackgroundColour(self.selectionColor)
+ event.Skip()
+
+ event = wxSymbolSelectionChanged(name = self.GetName(), doubleClick = False)
+ wx.PostEvent(self.GetParent(), event)
+
+ def OnDoubleClick(self, event):
+ event = wxSymbolSelectionChanged(name = self.GetName(), doubleClick = True)
+ wx.PostEvent(self.GetParent(), event)
+
+ def Deselect(self):
+ """!Panel deselected, background changes back to default"""
+ self.SetBackgroundColour(wx.NullColor)
+ self.selected = False
+
Modified: grass/trunk/gui/wxpython/psmap/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/psmap/dialogs.py 2012-01-09 17:45:28 UTC (rev 50110)
+++ grass/trunk/gui/wxpython/psmap/dialogs.py 2012-01-09 20:09:01 UTC (rev 50111)
@@ -2925,9 +2925,11 @@
self.select = Select(self, id = wx.ID_ANY,# size = globalvar.DIALOG_GSELECT_SIZE,
type = 'vector', multiple = False,
updateOnPopup = True, onPopup = None)
- topologyType = [_("points"), _("lines"), _("areas")]
- self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " %s " % _("Data Type"), choices = topologyType,
- majorDimension = 3, style = wx.RA_SPECIFY_COLS)
+ topologyTypeTr = [_("points"), _("lines"), _("areas")]
+ self.topologyTypeList = ["points", "lines", "areas"]
+ self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " %s " % _("Data Type"), choices = topologyTypeTr,
+ majorDimension = 3, style = wx.RA_SPECIFY_COLS)
+
self.AddVector = wx.Button(self, id = wx.ID_ANY, label = _("Add"))
gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
@@ -3008,16 +3010,17 @@
mapset = '(' + vmap.split('@')[1] + ')'
except IndexError:
mapset = ''
- type = self.vectorType.GetStringSelection()
- record = "%s - %s" % (vmap,type)
+ idx = self.vectorType.GetSelection()
+ ttype = self.topologyTypeList[idx]
+ record = "%s - %s" % (vmap, ttype)
id = wx.NewId()
lpos = 1
label = mapname + mapset
- self.vectorList.insert(0, [vmap, type, id, lpos, label])
+ self.vectorList.insert(0, [vmap, ttype, id, lpos, label])
self.reposition()
self.listbox.InsertItems([record], 0)
- vector = VProperties(id, type)
+ vector = VProperties(id, ttype)
self.tmpDialogDict[id] = vector.GetInstruction()
self.tmpDialogDict[id]['name'] = vmap
@@ -3224,7 +3227,7 @@
if id == item[2]:
self.vectorName = item[0]
self.type = item[1]
- self.SetTitle(self.vectorName + " "+ _("properties"))
+ self.SetTitle(_("%s properties") % self.vectorName)
#vector map info
self.connection = True
More information about the grass-commit
mailing list