2 @package gui_core.widgets
4 @brief Core GUI widgets
8 - widgets::ScrolledPanel
10 - widgets::FloatSlider
11 - widgets::SymbolButton
12 - widgets::StaticWrapText
13 - widgets::BaseValidator
14 - widgets::IntegerValidator
15 - widgets::FloatValidator
18 (C) 2008-2011 by the GRASS Development Team
20 This program is free software under the GNU General Public License
21 (>=v2). Read the file COPYING that comes with GRASS for details.
23 @author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
24 @author Enhancements by Michael Barton <michael.barton asu.edu>
25 @author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
33 import wx.lib.scrolledpanel
as SP
35 import wx.lib.agw.flatnotebook
as FN
37 import wx.lib.flatnotebook
as FN
39 from wx.lib.buttons
import ThemedGenBitmapTextButton
as BitmapTextButton
41 from wx.lib.buttons
import GenBitmapTextButton
as BitmapTextButton
43 import wx.lib.agw.customtreectrl
as CT
45 import wx.lib.customtreectrl
as CT
47 from core
import globalvar
50 from wx.lib.newevent
import NewEvent
51 wxSymbolSelectionChanged, EVT_SYMBOL_SELECTION_CHANGED = NewEvent()
54 """!Generic notebook widget
58 FN.FlatNotebook.__init__(self, parent, id = wx.ID_ANY, agwStyle = style, **kwargs)
60 FN.FlatNotebook.__init__(self, parent, id = wx.ID_ANY, style = style, **kwargs)
70 super(GNotebook, self).
AddPage(**kwargs)
83 @param page names, eg. 'layers', 'output', 'search', 'pyshell', 'nviz'
86 if self.GetSelection() != idx:
87 self.SetSelection(idx)
90 """!Get notebook page index
100 """!Custom ScrolledPanel to avoid strange behaviour concerning focus"""
101 def __init__(self, parent, style = wx.TAB_TRAVERSAL):
102 SP.ScrolledPanel.__init__(self, parent = parent, id = wx.ID_ANY, style = style)
107 class NumTextCtrl(wx.TextCtrl):
108 """!Class derived from wx.TextCtrl for numerical values only"""
111 wx.TextCtrl.__init__(self, parent = parent,
116 super(NumTextCtrl, self).
SetValue( str(value))
119 val = super(NumTextCtrl, self).
GetValue()
125 val =
''.join(
''.join(val.split(
'-')).
split(
'.'))
131 class FloatSlider(wx.Slider):
132 """!Class derived from wx.Slider for floats"""
134 Debug.msg(1,
"FloatSlider.__init__()")
135 wx.Slider.__init__(self, **kwargs)
143 if abs(value) < 1
and value != 0:
144 while abs(value) < 1:
148 super(FloatSlider, self).
SetValue(value)
150 Debug.msg(4,
"FloatSlider.SetValue(): value = %f" % value)
156 if abs(minValue) < 1
or abs(maxValue) < 1:
157 while (abs(minValue) < 1
and minValue != 0)
or (abs(maxValue) < 1
and maxValue != 0):
162 super(FloatSlider, self).
SetRange(minValue, maxValue)
163 Debug.msg(4,
"FloatSlider.SetRange(): minValue = %f, maxValue = %f" % (minValue, maxValue))
166 val = super(FloatSlider, self).
GetValue()
167 Debug.msg(4,
"FloatSlider.GetValue(): value = %f" % (val/self.
coef))
171 """!Button with symbol and label."""
172 def __init__(self, parent, usage, label, **kwargs):
175 @param parent parent (usually wx.Panel)
176 @param usage determines usage and picture
177 @param label displayed label
180 buffer = wx.EmptyBitmap(*size)
181 BitmapTextButton.__init__(self, parent = parent, label =
" " + label, bitmap = buffer, **kwargs)
184 dc.SelectObject(buffer)
185 maskColor = wx.Colour(255, 255, 255)
186 dc.SetBrush(wx.Brush(maskColor))
189 if usage ==
'record':
191 elif usage ==
'stop':
193 elif usage ==
'play':
195 elif usage ==
'pause':
198 if sys.platform !=
"win32":
199 buffer.SetMaskColour(maskColor)
200 self.SetBitmapLabel(buffer)
201 dc.SelectObject(wx.NullBitmap)
204 """!Draw record symbol"""
205 dc.SetBrush(wx.Brush(wx.Colour(255, 0, 0)))
206 dc.DrawCircle(size[0]/2, size[1] / 2, size[0] / 2)
209 """!Draw stop symbol"""
210 dc.SetBrush(wx.Brush(wx.Colour(50, 50, 50)))
211 dc.DrawRectangle(0, 0, size[0], size[1])
214 """!Draw play symbol"""
215 dc.SetBrush(wx.Brush(wx.Colour(0, 255, 0)))
216 points = (wx.Point(0, 0), wx.Point(0, size[1]), wx.Point(size[0], size[1] / 2))
217 dc.DrawPolygon(points)
220 """!Draw pause symbol"""
221 dc.SetBrush(wx.Brush(wx.Colour(50, 50, 50)))
222 dc.DrawRectangle(0, 0, 2 * size[0] / 5, size[1])
223 dc.DrawRectangle(3 * size[0] / 5, 0, 2 * size[0] / 5, size[1])
226 """!A Static Text field that wraps its text to fit its width,
227 enlarging its height if necessary.
229 def __init__(self, parent, id = wx.ID_ANY, label = '', *args, **kwds):
233 wx.StaticText.__init__(self, parent, id, label =
'', *args, **kwds)
236 self.Bind(wx.EVT_SIZE, self.
OnResize)
244 if not getattr(self,
"resizing",
False):
246 newSize = wx.Size(self.parent.GetSize().width - 50,
247 self.GetSize().height)
250 self.Wrap(newSize.width)
258 wx.PyValidator.__init__(self)
260 self.Bind(wx.EVT_TEXT, self.
OnText)
270 textCtrl = self.GetWindow()
271 text = textCtrl.GetValue()
277 textCtrl.SetBackgroundColour(
"grey")
282 sysColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
283 textCtrl.SetBackgroundColour(sysColor)
296 """!Validator for floating-point input"""
298 BaseValidator.__init__(self)
302 """!Clone validator"""
306 """!Validator for floating-point input"""
308 BaseValidator.__init__(self)
312 """!Clone validator"""
316 """!validates input in textctrls, taken from wxpython demo"""
318 wx.PyValidator.__init__(self)
320 self.Bind(wx.EVT_CHAR, self.
OnChar)
326 key = event.GetKeyCode()
327 if key < wx.WXK_SPACE
or key == wx.WXK_DELETE
or key > 255:
330 if self.
flag ==
'DIGIT_ONLY' and chr(key)
in string.digits +
'.-':
333 if not wx.Validator_IsSilent():
341 """ This validator checks condition and calls callback
342 in case the condition is not fulfilled.
345 """ Standard constructor.
347 @param condition function which accepts string value and returns T/F
348 @param callback function which is called when condition is not fulfilled
350 wx.PyValidator.__init__(self)
357 Note that every validator must implement the Clone() method.
362 """ Validate the contents of the given text control.
364 ctrl = self.GetWindow()
365 text = ctrl.GetValue()
373 """ Transfer data from validator to window.
379 """ Transfer data from window to validator.
385 def __init__(self, parent, id = wx.ID_ANY,
386 ctstyle = CT.TR_HIDE_ROOT | CT.TR_FULL_ROW_HIGHLIGHT | CT.TR_HAS_BUTTONS |
387 CT.TR_LINES_AT_ROOT | CT.TR_SINGLE, **kwargs):
389 super(ItemTree, self).
__init__(parent, id, agwStyle = ctstyle, **kwargs)
391 super(ItemTree, self).
__init__(parent, id, style = ctstyle, **kwargs)
393 self.
root = self.AddRoot(_(
"Menu tree"))
400 @param element element index (see self.searchBy)
403 @return list of found tree items
409 item = self.GetFirstChild(self.
root)[0]
417 def _processItem(self, item, element, value, listOfItems):
418 """!Search items (used by SearchItems)
420 @param item reference item
421 @param listOfItems list of found items
423 while item
and item.IsOk():
424 subItem = self.GetFirstChild(item)[0]
427 data = self.GetPyData(item)
429 if data
and element
in data
and \
430 value.lower()
in data[element].lower():
431 listOfItems.append(item)
433 item = self.GetNextSibling(item)
436 """!Get selected item"""
440 """!Highlight first found item in menu tree"""
444 idx = self.itemsMarked.index(self.
GetSelected()) + 1
456 for item
in self.root.GetChildren():
458 itemSelected = self.GetSelection()
460 self.ToggleItemSelection(itemSelected)
464 """!Panel for displaying one symbol.
466 Changes background when selected. Assumes that parent will catch
467 events emitted on mouse click. Used in gui_core::dialog::SymbolDialog.
470 """!Panel constructor
472 @param parent parent (gui_core::dialog::SymbolDialog)
473 @param symbolPath absolute path to symbol
475 wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.BORDER_RAISED)
476 self.SetName(os.path.splitext(os.path.basename(symbolPath))[0])
477 self.
sBmp = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap(symbolPath))
480 self.
selectColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)
483 sizer = wx.BoxSizer()
484 sizer.Add(item = self.
sBmp, proportion = 0, flag = wx.ALL | wx.ALIGN_CENTER, border = 5)
486 self.SetMinSize(self.GetBestSize())
487 self.SetSizerAndFit(sizer)
490 self.sBmp.Bind(wx.EVT_LEFT_DOWN, self.
OnLeftDown)
496 """!Panel selected, background changes"""
502 event = wxSymbolSelectionChanged(name = self.GetName(), doubleClick =
False)
503 wx.PostEvent(self.GetParent(), event)
506 event = wxSymbolSelectionChanged(name = self.GetName(), doubleClick =
True)
507 wx.PostEvent(self.GetParent(), event)
510 """!Panel deselected, background changes back to default"""
516 """!Select panel, no event emitted"""
def split
Platform spefic shlex.split.
A Static Text field that wraps its text to fit its width, enlarging its height if necessary...