- Phoenix-port of `wx.lib.buttons.py`, with unittest and documentation updated to Phoenix standards;
- Phoenix-port of part of the AGW library, including `AdvancedSplash`, `BalloonTip`, `ButtonPanel`, `CubeColourDialog`, `CustomTreeCtrl`, `FloatSpin`, `FoldPanelBar`, `FourWaySplitter`, `GenericMessageDialog`, `HyperLinkCtrl` and `HyperTreeList`. Unittests and documentation updated to Phoenix standards;
- Added the `wx2to3.py` module to `wx.lib`, to facilitate the port to Python 3 (AGW depends on it).


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@72112 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Andrea Gavana
2012-07-16 16:52:14 +00:00
parent 4f6b6ff7ee
commit 6bfa39aff0
26 changed files with 2605 additions and 627 deletions

View File

@@ -0,0 +1,32 @@
import imp_unittest, unittest
import wtc
import wx
import os
import wx.lib.agw.advancedsplash as AS
pngFile = os.path.join(os.path.dirname(__file__), 'toucan.png')
#---------------------------------------------------------------------------
class lib_agw_advancedsplash_Tests(wtc.WidgetTestCase):
def test_lib_agw_advancedsplashCtor(self):
splash = AS.AdvancedSplash(self.frame, -1, bitmap=wx.Bitmap(pngFile),
agwStyle=AS.AS_TIMEOUT|AS.AS_CENTER_ON_SCREEN,
timeout=250)
self.waitFor(300)
def test_lib_agw_advancedsplashConstantsExist(self):
AS.AS_CENTER_ON_PARENT
AS.AS_CENTER_ON_SCREEN
AS.AS_NO_CENTER
AS.AS_TIMEOUT
AS.AS_NOTIMEOUT
AS.AS_SHADOW_BITMAP
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,38 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.balloontip as BT
#---------------------------------------------------------------------------
class lib_agw_balloontip_Tests(wtc.WidgetTestCase):
def test_lib_agw_balloontipCtor(self):
tip = BT.BalloonTip(toptitle='Balloon', message='Hello wxPython',
shape=BT.BT_ROUNDED, tipstyle=BT.BT_BUTTON)
def test_lib_agw_balloontipMethods(self):
tip = BT.BalloonTip(toptitle='Balloon', message='Hello wxPython',
shape=BT.BT_ROUNDED, tipstyle=BT.BT_BUTTON)
self.assertTrue(tip.GetBalloonShape() == BT.BT_ROUNDED)
self.assertTrue(tip.GetBalloonTipStyle() == BT.BT_BUTTON)
tip.SetBalloonShape(BT.BT_RECTANGLE)
tip.SetBalloonTipStyle(BT.BT_LEAVE)
self.assertTrue(tip.GetBalloonShape() == BT.BT_RECTANGLE)
self.assertTrue(tip.GetBalloonTipStyle() == BT.BT_LEAVE)
def test_lib_agw_balloontipConstantsExist(self):
BT.BT_ROUNDED
BT.BT_RECTANGLE
BT.BT_LEAVE
BT.BT_CLICK
BT.BT_BUTTON
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,57 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.buttonpanel as BP
#---------------------------------------------------------------------------
class lib_agw_buttonpanel_Tests(wtc.WidgetTestCase):
def test_lib_agw_buttonpanelCtor(self):
bar = BP.ButtonPanel(self.frame, -1, 'sample text')
btn = BP.ButtonInfo(bar, wx.NewId(),
wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (32, 32)),
text='Button 1')
bar.AddButton(btn)
def test_lib_agw_buttonpanelMethods(self):
bar = BP.ButtonPanel(self.frame, -1, 'sample text')
btn = BP.ButtonInfo(bar, wx.NewId(),
wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (32, 32)),
text='Button 1')
bar.AddButton(btn)
bar.SetBarText('')
self.assertTrue(not bar.HasBarText())
bar.RemoveText()
self.assertTrue(not bar.HasBarText())
self.assertTrue(bar.IsStandard())
self.assertTrue(not bar.IsVertical())
def test_lib_agw_buttonpanelConstantsExist(self):
# ButtonPanel agwStyle
BP.BP_DEFAULT_STYLE
BP.BP_USE_GRADIENT
# ButtonPanel alignments
BP.BP_ALIGN_LEFT
BP.BP_ALIGN_RIGHT
BP.BP_ALIGN_TOP
BP.BP_ALIGN_BOTTOM
# HitTest flags
BP.BP_HT_BUTTON
BP.BP_HT_NONE
# Caption gradient types
BP.BP_GRADIENT_NONE
BP.BP_GRADIENT_VERTICAL
BP.BP_GRADIENT_HORIZONTAL
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,39 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.cubecolourdialog as CCD
#---------------------------------------------------------------------------
class lib_agw_cubecolourdialog_Tests(wtc.WidgetTestCase):
def test_lib_agw_cubecolourdialogCtor(self):
colourData = wx.ColourData()
colourData.SetColour(wx.RED)
dlg = CCD.CubeColourDialog(self.frame, colourData, agwStyle=0)
def test_lib_agw_cubecolourdialogMethods(self):
colourData = wx.ColourData()
colourData.SetColour(wx.BLUE)
dlg = CCD.CubeColourDialog(self.frame, colourData, agwStyle=0)
self.assertTrue(dlg.GetAGWWindowStyleFlag() == 0)
dlg.SetAGWWindowStyleFlag(CCD.CCD_SHOW_ALPHA)
self.assertTrue(dlg.GetAGWWindowStyleFlag() > 0)
colour = dlg.GetRGBAColour()
self.assertEqual(colour, wx.Colour('blue'))
ccd_colour = CCD.Colour(wx.Colour(colour))
html = CCD.rgb2html(ccd_colour)
self.assertTrue(html in CCD.HTMLCodes)
def test_lib_agw_cubecolourdialogConstantsExist(self):
# CubeColourDialog agwStyle
CCD.CCD_SHOW_ALPHA
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,212 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.customtreectrl as CT
#---------------------------------------------------------------------------
class lib_agw_customtreectrl_Tests(wtc.WidgetTestCase):
def test_lib_agw_customtreectrlCtor(self):
tree = CT.CustomTreeCtrl(self.frame)
self.assertEqual(tree.GetAGWWindowStyleFlag(), CT.TR_DEFAULT_STYLE)
self.assertEqual(tree.GetCount(), 0)
self.assertEqual(tree.GetRootItem(), None)
def test_lib_agw_customtreectrlTreeItem(self):
tree = CT.CustomTreeCtrl(self.frame)
root = tree.AddRoot('root item')
self.assertTrue(isinstance(root, CT.GenericTreeItem))
self.assertTrue(root.IsOk())
r = tree.GetRootItem()
self.assertTrue(r is root)
self.assertTrue(r == root)
child = tree.AppendItem(root, 'child item')
self.assertTrue(child is not root)
self.assertTrue(child != root)
def test_lib_agw_customtreectrlTreeItemData(self):
value = 'Some Python Object'
tree = CT.CustomTreeCtrl(self.frame)
root = tree.AddRoot('root item', data=value)
v = tree.GetItemData(root)
self.assertTrue(v == value)
tree.SetItemData(root, None)
self.assertTrue(tree.GetItemData(root) is None)
def test_lib_agw_customtreectrlTreeItemPyData(self):
# ensure that the "Py" versions works as the normal one
value = 'Some Python Object'
tree = CT.CustomTreeCtrl(self.frame)
root = tree.AddRoot('root item')
tree.SetItemPyData(root, value)
v = tree.GetItemPyData(root)
self.assertTrue(v == value)
tree.SetItemPyData(root, None)
self.assertTrue(tree.GetItemPyData(root) is None)
def test_lib_agw_customtreectrlGetSelections(self):
tree = CT.CustomTreeCtrl(self.frame, agwStyle=CT.TR_MULTIPLE)
root = tree.AddRoot('root item')
c1 = tree.AppendItem(root, 'c1')
c2 = tree.AppendItem(root, 'c2')
tree.SelectItem(c1)
tree.SelectItem(c2)
self.assertTrue(tree.IsSelected(c1))
self.assertTrue(tree.IsSelected(c2))
sel = tree.GetSelections()
self.assertTrue(isinstance(sel, list))
self.assertTrue(len(sel) == 2)
self.assertTrue(isinstance(sel[0], CT.GenericTreeItem))
def test_lib_agw_customtreectrlItemCheck(self):
tree = CT.CustomTreeCtrl(self.frame)
root = tree.AddRoot('root item')
# Checkboxes, there can be more than one checked at the same level
c1 = tree.AppendItem(root, 'c1', ct_type=1)
c2 = tree.AppendItem(root, 'c2', ct_type=1)
tree.CheckItem(c1)
tree.CheckItem(c2)
self.assertTrue(tree.IsItemChecked(c1))
self.assertTrue(tree.IsItemChecked(c2))
# RadioButtons, there can NOT be more than one checked at the same level
c1 = tree.AppendItem(root, 'c1', ct_type=2)
c2 = tree.AppendItem(root, 'c2', ct_type=2)
tree.CheckItem(c1)
tree.CheckItem(c2)
self.assertTrue(not tree.IsItemChecked(c1))
self.assertTrue(tree.IsItemChecked(c2))
def test_lib_agw_customtreectrlSetWindow(self):
tree = CT.CustomTreeCtrl(self.frame, agwStyle=CT.TR_DEFAULT_STYLE|CT.TR_HAS_VARIABLE_ROW_HEIGHT)
root = tree.AddRoot('root item')
c1 = tree.AppendItem(root, 'c1')
c2 = tree.AppendItem(root, 'c2')
window = wx.TextCtrl(tree, -1, 'Hello World')
tree.SetItemWindow(c2, window)
other = tree.GetItemWindow(c2)
self.assertTrue(window == other)
tree.DeleteAllItems()
self.assertTrue(tree.GetCount() == 0)
self.assertTrue(len(tree.GetChildren()) == 0)
def test_lib_agw_customtreectrlConstantsExist(self):
CT.TR_NO_BUTTONS
CT.TR_SINGLE
CT.TR_HAS_BUTTONS
CT.TR_NO_LINES
CT.TR_LINES_AT_ROOT
CT.TR_DEFAULT_STYLE
CT.TR_TWIST_BUTTONS
CT.TR_MULTIPLE
CT.TR_EXTENDED
CT.TR_HAS_VARIABLE_ROW_HEIGHT
CT.TR_EDIT_LABELS
CT.TR_ROW_LINES
CT.TR_HIDE_ROOT
CT.TR_FULL_ROW_HIGHLIGHT
CT.TR_AUTO_CHECK_CHILD
CT.TR_AUTO_TOGGLE_CHILD
CT.TR_AUTO_CHECK_PARENT
CT.TR_ALIGN_WINDOWS
CT.TR_ALIGN_WINDOWS_RIGHT
CT.TR_ELLIPSIZE_LONG_ITEMS
CT.TR_TOOLTIP_ON_LONG_ITEMS
CT.TreeItemIcon_Normal
CT.TreeItemIcon_Selected
CT.TreeItemIcon_Expanded
CT.TreeItemIcon_SelectedExpanded
CT.TreeItemIcon_Checked
CT.TreeItemIcon_NotChecked
CT.TreeItemIcon_Undetermined
CT.TreeItemIcon_Flagged
CT.TreeItemIcon_NotFlagged
CT.TREE_HITTEST_ABOVE
CT.TREE_HITTEST_BELOW
CT.TREE_HITTEST_NOWHERE
CT.TREE_HITTEST_ONITEMBUTTON
CT.TREE_HITTEST_ONITEMICON
CT.TREE_HITTEST_ONITEMINDENT
CT.TREE_HITTEST_ONITEMLABEL
CT.TREE_HITTEST_ONITEM
CT.TREE_HITTEST_ONITEMRIGHT
CT.TREE_HITTEST_TOLEFT
CT.TREE_HITTEST_TORIGHT
CT.TREE_HITTEST_ONITEMUPPERPART
CT.TREE_HITTEST_ONITEMLOWERPART
CT.TREE_HITTEST_ONITEMCHECKICON
CT.TREE_HITTEST_ONITEM
def test_lib_agw_customtreectrlEventsExist(self):
CT.wxEVT_TREE_BEGIN_DRAG
CT.wxEVT_TREE_BEGIN_RDRAG
CT.wxEVT_TREE_BEGIN_LABEL_EDIT
CT.wxEVT_TREE_END_LABEL_EDIT
CT.wxEVT_TREE_DELETE_ITEM
CT.wxEVT_TREE_GET_INFO
CT.wxEVT_TREE_SET_INFO
CT.wxEVT_TREE_ITEM_EXPANDED
CT.wxEVT_TREE_ITEM_EXPANDING
CT.wxEVT_TREE_ITEM_COLLAPSED
CT.wxEVT_TREE_ITEM_COLLAPSING
CT.wxEVT_TREE_SEL_CHANGED
CT.wxEVT_TREE_SEL_CHANGING
CT.wxEVT_TREE_KEY_DOWN
CT.wxEVT_TREE_ITEM_ACTIVATED
CT.wxEVT_TREE_ITEM_RIGHT_CLICK
CT.wxEVT_TREE_ITEM_MIDDLE_CLICK
CT.wxEVT_TREE_END_DRAG
CT.wxEVT_TREE_STATE_IMAGE_CLICK
CT.wxEVT_TREE_ITEM_GETTOOLTIP
CT.wxEVT_TREE_ITEM_MENU
CT.wxEVT_TREE_ITEM_CHECKING
CT.wxEVT_TREE_ITEM_CHECKED
CT.wxEVT_TREE_ITEM_HYPERLINK
CT.EVT_TREE_BEGIN_DRAG
CT.EVT_TREE_BEGIN_LABEL_EDIT
CT.EVT_TREE_BEGIN_RDRAG
CT.EVT_TREE_DELETE_ITEM
CT.EVT_TREE_END_DRAG
CT.EVT_TREE_END_LABEL_EDIT
CT.EVT_TREE_GET_INFO
CT.EVT_TREE_ITEM_ACTIVATED
CT.EVT_TREE_ITEM_CHECKED
CT.EVT_TREE_ITEM_CHECKING
CT.EVT_TREE_ITEM_COLLAPSED
CT.EVT_TREE_ITEM_COLLAPSING
CT.EVT_TREE_ITEM_EXPANDED
CT.EVT_TREE_ITEM_EXPANDING
CT.EVT_TREE_ITEM_GETTOOLTIP
CT.EVT_TREE_ITEM_HYPERLINK
CT.EVT_TREE_ITEM_MENU
CT.EVT_TREE_ITEM_MIDDLE_CLICK
CT.EVT_TREE_ITEM_RIGHT_CLICK
CT.EVT_TREE_KEY_DOWN
CT.EVT_TREE_SEL_CHANGED
CT.EVT_TREE_SEL_CHANGING
CT.EVT_TREE_SET_INFO
CT.EVT_TREE_STATE_IMAGE_CLICK
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,58 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.floatspin as FS
#---------------------------------------------------------------------------
class lib_agw_floatspin_Tests(wtc.WidgetTestCase):
def test_lib_agw_floatspinCtor(self):
floatspin = FS.FloatSpin(self.frame, min_val=0, max_val=1,
increment=0.01, value=0.1, agwStyle=FS.FS_LEFT)
floatspin.SetFormat('%f')
floatspin.SetDigits(2)
def test_lib_agw_floatspinMethods(self):
floatspin = FS.FloatSpin(self.frame, min_val=0, max_val=1,
increment=0.01, value=0.1, agwStyle=FS.FS_LEFT)
floatspin.SetFormat('%f')
floatspin.SetDigits(2)
# Some methods tests...
self.assertTrue(floatspin.GetFormat() == '%f')
self.assertEqual(floatspin.GetDigits(), 2)
# Should not be possible to set 100...
floatspin.SetValue(100.0)
self.assertTrue(floatspin.GetValue() == 0.1)
floatspin.SetValue(0.2)
floatspin.SetToDefaultValue()
self.assertTrue(floatspin.GetValue() == 0.1)
self.assertTrue(floatspin.IsFinite(floatspin.GetValue()))
self.assertTrue(not floatspin.InRange(50))
self.assertTrue(floatspin.HasRange())
self.assertEqual(floatspin.GetMin(), 0)
self.assertEqual(floatspin.GetMax(), 1)
self.assertEqual(floatspin.GetIncrement(), FS.FixedPoint(str(0.01), 20))
def test_lib_agw_floatspinConstantsExists(self):
FS.DEFAULT_PRECISION
FS.FS_CENTRE
FS.FS_LEFT
FS.FS_READONLY
FS.FS_RIGHT
def test_lib_agw_floatspinEvents(self):
FS.EVT_FLOATSPIN
FS.wxEVT_FLOATSPIN
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,72 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.foldpanelbar as FPB
#---------------------------------------------------------------------------
class lib_agw_foldpanelbar_Tests(wtc.WidgetTestCase):
def test_lib_agw_foldpanelbarCtor(self):
panel_bar = FPB.FoldPanelBar(self.frame, -1, agwStyle=FPB.FPB_VERTICAL)
fold_panel = panel_bar.AddFoldPanel("Thing")
thing = wx.TextCtrl(fold_panel, -1, size=(400, -1), style=wx.TE_MULTILINE)
panel_bar.AddFoldPanelWindow(fold_panel, thing)
def test_lib_agw_foldpanelbarMethods(self):
panel_bar = FPB.FoldPanelBar(self.frame, -1, agwStyle=FPB.FPB_VERTICAL)
fold_panel = panel_bar.AddFoldPanel("Thing")
thing = wx.TextCtrl(fold_panel, -1, size=(400, -1), style=wx.TE_MULTILINE)
panel_bar.AddFoldPanelWindow(fold_panel, thing)
# Some methods tests...
self.assertTrue(panel_bar.IsVertical())
self.assertEqual(panel_bar.GetCount(), 1)
# Separators do not count as they are not "real" windows
panel_bar.AddFoldPanelSeparator(fold_panel)
self.assertEqual(panel_bar.GetCount(), 1)
foldpanel = panel_bar.GetFoldPanel(0)
self.assertTrue(foldpanel.IsExpanded())
panel_bar.Collapse(foldpanel)
self.assertTrue(not foldpanel.IsExpanded())
def test_lib_agw_foldpanelbarConstantsExists(self):
FPB.CAPTIONBAR_FILLED_RECTANGLE
FPB.CAPTIONBAR_GRADIENT_H
FPB.CAPTIONBAR_GRADIENT_V
FPB.CAPTIONBAR_NOSTYLE
FPB.CAPTIONBAR_RECTANGLE
FPB.CAPTIONBAR_SINGLE
FPB.FPB_ALIGN_LEFT
FPB.FPB_ALIGN_WIDTH
FPB.FPB_BMP_RIGHTSPACE
FPB.FPB_COLLAPSE_TO_BOTTOM
FPB.FPB_DEFAULT_LEFTLINESPACING
FPB.FPB_DEFAULT_LEFTSPACING
FPB.FPB_DEFAULT_RIGHTLINESPACING
FPB.FPB_DEFAULT_RIGHTSPACING
FPB.FPB_DEFAULT_SPACING
FPB.FPB_EXCLUSIVE_FOLD
FPB.FPB_EXTRA_X
FPB.FPB_EXTRA_Y
FPB.FPB_HORIZONTAL
FPB.FPB_SINGLE_FOLD
FPB.FPB_VERTICAL
def test_lib_agw_foldpanelbarEvents(self):
FPB.EVT_CAPTIONBAR
FPB.wxEVT_CAPTIONBAR
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,61 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.fourwaysplitter as FWS
#---------------------------------------------------------------------------
class lib_agw_fourwaysplitter_Tests(wtc.WidgetTestCase):
def test_lib_agw_fourwaysplitterCtor(self):
splitter = FWS.FourWaySplitter(self.frame, -1, agwStyle=wx.SP_LIVE_UPDATE)
def test_lib_agw_fourwaysplitterMethods(self):
splitter = FWS.FourWaySplitter(self.frame, -1, agwStyle=wx.SP_LIVE_UPDATE)
panels = []
# Put in some coloured panels...
for colour in [wx.RED, wx.WHITE, wx.BLUE, wx.GREEN]:
panel = wx.Panel(splitter)
panel.SetBackgroundColour(colour)
splitter.AppendWindow(panel)
panels.append(panel)
# Some methods tests...
for index in range(4):
self.assertEqual(splitter.GetWindow(index), panels[index])
splitter.ExchangeWindows(panels[0], panels[3])
self.assertEqual(splitter.GetWindow(0), panels[3])
self.assertEqual(splitter.GetWindow(3), panels[0])
window = wx.Window(splitter)
splitter.ReplaceWindow(panels[3], window)
self.assertEqual(splitter.GetWindow(0), window)
splitter.SetExpanded(0)
for index in range(1, 4):
self.assertTrue(not splitter.GetWindow(index).IsShown())
def test_lib_agw_fourwaysplitterConstantsExists(self):
FWS.FLAG_CHANGED
FWS.FLAG_PRESSED
FWS.NOWHERE
FWS.SP_3DBORDER
FWS.SP_LIVE_UPDATE
FWS.SP_NOSASH
def test_lib_agw_fourwaysplitterEvents(self):
FWS.EVT_SPLITTER_SASH_POS_CHANGED
FWS.EVT_SPLITTER_SASH_POS_CHANGING
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,43 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.genericmessagedialog as GMD
#---------------------------------------------------------------------------
class lib_agw_genericmessagedialog_Tests(wtc.WidgetTestCase):
def test_lib_agw_genericmessagedialogCtor(self):
dlg = GMD.GenericMessageDialog(self.frame, 'Hello World', 'A Nice Message Box',
agwStyle=wx.ICON_INFORMATION|wx.OK)
def test_lib_agw_genericmessagedialogMethods(self):
dlg = GMD.GenericMessageDialog(self.frame, 'Hello World', 'A Nice Message Box',
agwStyle=wx.ICON_INFORMATION|wx.OK)
# Test custom and default button labels
for kind in ['OK', 'Yes', 'No', 'Help', 'Cancel']:
default = 'GetDefault%sLabel()'%kind
custom = 'GetCustom%sLabel()'%kind
self.assertEqual(eval('dlg.%s'%default), eval('dlg.%s'%custom))
self.assertTrue(not dlg.HasCustomBitmaps())
self.assertTrue(not dlg.GetExtendedMessage())
dlg.SetExtendedMessage('An extended message')
self.assertEqual(dlg.GetFullMessage(), '%s\n\n%s'%(dlg.GetMessage(), dlg.GetExtendedMessage()))
def test_lib_agw_genericmessagedialogConstantsExists(self):
GMD.BUTTON_SIZER_FLAGS
GMD.GMD_DEFAULT
GMD.GMD_USE_AQUABUTTONS
GMD.GMD_USE_GRADIENTBUTTONS
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,47 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.hyperlink as HL
#---------------------------------------------------------------------------
class lib_agw_hyperlink_Tests(wtc.WidgetTestCase):
def test_lib_agw_hyperlinkCtor(self):
link = HL.HyperLinkCtrl(self.frame, -1, 'wxPython Main Page', pos=(100, 100),
URL='http://www.wxpython.org/')
def test_lib_agw_hyperlinkMethods(self):
url = 'http://www.wxpython.org/'
link = HL.HyperLinkCtrl(self.frame, -1, 'wxPython Main Page', pos=(100, 100),
URL=url)
link.AutoBrowse(False)
link.SetColours('RED', 'GREEN', 'BLUE')
link.EnableRollover(True)
link.SetUnderlines(False, False, True)
link.SetBold(True)
link.OpenInSameWindow(True)
link.SetToolTip(wx.ToolTip('Hello World!'))
link.UpdateLink()
self.assertTrue(link.GetColours(), ('RED', 'GREEN', 'BLUE'))
self.assertTrue(not link.GetUnderlines()[0])
self.assertTrue(not link.GetVisited())
self.assertEqual(link.GetURL(), url)
def test_lib_agw_hyperlinkEvents(self):
HL.EVT_HYPERLINK_LEFT
HL.EVT_HYPERLINK_MIDDLE
HL.EVT_HYPERLINK_RIGHT
HL.wxEVT_HYPERLINK_LEFT
HL.wxEVT_HYPERLINK_MIDDLE
HL.wxEVT_HYPERLINK_RIGHT
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,84 @@
import imp_unittest, unittest
import wtc
import wx
import wx.lib.agw.hypertreelist as HTL
import wx.lib.agw.customtreectrl as CT
#---------------------------------------------------------------------------
class lib_agw_hypertreelist_Tests(wtc.WidgetTestCase):
def test_lib_agw_hypertreelistCtor(self):
tree = HTL.HyperTreeList(self.frame)
self.assertEqual(tree.GetAGWWindowStyleFlag(), CT.TR_DEFAULT_STYLE)
self.assertEqual(tree.GetRootItem(), None)
def test_lib_agw_hypertreelistTreeItem(self):
tree = HTL.HyperTreeList(self.frame)
tree.AddColumn("First column")
root = tree.AddRoot('root item')
self.assertTrue(isinstance(root, CT.GenericTreeItem))
self.assertTrue(root.IsOk())
r = tree.GetRootItem()
self.assertTrue(r is root)
self.assertTrue(r == root)
child = tree.AppendItem(root, 'child item')
self.assertTrue(child is not root)
self.assertTrue(child != root)
def test_lib_agw_hypertreelistColumns(self):
tree = HTL.HyperTreeList(self.frame)
tree.AddColumn("First column")
tree.AddColumn("Second column")
self.assertEqual(tree.GetColumnCount(), 2)
tree.RemoveColumn(0)
self.assertEqual(tree.GetColumnCount(), 1)
self.assertEqual(tree.GetColumnWidth(0), HTL._DEFAULT_COL_WIDTH)
tree.AddColumn("Second column")
tree.SetColumnShown(1, False)
self.assertTrue(not tree.IsColumnShown(1))
tree.SetColumnEditable(0, True)
self.assertTrue(tree.IsColumnEditable(0))
def test_lib_agw_hypertreelistConstantsExists(self):
HTL.TR_ALIGN_WINDOWS
HTL.TR_AUTO_CHECK_CHILD
HTL.TR_AUTO_CHECK_PARENT
HTL.TR_AUTO_TOGGLE_CHILD
HTL.TR_COLUMN_LINES
HTL.TR_EDIT_LABELS
HTL.TR_ELLIPSIZE_LONG_ITEMS
HTL.TR_EXTENDED
HTL.TR_FULL_ROW_HIGHLIGHT
HTL.TR_HAS_BUTTONS
HTL.TR_HAS_VARIABLE_ROW_HEIGHT
HTL.TR_HIDE_ROOT
HTL.TR_LINES_AT_ROOT
HTL.TR_MULTIPLE
HTL.TR_NO_BUTTONS
HTL.TR_NO_HEADER
HTL.TR_NO_LINES
HTL.TR_ROW_LINES
HTL.TR_SINGLE
HTL.TR_TWIST_BUTTONS
HTL.TR_VIRTUAL
HTL.TREE_HITTEST_ONITEMCHECKICON
def test_lib_agw_hypertreelistEvents(self):
HTL.EVT_TREE_ITEM_CHECKED
HTL.EVT_TREE_ITEM_CHECKING
HTL.EVT_TREE_ITEM_HYPERLINK
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,58 @@
import imp_unittest, unittest
import wtc
import wx
import os
import wx.lib.buttons as buttons
pngFile = os.path.join(os.path.dirname(__file__), 'toucan.png')
#---------------------------------------------------------------------------
class lib_buttons_Tests(wtc.WidgetTestCase):
def test_lib_buttons1(self):
btn = buttons.GenButton(self.frame, label='label')
btn = buttons.GenButton(self.frame, -1, 'label', (10,10), (100,-1), wx.BU_LEFT)
bmp = wx.Bitmap(pngFile)
btn = buttons.GenBitmapButton(self.frame, bitmap=bmp)
btn = buttons.GenBitmapTextButton(self.frame, label='label', bitmap=bmp)
btn.SetBitmapFocus(bmp)
btn.SetBitmapDisabled(bmp)
btn.SetBitmapSelected(bmp)
btn = buttons.GenBitmapToggleButton(self.frame, bitmap=bmp)
btn.SetToggle(True)
self.assertTrue(btn.GetValue())
self.assertEqual(btn.GetBitmapLabel(), bmp)
def test_lib_buttons2(self):
btn = buttons.ThemedGenButton(self.frame, label='label')
btn = buttons.ThemedGenButton(self.frame, -1, 'label', (10,10), (100,-1), wx.BU_LEFT)
bmp = wx.Bitmap(pngFile)
btn = buttons.ThemedGenBitmapButton(self.frame, bitmap=bmp)
btn = buttons.ThemedGenBitmapTextButton(self.frame, label='label', bitmap=bmp)
btn.SetBitmapFocus(bmp)
btn.SetBitmapDisabled(bmp)
btn.SetBitmapSelected(bmp)
btn = buttons.ThemedGenBitmapToggleButton(self.frame, bitmap=bmp)
btn.SetToggle(True)
self.assertTrue(btn.GetValue())
self.assertEqual(btn.GetBitmapLabel(), bmp)
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

View File

@@ -118,11 +118,11 @@ You can contact me at:
andrea.gavana@gmail.com
andrea.gavana@maerskoil.com
AGW version: 0.9.6
AGW version: 0.9.7
Last updated: 04 July 2012, 18.00 GMT
Last updated: 16 July 2012, 18.00 GMT
"""
__version__ = "0.9.6"
__version__ = "0.9.7"
__author__ = "Andrea Gavana <andrea.gavana@gmail.com>"

View File

@@ -3,7 +3,7 @@
# Python Code By:
#
# Andrea Gavana, @ 10 Oct 2005
# Latest Revision: 17 Aug 2011, 15.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List/Caveats
@@ -29,6 +29,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -122,9 +123,9 @@ License And Version
:class:`AdvancedSplash` control is distributed under the wxPython license.
Latest revision: Andrea Gavana @ 17 Aug 2011, 15.00 GMT
Latest revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.4
Version 0.5
"""
@@ -252,7 +253,7 @@ class AdvancedSplash(wx.Frame):
self.SetTextColour()
# Calculate The Shape Of AdvancedSplash Using The Input-Modified Bitmap
self.reg = wx.RegionFromBitmap(self.bmp)
self.reg = wx.Region(self.bmp)
# Don't Know If It Works On Other Platforms!!
# Tested Only In Windows XP/2000
@@ -275,7 +276,8 @@ class AdvancedSplash(wx.Frame):
if agwStyle & AS_TIMEOUT:
# Starts The Timer. Once Expired, AdvancedSplash Is Destroyed
self._splashtimer = wx.PyTimer(self.OnNotify)
self._splashtimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnNotify)
self._splashtimer.Start(timeout)
# Catch Some Mouse Events, To Behave Like wx.SplashScreen
@@ -346,8 +348,12 @@ class AdvancedSplash(wx.Frame):
wx.SafeYield(self, True)
def OnNotify(self):
""" Handles the timer expiration, and calls the `Close()` method. """
def OnNotify(self, event):
"""
Handles the timer expiration, and calls the `Close()` method.
:param `event`: a :class:`wx.TimerEvent` to be processed.
"""
self.Close()
@@ -546,3 +552,14 @@ class AdvancedSplash(wx.Frame):
return stringstyle, integerstyle
if __name__ == '__main__':
import wx
app = wx.App(0)
bitmap = wx.Bitmap(100, 100)
splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000)
app.MainLoop()

View File

@@ -3,7 +3,7 @@
# Python Code By:
#
# Andrea Gavana, @ 29 May 2005
# Latest Revision: 17 Aug 2011, 15.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List/Caveats
@@ -35,6 +35,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -89,7 +90,7 @@ Usage example::
def __init__(self, parent):
wx.Frame.__init(self, parent, -1, "BalloonTip Demo")
wx.Frame.__init__(self, parent, -1, "BalloonTip Demo")
panel = wx.Panel(self)
@@ -107,7 +108,7 @@ Usage example::
# Set the BalloonTip background colour
tipballoon.SetBalloonColour(wx.WHITE)
# Set the font for the balloon title
tipballoon.SetTitleFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False))
tipballoon.SetTitleFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False))
# Set the colour for the balloon title
tipballoon.SetTitleColour(wx.BLACK)
# Leave the message font as default
@@ -157,15 +158,17 @@ License And Version
BalloonTip is distributed under the wxPython license.
Latest revision: Andrea Gavana @ 17 Aug 2011, 15.00 GMT
Latest revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.2
Version 0.3
"""
import wx
import time
import wx.adv
from wx.lib.buttons import GenButton
# Define The Values For The BalloonTip Frame Shape
@@ -250,7 +253,7 @@ class BalloonFrame(wx.Frame):
if self._toptitle != "":
stt = wx.StaticText(panel, -1, self._toptitle)
stt.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False))
stt.SetFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False))
if self._topicon is None:
hsizer.Add((10,0), 0, wx.EXPAND)
@@ -263,7 +266,7 @@ class BalloonFrame(wx.Frame):
if self._tipstyle == BT_BUTTON:
self._closebutton = GenButton(panel, -1, "X", style=wx.NO_BORDER)
self._closebutton.SetMinSize((16,16))
self._closebutton.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False))
self._closebutton.SetFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False))
self._closebutton.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterButton)
self._closebutton.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveButton)
self._closebutton.SetUseFocusIndicator(False)
@@ -339,7 +342,7 @@ class BalloonFrame(wx.Frame):
size = self.GetSize()
pos = self.GetPosition()
dc = wx.MemoryDC(wx.EmptyBitmap(1,1))
dc = wx.MemoryDC(wx.Bitmap(1,1))
textlabel = self._balloonmsg.GetLabel()
textfont = self._balloonmsg.GetFont()
textextent = dc.GetFullTextExtent(textlabel, textfont)
@@ -380,12 +383,11 @@ class BalloonFrame(wx.Frame):
xpos = position[0]
ypos = position[1] - boxheight + 20
bmp = wx.EmptyBitmap(size.x,size.y)
bmp = wx.Bitmap(size.x,size.y)
dc = wx.BufferedDC(None, bmp)
dc.BeginDrawing()
dc.SetBackground(wx.Brush(wx.Colour(0,0,0), wx.SOLID))
dc.SetBackground(wx.Brush(wx.Colour(0,0,0)))
dc.Clear()
dc.SetPen(wx.Pen(wx.Colour(0,0,0), 1, wx.TRANSPARENT))
dc.SetPen(wx.Pen(wx.Colour(0,0,0), 1, wx.PENSTYLE_TRANSPARENT))
if self._shape == BT_ROUNDED:
dc.DrawRoundedRectangle(0, 20, boxwidth, boxheight-20, 12)
@@ -405,9 +407,7 @@ class BalloonFrame(wx.Frame):
else:
dc.DrawPolygon(((20, boxheight), (20, boxheight+20), (40, boxheight)))
dc.EndDrawing()
r = wx.RegionFromBitmapColour(bmp, wx.Colour(0,0,0))
r = wx.Region(bmp, wx.Colour(0, 0, 0))
self.hasShape = self.SetShape(r)
if self._tipstyle == BT_BUTTON:
@@ -472,7 +472,7 @@ class BalloonFrame(wx.Frame):
:param `event`: a :class:`CloseEvent` event to be processed.
"""
if isinstance(self._parent._widget, wx.TaskBarIcon):
if isinstance(self._parent._widget, wx.adv.TaskBarIcon):
self._parent.taskbarcreation = 0
self._parent.taskbartime.Stop()
del self._parent.taskbartime
@@ -577,8 +577,8 @@ class BalloonTip(object):
self._widget = widget
if isinstance(widget, wx.TaskBarIcon):
self._widget.Bind(wx.EVT_TASKBAR_MOVE, self.OnTaskBarMove)
if isinstance(widget, wx.adv.TaskBarIcon):
self._widget.Bind(wx.adv.EVT_TASKBAR_MOVE, self.OnTaskBarMove)
self._widget.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
self.taskbarcreation = 0
else:
@@ -668,7 +668,8 @@ class BalloonTip(object):
if not self._runningapp.__tooltipenabled__:
return
self.showtime = wx.PyTimer(self.NotifyTimer)
self.showtime = wx.Timer(self._widget)
self._widget.Bind(wx.EVT_TIMER, self.NotifyTimer, self.showtime)
self.showtime.Start(self._startdelaytime)
event.Skip()
@@ -716,9 +717,11 @@ class BalloonTip(object):
if self.taskbarcreation == 0:
self.mousepos = wx.GetMousePosition()
self.currentmousepos = self.mousepos
self.taskbartime = wx.PyTimer(self.TaskBarTimer)
self.taskbartime = wx.Timer(self._widget)
self._widget.Bind(wx.EVT_TIMER, self.TaskBarTimer, self.taskbartime)
self.taskbartime.Start(100)
self.showtime = wx.PyTimer(self.NotifyTimer)
self.showtime = wx.Timer(self._widget)
self._widget.Bind(wx.EVT_TIMER, self.NotifyTimer, self.showtime)
self.showtime.Start(self._startdelaytime)
if self.taskbarcreation == 0:
@@ -751,27 +754,35 @@ class BalloonTip(object):
event.Skip()
def NotifyTimer(self):
""" The creation timer has expired. Creates the :class:`BalloonTip` frame."""
def NotifyTimer(self, event):
"""
The creation timer has expired. Creates the :class:`BalloonTip` frame.
:param `event`: a :class:`wx.TimerEvent` to be processed.
"""
self.BalloonFrame = BalloonFrame(self._widget, classparent=self)
self.BalloonFrame.Show(True)
self.starttime = time.time()
if hasattr(self, "showtime"):
self.showtime.Stop()
del self.showtime
self.destroytime = wx.PyTimer(self.DestroyTimer)
self.destroytime = wx.Timer(self._widget)
self._widget.Bind(wx.EVT_TIMER, self.NotifyTimer, self.destroytime)
self.destroytime.Start(self._enddelaytime)
def TaskBarTimer(self):
def TaskBarTimer(self, event):
"""
This timer check periodically the mouse position.
If the current mouse position is sufficiently far from the coordinates
it had when entered the taskbar icon and the :class:`BalloonTip` style is
``BT_LEAVE``, the :class:`BalloonTip` frame is destroyed.
:param `event`: a :class:`wx.TimerEvent` to be processed.
"""
self.currentmousepos = wx.GetMousePosition()
@@ -791,8 +802,12 @@ class BalloonTip(object):
pass
def DestroyTimer(self):
""" The destruction timer has expired. Destroys the :class:`BalloonTip` frame."""
def DestroyTimer(self, event):
"""
The destruction timer has expired. Destroys the :class:`BalloonTip` frame.
:param `event`: a :class:`wx.TimerEvent` to be processed.
"""
self.destroytime.Stop()
del self.destroytime
@@ -838,7 +853,7 @@ class BalloonTip(object):
:raise: `Exception` if the `icon` bitmap is not a valid :class:`Bitmap`.
"""
if icon.Ok():
if icon.IsOk():
self._topicon = icon
else:
raise Exception("\nERROR: Invalid Image Passed To BalloonTip")
@@ -969,7 +984,7 @@ class BalloonTip(object):
"""
if font is None:
font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False)
font = wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False)
self._balloontitlefont = font
@@ -992,7 +1007,7 @@ class BalloonTip(object):
"""
if font is None:
font = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
font = wx.Font(8, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)
self._balloonmsgfont = font
@@ -1064,8 +1079,8 @@ class BalloonTip(object):
if hasattr(self, "BalloonFrame"):
if self.BalloonFrame:
try:
if isinstance(self._widget, wx.TaskBarIcon):
self._widget.Unbind(wx.EVT_TASKBAR_MOVE)
if isinstance(self._widget, wx.adv.TaskBarIcon):
self._widget.Unbind(wx.adv.EVT_TASKBAR_MOVE)
self.taskbartime.Stop()
del self.taskbartime
else:
@@ -1090,3 +1105,54 @@ class BalloonTip(object):
self._runningapp.__tooltipenabled__ = enable
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "BalloonTip Demo")
panel = wx.Panel(self)
# Let's suppose that in your application you have a wx.TextCtrl defined as:
mytextctrl = wx.TextCtrl(panel, -1, "I am a textctrl", pos=(100, 100))
# You can define your BalloonTip as follows:
tipballoon = BalloonTip(topicon=None, toptitle="textctrl",
message="this is a textctrl",
shape=BT_ROUNDED,
tipstyle=BT_LEAVE)
# Set the BalloonTip target
tipballoon.SetTarget(mytextctrl)
# Set the BalloonTip background colour
tipballoon.SetBalloonColour(wx.WHITE)
# Set the font for the balloon title
tipballoon.SetTitleFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False))
# Set the colour for the balloon title
tipballoon.SetTitleColour(wx.BLACK)
# Leave the message font as default
tipballoon.SetMessageFont()
# Set the message (tip) foreground colour
tipballoon.SetMessageColour(wx.LIGHT_GREY)
# Set the start delay for the BalloonTip
tipballoon.SetStartDelay(1000)
# Set the time after which the BalloonTip is destroyed
tipballoon.SetEndDelay(3000)
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -11,7 +11,7 @@
# Python Code By:
#
# Andrea Gavana, @ 02 Oct 2006
# Latest Revision: 17 Aug 2011, 15.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
@@ -22,6 +22,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -134,7 +135,7 @@ Usage example::
obj = event.GetEventObject()
# This will print the button label
print obj.GetText()
print(obj.GetText())
# our normal wxApp-derived class, as usual
@@ -179,9 +180,9 @@ License And Version
:class:`ButtonPanel` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 17 Aug 2011, 15.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.6.
Version 0.7.
"""
@@ -295,7 +296,7 @@ def BrightenColour(colour, factor):
else:
blue = val
return wx.Colour(red, green, blue)
return wx.Colour(int(red), int(green), int(blue))
# ----------------------------------------------------------------------------
@@ -310,7 +311,7 @@ def MakeDisabledBitmap(original):
"""
img = original.ConvertToImage()
return wx.BitmapFromImage(img.ConvertToGreyscale())
return wx.Bitmap(img.ConvertToGreyscale())
# ---------------------------------------------------------------------------- #
@@ -333,11 +334,11 @@ class BPArt(object):
:param integer `parentStyle`: the window style for :class:`ButtonPanel`.
"""
base_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)
base_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)
self._background_brush = wx.Brush(base_colour, wx.SOLID)
self._background_brush = wx.Brush(base_colour, wx.BRUSHSTYLE_SOLID)
self._gradient_colour_to = wx.WHITE
self._gradient_colour_from = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVECAPTION)
self._gradient_colour_from = wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION)
if parentStyle & BP_USE_GRADIENT:
self._border_pen = wx.Pen(wx.WHITE, 3)
@@ -348,18 +349,18 @@ class BPArt(object):
else:
self._border_pen = wx.Pen(BrightenColour(base_colour, 0.9), 3)
self._caption_text_colour = wx.BLACK
self._buttontext_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNTEXT)
self._buttontext_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT)
self._separator_pen = wx.Pen(BrightenColour(base_colour, 0.9))
self._gradient_type = BP_GRADIENT_NONE
self._buttontext_inactive_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT)
self._buttontext_inactive_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
self._selection_brush = wx.Brush(wx.Colour(225, 225, 255))
self._selection_pen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVECAPTION))
self._selection_pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION))
sysfont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
self._caption_font = wx.Font(sysfont.GetPointSize(), wx.DEFAULT, wx.NORMAL, wx.BOLD,
self._caption_font = wx.Font(sysfont.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD,
False, sysfont.GetFaceName())
self._buttontext_font = wx.Font(sysfont.GetPointSize(), wx.DEFAULT, wx.NORMAL, wx.NORMAL,
self._buttontext_font = wx.Font(sysfont.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD,
False, sysfont.GetFaceName())
self._separator_size = 7
@@ -606,12 +607,12 @@ class BPArt(object):
dc.SetPen(self._separator_pen)
if isVertical:
ystart = yend = rect.y + rect.height/2
ystart = yend = rect.y + rect.height//2
xstart = int(rect.x + 1.5*self._caption_border_size)
xend = int(rect.x + rect.width - 1.5*self._caption_border_size)
dc.DrawLine(xstart, ystart, xend, yend)
else:
xstart = xend = rect.x + rect.width/2
xstart = xend = rect.x + rect.width//2
ystart = int(rect.y + 1.5*self._caption_border_size)
yend = int(rect.y + rect.height - 1.5*self._caption_border_size)
dc.DrawLine(xstart, ystart, xend, yend)
@@ -670,19 +671,19 @@ class BPArt(object):
textW, textH = dc.GetTextExtent(text)
if textAlignment == BP_BUTTONTEXT_ALIGN_RIGHT:
fullExtent = bmpxsize + padding.x/2 + textW
bmpypos = rect.y + (rect.height - bmpysize)/2
bmpxpos = rect.x + (rect.width - fullExtent)/2
textxpos = bmpxpos + padding.x/2 + bmpxsize
textypos = bmpypos + (bmpysize - textH)/2
fullExtent = bmpxsize + padding.x//2 + textW
bmpypos = rect.y + (rect.height - bmpysize)//2
bmpxpos = rect.x + (rect.width - fullExtent)//2
textxpos = bmpxpos + padding.x//2 + bmpxsize
textypos = bmpypos + (bmpysize - textH)//2
else:
bmpxpos = rect.x + (rect.width - bmpxsize)/2
bmpxpos = rect.x + (rect.width - bmpxsize)//2
bmpypos = rect.y + padding.y
textxpos = rect.x + (rect.width - textW)/2
textypos = bmpypos + bmpysize + padding.y/2
textxpos = rect.x + (rect.width - textW)//2
textypos = bmpypos + bmpysize + padding.y//2
else:
bmpxpos = rect.x + (rect.width - bmpxsize)/2
bmpypos = rect.y + (rect.height - bmpysize)/2
bmpxpos = rect.x + (rect.width - bmpxsize)//2
bmpypos = rect.y + (rect.height - bmpysize)//2
else:
@@ -694,20 +695,20 @@ class BPArt(object):
textW, textH = dc.GetTextExtent(text)
if textAlignment == BP_BUTTONTEXT_ALIGN_RIGHT:
fullExtent = bmpxsize + padding.x/2 + textW
bmpypos = rect.y + (rect.height - bmpysize)/2
bmpxpos = rect.x + (rect.width - fullExtent)/2
textxpos = bmpxpos + padding.x/2 + bmpxsize
textypos = bmpypos + (bmpysize - textH)/2
fullExtent = bmpxsize + padding.x//2 + textW
bmpypos = rect.y + (rect.height - bmpysize)//2
bmpxpos = rect.x + (rect.width - fullExtent)//2
textxpos = bmpxpos + padding.x//2 + bmpxsize
textypos = bmpypos + (bmpysize - textH)//2
else:
fullExtent = bmpysize + padding.y/2 + textH
bmpxpos = rect.x + (rect.width - bmpxsize)/2
bmpypos = rect.y + (rect.height - fullExtent)/2
textxpos = rect.x + (rect.width - textW)/2
textypos = bmpypos + bmpysize + padding.y/2
fullExtent = bmpysize + padding.y//2 + textH
bmpxpos = rect.x + (rect.width - bmpxsize)//2
bmpypos = rect.y + (rect.height - fullExtent)//2
textxpos = rect.x + (rect.width - textW)//2
textypos = bmpypos + bmpysize + padding.y//2
else:
bmpxpos = rect.x + (rect.width - bmpxsize)/2
bmpypos = rect.y + (rect.height - bmpysize)/2
bmpxpos = rect.x + (rect.width - bmpxsize)//2
bmpypos = rect.y + (rect.height - bmpysize)//2
# Draw a button
# [ Padding | Text | .. Buttons .. | Padding ]
@@ -715,7 +716,7 @@ class BPArt(object):
if buttonStatus in ["Pressed", "Toggled", "Hover"]:
dc.SetBrush(self._selection_brush)
dc.SetPen(self._selection_pen)
dc.DrawRoundedRectangleRect(rect, 4)
dc.DrawRoundedRectangle(rect, 4)
if buttonStatus == "Pressed" or isToggled:
dx = dy = 1
@@ -766,7 +767,7 @@ class BPArt(object):
dc.SetBrush(backBrush)
dc.SetPen(self._border_pen)
dc.DrawRectangleRect(rect)
dc.DrawRectangle(rect)
def FillGradientColour(self, dc, rect):
@@ -794,7 +795,7 @@ class BPArt(object):
gstep = float((col2.Green() - col1.Green()))/float(size)
bstep = float((col2.Blue() - col1.Blue()))/float(size)
for coord in xrange(start, start + size):
for coord in range(start, start + size):
currCol = wx.Colour(col1.Red() + rf, col1.Green() + gf, col1.Blue() + bf)
dc.SetBrush(wx.Brush(currCol, wx.SOLID))
@@ -928,7 +929,7 @@ class Control(wx.EvtHandler):
return self.Enable(False)
def Enable(self, value=True):
def Enable(self, enable=True):
"""
Enable or disable the window for user input.
@@ -941,7 +942,7 @@ class Control(wx.EvtHandler):
well and they are reenabled again when the parent is.
"""
self.disabled = not value
self.disabled = not enable
return True
@@ -1784,7 +1785,7 @@ class ButtonInfo(Control):
# -- ButtonPanel class implementation ----------------------------------
# This is the main class.
class ButtonPanel(wx.PyPanel):
class ButtonPanel(wx.Panel):
"""
A custom panel class with gradient background shading with the possibility to
add buttons and controls still respecting the gradient background.
@@ -1803,7 +1804,7 @@ class ButtonPanel(wx.PyPanel):
:param string `name`: window class name.
"""
wx.PyPanel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,
wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,
wx.NO_BORDER, name=name)
self._vButtons = []
@@ -2331,7 +2332,7 @@ class ButtonPanel(wx.PyPanel):
break
# Leave out the last spacer, it has to be there always
for ii in xrange(len(nonspacers)-1):
for ii in range(len(nonspacers)-1):
indx = children.index(nonspacers[ii])
self._mainsizer.Show(indx, ii < indx1)
@@ -2395,7 +2396,7 @@ class ButtonPanel(wx.PyPanel):
nonspacers.reverse()
for jj in xrange(2, lennonspacers):
for jj in range(2, lennonspacers):
indx = allchildren.index(nonspacers[jj])
self._mainsizer.Show(indx, jj >= count)
@@ -2611,7 +2612,7 @@ class ButtonPanel(wx.PyPanel):
shortHelp = hit.GetShortHelp()
if shortHelp:
self.SetToolTipString(shortHelp)
self.SetToolTip(shortHelp)
self._haveTip = True
longHelp = hit.GetLongHelp()
@@ -2639,7 +2640,7 @@ class ButtonPanel(wx.PyPanel):
return
if self._haveTip:
self.SetToolTipString("")
self.SetToolTip("")
self._haveTip = False
if self._statusTimer and self._statusTimer.IsRunning():
@@ -2707,7 +2708,7 @@ class ButtonPanel(wx.PyPanel):
client rectangle contains the input point `pt`, or ``wx.NOT_FOUND`` and ``BP_HT_NONE``.
"""
for ii in xrange(len(self._vButtons)):
for ii in range(len(self._vButtons)):
if not self._vButtons[ii].IsEnabled():
continue
if self._vButtons[ii].GetRect().Contains(pt):
@@ -2744,7 +2745,7 @@ class ButtonPanel(wx.PyPanel):
"""
self._freezeCount = self._freezeCount + 1
wx.PyPanel.Freeze(self)
wx.Panel.Freeze(self)
def Thaw(self):
@@ -2757,7 +2758,7 @@ class ButtonPanel(wx.PyPanel):
raise Exception("\nERROR: Thawing Unfrozen ButtonPanel?")
self._freezeCount = self._freezeCount - 1
wx.PyPanel.Thaw(self)
wx.Panel.Thaw(self)
def IsFrozen(self):
@@ -2765,3 +2766,69 @@ class ButtonPanel(wx.PyPanel):
return self._freezeCount != 0
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id=-1, title='ButtonPanel', pos=wx.DefaultPosition,
size=(800, 600), style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
mainPanel = wx.Panel(self, -1)
self.logtext = wx.TextCtrl(mainPanel, -1, '', style=wx.TE_MULTILINE)
vSizer = wx.BoxSizer(wx.VERTICAL)
mainPanel.SetSizer(vSizer)
titleBar = ButtonPanel(mainPanel, -1, 'A Simple Test & Demo')
btn1 = ButtonInfo(titleBar, wx.NewId(),
wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (32, 32)),
text='Button 1')
titleBar.AddButton(btn1)
self.Bind(wx.EVT_BUTTON, self.OnButton, btn1)
btn2 = ButtonInfo(titleBar, wx.NewId(),
wx.ArtProvider.GetBitmap(wx.ART_TIP, wx.ART_OTHER, (32, 32)),
text='Button 2')
titleBar.AddButton(btn2)
self.Bind(wx.EVT_BUTTON, self.OnButton, btn2)
btn3 = ButtonInfo(titleBar, wx.NewId(),
wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_OTHER, (32, 32)),
text='Button 3')
titleBar.AddButton(btn3)
self.Bind(wx.EVT_BUTTON, self.OnButton, btn3)
vSizer.Add(titleBar, 0, wx.EXPAND)
vSizer.Add((20, 20))
vSizer.Add(self.logtext, 1, wx.EXPAND|wx.ALL, 5)
titleBar.DoLayout()
vSizer.Layout()
def OnButton(self, event):
''' Handler for the ``wx.EVT_BUTTON`` event. '''
obj = event.GetEventObject()
# This will print the button label
print(obj.GetText())
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -4,7 +4,7 @@
# Python Code By:
#
# Andrea Gavana, @ 16 Aug 2007
# Latest Revision: 26 Feb 2012, 15.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List
@@ -23,6 +23,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -124,14 +125,12 @@ License And Version
:class:`CubeColourDialog` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 26 Feb 2012, 15.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.4.
Version 0.5.
"""
__docformat__ = "epytext"
#----------------------------------------------------------------------
# Beginning Of CUBECOLOURDIALOG wxPython Code
@@ -1456,10 +1455,10 @@ def DrawCheckerBoard(dc, rect, checkColour, box=5):
dc.SetPen(checkPen)
dc.SetBrush(checkBrush)
dc.SetClippingRect(rect)
dc.SetClippingRegion(rect)
while y < rect.height:
x = box*((y/box)%2) + 2
x = box*((y//box)%2) + 2
while x < rect.width:
dc.DrawRectangle(x, y, box, box)
x += box*2
@@ -1620,7 +1619,7 @@ class LineDescription(object):
self.c = c
class BasePyControl(wx.PyControl):
class BasePyControl(wx.Control):
"""
Base class used to hold common code for the HSB colour wheel and the RGB
colour cube.
@@ -1635,7 +1634,7 @@ class BasePyControl(wx.PyControl):
:param `bitmap`: the background bitmap for this custom control.
"""
wx.PyControl.__init__(self, parent, style=wx.NO_BORDER)
wx.Control.__init__(self, parent, style=wx.NO_BORDER)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self._bitmap = bitmap
@@ -1807,6 +1806,7 @@ class RGBCube(BasePyControl):
BasePyControl.__init__(self, parent, bitmap=RGBCubeImage.GetBitmap())
self._index = -1
self._mouseIn = False
def DrawMarkers(self, dc=None):
@@ -1830,15 +1830,15 @@ class RGBCube(BasePyControl):
redLen = self._mainDialog._redLen
colour = self._mainDialog._colour
pt = [wx.Point() for i in xrange(3)]
pt[0] = PointOnLine(Vertex, Top, (colour.r*redLen)/255, redLen)
pt[1] = PointOnLine(Vertex, Left, (colour.g*greenLen)/255, greenLen)
pt[2] = PointOnLine(Vertex, Right, (colour.b*blueLen)/255, blueLen)
pt = [wx.Point() for i in range(3)]
pt[0] = PointOnLine(Vertex, Top, (colour.r*redLen)/255.0, redLen)
pt[1] = PointOnLine(Vertex, Left, (colour.g*greenLen)/255.0, greenLen)
pt[2] = PointOnLine(Vertex, Right, (colour.b*blueLen)/255.0, blueLen)
for i in xrange(3):
for i in range(3):
rect = wx.Rect(pt[i].x - RECT_WIDTH, pt[i].y - RECT_WIDTH, 2*RECT_WIDTH, 2*RECT_WIDTH)
rects.append(rect)
dc.DrawRectangleRect(rect)
dc.DrawRectangle(rect)
self.DrawLines(dc)
RestoreOldDC(dc, oldPen, oldBrush, oldMode)
@@ -1855,17 +1855,17 @@ class RGBCube(BasePyControl):
cuboid = self._mainDialog._cuboid
dc.DrawLinePoint(cuboid[1], cuboid[2])
dc.DrawLinePoint(cuboid[2], cuboid[3])
dc.DrawLinePoint(cuboid[3], cuboid[4])
dc.DrawLinePoint(cuboid[4], cuboid[5])
dc.DrawLinePoint(cuboid[5], cuboid[2])
dc.DrawLine(cuboid[1], cuboid[2])
dc.DrawLine(cuboid[2], cuboid[3])
dc.DrawLine(cuboid[3], cuboid[4])
dc.DrawLine(cuboid[4], cuboid[5])
dc.DrawLine(cuboid[5], cuboid[2])
dc.DrawLinePoint(cuboid[5], cuboid[6])
dc.DrawLinePoint(cuboid[6], cuboid[7])
dc.DrawLinePoint(cuboid[7], cuboid[4])
dc.DrawLine(cuboid[5], cuboid[6])
dc.DrawLine(cuboid[6], cuboid[7])
dc.DrawLine(cuboid[7], cuboid[4])
dc.DrawLinePoint(cuboid[1], cuboid[6])
dc.DrawLine(cuboid[1], cuboid[6])
def OnLeftDown(self, event):
@@ -1937,10 +1937,10 @@ class RGBCube(BasePyControl):
if val > redLen:
val = redLen
val = (float(val)/redLen)*255
val = (float(val)/redLen)*255.0
colour.r = int(val)
pt = PointOnLine(Vertex, Top, (colour.r*redLen)/255, redLen)
pt = PointOnLine(Vertex, Top, (colour.r*redLen)/255.0, redLen)
self._rects[RED] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
2*RECT_WIDTH, 2*RECT_WIDTH)
@@ -1956,10 +1956,10 @@ class RGBCube(BasePyControl):
if val > greenLen:
val = greenLen
val = (float(val)/greenLen)*255
val = (float(val)/greenLen)*255.0
colour.g = int(val)
pt = PointOnLine(Vertex, Left, (colour.g*greenLen)/255, greenLen)
pt = PointOnLine(Vertex, Left, (colour.g*greenLen)/255.0, greenLen)
self._rects[GREEN] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
2*RECT_WIDTH, 2*RECT_WIDTH)
@@ -1975,10 +1975,10 @@ class RGBCube(BasePyControl):
if val > blueLen:
val = blueLen
val = (float(val)/blueLen)*255
val = (float(val)/blueLen)*255.0
colour.b = int(val)
pt = PointOnLine(Vertex, Right, (colour.b*blueLen)/255, blueLen)
pt = PointOnLine(Vertex, Right, (colour.b*blueLen)/255.0, blueLen)
self._rects[BLUE] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
2*RECT_WIDTH, 2*RECT_WIDTH)
@@ -2031,7 +2031,7 @@ class HSVWheel(BasePyControl):
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
dc.DrawRectangleRect(self._mainDialog._currentRect)
dc.DrawRectangle(self._mainDialog._currentRect)
RestoreOldDC(dc, oldPen, oldBrush, oldMode)
@@ -2122,7 +2122,7 @@ class HSVWheel(BasePyControl):
mainDialog.DrawAlpha()
class BaseLineCtrl(wx.PyControl):
class BaseLineCtrl(wx.Control):
"""
Base class used to hold common code for the Alpha channel control and the
brightness palette control.
@@ -2136,7 +2136,7 @@ class BaseLineCtrl(wx.PyControl):
:param `parent`: the control parent window.
"""
wx.PyControl.__init__(self, parent, size=(20, 200), style=wx.NO_BORDER)
wx.Control.__init__(self, parent, size=(20, 200), style=wx.NO_BORDER)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self._mainDialog = wx.GetTopLevelParent(self)
@@ -2313,7 +2313,7 @@ class BrightCtrl(BaseLineCtrl):
dc.SetPen(wx.BLACK_PEN)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawRectangleRect(brightRect)
dc.DrawRectangle(brightRect)
self.DrawMarkers(dc)
@@ -2327,12 +2327,12 @@ class BrightCtrl(BaseLineCtrl):
brightRect = self.BuildRect()
d = brightRect.GetBottom() - pt.y
d *= 255
d *= 255.0
d /= brightRect.height
if d < 0:
d = 0
if d > 255:
d = 255;
d = 255
mainDialog = self._mainDialog
colour = mainDialog._colour
@@ -2371,7 +2371,7 @@ class BrightCtrl(BaseLineCtrl):
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
dc.DrawRectangleRect(brightMark)
dc.DrawRectangle(brightMark)
RestoreOldDC(dc, oldPen, oldBrush, oldMode)
@@ -2405,7 +2405,7 @@ class AlphaCtrl(BaseLineCtrl):
mem_dc = wx.MemoryDC()
fullRect = self.GetClientRect()
bmp = wx.EmptyBitmap(fullRect.width, fullRect.height)
bmp = wx.Bitmap(fullRect.width, fullRect.height)
mem_dc.SelectObject(bmp)
rect = self.BuildRect()
@@ -2414,7 +2414,7 @@ class AlphaCtrl(BaseLineCtrl):
mem_dc.Clear()
mem_dc.SetBrush(wx.WHITE_BRUSH)
mem_dc.DrawRectangleRect(rect)
mem_dc.DrawRectangle(rect)
DrawCheckerBoard(mem_dc, rect, checkColour)
self.DrawAlphaShading(mem_dc, rect)
@@ -2424,7 +2424,7 @@ class AlphaCtrl(BaseLineCtrl):
mem_dc.SetBrush(wx.TRANSPARENT_BRUSH)
mem_dc.SetPen(wx.BLACK_PEN)
mem_dc.DrawRectangleRect(rect)
mem_dc.DrawRectangle(rect)
mem_dc.SelectObject(wx.NullBitmap)
pdc.DrawBitmap(bmp, 0, 0)
@@ -2442,7 +2442,7 @@ class AlphaCtrl(BaseLineCtrl):
colour = self._mainDialog._colour.GetPyColour()
alpha = 255.0
alpha = 255
vstep = 255.0*2/(rect.height-1)
r, g, b = colour.Red(), colour.Green(), colour.Blue()
@@ -2465,7 +2465,7 @@ class AlphaCtrl(BaseLineCtrl):
alphaRect = self.BuildRect()
d = alphaRect.GetBottom() - pt.y
d *= 255
d *= 255.0
d /= alphaRect.height
if d < 0:
d = 0
@@ -2499,11 +2499,11 @@ class AlphaCtrl(BaseLineCtrl):
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
dc.DrawRectangleRect(alphaMark)
dc.DrawRectangle(alphaMark)
RestoreOldDC(dc, oldPen, oldBrush, oldMode)
class ColourPanel(wx.PyPanel):
class ColourPanel(wx.Panel):
"""
Simple custom class used to display "old" and "new" colour panels, with alpha
blending capabilities.
@@ -2518,7 +2518,7 @@ class ColourPanel(wx.PyPanel):
:param `style`: the :class:`ColourPanel` window style.
"""
wx.PyPanel.__init__(self, parent, style=style)
wx.Panel.__init__(self, parent, style=style)
self._mainDialog = wx.GetTopLevelParent(self)
self.Bind(wx.EVT_PAINT, self.OnPaint)
@@ -2540,7 +2540,7 @@ class ColourPanel(wx.PyPanel):
mem_dc = wx.MemoryDC()
rect = self.GetClientRect()
bmp = wx.EmptyBitmap(rect.width, rect.height)
bmp = wx.Bitmap(rect.width, rect.height)
mem_dc.SelectObject(bmp)
backBrush = wx.Brush(self.GetParent().GetBackgroundColour())
@@ -2548,7 +2548,7 @@ class ColourPanel(wx.PyPanel):
mem_dc.Clear()
mem_dc.SetBrush(wx.WHITE_BRUSH)
mem_dc.DrawRectangleRect(rect)
mem_dc.DrawRectangle(rect)
DrawCheckerBoard(mem_dc, rect, checkColour, box=10)
@@ -2556,7 +2556,7 @@ class ColourPanel(wx.PyPanel):
colour_gcdc = wx.Colour(self._colour.r, self._colour.g, self._colour.b, self._colour._alpha)
gcdc.SetBrush(wx.Brush(colour_gcdc))
gcdc.SetPen(wx.Pen(colour_gcdc))
gcdc.DrawRectangleRect(rect)
gcdc.DrawRectangle(rect)
mem_dc.SelectObject(wx.NullBitmap)
dc.DrawBitmap(bmp, 0, 0)
@@ -2623,7 +2623,7 @@ class ColourPanel(wx.PyPanel):
return False
class CustomPanel(wx.PyControl):
class CustomPanel(wx.Control):
"""
This panel displays a series of custom colours (chosen by the user) just like
the standard :class:`ColourDialog`.
@@ -2638,7 +2638,7 @@ class CustomPanel(wx.PyControl):
:param `colourData`: an instance of :class:`ColourData`.
"""
wx.PyControl.__init__(self, parent, style=wx.NO_BORDER)
wx.Control.__init__(self, parent, style=wx.NO_BORDER)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self._colourData = colourData
@@ -2664,9 +2664,9 @@ class CustomPanel(wx.PyControl):
curr = self._colourData.GetColour()
self._colourSelection = -1
for i in xrange(16):
for i in range(16):
c = self._colourData.GetCustomColour(i)
if c.Ok():
if c.IsOk():
self._customColours[i] = self._colourData.GetCustomColour(i)
else:
self._customColours[i] = wx.Colour(255, 255, 255)
@@ -2731,8 +2731,8 @@ class CustomPanel(wx.PyControl):
x, y = event.GetX(), event.GetY()
selX = (x - self._customColourRect.x)/(self._smallRectangleSize.x + self._gridSpacing)
selY = (y - self._customColourRect.y)/(self._smallRectangleSize.y + self._gridSpacing)
selX = (x - self._customColourRect.x)//(self._smallRectangleSize.x + self._gridSpacing)
selY = (y - self._customColourRect.y)//(self._smallRectangleSize.y + self._gridSpacing)
ptr = selX + selY*8
dc = wx.ClientDC(self)
@@ -2753,8 +2753,8 @@ class CustomPanel(wx.PyControl):
:param `dc`: an instance of :class:`DC`.
"""
for i in xrange(2):
for j in xrange(8):
for i in range(2):
for j in range(8):
ptr = i*8 + j
x = (j*(self._smallRectangleSize.x+self._gridSpacing)) + self._customColourRect.x
@@ -2785,7 +2785,7 @@ class CustomPanel(wx.PyControl):
deltaX = deltaY = 2
# User-defined colours
y = self._colourSelection/8
y = self._colourSelection//8
x = self._colourSelection - (y*8)
x = (x*(self._smallRectangleSize.x + self._gridSpacing) + self._customColourRect.x) - deltaX
@@ -3023,7 +3023,7 @@ class CubeColourDialog(wx.Dialog):
accessSizer.Add(self.accessCode, 0)
panelSizer.Add(newLabel, 0, wx.BOTTOM, 3)
panelSizer.Add(self.newColourPanel, 0, wx.EXPAND)
panelSizer.Add((0, 0), 1, wx.EXPAND)
panelSizer.Add(0, 0, 1, wx.EXPAND)
panelSizer.Add(accessSizer, 0, wx.TOP, 5)
mainSizer.Add(panelSizer, (2, 3), (1, 1), wx.ALL|wx.EXPAND, 10)
redLabel = wx.StaticText(self.mainPanel, -1, _("Red"))
@@ -3083,7 +3083,7 @@ class CubeColourDialog(wx.Dialog):
""" Initialize the :class:`CubeColourDialog`. """
hsvRect = self.hsvBitmap.GetClientRect()
self._centre = wx.Point(hsvRect.x + hsvRect.width/2, hsvRect.y + hsvRect.height/2)
self._centre = wx.Point(hsvRect.x + hsvRect.width//2, hsvRect.y + hsvRect.height//2)
self._redLen = Distance(Vertex, Top)
self._greenLen = Distance(Vertex, Left)
@@ -3108,7 +3108,7 @@ class CubeColourDialog(wx.Dialog):
self._lines[GREEN].slope = Slope(Left, Vertex)
self._lines[BLUE].slope = Slope(Right, Vertex)
for i in xrange(3):
for i in range(3):
self._lines[i].x = Vertex.x
self._lines[i].y = Vertex.y
self._lines[i].c = FindC(self._lines[i])
@@ -3121,7 +3121,7 @@ class CubeColourDialog(wx.Dialog):
gLen = (self._colour.g*self._greenLen)/255.0
bLen = (self._colour.b*self._blueLen)/255.0
lines = [LineDescription() for i in xrange(12)]
lines = [LineDescription() for i in range(12)]
self._cuboid = [None]*8
self._cuboid[0] = Vertex
@@ -3492,3 +3492,33 @@ class CubeColourDialog(wx.Dialog):
return (self._colour.h, self._colour.s, self._colour.v, self._colour._alpha)
if __name__ == '__main__':
import wx
# Our normal wxApp-derived class, as usual
app = wx.App(0)
colourData = wx.ColourData()
colourData.SetColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE))
dlg = CubeColourDialog(None, colourData)
if dlg.ShowModal() == wx.ID_OK:
# If the user selected OK, then the dialog's wx.ColourData will
# contain valid information. Fetch the data ...
colourData = dlg.GetColourData()
h, s, v, a = dlg.GetHSVAColour()
# ... then do something with it. The actual colour data will be
# returned as a three-tuple (r, g, b) in this particular case.
colour = colourData.GetColour()
r, g, b, alpha = colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()
print(("You selected (RGBA): %d, %d, %d, %d"%(r, g, b, alpha)))
print(("You selected (HSVA): %d, %d, %d, %d"%(h, s, v, a)))
# Once the dialog is destroyed, Mr. wx.ColourData is no longer your
# friend. Don't use it again!
dlg.Destroy()
app.MainLoop()

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
# Python Code By:
#
# Andrea Gavana, @ 16 Nov 2005
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List/Caveats
@@ -18,6 +18,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -31,7 +32,7 @@ Description
===========
:class:`FloatSpin` implements a floating point :class:`SpinCtrl`. It is built using a custom
:class:`PyControl`, composed by a :class:`TextCtrl` and a :class:`SpinButton`. In order to
:class:`Control`, composed by a :class:`TextCtrl` and a :class:`SpinButton`. In order to
correctly handle floating points numbers without rounding errors or non-exact
floating point representations, :class:`FloatSpin` uses the great :class:`FixedPoint` class
from Tim Peters.
@@ -135,9 +136,9 @@ License And Version
:class:`FloatSpin` control is distributed under the wxPython license.
Latest revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.9
Version 1.0
Backward Incompatibilities
@@ -176,6 +177,9 @@ import wx
import locale
from math import ceil, floor
# Python 2/3 compatibility helper
import wx.lib.wx2to3 as wx2to3
# Set The Styles For The Underline wx.TextCtrl
FS_READONLY = 1
""" Sets :class:`FloatSpin` as read-only control. """
@@ -201,7 +205,7 @@ EVT_FLOATSPIN = wx.PyEventBinder(wxEVT_FLOATSPIN, 1)
# Class FloatSpinEvent
# ---------------------------------------------------------------------------- #
class FloatSpinEvent(wx.PyCommandEvent):
class FloatSpinEvent(wx.CommandEvent):
""" This event will be sent when a ``EVT_FLOATSPIN`` event is mapped in the parent. """
def __init__(self, eventType, eventId=1, nSel=-1, nOldSel=-1):
@@ -214,7 +218,7 @@ class FloatSpinEvent(wx.PyCommandEvent):
:param `nOldSel`: the old selection.
"""
wx.PyCommandEvent.__init__(self, eventType, eventId)
wx.CommandEvent.__init__(self, eventType, eventId)
self._eventType = eventType
@@ -320,10 +324,10 @@ class FloatTextCtrl(wx.TextCtrl):
# This Is The Main Class Implementation
# ---------------------------------------------------------------------------- #
class FloatSpin(wx.PyControl):
class FloatSpin(wx.Control):
"""
:class:`FloatSpin` implements a floating point :class:`SpinCtrl`. It is built using a custom
:class:`PyControl`, composed by a :class:`TextCtrl` and a :class:`SpinButton`. In order to
:class:`Control`, composed by a :class:`TextCtrl` and a :class:`SpinButton`. In order to
correctly handle floating points numbers without rounding errors or non-exact
floating point representations, :class:`FloatSpin` uses the great :class:`FixedPoint` class
from Tim Peters.
@@ -363,7 +367,7 @@ class FloatSpin(wx.PyControl):
"""
wx.PyControl.__init__(self, parent, id, pos, size, style|wx.NO_BORDER|
wx.Control.__init__(self, parent, id, pos, size, style|wx.NO_BORDER|
wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN,
wx.DefaultValidator, name)
@@ -424,7 +428,7 @@ class FloatSpin(wx.PyControl):
height = best_size.GetHeight()
self._validkeycode = [43, 44, 45, 46, 69, 101, 127, 314]
self._validkeycode.extend(range(48, 58))
self._validkeycode.extend(list(range(48, 58)))
self._validkeycode.extend([wx.WXK_RETURN, wx.WXK_TAB, wx.WXK_BACK,
wx.WXK_LEFT, wx.WXK_RIGHT])
@@ -501,7 +505,7 @@ class FloatSpin(wx.PyControl):
self.Bind(wx.EVT_SIZE, self.OnSize)
# start Philip Semanchuk move
self.SetBestSize((width, height))
self.SetInitialSize((width, height))
# end Philip Semanchuk move
@@ -530,7 +534,7 @@ class FloatSpin(wx.PyControl):
minimal size which doesn't truncate the control, for a panel - the same
size as it would have after a call to `Fit()`.
:note: Overridden from :class:`PyControl`.
:note: Overridden from :class:`Control`.
"""
if self._spinctrl_bestsize.x == -999:
@@ -756,9 +760,9 @@ class FloatSpin(wx.PyControl):
self._textctrl.SetPosition((self._text_left, self._text_top))
text_width, text_height = self._textctrl.GetSizeTuple()
text_width, text_height = self._textctrl.GetSize()
spin_width, _ = self._spinbutton.GetSizeTuple()
spin_width, _ = self._spinbutton.GetSize()
text_width = event_width - (spin_width + self._gap + self._text_left)
@@ -1125,7 +1129,7 @@ class FloatSpin(wx.PyControl):
"""
if font is None:
font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
if not self._textctrl:
return False
@@ -1340,7 +1344,7 @@ class FixedPoint(object):
self.n = n
return
if isinstance(value, type(42)) or isinstance(value, type(42L)):
if isinstance(value, wx2to3.integer_types):
self.n = long(value) * _tento(p)
return
@@ -1361,7 +1365,7 @@ class FixedPoint(object):
# up all bits in 2 iterations for all known binary double-
# precision formats, and small enough to fit in an int.
CHUNK = 28
top = 0L
top = 0
# invariant: |value| = (top + f) * 2**e exactly
while f:
f = math.ldexp(f, CHUNK)
@@ -1379,7 +1383,7 @@ class FixedPoint(object):
if e >= 0:
n = top << e
else:
n = _roundquotient(top, 1L << -e)
n = _roundquotient(top, 1 << -e)
if value < 0:
n = -n
self.n = n
@@ -1387,7 +1391,7 @@ class FixedPoint(object):
if isinstance(value, type(42-42j)):
raise TypeError("can't convert complex to FixedPoint: " +
`value`)
repr(value))
# can we coerce to a float?
yes = 1
@@ -1409,7 +1413,7 @@ class FixedPoint(object):
self.__init__(aslong, p)
return
raise TypeError("can't convert to FixedPoint: " + `value`)
raise TypeError("can't convert to FixedPoint: " + repr(value))
def get_precision(self):
@@ -1438,9 +1442,9 @@ class FixedPoint(object):
p = int(precision)
except:
raise TypeError("precision not convertable to int: " +
`precision`)
repr(precision))
if p < 0:
raise ValueError("precision must be >= 0: " + `precision`)
raise ValueError("precision must be >= 0: " + repr(precision))
if p > self.p:
self.n = self.n * _tento(p - self.p)
@@ -1465,7 +1469,7 @@ class FixedPoint(object):
def __repr__(self):
return "FixedPoint" + `(str(self), self.p)`
return "FixedPoint" + repr((str(self), self.p))
def copy(self):
@@ -1576,7 +1580,7 @@ class FixedPoint(object):
# XXX note that __int__ inherits whatever __long__ does,
# XXX and .frac() is affected too
def __long__(self):
answer = abs(self.n) / _tento(self.p)
answer = abs(self.n) // _tento(self.p)
if self.n < 0:
answer = -answer
return answer
@@ -1605,7 +1609,7 @@ class FixedPoint(object):
p = 0
while p and n % 10 == 0:
p = p - 1
n = n / 10
n = n // 10
return n, p
# return 10L**n
@@ -1614,7 +1618,7 @@ def _tento(n, cache={}):
try:
return cache[n]
except KeyError:
answer = cache[n] = 10L ** n
answer = cache[n] = 10 ** n
return answer
# return xn, yn, p s.t.
@@ -1691,7 +1695,7 @@ del re
def _string2exact(s):
m = _parser(s)
if m is None:
raise ValueError("can't parse as number: " + `s`)
raise ValueError("can't parse as number: " + repr(s))
exp = m.group('exp')
if exp is None:
@@ -1719,3 +1723,34 @@ def _string2exact(s):
i = -i
return i, exp
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "FloatSpin Demo")
panel = wx.Panel(self)
floatspin = FloatSpin(panel, -1, pos=(50, 50), min_val=0, max_val=1,
increment=0.01, value=0.1, agwStyle=FS_LEFT)
floatspin.SetFormat("%f")
floatspin.SetDigits(2)
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -3,7 +3,7 @@
# Ported From Jorgen Bodde & Julian Smart (Extended Demo) C++ Code By:
#
# Andrea Gavana, @ 23 Mar 2005
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List
@@ -53,6 +53,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -128,16 +129,16 @@ Usage example::
text_ctrl = wx.TextCtrl(self, -1, size=(400, 100), style=wx.TE_MULTILINE)
panel_bar = fpb.FoldPanelBar(self, -1, agwStyle=fpb.FPB_HORIZONTAL|fpb.FPB_DEFAULT_STYLE)
panel_bar = fpb.FoldPanelBar(self, -1, agwStyle=fpb.FPB_VERTICAL)
fold_panel = panel_bar.AddFoldPanel("Thing")
thing = wx.TextCtrl(fold_panel, -1, size=(400, -1), style=wx.TE_MULTILINE)
panel_bar.AddFoldPanelWindow(fold_panel, thing)
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(text_ctrl, 1, wx.EXPAND)
main_sizer.Add(panel_bar, 0, wx.EXPAND)
main_sizer.Add(panel_bar, 1, wx.EXPAND)
self.SetSizer(main_sizer)
@@ -195,9 +196,9 @@ License And Version
:class:`FoldPanelBar` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.5
Version 0.6
"""
@@ -523,7 +524,7 @@ EmptyCaptionBarStyle = CaptionBarStyle()
# class CaptionBarEvent
# ---------------------------------------------------------------------------- #
class CaptionBarEvent(wx.PyCommandEvent):
class CaptionBarEvent(wx.CommandEvent):
"""
This event will be sent when a ``EVT_CAPTIONBAR`` is mapped in the parent.
It is to notify the parent that the bar is now in collapsed or expanded
@@ -537,7 +538,7 @@ class CaptionBarEvent(wx.PyCommandEvent):
:param `evtType`: the event type.
"""
wx.PyCommandEvent.__init__(self, evtType)
wx.CommandEvent.__init__(self, evtType)
def GetFoldStatus(self):
@@ -829,9 +830,9 @@ class CaptionBar(wx.Window):
dc.SetTextForeground(self._style.GetCaptionColour())
if vertical:
dc.DrawText(self._caption, 4, FPB_EXTRA_Y/2)
dc.DrawText(self._caption, 4, FPB_EXTRA_Y//2)
else:
dc.DrawRotatedText(self._caption, FPB_EXTRA_Y/2,
dc.DrawRotatedText(self._caption, FPB_EXTRA_Y//2,
wndRect.GetBottom() - 4, 90)
# draw small icon, either collapsed or expanded
@@ -844,11 +845,11 @@ class CaptionBar(wx.Window):
if vertical:
drw = wndRect.GetRight() - self._iconWidth - self._rightIndent
self._foldIcons.Draw(index, dc, drw,
(wndRect.GetHeight() - self._iconHeight)/2,
(wndRect.GetHeight() - self._iconHeight)//2,
wx.IMAGELIST_DRAW_TRANSPARENT)
else:
self._foldIcons.Draw(index, dc,
(wndRect.GetWidth() - self._iconWidth)/2,
(wndRect.GetWidth() - self._iconWidth)//2,
self._rightIndent, wx.IMAGELIST_DRAW_TRANSPARENT)
## event.Skip()
@@ -909,7 +910,7 @@ class CaptionBar(wx.Window):
send_event = True
elif event.LeftDClick():
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
send_event = True
elif event.Entering() and self._foldIcons:
@@ -919,12 +920,12 @@ class CaptionBar(wx.Window):
drw = (rect.GetWidth() - self._iconWidth - self._rightIndent)
if vertical and pt.x > drw or not vertical and \
pt.y < (self._iconHeight + self._rightIndent):
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
self.SetCursor(wx.Cursor(wx.CURSOR_HAND))
else:
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
elif event.Leaving():
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
elif event.Moving():
pt = event.GetPosition()
@@ -933,9 +934,9 @@ class CaptionBar(wx.Window):
drw = (rect.GetWidth() - self._iconWidth - self._rightIndent)
if vertical and pt.x > drw or not vertical and \
pt.y < (self._iconHeight + self._rightIndent):
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
self.SetCursor(wx.Cursor(wx.CURSOR_HAND))
else:
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
# send the collapse, expand event to the parent
@@ -1015,7 +1016,7 @@ class CaptionBar(wx.Window):
for y in range(rect.y, rect.y + rect.height):
currCol = (r1 + rf, g1 + gf, b1 + bf)
dc.SetBrush(wx.Brush(currCol, wx.SOLID))
dc.SetBrush(wx.Brush(currCol, wx.BRUSHSTYLE_SOLID))
dc.DrawRectangle(rect.x, rect.y + (y - rect.y), rect.width, rect.height)
rf = rf + rstep
gf = gf + gstep
@@ -1053,7 +1054,7 @@ class CaptionBar(wx.Window):
for x in range(rect.x, rect.x + rect.width):
currCol = (r1 + rf, g1 + gf, b1 + bf)
dc.SetBrush(wx.Brush(currCol, wx.SOLID))
dc.SetBrush(wx.Brush(currCol, wx.BRUSHSTYLE_SOLID))
dc.DrawRectangle(rect.x + (x - rect.x), rect.y, 1, rect.height)
rf = rf + rstep
gf = gf + gstep
@@ -1074,7 +1075,7 @@ class CaptionBar(wx.Window):
dc.SetPen(wx.TRANSPARENT_PEN)
# draw simple rectangle
dc.SetBrush(wx.Brush(self._style.GetFirstColour(), wx.SOLID))
dc.SetBrush(wx.Brush(self._style.GetFirstColour(), wx.BRUSHSTYLE_SOLID))
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
@@ -1093,10 +1094,10 @@ class CaptionBar(wx.Window):
if self._style.GetCaptionStyle() == CAPTIONBAR_RECTANGLE:
colour = self.GetParent().GetBackgroundColour()
br = wx.Brush(colour, wx.SOLID)
br = wx.Brush(colour, wx.BRUSHSTYLE_SOLID)
else:
colour = self._style.GetFirstColour()
br = wx.Brush(colour, wx.SOLID)
br = wx.Brush(colour, wx.BRUSHSTYLE_SOLID)
# setup the pen frame
@@ -1815,7 +1816,7 @@ class FoldPanelItem(wx.Panel):
xpos = (vertical and [leftSpacing] or [self._LastInsertPos + spacing])[0]
ypos = (vertical and [self._LastInsertPos + spacing] or [leftSpacing])[0]
window.SetDimensions(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING)
window.SetSize(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING)
self._LastInsertPos = self._LastInsertPos + wi.GetWindowLength(vertical)
self.ResizePanel()
@@ -1865,7 +1866,7 @@ class FoldPanelItem(wx.Panel):
xpos = (vertical and [-1] or [pos])[0]
ypos = (vertical and [pos] or [-1])[0]
self.SetDimensions(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING)
self.SetSize(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING)
self._itemPos = pos
self.Thaw()
@@ -2089,25 +2090,25 @@ class FoldWindowItem(object):
:see: :meth:`FoldPanelBar.AddFoldPanelWindow() <FoldPanelBar.AddFoldPanelWindow>` for a list of valid alignment flags.
"""
if not kw.has_key("Type"):
if "Type" not in kw:
raise Exception('ERROR: Missing Window Type Information. This Should Be "WINDOW" Or "SEPARATOR"')
if kw.get("Type") == "WINDOW":
# Window constructor. This initialises the class as a wx.Window Type
if kw.has_key("flags"):
if "flags" in kw:
self._flags = kw.get("flags")
else:
self._flags = FPB_ALIGN_WIDTH
if kw.has_key("spacing"):
if "spacing" in kw:
self._spacing = kw.get("spacing")
else:
self._spacing = FPB_DEFAULT_SPACING
if kw.has_key("leftSpacing"):
if "leftSpacing" in kw:
self._leftSpacing = kw.get("leftSpacing")
else:
self._leftSpacing = FPB_DEFAULT_LEFTSPACING
if kw.has_key("rightSpacing"):
if "rightSpacing" in kw:
self._rightSpacing = kw.get("rightSpacing")
else:
self._rightSpacing = FPB_DEFAULT_RIGHTSPACING
@@ -2120,27 +2121,27 @@ class FoldWindowItem(object):
elif kw.get("Type") == "SEPARATOR":
# separator constructor. This initialises the class as a separator type
if kw.has_key("y"):
if "y" in kw:
self._lineY = kw.get("y")
else:
raise Exception("ERROR: Undefined Y Position For The Separator")
if kw.has_key("lineColour"):
if "lineColour" in kw:
self._sepLineColour = kw.get("lineColour")
else:
self._sepLineColour = wx.BLACK
if kw.has_key("flags"):
if "flags" in kw:
self._flags = kw.get("flags")
else:
self._flags = FPB_ALIGN_WIDTH
if kw.has_key("spacing"):
if "spacing" in kw:
self._spacing = kw.get("spacing")
else:
self._spacing = FPB_DEFAULT_SPACING
if kw.has_key("leftSpacing"):
if "leftSpacing" in kw:
self._leftSpacing = kw.get("leftSpacing")
else:
self._leftSpacing = FPB_DEFAULT_LEFTSPACING
if kw.has_key("rightSpacing"):
if "rightSpacing" in kw:
self._rightSpacing = kw.get("rightSpacing")
else:
self._rightSpacing = FPB_DEFAULT_RIGHTSPACING
@@ -2244,3 +2245,39 @@ class FoldWindowItem(object):
self._wnd.SetSize((xsize, ysize))
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "FoldPanelBar Demo")
text_ctrl = wx.TextCtrl(self, -1, size=(400, 100), style=wx.TE_MULTILINE)
panel_bar = FoldPanelBar(self, -1, agwStyle=FPB_VERTICAL)
fold_panel = panel_bar.AddFoldPanel("Thing")
thing = wx.TextCtrl(fold_panel, -1, size=(400, -1), style=wx.TE_MULTILINE)
panel_bar.AddFoldPanelWindow(fold_panel, thing)
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(text_ctrl, 1, wx.EXPAND)
main_sizer.Add(panel_bar, 1, wx.EXPAND)
self.SetSizer(main_sizer)
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -2,7 +2,7 @@
# FOURWAYSPLITTER wxPython IMPLEMENTATION
#
# Andrea Gavana, @ 03 Nov 2006
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List
@@ -17,6 +17,7 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------------- #
@@ -126,14 +127,12 @@ License And Version
:class:`FourWaySplitter` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest Revision: Andrea Gavana @ 15 Jul 2012, 15.00 GMT
Version 0.4
Version 0.5
"""
__docformat__ = "epytext"
import wx
@@ -172,7 +171,7 @@ EVT_SPLITTER_SASH_POS_CHANGED = wx.EVT_SPLITTER_SASH_POS_CHANGED
# Class FourWaySplitterEvent
# ---------------------------------------------------------------------------- #
class FourWaySplitterEvent(wx.PyCommandEvent):
class FourWaySplitterEvent(wx.CommandEvent):
"""
This event class is almost the same as :class:`SplitterEvent` except
it adds an accessor for the sash index that is being changed. The
@@ -188,7 +187,7 @@ class FourWaySplitterEvent(wx.PyCommandEvent):
:param `splitter`: the associated :class:`FourWaySplitter` window.
"""
wx.PyCommandEvent.__init__(self, evtType)
wx.CommandEvent.__init__(self, evtType)
if splitter:
self.SetEventObject(splitter)
@@ -281,7 +280,7 @@ class FourWaySplitterEvent(wx.PyCommandEvent):
# Class FourWaySplitter
# ---------------------------------------------------------------------------- #
class FourWaySplitter(wx.PyPanel):
class FourWaySplitter(wx.Panel):
"""
This class is very similar to :class:`SplitterWindow` except that it
allows for four windows and two sashes. Many of the same styles,
@@ -312,7 +311,7 @@ class FourWaySplitter(wx.PyPanel):
chosen by either the windowing system or wxPython, depending on platform;
:param `size`: the control size. A value of (-1, -1) indicates a default size,
chosen by either the windowing system or wxPython, depending on platform;
:param `style`: the underlying :class:`PyPanel` window style;
:param `style`: the underlying :class:`Panel` window style;
:param `agwStyle`: the AGW-specific window style. It can be a combination of the
following bits:
@@ -337,7 +336,7 @@ class FourWaySplitter(wx.PyPanel):
self._agwStyle = agwStyle
# initialize the base class
wx.PyPanel.__init__(self, parent, id, pos, size, style, name)
wx.Panel.__init__(self, parent, id, pos, size, style, name)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self._windows = []
@@ -355,9 +354,9 @@ class FourWaySplitter(wx.PyPanel):
self._sashTrackerPen = wx.Pen(wx.BLACK, 2, wx.SOLID)
self._sashCursorWE = wx.StockCursor(wx.CURSOR_SIZEWE)
self._sashCursorNS = wx.StockCursor(wx.CURSOR_SIZENS)
self._sashCursorSIZING = wx.StockCursor(wx.CURSOR_SIZING)
self._sashCursorWE = wx.Cursor(wx.CURSOR_SIZEWE)
self._sashCursorNS = wx.Cursor(wx.CURSOR_SIZENS)
self._sashCursorSIZING = wx.Cursor(wx.CURSOR_SIZING)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_MOTION, self.OnMotion)
@@ -530,7 +529,7 @@ class FourWaySplitter(wx.PyPanel):
minimal size which doesn't truncate the control, for a panel - the same size
as it would have after a call to `Fit()`.
:note: Overridden from :class:`PyPanel`.
:note: Overridden from :class:`Panel`.
"""
if not self._windows:
@@ -579,21 +578,21 @@ class FourWaySplitter(wx.PyPanel):
if self._expanded < 0:
totw = width - barSize - 2*border
toth = height - barSize - 2*border
self._splitx = (self._fhor*totw)/10000
self._splity = (self._fver*toth)/10000
self._splitx = (self._fhor*totw)//10000
self._splity = (self._fver*toth)//10000
rightw = totw - self._splitx
bottomh = toth - self._splity
if win0:
win0.SetDimensions(0, 0, self._splitx, self._splity)
win0.SetSize(0, 0, self._splitx, self._splity)
win0.Show()
if win1:
win1.SetDimensions(self._splitx + barSize, 0, rightw, self._splity)
win1.SetSize(self._splitx + barSize, 0, rightw, self._splity)
win1.Show()
if win2:
win2.SetDimensions(0, self._splity + barSize, self._splitx, bottomh)
win2.SetSize(0, self._splity + barSize, self._splitx, bottomh)
win2.Show()
if win3:
win3.SetDimensions(self._splitx + barSize, self._splity + barSize, rightw, bottomh)
win3.SetSize(self._splitx + barSize, self._splity + barSize, rightw, bottomh)
win3.Show()
else:
@@ -601,7 +600,7 @@ class FourWaySplitter(wx.PyPanel):
if self._expanded < len(self._windows):
for ii, win in enumerate(self._windows):
if ii == self._expanded:
win.SetDimensions(0, 0, width-2*border, height-2*border)
win.SetSize(0, 0, width-2*border, height-2*border)
win.Show()
else:
win.Hide()
@@ -678,11 +677,11 @@ class FourWaySplitter(wx.PyPanel):
border = self._GetBorderSize()
self._fhor = (width > barSize and \
[(10000*self._splitx+(width-barSize-1))/(width-barSize)] \
[(10000*self._splitx+(width-barSize-1))//(width-barSize)] \
or [0])[0]
self._fver = (height > barSize and \
[(10000*self._splity+(height-barSize-1))/(height-barSize)] \
[(10000*self._splity+(height-barSize-1))//(height-barSize)] \
or [0])[0]
self._SizeWindows()
@@ -921,7 +920,7 @@ class FourWaySplitter(wx.PyPanel):
"""
backColour = self.GetBackgroundColour()
dc.SetBrush(wx.Brush(backColour, wx.SOLID))
dc.SetBrush(wx.Brush(backColour))
dc.SetPen(wx.Pen(backColour))
dc.Clear()
@@ -990,8 +989,8 @@ class FourWaySplitter(wx.PyPanel):
x1 = 0
x2 = 0
x1, y1 = self.ClientToScreenXY(x1, y1)
x2, y2 = self.ClientToScreenXY(x2, y2)
x1, y1 = self.ClientToScreen((x1, y1))
x2, y2 = self.ClientToScreen((x2, y2))
dc.DrawLine(x1, y1, x2, y2)
dc.SetLogicalFunction(wx.COPY)
@@ -1009,8 +1008,8 @@ class FourWaySplitter(wx.PyPanel):
y1 = 0
y2 = 0
x1, y1 = self.ClientToScreenXY(x1, y1)
x2, y2 = self.ClientToScreenXY(x2, y2)
x1, y1 = self.ClientToScreen((x1, y1))
x2, y2 = self.ClientToScreen((x2, y2))
dc.DrawLine(x1, y1, x2, y2)
dc.SetLogicalFunction(wx.COPY)
@@ -1022,8 +1021,8 @@ class FourWaySplitter(wx.PyPanel):
y1 = y
y2 = y
x1, y1 = self.ClientToScreenXY(x1, y1)
x2, y2 = self.ClientToScreenXY(x2, y2)
x1, y1 = self.ClientToScreen((x1, y1))
x2, y2 = self.ClientToScreen((x2, y2))
dc.DrawLine(x1, y1, x2, y2)
@@ -1032,8 +1031,8 @@ class FourWaySplitter(wx.PyPanel):
y1 = 2
y2 = h-2
x1, y1 = self.ClientToScreenXY(x1, y1)
x2, y2 = self.ClientToScreenXY(x2, y2)
x1, y1 = self.ClientToScreen((x1, y1))
x2, y2 = self.ClientToScreen((x2, y2))
dc.DrawLine(x1, y1, x2, y2)
dc.SetLogicalFunction(wx.COPY)
@@ -1099,3 +1098,33 @@ class FourWaySplitter(wx.PyPanel):
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "FourWaySplitter Demo")
splitter = FourWaySplitter(self, -1, agwStyle=wx.SP_LIVE_UPDATE)
# Put in some coloured panels...
for colour in [wx.RED, wx.WHITE, wx.BLUE, wx.GREEN]:
panel = wx.Panel(splitter)
panel.SetBackgroundColour(colour)
splitter.AppendWindow(panel)
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -2,7 +2,7 @@
# GENERICMESSAGEDIALOG wxPython IMPLEMENTATION
#
# Andrea Gavana, @ 07 October 2008
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List
@@ -18,6 +18,7 @@
#
# Or, obviously, to the wxPython mailing list!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------------- #
@@ -121,9 +122,9 @@ License And Version
:class:`GenericMessageDialog` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.7
Version 0.8
"""
@@ -557,19 +558,19 @@ class StdDialogButtonSizer(wx.BoxSizer):
self.Add((0, 0), 1, wx.EXPAND, 0)
if self._buttonAffirmative:
self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogSizeToPixels(wx.Size(2, 0)).x)
self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogToPixels(wx.Size(2, 0)).x)
if self._buttonNegative:
self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogSizeToPixels(wx.Size(2, 0)).x)
self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogToPixels(wx.Size(2, 0)).x)
if self._buttonCancel:
self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogSizeToPixels(wx.Size(2, 0)).x)
self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogToPixels(wx.Size(2, 0)).x)
if self._buttonApply:
self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogSizeToPixels(wx.Size(2, 0)).x)
self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogToPixels(wx.Size(2, 0)).x)
if self._buttonHelp:
self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogSizeToPixels(wx.Size(2, 0)).x)
self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogToPixels(wx.Size(2, 0)).x)
self.Add((0, 0), 1, wx.EXPAND, 0)
@@ -577,22 +578,22 @@ class StdDialogButtonSizer(wx.BoxSizer):
# GTK+1 and any other platform
if self._buttonHelp:
self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogToPixels(wx.Size(4, 0)).x)
# extra whitespace between help and cancel/ok buttons
self.Add((0, 0), 1, wx.EXPAND, 0)
if self._buttonApply:
self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogToPixels(wx.Size(4, 0)).x)
if self._buttonAffirmative:
self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogToPixels(wx.Size(4, 0)).x)
if self._buttonNegative:
self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogToPixels(wx.Size(4, 0)).x)
if self._buttonCancel:
self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogToPixels(wx.Size(4, 0)).x)
# Cancel or help should be default
# self._buttonCancel.SetDefaultButton()
@@ -712,10 +713,10 @@ class GenericMessageDialog(wx.Dialog):
msgSizer = self.CreateTextSizer(message)
for index in xrange(len(msgSizer.GetChildren())):
for index in range(len(msgSizer.GetChildren())):
msgSizer.GetItem(index).GetWindow().SetFont(boldFont)
textsizer.AddF(msgSizer, wx.SizerFlags().Border(wx.BOTTOM, 20))
textsizer.Add(msgSizer, wx.SizerFlags().Border(wx.BOTTOM, 20))
lowerMessage = self.GetExtendedMessage()
else: # no extended message
@@ -745,12 +746,12 @@ class GenericMessageDialog(wx.Dialog):
topsizer.Fit(self)
size = self.GetSize()
if size.x < size.y*3/2:
size.x = size.y*3/2
if size.x < size.y*3//2:
size.x = size.y*3//2
self.SetSize(size)
self.Layout()
self.Centre(wx.BOTH | wx.CENTER_FRAME)
self.Centre(wx.BOTH)
self.Bind(wx.EVT_BUTTON, self.OnYes, id=wx.ID_YES)
self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)
@@ -934,8 +935,8 @@ class GenericMessageDialog(wx.Dialog):
# grouping elements
if wx.Platform != "__WXMAC__":
topsizer = wx.BoxSizer(wx.VERTICAL)
topsizer.AddF(wx.StaticLine(self), wx.SizerFlags().Expand().DoubleBorder(wx.BOTTOM))
topsizer.AddF(sizer, wx.SizerFlags().Expand())
topsizer.Add(wx.StaticLine(self), wx.SizerFlags().Expand().DoubleBorder(wx.BOTTOM))
topsizer.Add(sizer, wx.SizerFlags().Expand())
sizer = topsizer
return sizer
@@ -1463,12 +1464,9 @@ class GenericMessageDialog(wx.Dialog):
:return: a new message wrapped at maximum `wrap` pixels wide.
.. todo::
Estabilish if wrapping all messages by default is a better idea than
:todo: Estabilish if wrapping all messages by default is a better idea than
provide a keyword parameter to :class:`GenericMessageDialog`. A default maximum
line width might be the wxMac one, at 360 pixels.
"""
dc = wx.ClientDC(self)
@@ -1584,3 +1582,23 @@ class GenericMessageDialog(wx.Dialog):
return msg
if __name__ == '__main__':
import wx
# Our normal wxApp-derived class, as usual
app = wx.App(0)
main_message = "Hello world! I am the main message."
dlg = GenericMessageDialog(None, main_message, "A Nice Message Box",
agwStyle=wx.ICON_INFORMATION|wx.OK)
dlg.ShowModal()
dlg.Destroy()
app.MainLoop()

View File

@@ -3,7 +3,7 @@
# Ported From Angelo Mandato C++ Code By:
#
# Andrea Gavana, @ 27 Mar 2005
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# Original Web Site (For The C++ Code):
@@ -21,6 +21,7 @@
#
# Or, obviously, to the wxPython mailing list!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------- #
@@ -114,9 +115,9 @@ License And Version
:class:`HyperLinkCtrl` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 0.6
Version 0.7
"""
@@ -160,7 +161,7 @@ EVT_HYPERLINK_RIGHT = wx.PyEventBinder(wxEVT_HYPERLINK_RIGHT, 1)
# This class implements the event listener for the hyperlinks
# ------------------------------------------------------------
class HyperLinkEvent(wx.PyCommandEvent):
class HyperLinkEvent(wx.CommandEvent):
"""
Event object sent in response to clicking on a :class:`HyperLinkCtrl`.
"""
@@ -173,7 +174,7 @@ class HyperLinkEvent(wx.PyCommandEvent):
:param `eventId`: the event identifier.
"""
wx.PyCommandEvent.__init__(self, eventType, eventId)
wx.CommandEvent.__init__(self, eventType, eventId)
self._eventType = eventType
@@ -359,7 +360,7 @@ class HyperLinkCtrl(StaticText):
menuPopUp = wx.Menu("", wx.MENU_TEAROFF)
menuPopUp.Append(wxHYPERLINKS_POPUP_COPY, "Copy HyperLink")
self.Bind(wx.EVT_MENU, self.OnPopUpCopy, id=wxHYPERLINKS_POPUP_COPY)
self.PopupMenu(menuPopUp, wx.Point(event.X, event.Y))
self.PopupMenu(menuPopUp, wx.Point(event.x, event.y))
menuPopUp.Destroy()
self.Unbind(wx.EVT_MENU, id=wxHYPERLINKS_POPUP_COPY)
@@ -503,10 +504,10 @@ class HyperLinkCtrl(StaticText):
"""
Sets link cursor properties.
:param `cur`: an integer representing a :class:`StockCursor` constant.
:param `cur`: an integer representing a :ref:`StockCursor` constant.
"""
self._CursorHand = wx.StockCursor(cur)
self._CursorHand = wx.Cursor(cur)
def GetLinkCursor(self):
@@ -620,3 +621,45 @@ class HyperLinkCtrl(StaticText):
self._DoPopup = DoPopup
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "HyperLink Demo")
panel = wx.Panel(self, -1)
# Default Web links:
hyper1 = HyperLinkCtrl(panel, -1, "wxPython Main Page", pos=(100, 100),
URL="http://www.wxpython.org/")
# Web link with underline rollovers, opens in same window
hyper2 = HyperLinkCtrl(panel, -1, "My Home Page", pos=(100, 150),
URL="http://xoomer.virgilio.it/infinity77/")
hyper2.AutoBrowse(False)
hyper2.SetColours("BLUE", "BLUE", "BLUE")
hyper2.EnableRollover(True)
hyper2.SetUnderlines(False, False, True)
hyper2.SetBold(True)
hyper2.OpenInSameWindow(True)
hyper2.SetToolTip(wx.ToolTip("Hello World!"))
hyper2.UpdateLink()
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -1,14 +1,14 @@
# --------------------------------------------------------------------------------- #
# HYPERTREELIST wxPython IMPLEMENTATION
# Inspired By And Heavily Based On wx.gizmos.TreeListCtrl.
# Inspired By And Heavily Based On wx.adv.TreeListCtrl.
#
# Andrea Gavana, @ 08 May 2006
# Latest Revision: 14 Mar 2012, 21.00 GMT
# Latest Revision: 16 Jul 2012, 15.00 GMT
#
#
# TODO List
#
# Almost All The Features Of wx.gizmos.TreeListCtrl Are Available, And There Is
# Almost All The Features Of wx.adv.TreeListCtrl Are Available, And There Is
# Practically No Limit In What Could Be Added To This Class. The First Things
# That Comes To My Mind Are:
#
@@ -35,26 +35,27 @@
#
# Or, Obviously, To The wxPython Mailing List!!!
#
# Tags: phoenix-port, unittest, documented
#
# End Of Comments
# --------------------------------------------------------------------------------- #
"""
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`gizmos.TreeListCtrl`, with
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`adv.TreeListCtrl`, with
some more functionalities.
Description
===========
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`gizmos.TreeListCtrl`, with
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`adv.TreeListCtrl`, with
almost the same base functionalities plus some more enhancements. This class does
not rely on the native control, as it is a full owner-drawn tree-list control.
:class:`HyperTreeList` is somewhat an hybrid between :class:`~lib.agw.customtreectrl.CustomTreeCtrl` and :class:`gizmos.TreeListCtrl`.
:class:`HyperTreeList` is somewhat an hybrid between :class:`~lib.agw.customtreectrl.CustomTreeCtrl` and :class:`adv.TreeListCtrl`.
In addition to the standard :class:`gizmos.TreeListCtrl` behaviour this class supports:
In addition to the standard :class:`adv.TreeListCtrl` behaviour this class supports:
* CheckBox-type items: checkboxes are easy to handle, just selected or unselected
state with no particular issues in handling the item's children;
@@ -92,7 +93,7 @@ And a lot more. Check the demo for an almost complete review of the functionalit
Base Functionalities
====================
:class:`HyperTreeList` supports all the :class:`gizmos.TreeListCtrl` styles, except:
:class:`HyperTreeList` supports all the :class:`adv.TreeListCtrl` styles, except:
- ``TR_EXTENDED``: supports for this style is on the todo list (Am I sure of this?).
@@ -113,7 +114,7 @@ ellipsized:
:class:`HyperTreeList` is low (`New in version 0.9.3`).
All the methods available in :class:`gizmos.TreeListCtrl` are also available in :class:`HyperTreeList`.
All the methods available in :class:`adv.TreeListCtrl` are also available in :class:`HyperTreeList`.
Usage
@@ -157,7 +158,7 @@ Usage example::
Events
======
All the events supported by :class:`gizmos.TreeListCtrl` are also available in :class:`HyperTreeList`,
All the events supported by :class:`adv.TreeListCtrl` are also available in :class:`HyperTreeList`,
with a few exceptions:
- ``EVT_TREE_GET_INFO`` (don't know what this means);
@@ -206,9 +207,9 @@ Window Styles Hex Value Description
``TR_HIDE_ROOT`` 0x800 Use this style to suppress the display of the root node, effectively causing the first-level nodes to appear as a series of root nodes.
``TR_COLUMN_LINES`` 0x1000 Use this style to draw a contrasting border between displayed columns.
``TR_FULL_ROW_HIGHLIGHT`` 0x2000 Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful for checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS`` 0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
``TR_NO_HEADER`` 0x40000 Use this style to hide the columns header.
``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`HyperTreeList` columns is low.
@@ -261,22 +262,25 @@ License And Version
:class:`HyperTreeList` is distributed under the wxPython license.
Latest Revision: Andrea Gavana @ 14 Mar 2012, 21.00 GMT
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
Version 1.3
Version 1.4
"""
import wx
import wx.gizmos
import wx.adv
from customtreectrl import CustomTreeCtrl
from customtreectrl import DragImage, TreeEvent, GenericTreeItem, ChopText
from customtreectrl import TreeEditTimer as TreeListEditTimer
from customtreectrl import EVT_TREE_ITEM_CHECKING, EVT_TREE_ITEM_CHECKED, EVT_TREE_ITEM_HYPERLINK
# Python 2/3 compatibility helper
import wx.lib.wx2to3 as wx2to3
# Version Info
__version__ = "1.3"
__version__ = "1.4"
# --------------------------------------------------------------------------
# Constants
@@ -322,12 +326,14 @@ TR_SINGLE = wx.TR_SINGLE # for convenience
""" For convenience to document that only one item may be selected at a time. Selecting another item causes the current selection, if any, to be deselected. This is the default. """
TR_MULTIPLE = wx.TR_MULTIPLE # can select multiple items
""" Use this style to allow a range of items to be selected. If a second range is selected, the current range, if any, is deselected. """
TR_EXTENDED = wx.TR_EXTENDED # TODO: allow extended selection
TR_EXTENDED = 0x40 # TODO: allow extended selection
""" Use this style to allow disjoint items to be selected. (Only partially implemented; may not work in all cases). """
TR_HAS_VARIABLE_ROW_HEIGHT = wx.TR_HAS_VARIABLE_ROW_HEIGHT # what it says
""" Use this style to cause row heights to be just big enough to fit the content. If not set, all rows use the largest row height. The default is that this flag is unset. """
TR_EDIT_LABELS = wx.TR_EDIT_LABELS # can edit item labels
""" Use this style if you wish the user to be able to edit labels in the tree control. """
TR_COLUMN_LINES = 0x1000 # put column border around items
""" Use this style to draw a contrasting border between displayed columns. """
TR_ROW_LINES = wx.TR_ROW_LINES # put border around items
""" Use this style to draw a contrasting border between displayed rows. """
TR_HIDE_ROOT = wx.TR_HIDE_ROOT # don't display root node
@@ -336,11 +342,11 @@ TR_FULL_ROW_HIGHLIGHT = wx.TR_FULL_ROW_HIGHLIGHT # highlight full
""" Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window. """
TR_AUTO_CHECK_CHILD = 0x04000 # only meaningful for checkboxes
""" Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well. """
""" Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well. """
TR_AUTO_TOGGLE_CHILD = 0x08000 # only meaningful for checkboxes
""" Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly. """
""" Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly. """
TR_AUTO_CHECK_PARENT = 0x10000 # only meaningful for checkboxes
""" Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well. """
""" Only meaningful for checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well. """
TR_ALIGN_WINDOWS = 0x20000 # to align windows horizontally for items at the same level
""" Flag used to align windows (in items with windows) at the same horizontal position. """
TR_ELLIPSIZE_LONG_ITEMS = 0x80000 # to ellipsize long items when horizontal space is low
@@ -409,9 +415,9 @@ class TreeListColumnInfo(object):
self._selected_image = -1
self._shown = shown
self._edit = edit
self._font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
self._font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
if colour is None:
self._colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self._colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
else:
self._colour = colour
@@ -613,8 +619,8 @@ class TreeListHeaderWindow(wx.Window):
wx.Window.__init__(self, parent, id, pos, size, style, name=name)
self._owner = owner
self._currentCursor = wx.StockCursor(wx.CURSOR_DEFAULT)
self._resizeCursor = wx.StockCursor(wx.CURSOR_SIZEWE)
self._currentCursor = wx.Cursor(wx.CURSOR_DEFAULT)
self._resizeCursor = wx.Cursor(wx.CURSOR_SIZEWE)
self._isDragging = False
self._dirty = False
self._total_col_width = 0
@@ -832,7 +838,7 @@ class TreeListHeaderWindow(wx.Window):
numColumns = self.GetColumnCount()
for i in xrange(numColumns):
for i in range(numColumns):
if x >= w:
break
@@ -925,7 +931,7 @@ class TreeListHeaderWindow(wx.Window):
colLeft = 0
numColumns = self.GetColumnCount()
for col in xrange(numColumns):
for col in range(numColumns):
if not self.IsColumnShown(col):
continue
@@ -1038,7 +1044,7 @@ class TreeListHeaderWindow(wx.Window):
# find the column where this event occured
countCol = self.GetColumnCount()
for column in xrange(countCol):
for column in range(countCol):
if not self.IsColumnShown(column):
continue # do next if not shown
@@ -1394,7 +1400,7 @@ class TreeListItem(GenericTreeItem):
maincol = theCtrl.GetMainColumn()
# check for above/below middle
y_mid = self._y + h/2
y_mid = self._y + h//2
if point.y < y_mid:
flags |= wx.TREE_HITTEST_ONITEMUPPERPART
else:
@@ -1448,7 +1454,7 @@ class TreeListItem(GenericTreeItem):
# check for right of label
end = 0
for i in xrange(maincol):
for i in range(maincol):
end += header_win.GetColumnWidth(i)
if ((point.x > (self._text_x + self._width)) and (point.x <= end)):
flags |= wx.TREE_HITTEST_ONITEMRIGHT
@@ -1457,7 +1463,7 @@ class TreeListItem(GenericTreeItem):
# else check for each column except main
x = 0
for j in xrange(theCtrl.GetColumnCount()):
for j in range(theCtrl.GetColumnCount()):
if not header_win.IsColumnShown(j):
continue
w = header_win.GetColumnWidth(j)
@@ -1801,7 +1807,7 @@ class EditCtrl(object):
if column > 0:
x = 0
for i in xrange(column):
for i in range(column):
if not self._owner.GetParent()._header_win.IsColumnShown(i):
continue # do next column if not shown
@@ -2041,9 +2047,9 @@ class TreeListMainWindow(CustomTreeCtrl):
``TR_ROW_LINES`` 0x400 Use this style to draw a contrasting border between displayed rows.
``TR_HIDE_ROOT`` 0x800 Use this style to suppress the display of the root node, effectively causing the first-level nodes to appear as a series of root nodes.
``TR_FULL_ROW_HIGHLIGHT`` 0x2000 Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful for checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS`` 0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
``TR_NO_HEADER`` 0x40000 Use this style to hide the columns header.
``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`~lib.agw.customtreectrl.CustomTreeCtrl` is low.
@@ -2536,7 +2542,7 @@ class TreeListMainWindow(CustomTreeCtrl):
for child in self._itemWithWindow:
if not self.IsItemVisible(child):
for column in xrange(self.GetColumnCount()):
for column in range(self.GetColumnCount()):
wnd = child.GetWindow(column)
if wnd and wnd.IsShown():
wnd.Hide()
@@ -2559,7 +2565,7 @@ class TreeListMainWindow(CustomTreeCtrl):
item.Enable(enable)
for column in xrange(self.GetColumnCount()):
for column in range(self.GetColumnCount()):
wnd = item.GetWindow(column)
# Handles the eventual window associated to the item
@@ -2641,14 +2647,14 @@ class TreeListMainWindow(CustomTreeCtrl):
if item._y < start_y+3:
# going down, item should appear at top
self.SetScrollbars(xUnit, yUnit, (xUnit and [x/xUnit] or [0])[0], (yUnit and [y/yUnit] or [0])[0],
x_pos, (yUnit and [item._y/yUnit] or [0])[0])
self.SetScrollbars(xUnit, yUnit, (xUnit and [x//xUnit] or [0])[0], (yUnit and [y//yUnit] or [0])[0],
x_pos, (yUnit and [item._y//yUnit] or [0])[0])
elif item._y+self.GetLineHeight(item) > start_y+client_h:
# going up, item should appear at bottom
item._y += yUnit + 2
self.SetScrollbars(xUnit, yUnit, (xUnit and [x/xUnit] or [0])[0], (yUnit and [y/yUnit] or [0])[0],
x_pos, (yUnit and [(item._y+self.GetLineHeight(item)-client_h)/yUnit] or [0])[0])
self.SetScrollbars(xUnit, yUnit, (xUnit and [x//xUnit] or [0])[0], (yUnit and [y//yUnit] or [0])[0],
x_pos, (yUnit and [(item._y+self.GetLineHeight(item)-client_h)//yUnit] or [0])[0])
def SetDragItem(self, item):
@@ -2688,7 +2694,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if x < self.GetClientSize().GetWidth():
x_pos = 0
self.SetScrollbars(xUnit, yUnit, x/xUnit, y/yUnit, x_pos, y_pos)
self.SetScrollbars(xUnit, yUnit, x//xUnit, y//yUnit, x_pos, y_pos)
else:
self.SetScrollbars(0, 0, 0, 0)
@@ -2718,7 +2724,7 @@ class TreeListMainWindow(CustomTreeCtrl):
w, h = dc.GetTextExtent(t)
plus = textrect.Width - w
if alignment == wx.ALIGN_CENTER:
plus /= 2
plus //= 2
dc.DrawLabel(t, wx.Rect(textrect.X + plus, yorigin, w, yorigin+h))
yorigin += h
return
@@ -2741,9 +2747,9 @@ class TreeListMainWindow(CustomTreeCtrl):
if item.IsSelected():
if (wx.Platform == "__WXMAC__" and self._hasFocus):
colTextHilight = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
colTextHilight = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
else:
colTextHilight = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
colTextHilight = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
else:
attr = item.GetAttributes()
@@ -2755,11 +2761,11 @@ class TreeListMainWindow(CustomTreeCtrl):
total_w = self._owner.GetHeaderWindow().GetWidth()
total_h = self.GetLineHeight(item)
off_h = (self.HasAGWFlag(wx.TR_ROW_LINES) and [1] or [0])[0]
off_w = (self.HasAGWFlag(wx.TR_COLUMN_LINES) and [1] or [0])[0]
off_h = (self.HasAGWFlag(TR_ROW_LINES) and [1] or [0])[0]
off_w = (self.HasAGWFlag(TR_COLUMN_LINES) and [1] or [0])[0]
## clipper = wx.DCClipper(dc, 0, item.GetY(), total_w, total_h) # only within line
text_w, text_h, dummy = dc.GetMultiLineTextExtent(item.GetText(self.GetMainColumn()))
text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(item.GetText(self.GetMainColumn()))
drawItemBackground = False
# determine background and show it
@@ -2769,7 +2775,7 @@ class TreeListMainWindow(CustomTreeCtrl):
else:
colBg = self._backgroundColour
dc.SetBrush(wx.Brush(colBg, wx.SOLID))
dc.SetBrush(wx.Brush(colBg))
dc.SetPen(wx.TRANSPARENT_PEN)
if self.HasAGWFlag(wx.TR_FULL_ROW_HIGHLIGHT):
@@ -2807,7 +2813,7 @@ class TreeListMainWindow(CustomTreeCtrl):
else:
dc.SetBrush((self._hasFocus and [self._hilightBrush] or [self._hilightUnfocusedBrush])[0])
dc.SetPen((self._hasFocus and [self._borderPen] or [wx.TRANSPARENT_PEN])[0])
dc.DrawRectangleRect(itemrect)
dc.DrawRectangle(itemrect)
dc.SetTextForeground(colTextHilight)
@@ -2817,8 +2823,8 @@ class TreeListMainWindow(CustomTreeCtrl):
elif drawItemBackground:
itemrect = wx.Rect(0, item.GetY() + off_h, total_w-1, total_h - off_h)
dc.SetBrush(wx.Brush(colBg, wx.SOLID))
dc.DrawRectangleRect(itemrect)
dc.SetBrush(wx.Brush(colBg))
dc.DrawRectangle(itemrect)
dc.SetTextForeground(colText)
else:
@@ -2828,11 +2834,11 @@ class TreeListMainWindow(CustomTreeCtrl):
dc.SetTextForeground(colText)
text_extraH = (total_h > text_h and [(total_h - text_h)/2] or [0])[0]
img_extraH = (total_h > self._imgHeight and [(total_h-self._imgHeight)/2] or [0])[0]
text_extraH = (total_h > text_h and [(total_h - text_h)//2] or [0])[0]
img_extraH = (total_h > self._imgHeight and [(total_h-self._imgHeight)//2] or [0])[0]
x_colstart = 0
for i in xrange(self.GetColumnCount()):
for i in range(self.GetColumnCount()):
if not self._owner.GetHeaderWindow().IsColumnShown(i):
continue
@@ -2847,7 +2853,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self.HasButtons():
x += (self._btnWidth-self._btnWidth2) + _LINEATROOT
else:
x -= self._indent/2
x -= self._indent//2
if self._imageListNormal:
image = item.GetCurrentImage(i)
@@ -2869,14 +2875,14 @@ class TreeListMainWindow(CustomTreeCtrl):
text = item.GetText(i)
alignment = self._owner.GetHeaderWindow().GetColumn(i).GetAlignment()
text_w, dummy, dummy = dc.GetMultiLineTextExtent(text)
text_w, dummy, dummy = dc.GetFullMultiLineTextExtent(text)
if alignment == wx.ALIGN_RIGHT:
w = col_w - (image_w + wcheck + text_w + off_w + _MARGIN + 1)
x += (w > 0 and [w] or [0])[0]
elif alignment == wx.ALIGN_CENTER:
w = (col_w - (image_w + wcheck + text_w + off_w + _MARGIN))/2
w = (col_w - (image_w + wcheck + text_w + off_w + _MARGIN))//2
x += (w > 0 and [w] or [0])[0]
else:
if image_w == 0 and wcheck:
@@ -2914,7 +2920,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED
wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, itemrect, flags)
else:
dc.DrawRectangleRect(itemrect)
dc.DrawRectangle(itemrect)
dc.SetTextForeground(colTextHilight)
@@ -2927,8 +2933,8 @@ class TreeListMainWindow(CustomTreeCtrl):
elif drawItemBackground:
itemrect = wx.Rect(text_x-2, item.GetY() + off_h, text_w+2*_MARGIN, total_h - off_h)
dc.SetBrush(wx.Brush(colBg, wx.SOLID))
dc.DrawRectangleRect(itemrect)
dc.SetBrush(wx.Brush(colBg))
dc.DrawRectangle(itemrect)
else:
dc.SetTextForeground(colText)
@@ -2936,8 +2942,8 @@ class TreeListMainWindow(CustomTreeCtrl):
else:
dc.SetTextForeground(colText)
if self.HasAGWFlag(wx.TR_COLUMN_LINES): # vertical lines between columns
pen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.SOLID)
if self.HasAGWFlag(TR_COLUMN_LINES): # vertical lines between columns
pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.SOLID)
dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0])
dc.DrawLine(x_colstart+col_w-1, item.GetY(), x_colstart+col_w-1, item.GetY()+total_h)
@@ -2968,11 +2974,11 @@ class TreeListMainWindow(CustomTreeCtrl):
imglist.Draw(checkimage, dc,
item.GetX() + btnWidth + _MARGIN,
item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)/2] or [0])[0]+1,
item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)//2] or [0])[0]+1,
wx.IMAGELIST_DRAW_TRANSPARENT)
text_w, text_h, dummy = dc.GetMultiLineTextExtent(text)
text_extraH = (total_h > text_h and [(total_h - text_h)/2] or [0])[0]
text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(text)
text_extraH = (total_h > text_h and [(total_h - text_h)//2] or [0])[0]
text_y = item.GetY() + text_extraH
textrect = wx.Rect(text_x, text_y, text_w, text_h)
@@ -3000,10 +3006,10 @@ class TreeListMainWindow(CustomTreeCtrl):
wndx = text_x
else:
wndx = text_x + text_w + 2*_MARGIN
xa, ya = self.CalcScrolledPosition((0, item.GetY()))
xa, ya = self.CalcScrolledPosition(0, item.GetY())
wndx += xa
if item.GetHeight() > item.GetWindowSize(i)[1]:
ya += (item.GetHeight() - item.GetWindowSize(i)[1])/2
ya += (item.GetHeight() - item.GetWindowSize(i)[1])//2
if not wnd.IsShown():
wnd.Show()
@@ -3049,7 +3055,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self.HasButtons():
x += (self._btnWidth-self._btnWidth2) # half button space
else:
x += (self._indent-self._indent/2)
x += (self._indent-self._indent//2)
if self.HasAGWFlag(wx.TR_HIDE_ROOT):
x += self._indent*(level-1) # indent but not level 1
@@ -3062,21 +3068,21 @@ class TreeListMainWindow(CustomTreeCtrl):
h = self.GetLineHeight(item)
y_top = y
y_mid = y_top + (h/2)
y_mid = y_top + (h//2)
y += h
exposed_x = dc.LogicalToDeviceX(0)
exposed_y = dc.LogicalToDeviceY(y_top)
# horizontal lines between rows?
draw_row_lines = self.HasAGWFlag(wx.TR_ROW_LINES)
draw_row_lines = self.HasAGWFlag(TR_ROW_LINES)
if self.IsExposed(exposed_x, exposed_y, _MAX_WIDTH, h + draw_row_lines):
if draw_row_lines:
total_width = self._owner.GetHeaderWindow().GetWidth()
# if the background colour is white, choose a
# contrasting colour for the lines
pen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.SOLID)
pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.SOLID)
dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0])
dc.DrawLine(0, y_top, total_width, y_top)
dc.DrawLine(0, y_top+h, total_width, y_top+h)
@@ -3107,7 +3113,7 @@ class TreeListMainWindow(CustomTreeCtrl):
else:
dc.DrawLine(x2, y_mid, x3 + _LINEATROOT, y_mid)
else:
dc.DrawLine(x2, y_mid, x - self._indent/2, y_mid)
dc.DrawLine(x2, y_mid, x - self._indent//2, y_mid)
if item.HasPlus() and self.HasButtons(): # should the item show a button?
@@ -3130,16 +3136,16 @@ class TreeListMainWindow(CustomTreeCtrl):
# draw the twisty button here
dc.SetPen(wx.BLACK_PEN)
dc.SetBrush(self._hilightBrush)
button = [wx.Point() for j in xrange(3)]
button = [wx.Point() for j in range(3)]
if item.IsExpanded():
button[0].x = x - (self._btnWidth2+1)
button[0].y = y_mid - (self._btnHeight/3)
button[0].y = y_mid - (self._btnHeight//3)
button[1].x = x + (self._btnWidth2+1)
button[1].y = button[0].y
button[2].x = x
button[2].y = button[0].y + (self._btnHeight2+1)
else:
button[0].x = x - (self._btnWidth/3)
button[0].x = x - (self._btnWidth//3)
button[0].y = y_mid - (self._btnHeight2+1)
button[1].x = button[0].x
button[1].y = y_mid + (self._btnHeight2+1)
@@ -3167,7 +3173,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self._imgWidth > 0:
oldY = y_mid + self._imgHeight2
else:
oldY = y_mid + h/2
oldY = y_mid + h//2
for child in item.GetChildren():
@@ -3175,7 +3181,7 @@ class TreeListMainWindow(CustomTreeCtrl):
# draw vertical line
if not self.HasAGWFlag(wx.TR_NO_LINES):
Y1 = child.GetY() + child.GetHeight()/2
Y1 = child.GetY() + child.GetHeight()//2
dc.DrawLine(x, oldY, x, Y1)
return y, x_maincol
@@ -3209,7 +3215,7 @@ class TreeListMainWindow(CustomTreeCtrl):
# paint the background
dc = wx.BufferedPaintDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.SetClippingRegion(rect)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
if self._backgroundImage:
self.TileBackground(dc)
@@ -3231,21 +3237,21 @@ class TreeListMainWindow(CustomTreeCtrl):
self._btnWidth = _BTNWIDTH
self._btnHeight = _BTNHEIGHT
self._btnWidth2 = self._btnWidth/2
self._btnHeight2 = self._btnHeight/2
self._btnWidth2 = self._btnWidth//2
self._btnHeight2 = self._btnHeight//2
# calculate image size
if self._imageListNormal:
self._imgWidth, self._imgHeight = self._imageListNormal.GetSize(0)
self._imgWidth2 = self._imgWidth/2
self._imgHeight2 = self._imgHeight/2
self._imgWidth2 = self._imgWidth//2
self._imgHeight2 = self._imgHeight//2
if self._imageListCheck:
self._checkWidth, self._checkHeight = self._imageListCheck.GetSize(0)
self._checkWidth2 = self._checkWidth/2
self._checkHeight2 = self._checkHeight/2
self._checkWidth2 = self._checkWidth//2
self._checkHeight2 = self._checkHeight//2
# calculate indent size
if self._imageListButtons:
@@ -3259,7 +3265,7 @@ class TreeListMainWindow(CustomTreeCtrl):
# calculate column start and paint
x_maincol = 0
for i in xrange(self.GetMainColumn()):
for i in range(self.GetMainColumn()):
if not self._owner.GetHeaderWindow().IsColumnShown(i):
continue
x_maincol += self._owner.GetHeaderWindow().GetColumnWidth(i)
@@ -3320,7 +3326,8 @@ class TreeListMainWindow(CustomTreeCtrl):
column = -1
return None, flags, column
hit, flags, column = self._anchor.HitTest(self.CalcUnscrolledPosition(point), self, flags, column, 0)
pt = wx.Point(self.CalcUnscrolledPosition(point.x, point.y))
hit, flags, column = self._anchor.HitTest(pt, self, flags, column, 0)
if not hit:
flags = wx.TREE_HITTEST_NOWHERE
column = -1
@@ -3398,7 +3405,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self._curColumn == -1:
self._curColumn = 0
self.SetItemText(self._editItem, unicode(value), self._curColumn)
self.SetItemText(self._editItem, wx2to3.text_type(value), self._curColumn)
def OnCancelEdit(self):
@@ -3445,7 +3452,8 @@ class TreeListMainWindow(CustomTreeCtrl):
# determine event
p = wx.Point(event.GetX(), event.GetY())
flags = 0
item, flags, column = self._anchor.HitTest(self.CalcUnscrolledPosition(p), self, flags, self._curColumn, 0)
pt = wx.Point(self.CalcUnscrolledPosition(p.x, p.y))
item, flags, column = self._anchor.HitTest(pt, self, flags, self._curColumn, 0)
underMouse = item
underMouseChanged = underMouse != self._underMouse
@@ -3484,11 +3492,11 @@ class TreeListMainWindow(CustomTreeCtrl):
self.SetToolTip(hevent._label)
if hoverItem.IsHyperText() and (flags & wx.TREE_HITTEST_ONITEMLABEL) and hoverItem.IsEnabled():
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
self.SetCursor(wx.Cursor(wx.CURSOR_HAND))
self._isonhyperlink = True
else:
if self._isonhyperlink:
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
self._isonhyperlink = False
# we only process dragging here
@@ -3766,8 +3774,8 @@ class TreeListMainWindow(CustomTreeCtrl):
dc.SetFont(self._normalFont)
text_w = text_h = wnd_w = wnd_h = 0
for column in xrange(self.GetColumnCount()):
w, h, dummy = dc.GetMultiLineTextExtent(item.GetText(column))
for column in range(self.GetColumnCount()):
w, h, dummy = dc.GetFullMultiLineTextExtent(item.GetText(column))
text_w, text_h = max(w, text_w), max(h, text_h)
wnd = item.GetWindow(column)
@@ -3776,7 +3784,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if column == self._main_column:
wnd_w = item.GetWindowSize(column)[0]
text_w, dummy, dummy = dc.GetMultiLineTextExtent(item.GetText(self._main_column))
text_w, dummy, dummy = dc.GetFullMultiLineTextExtent(item.GetText(self._main_column))
text_h+=2
# restore normal font
@@ -3804,7 +3812,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if total_h < 30:
total_h += 2 # at least 2 pixels
else:
total_h += total_h/10 # otherwise 10% extra spacing
total_h += total_h//10 # otherwise 10% extra spacing
if total_h > self._lineHeight:
self._lineHeight = max(total_h, wnd_h+2)
@@ -3831,7 +3839,7 @@ class TreeListMainWindow(CustomTreeCtrl):
if self.HasButtons():
x += (self._btnWidth-self._btnWidth2) # half button space
else:
x += (self._indent-self._indent/2)
x += (self._indent-self._indent//2)
if self.HasAGWFlag(wx.TR_HIDE_ROOT):
x += self._indent * (level-1) # indent but not level 1
@@ -3845,7 +3853,7 @@ class TreeListMainWindow(CustomTreeCtrl):
children = item.GetChildren()
count = len(children)
level = level + 1
for n in xrange(count):
for n in range(count):
y = self.CalculateLevel(children[n], dc, level, y, x_colstart) # recurse
return y
@@ -3864,7 +3872,7 @@ class TreeListMainWindow(CustomTreeCtrl):
children = item.GetChildren()
count = len(children)
level = level + 1
for n in xrange(count):
for n in range(count):
y = self.CalculateLevel(children[n], dc, level, y, x_colstart) # recurse
return y
@@ -3883,7 +3891,7 @@ class TreeListMainWindow(CustomTreeCtrl):
dc.SetPen(self._dottedPen)
y, x_colstart = 2, 0
for i in xrange(self.GetMainColumn()):
for i in range(self.GetMainColumn()):
if not self._owner.GetHeaderWindow().IsColumnShown(i):
continue
x_colstart += self._owner.GetHeaderWindow().GetColumnWidth(i)
@@ -3947,7 +3955,7 @@ class TreeListMainWindow(CustomTreeCtrl):
dc = wx.ClientDC(self)
dc.SetFont(font)
w, h, dummy = dc.GetMultiLineTextExtent(item.GetText(column))
w, h, dummy = dc.GetFullMultiLineTextExtent(item.GetText(column))
w += 2*_MARGIN
# calculate width
@@ -4073,9 +4081,9 @@ _methods = ["GetIndent", "SetIndent", "GetSpacing", "SetSpacing", "GetImageList"
"SetItem3State", "SetItem3StateValue", "GetItem3StateValue", "IsItem3State", "GetPrev"]
class HyperTreeList(wx.PyControl):
class HyperTreeList(wx.Control):
"""
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`gizmos.TreeListCtrl`, with
:class:`HyperTreeList` is a class that mimics the behaviour of :class:`adv.TreeListCtrl`, with
almost the same base functionalities plus some more enhancements. This class does
not rely on the native control, as it is a full owner-drawn tree-list control.
"""
@@ -4114,9 +4122,9 @@ class HyperTreeList(wx.PyControl):
``TR_HIDE_ROOT`` 0x800 Use this style to suppress the display of the root node, effectively causing the first-level nodes to appear as a series of root nodes.
``TR_COLUMN_LINES`` 0x1000 Use this style to draw a contrasting border between displayed columns.
``TR_FULL_ROW_HIGHLIGHT`` 0x2000 Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful for checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS`` 0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
``TR_NO_HEADER`` 0x40000 Use this style to hide the columns header.
``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`~lib.agw.customtreectrl.CustomTreeCtrl` is low.
@@ -4127,7 +4135,7 @@ class HyperTreeList(wx.PyControl):
:param `name`: window name.
"""
wx.PyControl.__init__(self, parent, id, pos, size, style, validator, name)
wx.Control.__init__(self, parent, id, pos, size, style, validator, name)
self._header_win = None
self._main_win = None
@@ -4184,15 +4192,15 @@ class HyperTreeList(wx.PyControl):
has_header = self._agwStyle & TR_NO_HEADER == 0
if self._header_win and has_header:
self._header_win.SetDimensions(0, 0, w, self._headerHeight)
self._header_win.SetSize(0, 0, w, self._headerHeight)
self._header_win.Refresh()
else:
self._header_win.SetDimensions(0, 0, 0, 0)
self._header_win.SetSize(0, 0, 0, 0)
if self._main_win and has_header:
self._main_win.SetDimensions(0, self._headerHeight + 1, w, h - self._headerHeight - 1)
self._main_win.SetSize(0, self._headerHeight + 1, w, h - self._headerHeight - 1)
else:
self._main_win.SetDimensions(0, 0, w, h)
self._main_win.SetSize(0, 0, w, h)
def OnSize(self, event):
@@ -4233,7 +4241,7 @@ class HyperTreeList(wx.PyControl):
if not self._header_win:
return
for column in xrange(self.GetColumnCount()):
for column in range(self.GetColumnCount()):
self._header_win.SetColumn(column, self.GetColumn(column).SetFont(font))
self._header_win.Refresh()
@@ -4275,9 +4283,9 @@ class HyperTreeList(wx.PyControl):
``TR_HIDE_ROOT`` 0x800 Use this style to suppress the display of the root node, effectively causing the first-level nodes to appear as a series of root nodes.
``TR_COLUMN_LINES`` 0x1000 Use this style to draw a contrasting border between displayed columns.
``TR_FULL_ROW_HIGHLIGHT`` 0x2000 Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_AUTO_CHECK_CHILD`` 0x4000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are checked/unchecked as well.
``TR_AUTO_TOGGLE_CHILD`` 0x8000 Only meaningful for checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT`` 0x10000 Only meaningful for checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS`` 0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
``TR_NO_HEADER`` 0x40000 Use this style to hide the columns header.
``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`~lib.agw.customtreectrl.CustomTreeCtrl` is low.
@@ -4340,7 +4348,7 @@ class HyperTreeList(wx.PyControl):
you may wish to call :meth:`Window.ClearBackground` or :meth:`Window.Refresh` after
calling this function.
:note: Overridden from :class:`PyControl`.
:note: Overridden from :class:`Control`.
"""
if not self._main_win:
@@ -4356,7 +4364,7 @@ class HyperTreeList(wx.PyControl):
:param `colour`: the colour to be used as the foreground colour, pass
:class:`NullColour` to reset to the default colour.
:note: Overridden from :class:`PyControl`.
:note: Overridden from :class:`Control`.
"""
if not self._main_win:
@@ -4377,7 +4385,7 @@ class HyperTreeList(wx.PyControl):
font = self._header_win.GetFont()
dc = wx.ClientDC(self._header_win)
width, dummy, dummy = dc.GetMultiLineTextExtent(self._header_win.GetColumnText(column))
width, dummy, dummy = dc.GetFullMultiLineTextExtent(self._header_win.GetColumnText(column))
# Search TreeListHeaderWindow.OnPaint to understand this:
width += 2*_EXTRA_WIDTH + _MARGIN
@@ -4672,7 +4680,7 @@ class HyperTreeList(wx.PyControl):
event loop iteration, if you need to update the window immediately you should
use `Update` instead.
:note: Overridden from :class:`PyControl`.
:note: Overridden from :class:`Control`.
"""
self._main_win.Refresh(erase, rect)
@@ -4703,7 +4711,7 @@ class HyperTreeList(wx.PyControl):
minimal size which doesn't truncate the control, for a panel - the same size
as it would have after a call to `Fit()`.
:note: Overridden from :class:`PyControl`.
:note: Overridden from :class:`Control`.
"""
# something is better than nothing...
@@ -4827,9 +4835,9 @@ class HyperTreeList(wx.PyControl):
"""
attr = wx.VisualAttributes()
attr.colFg = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
attr.colBg = wx.SystemSettings_GetColour(wx.SYS_COLOUR_LISTBOX)
attr.font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
attr.colFg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
attr.colBg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_LISTBOX)
attr.font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
return attr
GetClassDefaultAttributes = classmethod(GetClassDefaultAttributes)
@@ -4851,3 +4859,37 @@ def create_delegator_for(method):
for method in _methods:
setattr(HyperTreeList, method, create_delegator_for(method))
if __name__ == '__main__':
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "HyperTreeList Demo")
tree_list = HyperTreeList(self)
tree_list.AddColumn("First column")
root = tree_list.AddRoot("Root", ct_type=1)
parent = tree_list.AppendItem(root, "First child", ct_type=1)
child = tree_list.AppendItem(parent, "First Grandchild", ct_type=1)
tree_list.AppendItem(root, "Second child", ct_type=1)
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

View File

@@ -9,6 +9,7 @@
# RCS-ID: $Id$
# Copyright: (c) 1999 by Total Control Software
# Licence: wxWindows license
# Tags: phoenix-port, unittest, documented
#----------------------------------------------------------------------
# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
@@ -18,9 +19,44 @@
"""
This module implements various forms of generic buttons, meaning that
they are not built on native controls but are self-drawn. They act
like normal buttons but you are able to better control how they look,
bevel width, colours, etc.
they are not built on native controls but are self-drawn.
Description
===========
This module implements various forms of generic buttons, meaning that
they are not built on native controls but are self-drawn.
They act like normal buttons but you are able to better control how they look,
bevel width, colours, etc...
Usage
=====
Sample usage::
import wx
import wx.lib.buttons as buttons
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, wx.ID_ANY, title, size=(400, 300))
panel = wx.Panel(self)
# Build a bitmap button and a normal one
bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (16, 16))
btn1 = buttons.ThemedGenBitmapButton(panel, -1, bmp, pos=(50, 50))
btn2 = buttons.GenButton(panel, -1, "Hello World!", pos=(50, 100))
app = wx.App()
frame = MyFrame(None, 'wx.lib.buttons Test')
frame.Show()
app.MainLoop()
"""
import wx
@@ -29,30 +65,67 @@ import imageutils
#----------------------------------------------------------------------
class GenButtonEvent(wx.PyCommandEvent):
"""Event sent from the generic buttons when the button is activated. """
class GenButtonEvent(wx.CommandEvent):
""" Event sent from the generic buttons when the button is activated. """
def __init__(self, eventType, id):
wx.PyCommandEvent.__init__(self, eventType, id)
"""
Default class constructor.
:param integer `eventType`: the event type;
:param integer `id`: the event identifier.
"""
wx.CommandEvent.__init__(self, eventType, id)
self.isDown = False
self.theButton = None
def SetIsDown(self, isDown):
"""
Set the button toggle status as 'down' or 'up'.
:param bool `isDown`: ``True`` if the button is clicked, ``False`` otherwise.
"""
self.isDown = isDown
def GetIsDown(self):
"""
Returns the button toggle status as ``True`` if the button is down, ``False``
otherwise.
:rtype: bool
"""
return self.isDown
def SetButtonObj(self, btn):
"""
Sets the event object for the event.
:param `btn`: the button object, an instance of :class:`GenButton`.
"""
self.theButton = btn
def GetButtonObj(self):
"""
Returns the object associated with this event.
:return: An instance of :class:`GenButton`.
"""
return self.theButton
#----------------------------------------------------------------------
class GenButton(wx.PyControl):
"""A generic button, and base class for the other generic buttons."""
class GenButton(wx.Control):
""" A generic button, and base class for the other generic buttons. """
labelDelta = 1
@@ -60,14 +133,35 @@ class GenButton(wx.PyControl):
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = 0, validator = wx.DefaultValidator,
name = "genbutton"):
"""
Default class constructor.
:param Window `parent`: parent window. Must not be ``None``;
:param integer `id`: window identifier. A value of -1 indicates a default value;
:param string `label`: the button text label;
:param `pos`: the control position. A value of (-1, -1) indicates a default position,
chosen by either the windowing system or wxPython, depending on platform;
:type `pos`: tuple or :class:`Point`
:param `size`: the control size. A value of (-1, -1) indicates a default size,
chosen by either the windowing system or wxPython, depending on platform;
:type `size`: tuple or :class:`Size`
:param integer `style`: the button style;
:param Validator `validator`: the validator associated with the button;
:param string `name`: the button name.
.. seealso:: :class:`Button` for a list of valid window styles.
"""
cstyle = style
if cstyle & wx.BORDER_MASK == 0:
cstyle |= wx.BORDER_NONE
wx.PyControl.__init__(self, parent, id, pos, size, cstyle, validator, name)
wx.Control.__init__(self, parent, id, pos, size, cstyle, validator, name)
self.up = True
self.hasFocus = False
self.style = style
if style & wx.BORDER_NONE:
self.bezelWidth = 0
self.useFocusInd = False
@@ -93,12 +187,14 @@ class GenButton(wx.PyControl):
self.Bind(wx.EVT_SIZE, self.OnSize)
self.InitOtherEvents()
def InitOtherEvents(self):
"""
Override in a subclass to initialize any other events that
need to be bound. Added so __init__ doesn't need to be
overriden, which is complicated with multiple inheritance
Override this method in a subclass to initialize any other events that
need to be bound. Added so :meth:`__init__` doesn't need to be
overriden, which is complicated with multiple inheritance.
"""
pass
@@ -106,10 +202,16 @@ class GenButton(wx.PyControl):
"""
Given the current font and bezel width settings, calculate
and set a good size.
:param `size`: an instance of :class:`Size` or ``None``, in which case the wxPython
``DefaultSize`` is used instead.
"""
if size is None:
size = wx.DefaultSize
wx.PyControl.SetInitialSize(self, size)
wx.Control.SetInitialSize(self, size)
SetBestSize = SetInitialSize
@@ -117,7 +219,12 @@ class GenButton(wx.PyControl):
"""
Overridden base class virtual. Determines the best size of the
button based on the label and bezel size.
:return: An instance of :class:`Size`.
.. note:: Overridden from :class:`Control`.
"""
w, h, useMin = self._GetLabelSize()
if self.style & wx.BU_EXACTFIT:
width = w + 2 + 2 * self.bezelWidth + 4 * int(self.useFocusInd)
@@ -132,19 +239,30 @@ class GenButton(wx.PyControl):
height = defSize.height
width = width + self.bezelWidth - 1
height = height + self.bezelWidth - 1
return (width, height)
return wx.Size(width, height)
def AcceptsFocus(self):
"""Overridden base class virtual."""
"""
Can this window be given focus by mouse click?
.. note:: Overridden from :class:`Control`.
"""
return self.IsShown() and self.IsEnabled()
def GetDefaultAttributes(self):
"""
Overridden base class virtual. By default we should use
the same font/colour attributes as the native Button.
the same font/colour attributes as the native :class:`Button`.
:return: an instance of :class:`VisualAttributes`.
.. note:: Overridden from :class:`Control`.
"""
return wx.Button.GetClassDefaultAttributes()
@@ -152,30 +270,65 @@ class GenButton(wx.PyControl):
"""
Overridden base class virtual. Buttons usually don't inherit
the parent's colours.
.. note:: Overridden from :class:`Control`.
"""
return False
def Enable(self, enable=True):
"""
Enables/disables the button.
:param bool `enable`: ``True`` to enable the button, ``False`` to disable it.
.. note:: Overridden from :class:`Control`.
"""
if enable != self.IsEnabled():
wx.PyControl.Enable(self, enable)
wx.Control.Enable(self, enable)
self.Refresh()
def SetBezelWidth(self, width):
"""Set the width of the 3D effect"""
"""
Sets the width of the 3D effect.
:param integer `width`: the 3D border width, in pixels.
"""
self.bezelWidth = width
def GetBezelWidth(self):
"""Return the width of the 3D effect"""
"""
Returns the width of the 3D effect, in pixels.
:rtype: integer
"""
return self.bezelWidth
def SetUseFocusIndicator(self, flag):
"""Specifiy if a focus indicator (dotted line) should be used"""
"""
Specifies if a focus indicator (dotted line) should be used.
:param bool `flag`: ``True`` to draw a focus ring, ``False`` otherwise.
"""
self.useFocusInd = flag
def GetUseFocusIndicator(self):
"""Return focus indicator flag"""
"""
Returns the focus indicator flag, specifying if a focus indicator
(dotted line) is being used.
:rtype: bool
"""
return self.useFocusInd
@@ -184,8 +337,9 @@ class GenButton(wx.PyControl):
Calculate a new set of highlight and shadow colours based on
the background colour. Works okay if the colour is dark...
"""
faceClr = self.GetBackgroundColour()
r, g, b = faceClr.Get()
r, g, b, a = faceClr
fr, fg, fb = min(255,r+32), min(255,g+32), min(255,b+32)
self.faceDnClr = wx.Colour(fr, fg, fb)
sr, sg, sb = max(0,r-32), max(0,g-32), max(0,b-32)
@@ -196,26 +350,62 @@ class GenButton(wx.PyControl):
def SetBackgroundColour(self, colour):
wx.PyControl.SetBackgroundColour(self, colour)
"""
Sets the :class:`GenButton` background colour.
:param `colour`: a valid :class:`Colour` object.
.. note:: Overridden from :class:`Control`.
"""
wx.Control.SetBackgroundColour(self, colour)
self.InitColours()
def SetForegroundColour(self, colour):
wx.PyControl.SetForegroundColour(self, colour)
"""
Sets the :class:`GenButton` foreground colour.
:param `colour`: a valid :class:`Colour` object.
.. note:: Overridden from :class:`Control`.
"""
wx.Control.SetForegroundColour(self, colour)
self.InitColours()
def SetDefault(self):
"""
This sets the :class:`GenButton` to be the default item for the panel or dialog box.
.. note:: Under Windows, only dialog box buttons respond to this function. As normal
under Windows and Motif, pressing return causes the default button to be depressed
when the return key is pressed. See also :meth:`Window.SetFocus` which sets the
keyboard focus for windows and text panel items, and :meth:`TopLevelWindow.SetDefaultItem`.
.. note:: Note that under Motif, calling this function immediately after creation of a button
and before the creation of other buttons will cause misalignment of the row of buttons,
since default buttons are larger. To get around this, call :meth:`SetDefault` after you
have created a row of buttons: wxPython will then set the size of all buttons currently
on the panel to the same size.
"""
tlw = wx.GetTopLevelParent(self)
if hasattr(tlw, 'SetDefaultItem'):
tlw.SetDefaultItem(self)
def _GetLabelSize(self):
""" used internally """
""" Used internally. """
w, h = self.GetTextExtent(self.GetLabel())
return w, h, True
def Notify(self):
""" Actually sends a ``wx.EVT_BUTTON`` event to the listener (if any). """
evt = GenButtonEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
evt.SetIsDown(not self.up)
evt.SetButtonObj(self)
@@ -226,18 +416,18 @@ class GenButton(wx.PyControl):
def DrawBezel(self, dc, x1, y1, x2, y2):
# draw the upper left sides
if self.up:
dc.SetPen(wx.Pen(self.highlightPenClr, 1, wx.SOLID))
dc.SetPen(wx.Pen(self.highlightPenClr, 1))
else:
dc.SetPen(wx.Pen(self.shadowPenClr, 1, wx.SOLID))
dc.SetPen(wx.Pen(self.shadowPenClr, 1))
for i in range(self.bezelWidth):
dc.DrawLine(x1+i, y1, x1+i, y2-i)
dc.DrawLine(x1, y1+i, x2-i, y1+i)
# draw the lower right sides
if self.up:
dc.SetPen(wx.Pen(self.shadowPenClr, 1, wx.SOLID))
dc.SetPen(wx.Pen(self.shadowPenClr, 1))
else:
dc.SetPen(wx.Pen(self.highlightPenClr, 1, wx.SOLID))
dc.SetPen(wx.Pen(self.highlightPenClr, 1))
for i in range(self.bezelWidth):
dc.DrawLine(x1+i, y2-i, x2+1, y2-i)
dc.DrawLine(x2-i, y1+i, x2-i, y2)
@@ -259,7 +449,7 @@ class GenButton(wx.PyControl):
def DrawFocusIndicator(self, dc, w, h):
bw = self.bezelWidth
textClr = self.GetForegroundColour()
focusIndPen = wx.Pen(textClr, 1, wx.USER_DASH)
focusIndPen = wx.Pen(textClr, 1, wx.PENSTYLE_USER_DASH)
focusIndPen.SetDashes([1,1])
focusIndPen.SetCap(wx.CAP_BUTT)
@@ -275,7 +465,13 @@ class GenButton(wx.PyControl):
def OnPaint(self, event):
(width, height) = self.GetClientSizeTuple()
"""
Handles the ``wx.EVT_PAINT`` event for :class:`GenButton`.
:param `event`: a :class:`PaintEvent` event to be processed.
"""
(width, height) = self.GetClientSize()
x1 = y1 = 0
x2 = width-1
y2 = height-1
@@ -293,14 +489,26 @@ class GenButton(wx.PyControl):
def OnSize(self, event):
"""
Handles the ``wx.EVT_SIZE`` event for :class:`GenButton`.
:param `event`: a :class:`SizeEvent` event to be processed.
"""
self.Refresh()
event.Skip()
def GetBackgroundBrush(self, dc):
"""
Returns the current :class:`Brush` to be used to draw the button background.
:param DC `dc`: the device context used to draw the button background.
"""
if self.up:
colBg = self.GetBackgroundColour()
brush = wx.Brush(colBg, wx.SOLID)
brush = wx.Brush(colBg)
if self.style & wx.BORDER_NONE:
myAttr = self.GetDefaultAttributes()
parAttr = self.GetParent().GetDefaultAttributes()
@@ -315,17 +523,24 @@ class GenButton(wx.PyControl):
brush = None
elif myDef and not parDef:
colBg = self.GetParent().GetBackgroundColour()
brush = wx.Brush(colBg, wx.SOLID)
brush = wx.Brush(colBg)
else:
# this line assumes that a pressed button should be hilighted with
# a solid colour even if the background is supposed to be transparent
brush = wx.Brush(self.faceDnClr, wx.SOLID)
brush = wx.Brush(self.faceDnClr)
return brush
def OnLeftDown(self, event):
"""
Handles the ``wx.EVT_LEFT_DOWN`` event for :class:`GenButton`.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled():
return
self.up = False
self.CaptureMouse()
self.SetFocus()
@@ -334,8 +549,15 @@ class GenButton(wx.PyControl):
def OnLeftUp(self, event):
"""
Handles the ``wx.EVT_LEFT_UP`` event for :class:`GenButton`.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled() or not self.HasCapture():
return
if self.HasCapture():
self.ReleaseMouse()
if not self.up: # if the button was down when the mouse was released...
@@ -347,58 +569,113 @@ class GenButton(wx.PyControl):
def OnMotion(self, event):
"""
Handles the ``wx.EVT_MOTION`` event for :class:`GenButton`.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled() or not self.HasCapture():
return
if event.LeftIsDown() and self.HasCapture():
x,y = event.GetPositionTuple()
w,h = self.GetClientSizeTuple()
x,y = event.GetPosition()
w,h = self.GetClientSize()
if self.up and x<w and x>=0 and y<h and y>=0:
self.up = False
self.Refresh()
return
if not self.up and (x<0 or y<0 or x>=w or y>=h):
self.up = True
self.Refresh()
return
event.Skip()
def OnGainFocus(self, event):
"""
Handles the ``wx.EVT_SET_FOCUS`` event for :class:`GenButton`.
:param `event`: a :class:`FocusEvent` event to be processed.
"""
self.hasFocus = True
self.Refresh()
self.Update()
def OnLoseFocus(self, event):
"""
Handles the ``wx.EVT_KILL_FOCUS`` event for :class:`GenButton`.
:param `event`: a :class:`FocusEvent` event to be processed.
"""
self.hasFocus = False
self.Refresh()
self.Update()
def OnKeyDown(self, event):
"""
Handles the ``wx.EVT_KEY_DOWN`` event for :class:`GenButton`.
:param `event`: a :class:`KeyEvent` event to be processed.
"""
if self.hasFocus and event.GetKeyCode() == ord(" "):
self.up = False
self.Refresh()
event.Skip()
def OnKeyUp(self, event):
"""
Handles the ``wx.EVT_KEY_UP`` event for :class:`GenButton`.
:param `event`: a :class:`KeyEvent` event to be processed.
"""
if self.hasFocus and event.GetKeyCode() == ord(" "):
self.up = True
self.Notify()
self.Refresh()
event.Skip()
#----------------------------------------------------------------------
class GenBitmapButton(GenButton):
"""A generic bitmap button."""
""" A generic bitmap button. """
def __init__(self, parent, id=-1, bitmap=wx.NullBitmap,
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = 0, validator = wx.DefaultValidator,
name = "genbutton"):
"""
Default class constructor.
:param Window `parent`: parent window. Must not be ``None``;
:param integer `id`: window identifier. A value of -1 indicates a default value;
:param Bitmap `bitmap`: the button bitmap;
:param `pos`: the control position. A value of (-1, -1) indicates a default position,
chosen by either the windowing system or wxPython, depending on platform;
:type `pos`: tuple or :class:`Point`
:param `size`: the control size. A value of (-1, -1) indicates a default size,
chosen by either the windowing system or wxPython, depending on platform;
:type `size`: tuple or :class:`Size`
:param integer `style`: the button style;
:param Validator `validator`: the validator associated to the button;
:param string `name`: the button name.
.. seealso:: :class:`Button` for a list of valid window styles.
"""
self.bmpDisabled = None
self.bmpFocus = None
self.bmpSelected = None
@@ -407,49 +684,132 @@ class GenBitmapButton(GenButton):
def GetBitmapLabel(self):
"""
Returns the bitmap for the button's normal state.
:rtype: :class:`Bitmap`
.. seealso:: :meth:`SetBitmapLabel`
"""
return self.bmpLabel
def GetBitmapDisabled(self):
"""
Returns the bitmap for the button's disabled state, which may be invalid.
:rtype: :class:`Bitmap`
.. seealso:: :meth:`SetBitmapDisabled`
"""
return self.bmpDisabled
def GetBitmapFocus(self):
"""
Returns the bitmap for the button's focused state, which may be invalid.
:rtype: :class:`Bitmap`
.. seealso:: :meth:`SetBitmapFocus`
"""
return self.bmpFocus
def GetBitmapSelected(self):
"""
Returns the bitmap for the button's pressed state, which may be invalid.
:rtype: :class:`Bitmap`
.. seealso:: :meth:`SetBitmapSelected`
"""
return self.bmpSelected
def SetBitmapDisabled(self, bitmap):
"""Set bitmap to display when the button is disabled"""
"""
Sets the bitmap for the disabled button appearance.
:param Bitmap `bitmap`: the bitmap for the disabled button appearance.
.. seealso::
:meth:`GetBitmapDisabled`, :meth:`SetBitmapLabel`,
:meth:`SetBitmapSelected`, :meth:`SetBitmapFocus`
"""
self.bmpDisabled = bitmap
def SetBitmapFocus(self, bitmap):
"""Set bitmap to display when the button has the focus"""
"""
Sets the bitmap for the focused button appearance.
:param Bitmap `bitmap`: the bitmap for the focused button appearance.
.. seealso::
:meth:`GetBitmapFocus`, :meth:`SetBitmapLabel`,
:meth:`SetBitmapSelected`, :meth:`SetBitmapDisabled`
"""
self.bmpFocus = bitmap
self.SetUseFocusIndicator(False)
def SetBitmapSelected(self, bitmap):
"""Set bitmap to display when the button is selected (pressed down)"""
"""
Sets the bitmap for the selected (depressed) button appearance.
:param Bitmap `bitmap`: the bitmap for the selected (depressed) button appearance.
.. seealso::
:meth:`GetBitmapSelected`, :meth:`SetBitmapLabel`,
:meth:`SetBitmapDisabled`, :meth:`SetBitmapFocus`
"""
self.bmpSelected = bitmap
def SetBitmapLabel(self, bitmap, createOthers=True):
"""
Set the bitmap to display normally.
This is the only one that is required. If
createOthers is True, then the other bitmaps
will be generated on the fly. Currently,
only the disabled bitmap is generated.
This is the only one that is required.
If `createOthers` is ``True`, then the other bitmaps will be generated
on the fly. Currently, only the disabled bitmap is generated.
:param Bitmap `bitmap`: the bitmap for the normal button appearance.
.. note:: This is the bitmap used for the unselected state, and for all other
states if no other bitmaps are provided.
"""
self.bmpLabel = bitmap
if bitmap is not None and createOthers:
image = wx.ImageFromBitmap(bitmap)
image = bitmap.ConvertToImage()
imageutils.grayOut(image)
self.SetBitmapDisabled(wx.BitmapFromImage(image))
self.SetBitmapDisabled(wx.Bitmap(image))
def _GetLabelSize(self):
""" used internally """
""" Used internally. """
if not self.bmpLabel:
return -1, -1, False
return self.bmpLabel.GetWidth()+2, self.bmpLabel.GetHeight()+2, False
def DrawLabel(self, dc, width, height, dx=0, dy=0):
bmp = self.bmpLabel
if self.bmpDisabled and not self.IsEnabled():
@@ -469,17 +829,39 @@ class GenBitmapButton(GenButton):
class GenBitmapTextButton(GenBitmapButton):
"""A generic bitmapped button with text label"""
""" A generic bitmapped button with text label. """
def __init__(self, parent, id=-1, bitmap=wx.NullBitmap, label='',
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = 0, validator = wx.DefaultValidator,
name = "genbutton"):
"""
Default class constructor.
:param Window `parent`: parent window. Must not be ``None``;
:param integer `id`: window identifier. A value of -1 indicates a default value;
:param Bitmap `bitmap`: the button bitmap;
:param string `label`: the button text label;
:param `pos`: the control position. A value of (-1, -1) indicates a default position,
chosen by either the windowing system or wxPython, depending on platform;
:type `pos`: tuple or :class:`Point`
:param `size`: the control size. A value of (-1, -1) indicates a default size,
chosen by either the windowing system or wxPython, depending on platform;
:type `size`: tuple or :class:`Size`
:param integer `style`: the button style;
:param Validator `validator`: the validator associated to the button;
:param string `name`: the button name.
.. seealso:: :class:`Button` for a list of valid window styles.
"""
GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style, validator, name)
self.SetLabel(label)
def _GetLabelSize(self):
""" used internally """
""" Used internally. """
w, h = self.GetTextExtent(self.GetLabel())
if not self.bmpLabel:
return w, h, True # if there isn't a bitmap use the size of the text
@@ -532,54 +914,114 @@ class GenBitmapTextButton(GenBitmapButton):
#----------------------------------------------------------------------
class __ToggleMixin:
class __ToggleMixin(object):
"""
A mixin that allows to transform :class:`GenButton` in the corresponding toggle button.
"""
def SetToggle(self, flag):
"""
Sets the button as toggled/not toggled.
:param bool `flag`: ``True`` to set the button as toggled, ``False`` otherwise.
"""
self.up = not flag
self.Refresh()
SetValue = SetToggle
def GetToggle(self):
"""
Returns the toggled state of a button.
:return: ``True`` is the button is toggled, ``False`` if it is not toggled.
"""
return not self.up
GetValue = GetToggle
def OnLeftDown(self, event):
"""
Handles the ``wx.EVT_LEFT_DOWN`` event for :class:`GenButton` when used as toggle button.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled():
return
self.saveUp = self.up
self.up = not self.up
self.CaptureMouse()
self.SetFocus()
self.Refresh()
def OnLeftUp(self, event):
"""
Handles the ``wx.EVT_LEFT_UP`` event for :class:`GenButton` when used as toggle button.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled() or not self.HasCapture():
return
if self.HasCapture():
self.ReleaseMouse()
self.Refresh()
if self.up != self.saveUp:
self.Notify()
def OnKeyDown(self, event):
"""
Handles the ``wx.EVT_KEY_DOWN`` event for :class:`GenButton` when used as toggle button.
:param `event`: a :class:`KeyEvent` event to be processed.
"""
event.Skip()
def OnMotion(self, event):
"""
Handles the ``wx.EVT_MOTION`` event for :class:`GenButton` when used as toggle button.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
if not self.IsEnabled():
return
if event.LeftIsDown() and self.HasCapture():
x,y = event.GetPositionTuple()
w,h = self.GetClientSizeTuple()
x,y = event.GetPosition()
w,h = self.GetClientSize()
if x<w and x>=0 and y<h and y>=0:
self.up = not self.saveUp
self.Refresh()
return
if (x<0 or y<0 or x>=w or y>=h):
self.up = self.saveUp
self.Refresh()
return
event.Skip()
def OnKeyUp(self, event):
"""
Handles the ``wx.EVT_KEY_UP`` event for :class:`GenButton` when used as toggle button.
:param `event`: a :class:`KeyEvent` event to be processed.
"""
if self.hasFocus and event.GetKeyCode() == ord(" "):
self.up = not self.up
self.Notify()
@@ -590,31 +1032,45 @@ class __ToggleMixin:
class GenToggleButton(__ToggleMixin, GenButton):
"""A generic toggle button"""
""" A generic toggle button. """
pass
class GenBitmapToggleButton(__ToggleMixin, GenBitmapButton):
"""A generic toggle bitmap button"""
""" A generic toggle bitmap button. """
pass
class GenBitmapTextToggleButton(__ToggleMixin, GenBitmapTextButton):
"""A generic toggle bitmap button with text label"""
""" A generic toggle bitmap button with text label. """
pass
#----------------------------------------------------------------------
class __ThemedMixin:
""" Use the native renderer to draw the bezel, also handle mouse-overs"""
class __ThemedMixin(object):
""" Uses the native renderer to draw the bezel, also handle mouse-overs. """
def InitOtherEvents(self):
""" Initializes other events needed for themed buttons. """
self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouse)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouse)
def OnMouse(self, evt):
def OnMouse(self, event):
"""
Handles the ``wx.EVT_ENTER_WINDOW`` and ``wx.EVT_LEAVE_WINDOW`` events for
:class:`GenButton` when used as a themed button.
:param `event`: a :class:`MouseEvent` event to be processed.
"""
self.Refresh()
evt.Skip()
event.Skip()
def DrawBezel(self, dc, x1, y1, x2, y2):
rect = wx.Rect(x1, y1, x2, y2)
if self.up:
state = 0
@@ -630,27 +1086,27 @@ class __ThemedMixin:
class ThemedGenButton(__ThemedMixin, GenButton):
"""A themed generic button"""
""" A themed generic button. """
pass
class ThemedGenBitmapButton(__ThemedMixin, GenBitmapButton):
"""A themed generic bitmap button."""
""" A themed generic bitmap button. """
pass
class ThemedGenBitmapTextButton(__ThemedMixin, GenBitmapTextButton):
"""A themed generic bitmapped button with text label"""
""" A themed generic bitmapped button with text label. """
pass
class ThemedGenToggleButton(__ThemedMixin, GenToggleButton):
"""A themed generic toggle button"""
""" A themed generic toggle button. """
pass
class ThemedGenBitmapToggleButton(__ThemedMixin, GenBitmapToggleButton):
"""A themed generic toggle bitmap button"""
""" A themed generic toggle bitmap button. """
pass
class ThemedGenBitmapTextToggleButton(__ThemedMixin, GenBitmapTextToggleButton):
"""A themed generic toggle bitmap button with text label"""
""" A themed generic toggle bitmap button with text label. """
pass

274
wx/lib/wx2to3.py Normal file
View File

@@ -0,0 +1,274 @@
"""Utilities for writing code that runs on Python 2 and 3"""
import operator
import sys
import types
__author__ = "Benjamin Peterson <benjamin@python.org>"
__version__ = "1.1.0"
# True if we are running on Python 3.
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes
MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
class_types = (type, types.ClassType)
text_type = unicode
binary_type = str
if sys.platform == "java":
# Jython always uses 32 bits.
MAXSIZE = int((1 << 31) - 1)
else:
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
class X(object):
def __len__(self):
return 1 << 31
try:
len(X())
except OverflowError:
# 32-bit
MAXSIZE = int((1 << 31) - 1)
else:
# 64-bit
MAXSIZE = int((1 << 63) - 1)
del X
def _add_doc(func, doc):
"""Add documentation to a function."""
func.__doc__ = doc
if PY3:
_meth_func = "__func__"
_meth_self = "__self__"
_func_code = "__code__"
_func_defaults = "__defaults__"
_iterkeys = "keys"
_itervalues = "values"
_iteritems = "items"
else:
_meth_func = "im_func"
_meth_self = "im_self"
_func_code = "func_code"
_func_defaults = "func_defaults"
_iterkeys = "iterkeys"
_itervalues = "itervalues"
_iteritems = "iteritems"
try:
advance_iterator = next
except NameError:
def advance_iterator(it):
return it.next()
next = advance_iterator
if PY3:
def get_unbound_function(unbound):
return unbound
Iterator = object
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
else:
def get_unbound_function(unbound):
return unbound.im_func
class Iterator(object):
def next(self):
return type(self).__next__(self)
callable = callable
_add_doc(get_unbound_function,
"""Get the function out of a possibly unbound function""")
get_method_function = operator.attrgetter(_meth_func)
get_method_self = operator.attrgetter(_meth_self)
get_function_code = operator.attrgetter(_func_code)
get_function_defaults = operator.attrgetter(_func_defaults)
def iterkeys(d):
"""Return an iterator over the keys of a dictionary."""
return getattr(d, _iterkeys)()
def itervalues(d):
"""Return an iterator over the values of a dictionary."""
return getattr(d, _itervalues)()
def iteritems(d):
"""Return an iterator over the (key, value) pairs of a dictionary."""
return getattr(d, _iteritems)()
if PY3:
def b(s):
return s.encode("latin-1")
def u(s):
return s
if sys.version_info[1] <= 1:
def int2byte(i):
return bytes((i,))
else:
# This is about 2x faster than the implementation above on 3.2+
int2byte = operator.methodcaller("to_bytes", 1, "big")
import io
StringIO = io.StringIO
BytesIO = io.BytesIO
import pickle
pickle = pickle
else:
def b(s):
return s
def u(s):
return unicode(s, "unicode_escape")
int2byte = chr
import StringIO
StringIO = BytesIO = StringIO.StringIO
import cPickle
pickle = cPickle
_add_doc(b, """Byte literal""")
_add_doc(u, """Text literal""")
# Sorting stuff
if PY3:
def cmp2key(mycmp):
"""
Converts a `cmp=` function into a `key=` function for sorting purposes.
This is another bright idea coming from Python 3 (!).
:param `mycmp`: a Python-2 compatible `cmp` sorting function.
:returns: Something that can be used as a sorting thing in Python 3.
"""
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __cmp__(self, other):
return mycmp(self.obj, other.obj)
return K
def sort(alist, cmp_function):
new_list = sorted(alist, key=cmp2key(cmp_function))
return new_list
else:
def sort(alist, cmp_function):
alist.sort(cmp_function)
return alist
if PY3:
import builtins
exec_ = getattr(builtins, "exec")
def reraise(tp, value, tb=None):
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
print_ = getattr(builtins, "print")
del builtins
else:
def exec_(code, globs=None, locs=None):
"""Execute code in a namespace."""
if globs is None:
frame = sys._getframe(1)
globs = frame.f_globals
if locs is None:
locs = frame.f_locals
del frame
elif locs is None:
locs = globs
exec("""exec code in globs, locs""")
exec_("""def reraise(tp, value, tb=None):
raise tp, value, tb
""")
def print_(*args, **kwargs):
"""The new-style print function."""
fp = kwargs.pop("file", sys.stdout)
if fp is None:
return
def write(data):
if not isinstance(data, basestring):
data = str(data)
fp.write(data)
want_unicode = False
sep = kwargs.pop("sep", None)
if sep is not None:
if isinstance(sep, unicode):
want_unicode = True
elif not isinstance(sep, str):
raise TypeError("sep must be None or a string")
end = kwargs.pop("end", None)
if end is not None:
if isinstance(end, unicode):
want_unicode = True
elif not isinstance(end, str):
raise TypeError("end must be None or a string")
if kwargs:
raise TypeError("invalid keyword arguments to print()")
if not want_unicode:
for arg in args:
if isinstance(arg, unicode):
want_unicode = True
break
if want_unicode:
newline = unicode("\n")
space = unicode(" ")
else:
newline = "\n"
space = " "
if sep is None:
sep = space
if end is None:
end = newline
for i, arg in enumerate(args):
if i:
write(sep)
write(arg)
write(end)
_add_doc(reraise, """Reraise an exception.""")
def with_metaclass(meta, base=object):
"""Create a base class with a metaclass."""
return meta("NewBase", (base,), {})