From 6bfa39aff05879365c264e2293a1a90c5d953d64 Mon Sep 17 00:00:00 2001 From: Andrea Gavana Date: Mon, 16 Jul 2012 16:52:14 +0000 Subject: [PATCH] Phoenix: - 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 --- unittests/test_lib_agw_advancedsplash.py | 32 + unittests/test_lib_agw_balloontip.py | 38 ++ unittests/test_lib_agw_buttonpanel.py | 57 ++ unittests/test_lib_agw_cubecolourdialog.py | 39 ++ unittests/test_lib_agw_customtreectrl.py | 212 +++++++ unittests/test_lib_agw_floatspin.py | 58 ++ unittests/test_lib_agw_foldpanelbar.py | 72 +++ unittests/test_lib_agw_fourwaysplitter.py | 61 ++ .../test_lib_agw_genericmessagedialog.py | 43 ++ unittests/test_lib_agw_hyperlink.py | 47 ++ unittests/test_lib_agw_hypertreelist.py | 84 +++ unittests/test_lib_buttons.py | 58 ++ wx/lib/agw/__init__.py | 6 +- wx/lib/agw/advancedsplash.py | 31 +- wx/lib/agw/balloontip.py | 134 +++- wx/lib/agw/buttonpanel.py | 173 +++-- wx/lib/agw/cubecolourdialog.py | 152 +++-- wx/lib/agw/customtreectrl.py | 355 ++++++----- wx/lib/agw/floatspin.py | 93 ++- wx/lib/agw/foldpanelbar.py | 109 ++-- wx/lib/agw/fourwaysplitter.py | 93 ++- wx/lib/agw/genericmessagedialog.py | 70 ++- wx/lib/agw/hyperlink.py | 59 +- wx/lib/agw/hypertreelist.py | 288 +++++---- wx/lib/buttons.py | 594 ++++++++++++++++-- wx/lib/wx2to3.py | 274 ++++++++ 26 files changed, 2605 insertions(+), 627 deletions(-) create mode 100644 unittests/test_lib_agw_advancedsplash.py create mode 100644 unittests/test_lib_agw_balloontip.py create mode 100644 unittests/test_lib_agw_buttonpanel.py create mode 100644 unittests/test_lib_agw_cubecolourdialog.py create mode 100644 unittests/test_lib_agw_customtreectrl.py create mode 100644 unittests/test_lib_agw_floatspin.py create mode 100644 unittests/test_lib_agw_foldpanelbar.py create mode 100644 unittests/test_lib_agw_fourwaysplitter.py create mode 100644 unittests/test_lib_agw_genericmessagedialog.py create mode 100644 unittests/test_lib_agw_hyperlink.py create mode 100644 unittests/test_lib_agw_hypertreelist.py create mode 100644 unittests/test_lib_buttons.py create mode 100644 wx/lib/wx2to3.py diff --git a/unittests/test_lib_agw_advancedsplash.py b/unittests/test_lib_agw_advancedsplash.py new file mode 100644 index 00000000..35a2fc28 --- /dev/null +++ b/unittests/test_lib_agw_advancedsplash.py @@ -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() diff --git a/unittests/test_lib_agw_balloontip.py b/unittests/test_lib_agw_balloontip.py new file mode 100644 index 00000000..597a37c0 --- /dev/null +++ b/unittests/test_lib_agw_balloontip.py @@ -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() diff --git a/unittests/test_lib_agw_buttonpanel.py b/unittests/test_lib_agw_buttonpanel.py new file mode 100644 index 00000000..bae292f4 --- /dev/null +++ b/unittests/test_lib_agw_buttonpanel.py @@ -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() diff --git a/unittests/test_lib_agw_cubecolourdialog.py b/unittests/test_lib_agw_cubecolourdialog.py new file mode 100644 index 00000000..108b1929 --- /dev/null +++ b/unittests/test_lib_agw_cubecolourdialog.py @@ -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() diff --git a/unittests/test_lib_agw_customtreectrl.py b/unittests/test_lib_agw_customtreectrl.py new file mode 100644 index 00000000..f61760c6 --- /dev/null +++ b/unittests/test_lib_agw_customtreectrl.py @@ -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() diff --git a/unittests/test_lib_agw_floatspin.py b/unittests/test_lib_agw_floatspin.py new file mode 100644 index 00000000..85842146 --- /dev/null +++ b/unittests/test_lib_agw_floatspin.py @@ -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() diff --git a/unittests/test_lib_agw_foldpanelbar.py b/unittests/test_lib_agw_foldpanelbar.py new file mode 100644 index 00000000..76cf2560 --- /dev/null +++ b/unittests/test_lib_agw_foldpanelbar.py @@ -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() diff --git a/unittests/test_lib_agw_fourwaysplitter.py b/unittests/test_lib_agw_fourwaysplitter.py new file mode 100644 index 00000000..98fa0007 --- /dev/null +++ b/unittests/test_lib_agw_fourwaysplitter.py @@ -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() diff --git a/unittests/test_lib_agw_genericmessagedialog.py b/unittests/test_lib_agw_genericmessagedialog.py new file mode 100644 index 00000000..b4fe1b2e --- /dev/null +++ b/unittests/test_lib_agw_genericmessagedialog.py @@ -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() diff --git a/unittests/test_lib_agw_hyperlink.py b/unittests/test_lib_agw_hyperlink.py new file mode 100644 index 00000000..045baaba --- /dev/null +++ b/unittests/test_lib_agw_hyperlink.py @@ -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() diff --git a/unittests/test_lib_agw_hypertreelist.py b/unittests/test_lib_agw_hypertreelist.py new file mode 100644 index 00000000..f942defb --- /dev/null +++ b/unittests/test_lib_agw_hypertreelist.py @@ -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() diff --git a/unittests/test_lib_buttons.py b/unittests/test_lib_buttons.py new file mode 100644 index 00000000..7553915e --- /dev/null +++ b/unittests/test_lib_buttons.py @@ -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() \ No newline at end of file diff --git a/wx/lib/agw/__init__.py b/wx/lib/agw/__init__.py index 3939b886..e6c63178 100644 --- a/wx/lib/agw/__init__.py +++ b/wx/lib/agw/__init__.py @@ -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 " diff --git a/wx/lib/agw/advancedsplash.py b/wx/lib/agw/advancedsplash.py index 541cee43..13057258 100644 --- a/wx/lib/agw/advancedsplash.py +++ b/wx/lib/agw/advancedsplash.py @@ -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() diff --git a/wx/lib/agw/balloontip.py b/wx/lib/agw/balloontip.py index 30a2b6c1..534b5e97 100644 --- a/wx/lib/agw/balloontip.py +++ b/wx/lib/agw/balloontip.py @@ -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() - self.showtime.Stop() - del self.showtime + 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() + + + \ No newline at end of file diff --git a/wx/lib/agw/buttonpanel.py b/wx/lib/agw/buttonpanel.py index 4aaee464..7e5f073d 100644 --- a/wx/lib/agw/buttonpanel.py +++ b/wx/lib/agw/buttonpanel.py @@ -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,8 +1804,8 @@ class ButtonPanel(wx.PyPanel): :param string `name`: window class name. """ - wx.PyPanel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, - wx.NO_BORDER, name=name) + wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, + wx.NO_BORDER, name=name) self._vButtons = [] self._vSeparators = [] @@ -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() + \ No newline at end of file diff --git a/wx/lib/agw/cubecolourdialog.py b/wx/lib/agw/cubecolourdialog.py index 3be59646..f9e6c888 100644 --- a/wx/lib/agw/cubecolourdialog.py +++ b/wx/lib/agw/cubecolourdialog.py @@ -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() diff --git a/wx/lib/agw/customtreectrl.py b/wx/lib/agw/customtreectrl.py index 880acc79..17bba8de 100644 --- a/wx/lib/agw/customtreectrl.py +++ b/wx/lib/agw/customtreectrl.py @@ -3,7 +3,7 @@ # Inspired By And Heavily Based On wxGenericTreeCtrl. # # Andrea Gavana, @ 17 May 2006 -# Latest Revision: 22 May 2012, 21.00 GMT +# Latest Revision: 16 Jul 2012, 15.00 GMT # # # TODO List @@ -33,6 +33,7 @@ # # Or, Obviously, To The wxPython Mailing List!!! # +# Tags: phoenix-port, unittest, documented # # End Of Comments # --------------------------------------------------------------------------------- # @@ -147,7 +148,7 @@ Usage example:: def __init__(self, parent): - wx.Frame.__init(self, parent, -1, "CustomTreeCtrl Demo") + wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") # Create a CustomTreeCtrl instance custom_tree = CT.CustomTreeCtrl(self, agwStyle=wx.TR_DEFAULT_STYLE) @@ -157,9 +158,9 @@ Usage example:: # Create an image list to add icons next to an item il = wx.ImageList(16, 16) - fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, 16)) - fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, 16)) - fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, 16)) + fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) + fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) + fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) custom_tree.SetImageList(il) @@ -179,9 +180,8 @@ Usage example:: for z in range(5): item = custom_tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z)) custom_tree.SetItemImage(item, fileidx, wx.TreeItemIcon_Normal) - custom_tree.SetItemImage(item, smileidx, wx.TreeItemIcon_Selected) - custom_tree.Expand(self.root) + custom_tree.Expand(root) # our normal wxApp-derived class, as usual @@ -249,9 +249,9 @@ Window Styles Hex Value Description ``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_ALIGN_WINDOWS_RIGHT`` 0x40000 Flag used to align windows (in items with windows) to the rightmost edge of :class:`CustomTreeCtrl`. ``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`CustomTreeCtrl` is low. @@ -299,18 +299,21 @@ License And Version :class:`CustomTreeCtrl` is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 22 May 2012, 21.00 GMT +Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT -Version 2.6 +Version 2.7 """ # Version Info -__version__ = "2.6" +__version__ = "2.7" import wx from wx.lib.expando import ExpandoTextCtrl +# Python 2/3 compatibility helper +import wx.lib.wx2to3 as wx2to3 + # ---------------------------------------------------------------------------- # Constants # ---------------------------------------------------------------------------- @@ -367,7 +370,7 @@ 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. """ @@ -381,11 +384,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_ALIGN_WINDOWS_RIGHT = 0x40000 # to align windows to the rightmost edge of CustomTreeCtrl @@ -550,7 +553,7 @@ def MakeDisabledBitmap(original): """ img = original.ConvertToImage() - return wx.BitmapFromImage(img.ConvertToGreyscale()) + return wx.Bitmap(img.ConvertToGreyscale()) # ---------------------------------------------------------------------------- @@ -571,14 +574,14 @@ def DrawTreeItemButton(win, dc, rect, flags): # white background dc.SetPen(wx.GREY_PEN) dc.SetBrush(wx.WHITE_BRUSH) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) # black lines - xMiddle = rect.x + rect.width/2 - yMiddle = rect.y + rect.height/2 + xMiddle = rect.x + rect.width//2 + yMiddle = rect.y + rect.height//2 # half of the length of the horz lines in "-" and "+" - halfWidth = rect.width/2 - 2 + halfWidth = rect.width//2 - 2 dc.SetPen(wx.BLACK_PEN) dc.DrawLine(xMiddle - halfWidth, yMiddle, xMiddle + halfWidth + 1, yMiddle) @@ -586,7 +589,7 @@ def DrawTreeItemButton(win, dc, rect, flags): if not flags & _CONTROL_EXPANDED: # turn "-" into "+" - halfHeight = rect.height/2 - 2 + halfHeight = rect.height//2 - 2 dc.DrawLine(xMiddle, yMiddle - halfHeight, xMiddle, yMiddle + halfHeight + 1) @@ -634,7 +637,7 @@ def ChopText(dc, text, max_size): """ # first check if the text fits with no problems - x, y, dummy = dc.GetMultiLineTextExtent(text) + x, y, dummy = dc.GetFullMultiLineTextExtent(text) if x <= max_size: return text @@ -642,7 +645,7 @@ def ChopText(dc, text, max_size): textLen = len(text) last_good_length = 0 - for i in xrange(textLen, -1, -1): + for i in range(textLen, -1, -1): s = text[0:i] s += "..." @@ -693,7 +696,7 @@ class DragImage(wx.DragImage): tempdc = wx.ClientDC(treeCtrl) tempdc.SetFont(font) - width, height, dummy = tempdc.GetMultiLineTextExtent(text + "M") + width, height, dummy = tempdc.GetFullMultiLineTextExtent(text + "M") image = item.GetCurrentImage() @@ -725,13 +728,13 @@ class DragImage(wx.DragImage): if image_w: ximagepos = wcheck - yimagepos = ((total_h > image_h) and [(total_h-image_h)/2] or [0])[0] + yimagepos = ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0] if checkimage is not None: xcheckpos = 2 - ycheckpos = ((total_h > image_h) and [(total_h-image_h)/2] or [0])[0] + 2 + ycheckpos = ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0] + 2 - extraH = ((total_h > height) and [(total_h - height)/2] or [0])[0] + extraH = ((total_h > height) and [(total_h - height)//2] or [0])[0] xtextpos = wcheck + image_w ytextpos = extraH @@ -742,7 +745,7 @@ class DragImage(wx.DragImage): 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 total_w = image_w + wcheck + width @@ -778,7 +781,7 @@ class DragImage(wx.DragImage): memory = wx.MemoryDC() - bitmap = wx.EmptyBitmap(self._total_w, self._total_h) + bitmap = wx.Bitmap(self._total_w, self._total_h) memory.SelectObject(bitmap) if wx.Platform == '__WXMAC__': @@ -808,8 +811,8 @@ class DragImage(wx.DragImage): timg = bitmap.ConvertToImage() if not timg.HasAlpha(): timg.InitAlpha() - for y in xrange(timg.GetHeight()): - for x in xrange(timg.GetWidth()): + for y in range(timg.GetHeight()): + for x in range(timg.GetWidth()): pix = wx.Colour(timg.GetRed(x, y), timg.GetGreen(x, y), timg.GetBlue(x, y)) @@ -938,15 +941,15 @@ class TreeItemAttr(object): # ---------------------------------------------------------------------------- -# CommandTreeEvent Is A Special Subclassing Of wx.PyCommandEvent +# CommandTreeEvent Is A Special Subclassing Of wx.CommandEvent # # NB: Note That Not All The Accessors Make Sense For All The Events, See The # Event Description Below. # ---------------------------------------------------------------------------- -class CommandTreeEvent(wx.PyCommandEvent): +class CommandTreeEvent(wx.CommandEvent): """ - :class:`CommandTreeEvent` is a special subclassing of :class:`PyCommandEvent`. + :class:`CommandTreeEvent` is a special subclassing of :class:`CommandEvent`. :note: Not all the accessors make sense for all the events, see the event description for every method in this class. """ @@ -965,7 +968,7 @@ class CommandTreeEvent(wx.PyCommandEvent): :param string `label`: a :class:`GenericTreeItem` text label. """ - wx.PyCommandEvent.__init__(self, evtType, evtId, **kwargs) + wx.CommandEvent.__init__(self, evtType, evtId, **kwargs) self._item = item self._evtKey = evtKey self._pointDrag = point @@ -1421,7 +1424,7 @@ class TreeTextCtrl(ExpandoTextCtrl): mySize = self.GetSize() dc = wx.ClientDC(self) - sx, sy, dummy = dc.GetMultiLineTextExtent(self.GetValue() + "M") + sx, sy, dummy = dc.GetFullMultiLineTextExtent(self.GetValue() + "M") if myPos.x + sx > parentSize.x: sx = parentSize.x - myPos.x @@ -2397,7 +2400,7 @@ class GenericTreeItem(object): total = count - for n in xrange(count): + for n in range(count): total += self._children[n].GetChildrenCount() return total @@ -2452,7 +2455,7 @@ class GenericTreeItem(object): if point.y > self._y and point.y < self._y + h: - y_mid = self._y + h/2 + y_mid = self._y + h//2 if point.y < y_mid: flags |= TREE_HITTEST_ONITEMUPPERPART @@ -2594,7 +2597,7 @@ class GenericTreeItem(object): # This Is The Main Class. # ----------------------------------------------------------------------------- -class CustomTreeCtrl(wx.PyScrolledWindow): +class CustomTreeCtrl(wx.ScrolledWindow): """ :class:`CustomTreeCtrl` is a class that mimics the behaviour of :class:`TreeCtrl`, with almost the same base functionalities plus some more enhancements. This class does not rely on @@ -2615,7 +2618,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :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 underlying :class:`PyScrolledWindow` style; + :param integer `style`: the underlying :class:`ScrolledWindow` style; :param integer `agwStyle`: the AGW-specific window style for :class:`CustomTreeCtrl`. It can be a combination of the following bits: @@ -2636,9 +2639,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): ``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_ALIGN_WINDOWS_RIGHT`` 0x40000 Flag used to align windows (in items with windows) to the rightmost edge of :class:`CustomTreeCtrl`. ``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`CustomTreeCtrl` is low. @@ -2661,8 +2664,8 @@ class CustomTreeCtrl(wx.PyScrolledWindow): self._spacing = 18 # Brushes for focused/unfocused items (also gradient type) - self._hilightBrush = wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)) - btnshadow = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) + self._hilightBrush = wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)) + btnshadow = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNSHADOW) self._hilightUnfocusedBrush = wx.Brush(btnshadow) r, g, b = btnshadow.Red(), btnshadow.Green(), btnshadow.Blue() backcolour = (max((r >> 1) - 20, 0), @@ -2698,20 +2701,20 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # Default normal and bold fonts for an item self._hasFont = True - self._normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + self._normalFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) family = self._normalFont.GetFamily() if family == wx.FONTFAMILY_UNKNOWN: family = wx.FONTFAMILY_SWISS self._boldFont = wx.Font(self._normalFont.GetPointSize(), family, - self._normalFont.GetStyle(), wx.BOLD, self._normalFont.GetUnderlined(), + self._normalFont.GetStyle(), wx.FONTWEIGHT_BOLD, self._normalFont.GetUnderlined(), self._normalFont.GetFaceName(), self._normalFont.GetEncoding()) self._italicFont = wx.Font(self._normalFont.GetPointSize(), family, - wx.FONTSTYLE_ITALIC, wx.NORMAL, self._normalFont.GetUnderlined(), + wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL, self._normalFont.GetUnderlined(), self._normalFont.GetFaceName(), self._normalFont.GetEncoding()) # Hyperlinks things self._hypertextfont = wx.Font(self._normalFont.GetPointSize(), family, - self._normalFont.GetStyle(), wx.NORMAL, True, + self._normalFont.GetStyle(), wx.FONTWEIGHT_NORMAL, True, self._normalFont.GetFaceName(), self._normalFont.GetEncoding()) self._hypertextnewcolour = wx.BLUE self._hypertextvisitedcolour = wx.Colour(200, 47, 200) @@ -2728,7 +2731,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): self._disabledColour = wx.Colour(180, 180, 180) # Gradient selection colours - self._firstcolour = colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) + self._firstcolour = colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._secondcolour = wx.WHITE self._usegradients = False self._gradientstyle = 0 # Horizontal Gradient @@ -2750,7 +2753,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # Pen Used To Draw The Border Around Selected Items self._borderPen = wx.BLACK_PEN - self._cursor = wx.StockCursor(wx.CURSOR_ARROW) + self._cursor = wx.Cursor(wx.CURSOR_ARROW) # For Appended Windows self._hasWindows = False @@ -2775,7 +2778,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): self._separatorPen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)) # Create our container... at last! - wx.PyScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) + wx.ScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) self._agwStyle = agwStyle @@ -2823,12 +2826,12 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :note: This method always returns ``True`` as we always accept focus from mouse click. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ # overridden base class method, allows this ctrl to # participate in the tab-order, etc. It's overridable because - # of deriving this class from wx.PyScrolledWindow... + # of deriving this class from wx.ScrolledWindow... return True @@ -2866,7 +2869,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :return: An instance of :class:`Bitmap`, representing a native looking checkbox or radiobutton. """ - bmp = wx.EmptyBitmap(x, y) + bmp = wx.Bitmap(x, y) mdc = wx.MemoryDC(bmp) mask = wx.Colour(0xfe, 0xfe, 0xfe) mdc.SetBackground(wx.Brush(mask)) @@ -3573,7 +3576,8 @@ class CustomTreeCtrl(wx.PyScrolledWindow): return item.GetData() - GetItemPyData = GetPyData + GetItemPyData = GetPyData + GetItemData = GetPyData def GetItemTextColour(self, item): @@ -3694,6 +3698,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): item.SetData(data) SetItemPyData = SetPyData + SetItemData = SetPyData def SetItemHasChildren(self, item, has=True): @@ -3745,8 +3750,8 @@ class CustomTreeCtrl(wx.PyScrolledWindow): """ if highlight: - bg = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) - fg = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) + bg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) + fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) item.Attr().SetTextColour(fg) item.Attr.SetBackgroundColour(bg) @@ -3807,10 +3812,10 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :param `font`: a valid :class:`Font` instance. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ - wx.PyScrolledWindow.SetFont(self, font) + wx.ScrolledWindow.SetFont(self, font) self._normalFont = font family = self._normalFont.GetFamily() @@ -3819,11 +3824,11 @@ class CustomTreeCtrl(wx.PyScrolledWindow): family = wx.FONTFAMILY_SWISS self._boldFont = wx.Font(self._normalFont.GetPointSize(), family, - self._normalFont.GetStyle(), wx.BOLD, self._normalFont.GetUnderlined(), + self._normalFont.GetStyle(), wx.FONTWEIGHT_BOLD, self._normalFont.GetUnderlined(), self._normalFont.GetFaceName(), self._normalFont.GetEncoding()) self._italicFont = wx.Font(self._normalFont.GetPointSize(), family, - wx.FONTSTYLE_ITALIC, wx.NORMAL, self._normalFont.GetUnderlined(), + wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL, self._normalFont.GetUnderlined(), self._normalFont.GetFaceName(), self._normalFont.GetEncoding()) self.CalculatePositions() @@ -3999,7 +4004,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): """ if colour is None: - colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) + colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._firstcolour = colour if self._usegradients: @@ -5560,7 +5565,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): count = len(children) - for n in xrange(index+1, count): + for n in range(index+1, count): if self.TagAllChildrenUntilLast(children[n], last_item, select): return True @@ -5822,7 +5827,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if wx.Platform in ["__WXMSW__", "__WXMAC__"]: self.Update() else: - wx.YieldIfNeeded() + wx.SafeYield() # now scroll to the item item_y = item.GetY() @@ -5841,7 +5846,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): x += _PIXELS_PER_UNIT + 2 # one more scrollbar unit + 2 pixels x_pos = self.GetScrollPos(wx.HORIZONTAL) # Item should appear at top - self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x/_PIXELS_PER_UNIT, y/_PIXELS_PER_UNIT, x_pos, item_y/_PIXELS_PER_UNIT) + self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x//_PIXELS_PER_UNIT, y//_PIXELS_PER_UNIT, x_pos, item_y//_PIXELS_PER_UNIT) elif item_y+self.GetLineHeight(item) > start_y+client_h: @@ -5852,7 +5857,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): item_y += _PIXELS_PER_UNIT+2 x_pos = self.GetScrollPos(wx.HORIZONTAL) # Item should appear at bottom - self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x/_PIXELS_PER_UNIT, y/_PIXELS_PER_UNIT, x_pos, (item_y+self.GetLineHeight(item)-client_h)/_PIXELS_PER_UNIT ) + self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x//_PIXELS_PER_UNIT, y//_PIXELS_PER_UNIT, x_pos, (item_y+self.GetLineHeight(item)-client_h)//_PIXELS_PER_UNIT ) def OnCompareItems(self, item1, item2): @@ -5890,7 +5895,8 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if len(children) > 1: self._dirty = True - children.sort(self.OnCompareItems) + children = wx2to3.sort(children, self.OnCompareItems) + item._children = children def GetImageList(self): @@ -5960,7 +5966,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # necessary (which might look ugly). n = self._imageListNormal.GetImageCount() - for i in xrange(n): + for i in range(n): width, height = self._imageListNormal.GetSize(i) @@ -5974,7 +5980,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # necessary (which might look ugly). n = self._imageListButtons.GetImageCount() - for i in xrange(n): + for i in range(n): width, height = self._imageListButtons.GetSize(i) @@ -5988,7 +5994,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # necessary (which might look ugly). n = self._imageListCheck.GetImageCount() - for i in xrange(n): + for i in range(n): width, height = self._imageListCheck.GetSize(i) @@ -6002,7 +6008,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # necessary (which might look ugly). n = self._imageListLeft.GetImageCount() - for i in xrange(n): + for i in range(n): width, height = self._imageListLeft.GetSize(i) @@ -6012,7 +6018,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if self._lineHeight < 30: self._lineHeight += 2 # at least 2 pixels else: - self._lineHeight += self._lineHeight/10 # otherwise 10% extra spacing + self._lineHeight += self._lineHeight//10 # otherwise 10% extra spacing def SetImageList(self, imageList): @@ -6038,7 +6044,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): sz = imageList.GetSize(0) self._grayedImageList = wx.ImageList(sz[0], sz[1], True, 0) - for ii in xrange(imageList.GetImageCount()): + for ii in range(imageList.GetImageCount()): bmp = imageList.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) self._grayedImageList.Add(newbmp) @@ -6066,7 +6072,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): sz = imageList.GetSize(0) self._grayedImageListLeft = wx.ImageList(sz[0], sz[1], True, 0) - for ii in xrange(imageList.GetImageCount()): + for ii in range(imageList.GetImageCount()): bmp = imageList.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) self._grayedImageListLeft.Add(newbmp) @@ -6172,7 +6178,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): sizex, sizey = imglist.GetSize(0) self._imageListCheck = imglist - for ii in xrange(self._imageListCheck.GetImageCount()): + for ii in range(self._imageListCheck.GetImageCount()): bmp = self._imageListCheck.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) @@ -6235,7 +6241,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # ----------------------------------------------------------------------------- def AdjustMyScrollbars(self): - """ Internal method used to adjust the :class:`PyScrolledWindow` scrollbars. """ + """ Internal method used to adjust the :class:`ScrolledWindow` scrollbars. """ if self._anchor: @@ -6244,7 +6250,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): x += _PIXELS_PER_UNIT + 2 # one more scrollbar unit + 2 pixels x_pos = self.GetScrollPos(wx.HORIZONTAL) y_pos = self.GetScrollPos(wx.VERTICAL) - self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x/_PIXELS_PER_UNIT, y/_PIXELS_PER_UNIT, x_pos, y_pos) + self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x//_PIXELS_PER_UNIT, y//_PIXELS_PER_UNIT, x_pos, y_pos) else: @@ -6299,9 +6305,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): rf, gf, bf = 0, 0, 0 - for y in xrange(rect.y, rect.y + rect.height): + 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, y, rect.width, 1) rf = rf + rstep gf = gf + gstep @@ -6309,7 +6315,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): dc.SetPen(oldpen) dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) dc.SetBrush(oldbrush) @@ -6347,9 +6353,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): rf, gf, bf = 0, 0, 0 - for x in xrange(rect.x, rect.x + rect.width): + for x in range(rect.x, rect.x + rect.width): currCol = (int(r1 + rf), int(g1 + gf), int(b1 + bf)) - dc.SetBrush(wx.Brush(currCol, wx.SOLID)) + dc.SetBrush(wx.Brush(currCol, wx.BRUSHSTYLE_SOLID)) dc.DrawRectangle(x, rect.y, 1, rect.height) rf = rf + rstep gf = gf + gstep @@ -6357,7 +6363,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): dc.SetPen(oldpen) dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) dc.SetBrush(oldbrush) @@ -6406,9 +6412,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): rf, gf, bf = 0, 0, 0 dc.SetPen(wx.TRANSPARENT_PEN) - for y in xrange(filRect.y, filRect.y + filRect.height): + for y in range(filRect.y, filRect.y + filRect.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(filRect.x, y, filRect.width, 1) rf = rf + rstep gf = gf + gstep @@ -6416,10 +6422,10 @@ class CustomTreeCtrl(wx.PyScrolledWindow): dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.SetPen(wx.Pen(outer)) - dc.DrawRoundedRectangleRect(bdrRect, 3) + dc.DrawRoundedRectangle(bdrRect, 3) bdrRect.Deflate(1, 1) dc.SetPen(wx.Pen(inner)) - dc.DrawRoundedRectangleRect(bdrRect, 2) + dc.DrawRoundedRectangle(bdrRect, 2) dc.SetPen(oldpen) dc.SetBrush(oldbrush) @@ -6459,7 +6465,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): else: dc.SetTextForeground(self.GetHyperTextNewColour()) - text_w, text_h, dummy = dc.GetMultiLineTextExtent(item.GetText()) + text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(item.GetText()) w, h = self.GetClientSize() image = item.GetCurrentImage() @@ -6501,7 +6507,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if wx.Platform == "__WXMAC__": if not self._hasFocus: dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetPen(wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT), 1, wx.SOLID)) + dc.SetPen(wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT), 1, wx.SOLID)) else: dc.SetBrush(self._hilightBrush) else: @@ -6514,7 +6520,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): else: colBg = self._backgroundColour - dc.SetBrush(wx.Brush(colBg, wx.SOLID)) + dc.SetBrush(wx.Brush(colBg, wx.BRUSHSTYLE_SOLID)) dc.SetPen(wx.TRANSPARENT_PEN) offset = (self.HasAGWFlag(TR_ROW_LINES) and [1] or [0])[0] @@ -6538,7 +6544,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) else: - dc.DrawRectangleRect(itemrect) + dc.DrawRectangle(itemrect) else: if drawItemBackground: minusicon = wcheck + image_w - 2 @@ -6546,7 +6552,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): item.GetY()+offset, item.GetWidth()-minusicon, total_h-offset) - dc.DrawRectangleRect(itemrect) + dc.DrawRectangle(itemrect) else: @@ -6584,7 +6590,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) else: - dc.DrawRectangleRect(itemrect) + dc.DrawRectangle(itemrect) # On GTK+ 2, drawing a 'normal' background is wrong for themes that # don't allow backgrounds to be customized. Not drawing the background, @@ -6609,7 +6615,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): else: # Vertical self.DrawVerticalGradient(dc, itemrect, self._hasFocus) else: - dc.DrawRectangleRect(itemrect) + dc.DrawRectangle(itemrect) if image != _NO_IMAGE: @@ -6621,7 +6627,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): imglist.Draw(image, dc, item.GetX() + wcheck, - item.GetY() + ((total_h > image_h) and [(total_h-image_h)/2] or [0])[0], + item.GetY() + ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0], wx.IMAGELIST_DRAW_TRANSPARENT) dc.DestroyClippingRegion() @@ -6634,7 +6640,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): imglist.Draw(checkimage, dc, item.GetX(), - item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)/2] or [0])[0], + item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)//2] or [0])[0], wx.IMAGELIST_DRAW_TRANSPARENT) if leftimage != _NO_IMAGE: @@ -6645,11 +6651,11 @@ class CustomTreeCtrl(wx.PyScrolledWindow): imglist.Draw(leftimage, dc, 4, - item.GetY() + ((total_h > l_image_h) and [(total_h-l_image_h)/2] or [0])[0], + item.GetY() + ((total_h > l_image_h) and [(total_h-l_image_h)//2] or [0])[0], wx.IMAGELIST_DRAW_TRANSPARENT) dc.SetBackgroundMode(wx.TRANSPARENT) - extraH = ((total_h > text_h) and [(total_h - text_h)/2] or [0])[0] + extraH = ((total_h > text_h) and [(total_h - text_h)//2] or [0])[0] textrect = wx.Rect(wcheck + image_w + item.GetX(), item.GetY() + extraH, text_w, text_h) @@ -6675,7 +6681,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): xa, ya = self.CalcScrolledPosition((0, item.GetY())) wndx += xa if item.GetHeight() > item.GetWindowSize()[1]: - ya += (item.GetHeight() - item.GetWindowSize()[1])/2 + ya += (item.GetHeight() - item.GetWindowSize()[1])//2 if align == 1: # Horizontal alignment of windows @@ -6703,7 +6709,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): separatorPen = wx.GREY_PEN dc.SetPen(separatorPen) - dc.DrawLine(item.GetX()+2, item.GetY()+total_h/2, w, item.GetY()+total_h/2) + dc.DrawLine(item.GetX()+2, item.GetY()+total_h//2, w, item.GetY()+total_h//2) dc.SetPen(oldPen) # restore normal font @@ -6718,7 +6724,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param `dc`: an instance of :class:`DC`; :param integer `level`: the item level in the tree hierarchy; - :param integer `y`: the current vertical position in the :class:`PyScrolledWindow`; + :param integer `y`: the current vertical position in the :class:`ScrolledWindow`; :param integer `align`: an integer specifying the alignment type: =============== ========================================= @@ -6790,9 +6796,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if item.IsSelected(): if (wx.Platform == "__WXMAC__" and self._hasFocus): - colText = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) + colText = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) else: - colText = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) + colText = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) if self._vistaselection: colText = wx.BLACK @@ -6854,8 +6860,8 @@ class CustomTreeCtrl(wx.PyScrolledWindow): image += TreeItemIcon_Selected - TreeItemIcon_Normal image_w, image_h = self._imageListButtons.GetSize(image) - xx = x - image_w/2 - yy = y_mid - image_h/2 + xx = x - image_w//2 + yy = y_mid - image_h//2 dc.SetClippingRegion(xx, yy, image_w, image_h) self._imageListButtons.Draw(image, dc, xx, yy, @@ -6901,7 +6907,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if item == self._underMouse: flag |= _CONTROL_CURRENT - self._drawingfunction(self, dc, wx.Rect(x - wImage/2, y_mid - hImage/2, wImage, hImage), flag) + self._drawingfunction(self, dc, wx.Rect(x - wImage//2, y_mid - hImage//2, wImage, hImage), flag) if item.IsExpanded(): @@ -7017,7 +7023,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if not dc: dc = wx.ClientDC(self) rect = self.GetUpdateRegion().GetBox() - dc.SetClippingRect(rect) + dc.SetClippingRegion(rect) self.TileBackground(dc) @@ -7128,7 +7134,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): event = TreeEvent(wxEVT_TREE_ITEM_MENU, self.GetId()) event._item = self._current # Use the left edge, vertical middle - event._pointDrag = wx.Point(itemRect.GetX(), itemRect.GetY() + itemRect.GetHeight()/2) + event._pointDrag = wx.Point(itemRect.GetX(), itemRect.GetY() + itemRect.GetHeight()//2) event.SetEventObject(self) self.GetEventHandler().ProcessEvent(event) @@ -7421,8 +7427,9 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if self._anchor == None: flags = TREE_HITTEST_NOWHERE return None, flags - - hit, flags = self._anchor.HitTest(self.CalcUnscrolledPosition(point), self, flags, 0) + + point = self.CalcUnscrolledPosition(*point) + hit, flags = self._anchor.HitTest(point, self, flags, 0) if hit == None: flags = TREE_HITTEST_NOWHERE @@ -7489,7 +7496,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if wx.Platform in ["__WXMSW__", "__WXMAC__"]: self.Update() else: - wx.YieldIfNeeded() + wx.SafeYield() if self._editCtrl != None and item != self._editCtrl.item(): self._editCtrl.StopEditing() @@ -7562,7 +7569,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): if not self._anchor: return - pt = self.CalcUnscrolledPosition(event.GetPosition()) + pt = wx.Point(self.CalcUnscrolledPosition(*event.GetPosition())) # Is the mouse over a tree item button? flags = 0 @@ -7600,30 +7607,30 @@ class CustomTreeCtrl(wx.PyScrolledWindow): elif self.HasAGWFlag(TR_TOOLTIP_ON_LONG_ITEMS): - tip = self.GetToolTipString() + tip = self.GetToolTipText() if hoverItem.IsSeparator(): if tip: - self.SetToolTipString('') + self.SetToolTip('') else: maxsize = self.GetItemSize(hoverItem) itemText = hoverItem.GetText() dc = wx.ClientDC(self) - if dc.GetMultiLineTextExtent(itemText)[0] > maxsize: + if dc.GetFullMultiLineTextExtent(itemText)[0] > maxsize: if tip != itemText: - self.SetToolTipString(itemText) + self.SetToolTip(itemText) else: if tip: - self.SetToolTipString('') + self.SetToolTip('') if hoverItem.IsHyperText() and (flags & 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 process left mouse up event (enables in-place edit), right down @@ -7656,7 +7663,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): nevent = TreeEvent(command, self.GetId()) nevent._item = self._current nevent.SetEventObject(self) - newpt = self.CalcScrolledPosition(pt) + newpt = self.CalcScrolledPosition(*pt) nevent.SetPoint(newpt) # by default the dragging is not supported, the user code must @@ -7694,11 +7701,11 @@ class CustomTreeCtrl(wx.PyScrolledWindow): self._dragImage = DragImage(self, self._current) self._dragImage.BeginDrag(wx.Point(0,0), self) self._dragImage.Show() - self._dragImage.Move(self.CalcScrolledPosition(pt)) + self._dragImage.Move(self.CalcScrolledPosition(*pt)) elif event.Dragging() and self._isDragging: - self._dragImage.Move(self.CalcScrolledPosition(pt)) + self._dragImage.Move(self.CalcScrolledPosition(*pt)) if self._countDrag == 0 and item: self._oldItem = item @@ -7739,7 +7746,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # generate the drag end event event = TreeEvent(wxEVT_TREE_END_DRAG, self.GetId()) event._item = item - event._pointDrag = self.CalcScrolledPosition(pt) + event._pointDrag = self.CalcScrolledPosition(*pt) event.SetEventObject(self) self.GetEventHandler().ProcessEvent(event) @@ -7753,7 +7760,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): self.Refresh() else: # Probably this is not enough on GTK. Try a Refresh() if it does not work. - wx.YieldIfNeeded() + wx.SafeYield() else: @@ -7792,7 +7799,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): nevent = TreeEvent(wxEVT_TREE_ITEM_RIGHT_CLICK, self.GetId()) nevent._item = item - nevent._pointDrag = self.CalcScrolledPosition(pt) + nevent._pointDrag = self.CalcScrolledPosition(*pt) nevent.SetEventObject(self) event.Skip(not self.GetEventHandler().ProcessEvent(nevent)) @@ -7800,7 +7807,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # the RIGHT_CLICK event. TODO: This behaviour may change. nevent2 = TreeEvent(wxEVT_TREE_ITEM_MENU, self.GetId()) nevent2._item = item - nevent2._pointDrag = self.CalcScrolledPosition(pt) + nevent2._pointDrag = self.CalcScrolledPosition(*pt) nevent2.SetEventObject(self) self.GetEventHandler().ProcessEvent(nevent2) @@ -7914,7 +7921,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): # send activate event first nevent = TreeEvent(wxEVT_TREE_ITEM_ACTIVATED, self.GetId()) nevent._item = item - nevent._pointDrag = self.CalcScrolledPosition(pt) + nevent._pointDrag = self.CalcScrolledPosition(*pt) nevent.SetEventObject(self) if not self.GetEventHandler().ProcessEvent(nevent): @@ -7995,7 +8002,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): else: dc.SetFont(self._normalFont) - text_w, text_h, dummy = dc.GetMultiLineTextExtent(item.GetText()) + text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(item.GetText()) text_h+=2 # restore normal font @@ -8023,7 +8030,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): 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 = total_h @@ -8060,7 +8067,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param `dc`: an instance of :class:`DC`; :param integer `level`: the item level in the tree hierarchy; - :param integer `y`: the current vertical position inside the :class:`PyScrolledWindow`; + :param integer `y`: the current vertical position inside the :class:`ScrolledWindow`; :param integer `align`: an integer specifying the alignment type: =============== ========================================= @@ -8071,7 +8078,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): 2 Windows (in items with windows) are aligned at the rightmost edge of :class:`CustomTreeCtrl`. =============== ========================================= - :return: The new `y` vertical position inside the :class:`PyScrolledWindow`. + :return: The new `y` vertical position inside the :class:`ScrolledWindow`. """ x = level*self._indent @@ -8087,7 +8094,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): 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, align) # recurse return y @@ -8106,7 +8113,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): 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, align) # recurse return y @@ -8282,7 +8289,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :param `colour`: the colour to be used as the background colour, pass :class:`NullColour` to reset to the default colour. - :return: ``False`` if the underlying :class:`PyScrolledWindow` does not accept + :return: ``False`` if the underlying :class:`ScrolledWindow` does not accept the new colour, ``True`` otherwise. :note: The background colour is usually painted by the default :class:`EraseEvent` @@ -8292,10 +8299,10 @@ class CustomTreeCtrl(wx.PyScrolledWindow): you may wish to call :meth:`Window.ClearBackground` or :meth:`Window.Refresh` after calling this function. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ - if not wx.PyScrolledWindow.SetBackgroundColour(self, colour): + if not wx.ScrolledWindow.SetBackgroundColour(self, colour): return False if self._freezeCount: @@ -8313,13 +8320,13 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :param `colour`: the colour to be used as the foreground colour, pass :class:`NullColour` to reset to the default colour. - :return: ``False`` if the underlying :class:`PyScrolledWindow` does not accept + :return: ``False`` if the underlying :class:`ScrolledWindow` does not accept the new colour, ``True`` otherwise. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ - if not wx.PyScrolledWindow.SetForegroundColour(self, colour): + if not wx.ScrolledWindow.SetForegroundColour(self, colour): return False if self._freezeCount: @@ -8349,7 +8356,7 @@ class CustomTreeCtrl(wx.PyScrolledWindow): :return: An instance of :class:`Size`. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ # something is better than nothing... @@ -8453,11 +8460,67 @@ class CustomTreeCtrl(wx.PyScrolledWindow): """ 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) + +if __name__ == '__main__': + + import wx + + class MyFrame(wx.Frame): + + def __init__(self, parent): + + wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") + + # Create a CustomTreeCtrl instance + custom_tree = CustomTreeCtrl(self, agwStyle=wx.TR_DEFAULT_STYLE) + custom_tree.SetBackgroundColour(wx.WHITE) + + # Add a root node to it + root = custom_tree.AddRoot("The Root Item") + + # Create an image list to add icons next to an item + il = wx.ImageList(16, 16) + fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) + fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) + fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) + + custom_tree.SetImageList(il) + + custom_tree.SetItemImage(root, fldridx, wx.TreeItemIcon_Normal) + custom_tree.SetItemImage(root, fldropenidx, wx.TreeItemIcon_Expanded) + + for x in range(15): + child = custom_tree.AppendItem(root, "Item %d" % x) + custom_tree.SetItemImage(child, fldridx, wx.TreeItemIcon_Normal) + custom_tree.SetItemImage(child, fldropenidx, wx.TreeItemIcon_Expanded) + + for y in range(5): + last = custom_tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y))) + custom_tree.SetItemImage(last, fldridx, wx.TreeItemIcon_Normal) + custom_tree.SetItemImage(last, fldropenidx, wx.TreeItemIcon_Expanded) + + for z in range(5): + item = custom_tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z)) + custom_tree.SetItemImage(item, fileidx, wx.TreeItemIcon_Normal) + + custom_tree.Expand(root) + + + # our normal wxApp-derived class, as usual + + app = wx.App(0) + + frame = MyFrame(None) + app.SetTopWindow(frame) + frame.Show() + + app.MainLoop() + \ No newline at end of file diff --git a/wx/lib/agw/floatspin.py b/wx/lib/agw/floatspin.py index 70fa2dc6..c2233568 100644 --- a/wx/lib/agw/floatspin.py +++ b/wx/lib/agw/floatspin.py @@ -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,9 +367,9 @@ class FloatSpin(wx.PyControl): """ - wx.PyControl.__init__(self, parent, id, pos, size, style|wx.NO_BORDER| - wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN, - wx.DefaultValidator, name) + wx.Control.__init__(self, parent, id, pos, size, style|wx.NO_BORDER| + wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN, + wx.DefaultValidator, name) # Don't call SetRange here, because it will try to modify # self._value whose value doesn't exist yet. @@ -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() + + \ No newline at end of file diff --git a/wx/lib/agw/foldpanelbar.py b/wx/lib/agw/foldpanelbar.py index 42c58cbc..15f93a20 100644 --- a/wx/lib/agw/foldpanelbar.py +++ b/wx/lib/agw/foldpanelbar.py @@ -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() ` 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() + \ No newline at end of file diff --git a/wx/lib/agw/fourwaysplitter.py b/wx/lib/agw/fourwaysplitter.py index b9000bc6..c9e5bf38 100644 --- a/wx/lib/agw/fourwaysplitter.py +++ b/wx/lib/agw/fourwaysplitter.py @@ -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() diff --git a/wx/lib/agw/genericmessagedialog.py b/wx/lib/agw/genericmessagedialog.py index 027f11df..3e23b0ff 100644 --- a/wx/lib/agw/genericmessagedialog.py +++ b/wx/lib/agw/genericmessagedialog.py @@ -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 - provide a keyword parameter to :class:`GenericMessageDialog`. A default maximum - line width might be the wxMac one, at 360 pixels. - + :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() + + \ No newline at end of file diff --git a/wx/lib/agw/hyperlink.py b/wx/lib/agw/hyperlink.py index 511fac65..e14b6988 100644 --- a/wx/lib/agw/hyperlink.py +++ b/wx/lib/agw/hyperlink.py @@ -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() + \ No newline at end of file diff --git a/wx/lib/agw/hypertreelist.py b/wx/lib/agw/hypertreelist.py index eb91545c..198a514b 100644 --- a/wx/lib/agw/hypertreelist.py +++ b/wx/lib/agw/hypertreelist.py @@ -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) @@ -3319,8 +3325,9 @@ class TreeListMainWindow(CustomTreeCtrl): flags = wx.TREE_HITTEST_NOWHERE 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() + + \ No newline at end of file diff --git a/wx/lib/buttons.py b/wx/lib/buttons.py index 1d874374..68e347f5 100644 --- a/wx/lib/buttons.py +++ b/wx/lib/buttons.py @@ -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,18 +202,29 @@ 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 def DoGetBestSize(self): """ - Overridden base class virtual. Determines the best size of the + 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,60 +239,107 @@ 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. + Overridden base class virtual. By default we should use + 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() def ShouldInheritColours(self): """ - Overridden base class virtual. Buttons usually don't inherit + 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 def InitColours(self): """ Calculate a new set of highlight and shadow colours based on - the background colour. Works okay if the colour is dark... + 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=0 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=0 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 diff --git a/wx/lib/wx2to3.py b/wx/lib/wx2to3.py new file mode 100644 index 00000000..bf4637de --- /dev/null +++ b/wx/lib/wx2to3.py @@ -0,0 +1,274 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__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,), {}) +